Import the package and choose a movie directory to work with.
If you don't have a movie, just give a directory for an example movie. We'll fill it with fake image files below.
from path import path # Used in examples
import runtrackpy
movdir = path('bigtracks-demo-movie').abspath()
print movdir
movdir.makedirs_p()
frames_extension = 'PNG'
frames_pattern = '*.' + frames_extension
If you have your own data and want to try it out, skip this part!
bigtracks
contains a function for making fake images with random particle motion. We'll save a series of them to the movie directory chosen above.
import runtrackpy.test
import scipy.misc
for framenumber in range(20):
x, y, img = runtrackpy.test.fake_image(framenumber)
scipy.misc.imsave(movdir / 'example_%.4i.%s' % (framenumber, frames_extension), img)
print runtrackpy.track.__doc__
OK, let's load a sample frame, set some basic parameters, and try them out.
imgfiles = movdir.glob(frames_pattern)
im = imread(imgfiles[0])
def crop():
pass
# If you wish, set a restricted view here, so you can zoom in on details.
#xlim(0, 240)
#ylim(0, 240)
imshow(im)
gray()
colorbar()
crop()
gcf().set_size_inches(10, 10)
params = dict(bright=1, featsize=5, bphigh=2, threshold=0.5, maxdisp=3 * sqrt(8))
features = runtrackpy.track.identify_frame(im, params)
imshow(im)
plot(features.x, features.y, 'r+', markersize=10)
axis('image')
crop()
We can check things like the quality of subpixel resolution (insufficient statistics in the example dataset)
hist((features.x % 1, features.y % 1));
In order to speed things up, we do only the first 2 frames.
First, we need to clear any existing tracks file. track2disk()
will refuse to overwrite an existing file.
outputfile = movdir / 'bigtracks.h5'
if outputfile.exists():
outputfile.remove()
runtrackpy.track.track2disk(imgfiles, outputfile,
params,
#selectframes=range(1, 3), # To speed things up, we could do just 2 frames
progress=True)
So that the tracks-reading code can be released under a more flexible software license, it is in the pantracks
module.
All read-only access is with BigTracks
objects:
import pantracks
bt = pantracks.BigTracks(movdir / 'bigtracks.h5')
Number of frames in the file
bt.maxframe()
Assuming the file is not too big, it may be easiest to just get the whole thing.
bt.get_all()
However, the database is indexed by frame number and particle ID. This means that requesting data based on one (or both) of these quantities is very efficient, because the computer already knows where to look in the file, and does not have to read the whole thing. Therefore, for larger datasets it makes sense to load single frames as you need them:
ftr = bt.get_frame(1)
print ftr.frame.values[0] # Which frame was this, again?
ftr.head()
Or, if you're in a hurry,
ftr = bt[1]
print ftr.frame.values[0]
You can iterate over all frames in the file thusly:
for fnum in bt.framerange():
ftr = bt.get_frame(fnum)
print fnum, len(ftr)
You can make an arbitrary query to the underlying pytables
database, which may be more efficient than loading all the data and filtering it yourself.
ftr = bt.query('(x < xmax) & (y < ymax)', {'xmax': 100, 'ymax': 100})
ftr.x.max(), ftr.y.max(), ftr.frame.unique()
Finally, the pytables
Table
object is available if you are adventurous, enabling a ton of advanced capabilities. The following is equivalent to calling query_tracks
in the previous example, only now we're asking for certain particles.
import pandas
with bt:
ftr = pandas.DataFrame(bt.table.readWhere('(particle >= 2) & (particle <= 5)'))
ftr.particle.min(), ftr.particle.max(), ftr.frame.unique()
Using the BigTracks
object as a context, as already seen above, means that the file is opened just once, and so it should speed up "batch" operations:
%%timeit
for fnum in range(10):
ftr = bt.get_frame(1)
%%timeit
with bt:
for i in range(10):
ftr = bt.get_frame(1)
In all cases, the file is never left open. This avoids the occurrence of Bad Things if its contents are subsequently changed.
How many of the particles in the first frame make it to the nth frame? bigtracks.read
makes this more convenient. For the example dataset it's pretty boring.
btq = pantracks.bigtracks.compute_quality(bt, frame_interval=1)
btq.head()
The plot shows fluctuations in the number of features identified in each frame, as well as the fraction of particles lost since the first frame.
pantracks.bigtracks.plot_quality(btq)