Archive for June, 2012

Tap density setup

As promised, here is a description of the tap density apparatus. Below is a Sketchup of the final rendition of the apparatus. It uses two optical posts and post holders from Thorlabs as the piston and guide respectively. The two posts are fixed together by a baseplate spacer. The baseplate is screwed into the post holders using the post holder’s thumb screws. I removed the inner tightening screw of the thumbscrew to allow for better ventilation of air when the column is tapped. The graduated column is held onto the post holder with a few hose clamps. The hose clamps are then connected to each other using PCB spacers.

Below is a complete bill of materials.

Personally, I wouldn’t use Fisher brand glassware as I’m typically rough with glass and Fisher products have a difficult time standing up to my abuse. Below are pictures of the setup.

The above picture shows the actual setup. The system is clamped down to the table using a C-clamp to enhance stability. Behind the cylinder in the background is a plastic square holding up a white sheet of paper. This is used to create a shadow of the cylinder as seen below. The shadow is generated by using the light source from a surplus-ed carousel slide projector which, I found out just now that you can still purchase on Amazon. Neat!

This shadow is imaged by a camera directly behind the screen.

The camera being used is a Logitech C910 camera. We are using GTK+ UVC Viewer—also known as guvcview—as the software to capture images. Unfortunately there have been problems in obtaining images and we have yet to determine a unified collection mechanism. But, guvcview is open source and is filling the bill for the moment.

I have been sorely wanting an optical table to conduct these experiments on. Especially since there is no means for us to keep things in one place other than to tape things down and there is no way for us to adjust things easily when we need to. This is just one of those things. If anyone out there wants to donate an optical table to me, please feel free to contact me through WordPress.

Taps are done with a spacer that is 0.5″ in height. The cylinder is placed on the spacer and then the spacer is removed, and…the harsh mistress known as gravity does her magic.

We have two separate scripts that analyze the data. One that Damian wrote in Python, and one that I wrote in Octave. I may incorporate the two so that we have a gui that can be used cross platform for future endeavors in the Smyth Lab. I’ll have to talk to Damian about that.

3 Comments

Lesson in python and keeping my mouth shut

I was asked to write a factorial function—on the spot in a pressurized situation—as a challenge and guess what, I couldn’t do it. This is a simple thing to do and it unfortunately took me a bit of time away from the pressure to accomplish it. I’ve never been asked to replicate a function that someone already wrote a library for. As such, I was caught way off guard and unfortunately got crazy defensive saying things like “I would never do something like that, it already exists”. Double wrong thing to say. This is undoubtably a side effect of me being a novice. I will make no claims to being a proficient programmer…yet. You better believe that is going to change. Unfortunately I failed miserably and in such a spectacular manner that it was comical.

At the time, I didn’t know about some simple tools that probably everyone on the planet that knows how to (or took classes to learn how to) program already knows about. I knew about the += command that adds the item from a loop in python but, I didn’t know that there was an analog *=. Turns out, there is and I made a complete ass of myself for not knowing about it. Lesson learned—I need to start doing programming homework problems I can find online. Nonetheless, here is my first attempt at the function. I’m writing this mainly because it is cathartic to write and I need to own my mistake.


def fact(n):
result = 1
for item in n:
result *= item
return result

Of course, there are other things to add to the definition above such as checks to ensure that the list n is what you are expecting it to be. If it is a single number, then that needs to be handled.


def fact(n):
 result = 1
 if type(n) != list:
 result = n
 elif type(n) == list:
 for item in n:
 result *= item
 return result

If the input is 0, then that has to be handled as well.


def fact(n):
 result = 1
 if n == 0 or 0.:
 result = 1
 elif type(n) != list:
 result = n
 elif type(n) == list:
 for item in n:
 result *= item
 return result

And finally if a zero occurs in the list, one has to handle that. I did it by filtering them out.


def fact(n):
 result = 1
 if n == 0 or 0.:
 result = 1
 elif type(n) != list:
 result = n
 elif type(n) == list:
 temp = [ item for item in n if item > 0 ]
 for item in temp:
 result *= item
 return result

While this works, it is too little too late for my pressurized situation. I need to just keep practicing. I’m sure there are more elegant and easier ways to do what I did above but, it is the first thing I got to work properly.

hahaha

I’m still an idiot as the above code is completely wrong. Not for what it does, but because it is not a factorial. Oh well, still lessons learning. I’m happy to wear this mistake like a badge of honor. At any rate, this is correct.


def fact(n):
 result = 1
 if type(n) != int:
 print 'Error, fact takes an integer.'
 nList = [ x for x in range(1,n+1) ]
 if n == 0:
 result = 1
 for item in nList:
 result *= item
 return result

