COS 126 Programming Assignment

The Atomic Nature of Matter

Re-affirm the atomic nature of matter by tracking the motion of particles undergoing Brownian motion, fitting this data to Einstein's model, and estimating Avogadro's number.

Historical perspective. The atom played a central role in 20th century physics and chemistry, but prior to 1908 the reality of atoms and molecules was not universally accepted. In 1827, the botanist Robert Brown observed the random erratic motion of microscopic particles suspended within the vacuoles of pollen grains. This motion would later become known as Brownian motion. Einstein hypothesized that this motion was the result of millions of even smaller particles—atoms and molecules—colliding with the larger particles.

In one of his "miraculous year" (1905) papers, Einstein formulated a quantitative theory of Brownian motion in an attempt to justify the "existence of atoms of definite finite size." His theory provided experimentalists with a method to count molecules with an ordinary microscope by observing their collective effect on a larger immersed particle. In 1908 Jean Baptiste Perrin used the recently invented ultramicroscope to experimentally validate Einstein's kinetic theory of Brownian motion, thereby providing the first direct evidence supporting the atomic nature of matter. His experiment also provided one of the earliest estimates of Avogadro's number. For this work, Perrin won the 1926 Nobel Prize in physics.

The problem. In this assignment, you will redo a version of Perrin's experiment. Your job is greatly simplified because with modern video and computer technology—in conjunction with your programming skills—it is possible to accurately measure and track the motion of an immersed particle undergoing Brownian motion. We supply video microscopy data of polystyrene spheres ("beads") suspended in water, undergoing Brownian motion. Your task is to write a program to analyze this data, determine how much each bead moves between observations, fit this data to Einstein's model, and estimate Avogadro's number.

The data.  We provide 10 datasets, obtained by William Ryu using fluorescent imaging. Each dataset is stored in a subdirectory (named run_1 through run_10) and contains a sequence of two hundred 640-by-480 color images (named frame00000.jpg through frame00199.jpg).

Here is a movie [ avi · mov ] of several beads undergoing Brownian motion. Below is a typical raw image (left) and a cleaned up version (right) using thresholding, as described below.

    frame of polystyrene spheres immersed in water         threshold frame of polystyrene spheres immersed in water

Each image shows a two-dimensional cross section of a microscope slide. The beads move in and out of the microscope's field of view (the x- and y-directions). Beads also move in the z-direction, so they can move in and out of the microscope's depth of focus; this results in halos, and it can also result in beads completely disappearing from the image.

I. Particle identification. The first challenge is to identify the beads amidst the noisy data. Each image is 640-by-480 pixels, and each pixel is represented by a Color object which needs to be converted to a luminance value ranging from 0.0 (black) to 255.0 (white). Whiter pixels correspond to beads (foreground) and blacker pixels to water (background). We break the problem into three pieces: (i) read an image, (ii) classify the pixels as foreground or background, and (iii) find the disc-shaped clumps of foreground pixels that constitute each bead.

II. Particle tracking. The next step is to determine how far a bead moves from one time t to the next time t + Δt. For our data, there are Δt = 0.5 seconds between frames. Assume the data is such that each bead moves a relatively small amount and that beads never collide with one another. (You must, however, account for the possibility that the bead disappears from the frame, either by departing the microscope's field of view in the x- or y- direction, or moving out of the microscope's depth of focus in the z-direction.) Thus, for each bead at time t + Δt, calculate the closest bead at time t (in Euclidean distance) and identify these two as the same bead. However, if the distance is too large—greater than delta pixels—assume that one of the beads has either just begun or ended its journey.

Write a main() method in BeadTracker.java that takes an integer min, a double value tau, a double value delta, and a sequence of image filenames as command-line arguments; identifies the beads (using the specified values for min and tau) in each image (using BeadFinder); and prints the distance that each bead moves from one frame to the next (assuming that distance is no longer than delta). You will do this for beads in each pair of consecutive frames, printing each distance that you discover, one after the other.

% java-introcs BeadTracker 25 180.0 25.0 run_1/*.jpg
 7.1833
 4.7932
 2.1693
 5.5287
 5.4292
 4.3962
...
Note: with this procedure, there is no need to build a data structure that tracks an individual bead through a sequence of frames.

III. Data analysis. Einstein's theory of Brownian motion connects microscopic properties (e.g., radius, diffusivity) of the beads to macroscopic properties (e.g., temperature, viscosity) of the fluid in which the beads are immersed. This amazing theory enables us to estimate Avogadro's number with an ordinary microscope by observing the collective effect of millions of water molecules on the beads.

For the final part, write a main() method in Avogadro.java that reads the radial displacements (r1, r2, r3, ...) from standard input and estimates Boltzmann's constant and Avogadro's number using the formulas described above.

% more displacements-run_1.txt
 7.1833
 4.7932
 2.1693
 5.5287
 5.4292  
 4.3962
...

% java-introcs Avogadro < displacements-run_1.txt
Boltzmann = 1.2535e-23
Avogadro  = 6.6329e+23

% java-introcs BeadTracker 25 180.0 25.0 run_1/*.jpg | java-introcs Avogadro
Boltzmann = 1.2535e-23
Avogadro  = 6.6329e+23

Output format. Use four digits of precision after the decimal point, both in BeadTracker and Avogadro.

Running-time analysis. Formulate a hypothesis for the running time (in seconds) of BeadTracker as a function of the input size n (total number of pixels read in across all frames being processed). Justify your hypothesis in your readme.txt file with empirical data.

Provided files. You can download the datasets and other helper files as atomic.zip (70 MB).

Submission. Submit Blob.java, BeadFinder.java, BeadTracker.java and Avogadro.java. You may assume access to stdlib.jar, Luminance.java, Stack.java, Queue.java, and ST.java. Finally, submit a readme.txt file (or partner readme file) and answer the questions, including the running-time analysis.


This assignment was created by David Botstein, Tamara Broderick, Ed Davisson, Daniel Marlow, William Ryu, and Kevin Wayne.
Copyright © 2005