Scripting TrackMate

Revision as of 02:21, 12 August 2012 by JeanYvesTinevez (talk | contribs) (Fix http links to source after mavenization)


TrackMate scripting principle

TrackMate_ can be used out of the GUI, using a scripting language that allows making calls to Java. The most simple way to get started is to use the Script Editor of Fiji, which takes care of the difficult & boring part for you (such as path). The examples proposed on this page all use Jython, but can be adapted to anything.

Since we are calling the internals of TrackMate, we must get to know a bit of its guts. I have tried to come up with a rational design; though not always successfully. There is 3 main classes to interact with in a script:

  • TrackMateModel (fiji.plugin.trackmate.TrackMateModel) is the class in charge of storing the data. It cannot do anything to create it. It can help you follow manual modifications you would made in the manual editing mode, interrogate it, ... but it is conceptually just a data recipient.
  • Settings (fiji.plugin.trackmate.Settings) is a part of the model. It is a class storing the fields that will configure TrackMate and pilot how the data is created. As you can see, it is mainly make of public fields.
  • TrackMate (fiji.plugin.trackmate.TrackMate_) is the actual Fiji plugin. When called from the Fiji menu, it launches the GUI. In scripts, we use it to actually perform the analysis tasks, such as generating spots from images, linking them into track, etc... It reads configuration information in the Settings object mentioned above and put the resulting data in the model.

So getting a working script is all about configuring a proper Settings object and calling exec* methods on a TrackMate_ object.


A full example

Here is an example of full tracking process, using the easy image found in the first tutorial. The following (Jython) script works as following:

  • It fetches the image from the web
  • It configures settings for segmentation and tracking
  • The model is instantiated, with the settings and imp objects
  • The TrackMate plugin is instantiated with the model object
  • Then the TrackMate object performs all the steps needed.
  • The final results is displayed as an overlay.


import fiji.plugin.trackmate.Settings;
import fiji.plugin.trackmate.TrackMateModel;
import fiji.plugin.trackmate.TrackMate_;
import fiji.plugin.trackmate.Logger;
import fiji.plugin.trackmate.segmentation.DogSegmenter;
import fiji.plugin.trackmate.tracking.SimpleFastLAPTracker;
import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer;

# Get currently selected image
# imp = WindowManager.getCurrentImage()
imp = IJ.openImage('http://fiji.sc/tinevez/TrackMate/FakeTracks.tif')
imp.show()

#------------------------
# Prepare settings object
#------------------------

settings = fiji.plugin.trackmate.Settings(imp)

# Configure segmenter
settings.segmenter = fiji.plugin.trackmate.segmentation.DogSegmenter()
settings.segmenterSettings = fiji.plugin.trackmate.segmentation.LogSegmenterSettings()
settings.segmenterSettings.expectedRadius = 2.5

# Configure tracker
settings.tracker = fiji.plugin.trackmate.tracking.SimpleFastLAPTracker()
settings.trackerSettings = fiji.plugin.trackmate.tracking.LAPTrackerSettings()

print(str(settings))

#-----------------------------
# Instantiate model and plugin
#-----------------------------

model = fiji.plugin.trackmate.TrackMateModel()
model.setSettings(settings)

trackmate = fiji.plugin.trackmate.TrackMate_(model)

#---------------------
# Execute segmentation
#---------------------

print('Segmenting with parameters:')
print(str(settings.segmenter))
print(str(settings.segmenterSettings))

trackmate.execSegmentation()

print(str(model.getSpots()))

#--------------------------
# Execute initial filtering
#--------------------------

model.setInitialSpotFilterValue(3.6)

print('Initial spot filtering with quality above ' + str(model.getInitialSpotFilterValue()))

trackmate.execInitialSpotFiltering()

print(str(model.getSpots()))

#--------------------------
# Execute spot filtering
#--------------------------

filter1 = fiji.plugin.trackmate.FeatureFilter('QUALITY', 20, True)

print('Spot filtering with ' + str(filter1))

model.addSpotFilter(filter1)
trackmate.execSpotFiltering()

print(str(model.getFilteredSpots()))

#-----------------
# Execute tracking
#-----------------

print('Tracking with parameters:')
print(str(settings.tracker))
print(str(settings.trackerSettings))

trackmate.execTracking()

print('Found ' + str(model.getNTracks()) + ' tracks.')