Leave a comment

Measuring tap densities

We have devised an apparatus that allows visualization of powder compactions for individual taps. The device has been in a state of constant flux as we try to iron out the bugs in the system and I will update my notebook with a description of the build soon. Up till now, most of our time has been building the device and making sure it works properly. Recently we were able to get data and both Damian and I have been working on building a script that programmatically calculates the distance powder compacts with each tap. While Damian and I are working on the same thing, his approach is very different and I must admit, I’m intrigued by his logic. Hopefully our scripts will output the same thing because if they don’t, we will have to debug things.

Below is a script that I have written in Octave. It should function fine in MatLab as well.


% Generate a list containing the names of the files to be analyzed.
fileDirectory = 'PATH/TO/DIRECTORY/';
filePattern = fullfile(fileDirectory, '*.png');
dataFiles = dir(filePattern);
baseFileName = {dataFiles.name}';
fullFileName = strcat(fileDirectory, '/', baseFileName);

plotDirectory = 'PATH/TO/PUT/PLOTS';
pixels = 56;
cutoffValue = 14000;
lactose = 'pharmatose125M';
sizeRange = '--63-150um';
trial = '--trial01';

saveName = strcat(lactose, sizeRange, trial);
plotTitle = saveName;

% Open the image file and obtain the roi.
for j = 1:numel(fullFileName)
 x = [ 0:1:250 ];
 image = imread(sprintf('%s', fullFileName{j}));
 roi = image(130:255, 225:475);
 [ m n ] = size(roi);
 for i = 1:n
 pixelSum(i) = sum(roi(:,i));
 endfor
 cutoff = [ x; pixelSum ]';
 ind = find(cutoff(:,2) >= cutoffValue);
 tap(j) = ind(1)*(1.27/pixels);
 tapY(j) = cutoff(ind(1), 2);
 X = x*(1.27/pixels);
 figure(j);
 subplot(2,1,1);
 imshow(image);
 subplot(2,1,2);
 hold on;
 plot(X, pixelSum, 'LineWidth', 1.2, 'b');
 plot(tap(j), tapY(j), 'ks', 'markersize', 10)
 xlabel('Distance (cm)');
 ylabel('Intensity (arb. units)');
 axis([0, 6, 8000, 26000])
 title(strcat(plotTitle, sprintf('--%04d.png', j)));
 legend('Pixel intensity values.', 'Point where the end of the shadow is defined.');
 set (gca, "xminortick", "on", "yminortick", "off")
 print(strcat(plotDirectory, strcat(saveName, sprintf('--%04d.png', j))))
 hold off;
 delete(j);
endfor

figure();
plot(X(1:201), tap, 'b.');
title(strcat(lactose, '--', sizeRange, '--', trial, '--Tapped density'));
xlabel('Number of taps')
ylabel('Distance (cm)')

The script will open .png files in the specified directory. The raw data looks like the figure below.

There is a ruler—top vertical bar—that is used to determine pixel sizes in the analysis. The ruler let us know that for (this set of images) 56 pixels equaled 1.27cm. Obviously the image is on its side and gravity is pointing to the left. This statement will become obvious in a later post. Nonetheless, these are what the raw image files look like.

Processing the images entails selecting a region of interest (ROI), summing all the pixel values (column-wise) in the ROI, and selecting the pixel value along the horizontal direction in the raw image where the summed pixel intensity is above some threshold. I have made the script output each plot which, increases the computation cost but I think is essential to ensuring the final output graph is okay or not. The intermediate processed graph looks like the image below.

Where I have ensured that the original image is attached to the pixel intensity graph for clarity. Just for fun, and to see if WordPress would allow me to do it, I have made an animated gif that shows the complete run of taps we performed. In order to visualize it, you need to click on the image and it will run in a new browser window—tested on Chrome.

Ultimately we are interested in compaction versus taps and the above script does give that output. There is still some massaging to be done with the script and the outputs of the graphs. I think I will want to do some analysis in qtiplot as well so the output will need to save the data appropriately. Nonetheless, here is the final graph that I was initially interested in producing.

Thanks again everyone for their help, suggestions, data taking and time working on this.

open notebook science logo

Leave a comment

Tap densities

First, I’d like to thank all the students for transitioning to WordPress. From what I can tell, OpenWetWare is not being developed any more and from my standpoint, should not be used. I will have to figure out a way to move notebook entries written there to WordPress for both me and Sarah.

Tumblr is a great blog type service and there is nothing wrong with it. I just felt that we should all be on the same page when it comes to notebook. Plus, WordPress will email when a notebook entry has been made. This is ideal for me and anyone that is working on multiple projects and wants to stay connected with the people updating things.

Thanks again everyone!

5 Comments