#----------------
# Display results
#----------------

displayer =  fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer()
displayer.setModel(model)
displayer.render()
displayer.refresh()


Loading and reading from a saved TrackMate XML file

Scripting is a good way to interrogate and play non-interactively with tracking results. The example below shows how to load a XML TrackMate file and rebuild a full working model from it.

That way you could for instance redo a full tracking process by only changing one parameter with respect to the saved one. You might also want to check results without relying on the GUI. Etc...

For the example below to work for you, you will have to edit line 12 and put the actual path to your TrackMate file.



import fiji.plugin.trackmate.io.TmXmlReader
import fiji.plugin.trackmate.Logger
import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer
import java.io.File


#----------------
# Setup variables
#----------------

# Put here the path to the TrackMate file you want to load
file = java.io.File('E:/Users/JeanYves/Desktop/Data/FakeTracks.xml')

# We have to feed a logger to the reader.
logger = fiji.plugin.trackmate.Logger.DEFAULT_LOGGER

#-------------------
# Instantiate reader
#-------------------

reader = fiji.plugin.trackmate.io.TmXmlReader(file, logger)

# We have to call 'parse()' before doing anything else. 
# Problems with the file will be detected here.
reader.parse()

#-----------------
# Get a full model
#-----------------

# This will return a fully working model, with everything
# stored in the file. Missing fields (e.g. tracks) will be 
# null or None in python
model = reader.getModel();
# model is a fiji.plugin.trackmate.TrackMateModel

#----------------
# Display results
#----------------

# We can now plainly display the model
displayer =  fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer()
displayer.setModel(model)
displayer.render()
displayer.refresh()

#---------------------------------------------
# Get only part of the data stored in the file
#---------------------------------------------

# You might want to access only separate parts of the 
# model. There are methods for that, but a certain order
# must be respected. For instance if you want the 
# filtered spots:

# You have to load first *all* the spots (can take a long time
# if your file is big):
spots = reader.getAllSpots()
# spots is a fiji.plugin.trackmate.SpotCollection

# Then feed the spot collection to the next method:
filtered_spots = reader.getFilteredSpots(spots)
print('Filtered spots:')
print(str(spots))

# If you want to get the tracks, it is a bit trickier. 
# Internally, the tracks are stored as a huge mathematical
# simple graph, which is what you retrieve from the file. 
# There are methods to rebuild the actual tracks, taking
# into account for everything, but frankly, if you want to 
# do that it is simpler to go through the model shown above.
# Here is how to retrieve the graph, which is actually more
# interesting than just the tracks:

graph = reader.readTrackGraph(filtered_spots)
# graph is a  org.jgrapht.graph.SimpleWeightedGraph
# with generic types: <fiji.plugin.trackmate.Spot, 
# org.jgrapht.graph.DefaultWeightedEdge>

#---------------------------------------
# Building a settings object from a file
#---------------------------------------

# Load the basic settings object
settings = reader.getSettings()
# settings is a fiji.plugin.trackmate.Settings
print(str('Basic settings:'))
print(str(settings))
# Note that the settings object is not initialized with
# stored image, segmentation settings and tracking settings.
# You have to reconstruct it manually by pulling stored 
# fields.

# Load the segmentation settings
reader.getSegmenterSettings(settings)
print('Segmenter settings:')
print(str(settings.segmenterSettings))

# Load the tracker settings
reader.getTrackerSettings(settings)
print('Tracker settings:')
print(str(settings.trackerSettings))

# Calling these 2 extra methods also instantiated 
# ready-to-rock segmenter and tracker, respectively:
print('Segmenter chosen:')
print(str(settings.segmenter))
print('Tracker chosen:')
print(str(settings.tracker))


# Load and display the naked image.
# Note that the XML file only stores a link to the image.
# If the link is not valid, the image will not be found.
imp = reader.getImage()
imp.show()

# We also have to feed it to the settings object:
settings.imp = imp

We did not cover how to retrieve saved filters nor the list of filtered tracks. You will have to rely on the javadoc of the TmXmlReader class for that, and apply what we saw. The only key thing to remember is to call the method doublet

reader = fiji.plugin.trackmate.io.TmXmlReader(file, logger)
reader.parse()

before questing the saved model.


JeanYvesTinevez 17:35, 20 June 2012 (CEST)