Calculating track features in TrackMate script

fiji
trackmate
#1

Hi,

I’m trying setup Trackmate to link at set of RoIs that have come out some segmentation code (rather than using TackMate’s spot detector). I’m having trouble calculating Trajectory features though. The script is attached at the end of the post.

Setting up the model

Following to the “Manually creating a model” example I store the coordinates in a spot collection and store them in the model object.

After setting up the model I call trackmate.execTracking() to link the spots into trajectories and the viewer and so forth work nicely.

Calculating trajectory features

I would like to calculate some more trajectory features. So I’ve added TrackDurationAnalyzer to the settings object in addition the the TrackIndexAnalyzer.

However when this runs there’s console exceptions when I call trackmate.computeTrackFeatures:

Exception in thread "TrackDurationAnalyzer thread 0" Exception in thread "TrackDurationAnalyzer thread 2" java.lang.NullPointerException
	at fiji.plugin.trackmate.features.track.TrackDurationAnalyzer$1.run(TrackDurationAnalyzer.java:121)
java.lang.NullPointerException
	at fiji.plugin.trackmate.features.track.TrackDurationAnalyzer$1.run(TrackDurationAnalyzer.java:121)
Exception in thread "TrackDurationAnalyzer thread 1" java.lang.NullPointerException
	at fiji.plugin.trackmate.features.track.TrackDurationAnalyzer$1.run(TrackDurationAnalyzer.java:121)

Not surprisingly, when I access the trajectory features they are Null.

What is way to set up the spots collection in the model so that the Trajectory analysers work?

Cheers,

Chris

from __future__ import print_function
from ij import IJ, ImagePlus, WindowManager
from ij.plugin.frame import RoiManager
import sys 

from fiji.plugin.trackmate import Model
from fiji.plugin.trackmate import Settings
from fiji.plugin.trackmate import TrackMate

# Create an empty model
model = Model()
import fiji.plugin.trackmate.Logger as Logger
model.setLogger(Logger.IJ_LOGGER)

settings = Settings()

frameGap=2
linkingMax=20.
closingMax=5.
from fiji.plugin.trackmate.tracking.sparselap import SparseLAPTrackerFactory
from fiji.plugin.trackmate.tracking import LAPUtils
settings.trackerFactory = SparseLAPTrackerFactory()
settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap()
settings.trackerSettings['MAX_FRAME_GAP']  = frameGap
settings.trackerSettings['LINKING_MAX_DISTANCE']  = linkingMax
settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE']  = closingMax

import fiji.plugin.trackmate.features.track.TrackIndexAnalyzer as TrackIndexAnalyzer
settings.addTrackAnalyzer( TrackIndexAnalyzer() )

import fiji.plugin.trackmate.features.track.TrackDurationAnalyzer as TrackDurationAnalyzer
settings.addTrackAnalyzer( TrackDurationAnalyzer() )
#import fiji.plugin.trackmate.features.track.TrackSpeedStatisticsAnalyzer as TrackSpeedStatisticsAnalyzer
#settings.addTrackAnalyzer(TrackSpeedStatisticsAnalyzer())

import fiji.plugin.trackmate.features.ModelFeatureUpdater as ModelFeatureUpdater
ModelFeatureUpdater( model, settings )

# add some spots by hand
from fiji.plugin.trackmate import SpotCollection,Spot
from math import pi,cos,sin

# add the spots to the collection
spots = SpotCollection()
for t in range(120):
	for i in range(3):
		spots.add(Spot((6+i)*100*cos(2*pi*(t+i*10)/400 )+2000, (6+i)*100*sin(2*pi*(t+i*10)/400)+2000,0.,10.,1.),t)

# put the spot collection in the model
model.beginUpdate() 		
model.setSpots(spots,True)
model.endUpdate()

trackmate = TrackMate(model, settings)
ok = trackmate.execTracking() 
#ok = trackmate.process()
print(ok,'TrackMate completed successfully.' )
print(str(trackmate.getErrorMessage()))
print( 'Found %d spots in %d tracks.' % ( model.getSpots().getNSpots( True ) , model.getTrackModel().nTracks( True ) ) )

trackmate.computeTrackFeatures(False)
sdfkl

from fiji.plugin.trackmate.features import TrackFeatureCalculator
tf = TrackFeatureCalculator( model, settings) 
ok = tf.checkInput()
if( ok ):
	print( "inout OK")
else:
	print(str(trackmate.getErrorMessage()))
tf.process()


if( False ):
	trackmate.computeTrackFeatures(False)
	from fiji.plugin.trackmate.features import TrackFeatureCalculator
	tf = TrackFeatureCalculator( model, settings) 
	ok = tf.process()
	tf.computeTrackFeatures( model.getTrackModel().trackIDs(True),True)
	print("track process ",ok)
	
	
	#trackmate.execAnalysis()
	# The feature model, that stores edge and track features.
	fm = model.getFeatureModel()
	analyzer = TrackDurationAnalyzer()
	analyzer.process( model.getTrackModel().trackIDs( True ), model );
	print("Speed",model.getFeatureModel().getTrackFeature( 0, TrackDurationAnalyzer.TRACK_DURATION ))



trackmate.computeTrackFeatures(True);
fm = model.getFeatureModel()

#trackFeatureValues = fm.getTrackFeatureValues();
#featureValues = trackFeatureValues.get('NUMBER_SPOTS');
#print(featureValues)

outputTrack=True
if( outputTrack ):
	for id in model.getTrackModel().trackIDs(True):
		print(id)
		track = model.getTrackModel().trackSpots(id)
		print(i,fm.getTrackFeature(id, 'TRACK_DURATION'))


from fiji.plugin.trackmate import SelectionModel
import fiji.plugin.trackmate.visualization.PerTrackFeatureColorGenerator as PerTrackFeatureColorGenerator
sm = SelectionModel(model)
color = PerTrackFeatureColorGenerator(model, 'TRACK_MEAN_SPEED')


# The TrackScheme view is a bit hard to interpret.
if( False):
	import fiji.plugin.trackmate.visualization.trackscheme.TrackScheme as TrackScheme
	trackscheme = TrackScheme(model, sm)
	trackscheme.setDisplaySettings('TrackColoring', color)
	trackscheme.render()

# You can create an hyperstack viewer without specifying any ImagePlus.
# It will then create a dummy one tuned to display the model content.
import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer as HyperStackDisplayer
view = HyperStackDisplayer(model, sm)
# Display tracks as comets
view.setDisplaySettings('TrackDisplaymode', 1)
view.setDisplaySettings('TrackDisplayDepth', 20)
view.setDisplaySettings('TrackColoring', color)
view.render()
0 Likes

#2

Ok it is tough to see the problem.
Could you clean up the script to remove anything unnecessary?
I see that there are some dangling uncalled function and random strings.

0 Likes

#3

Hi,

sorry about that, there was a random typo in there. I’ve cut down the script the bit and commented it some more.

It should show the stack analyser with three circular trajectories that are grey because the TRACK_DURATION is is Null. I trying to work out how to get the TRACK_DURATION and other track features to be calculated.

I’m not sure if I need the TrackFeatureCalculator or not so maybe ignore that part.

Cheers,

Chris

from __future__ import print_function
from ij import IJ, ImagePlus, WindowManager

from fiji.plugin.trackmate import Model
from fiji.plugin.trackmate import Settings
from fiji.plugin.trackmate import TrackMate

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Create an empty model
model = Model()
import fiji.plugin.trackmate.Logger as Logger
model.setLogger(Logger.IJ_LOGGER)

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Create settings
settings = Settings()

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# -	-	Setup the tracking
frameGap=2
linkingMax=20.
closingMax=5.
from fiji.plugin.trackmate.tracking.sparselap import SparseLAPTrackerFactory
from fiji.plugin.trackmate.tracking import LAPUtils
settings.trackerFactory = SparseLAPTrackerFactory()
settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap()
settings.trackerSettings['MAX_FRAME_GAP']  = frameGap
settings.trackerSettings['LINKING_MAX_DISTANCE']  = linkingMax
settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE']  = closingMax

# - - Add track analyzers
import fiji.plugin.trackmate.features.track.TrackIndexAnalyzer as TrackIndexAnalyzer
settings.addTrackAnalyzer( TrackIndexAnalyzer() )

import fiji.plugin.trackmate.features.track.TrackDurationAnalyzer as TrackDurationAnalyzer
settings.addTrackAnalyzer( TrackDurationAnalyzer() )


# Add modefl feature (not sure of this is needed)
import fiji.plugin.trackmate.features.ModelFeatureUpdater as ModelFeatureUpdater
ModelFeatureUpdater( model, settings )


# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# add some spots by hand
from fiji.plugin.trackmate import SpotCollection,Spot
from math import pi,cos,sin

# add the spots to the collection
spots = SpotCollection()
for t in range(120):
	for i in range(3):
		spots.add(Spot((6+i)*100*cos(2*pi*(t+i*10)/400 )+2000, (6+i)*100*sin(2*pi*(t+i*10)/400)+2000,0.,10.,1.),t)

# put the spot collection in the model
model.beginUpdate() 		
model.setSpots(spots,True)
model.endUpdate()

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
trackmate = TrackMate(model, settings)
ok = trackmate.execTracking() 
if( ok ):
	print('TrackMate completed successfully.' )
else:
	print(str(trackmate.getErrorMessage()))
print( 'Found %d spots in %d tracks.' % ( model.getSpots().getNSpots( True ) , model.getTrackModel().nTracks( True ) ) )

trackmate.computeTrackFeatures(False)

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
#  Feature calculator (not sure if this needed
from fiji.plugin.trackmate.features import TrackFeatureCalculator
tf = TrackFeatureCalculator( model, settings) 
ok = tf.checkInput()
if( ok ):
	print( "input OK")
else:
	print(str(trackmate.getErrorMessage()))
tf.process()
fm = model.getFeatureModel()


# Look to see if the duration is there
outputTrack=True
if( outputTrack ):
	for id in model.getTrackModel().trackIDs(True):
		dtrack = model.getTrackModel().trackSpots(id)
		print(id,fm.getTrackFeature(id, 'TRACK_DURATION'))

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Color the trajectories
from fiji.plugin.trackmate import SelectionModel
import fiji.plugin.trackmate.visualization.PerTrackFeatureColorGenerator as PerTrackFeatureColorGenerator
sm = SelectionModel(model)
#color = PerTrackFeatureColorGenerator(model, 'TRACK_INDEX')
color = PerTrackFeatureColorGenerator(model, 'TRACK_DURATION')


# You can create an hyperstack viewer without specifying any ImagePlus.
# It will then create a dummy one tuned to display the model content.
import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer as HyperStackDisplayer
view = HyperStackDisplayer(model, sm)
# Display tracks as comets
view.setDisplaySettings('TrackDisplaymode', 1)
view.setDisplaySettings('TrackDisplayDepth', 20)
view.setDisplaySettings('TrackColoring', color)
view.render()
0 Likes

#4

Ok found it.

The TrackDurationAnalyzer relies on a spot feature called POSITION_T to measure the time difference.

When you created the spots, you did not set this value, and the duration could be calculated. I slightly modified your script to do so, and also added the call to compute all features if you ever add some. Tell me if it works for you.
Best

from __future__ import print_function
from ij import IJ, ImagePlus, WindowManager

from fiji.plugin.trackmate import Model
from fiji.plugin.trackmate import Settings
from fiji.plugin.trackmate import TrackMate

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Create an empty model
model = Model()
import fiji.plugin.trackmate.Logger as Logger
model.setLogger(Logger.IJ_LOGGER)

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Create settings
settings = Settings()

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# -	-	Setup the tracking
frameGap=2
linkingMax=20.
closingMax=5.
from fiji.plugin.trackmate.tracking.sparselap import SparseLAPTrackerFactory
from fiji.plugin.trackmate.tracking import LAPUtils
settings.trackerFactory = SparseLAPTrackerFactory()
settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap()
settings.trackerSettings['MAX_FRAME_GAP']  = frameGap
settings.trackerSettings['LINKING_MAX_DISTANCE']  = linkingMax
settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE']  = closingMax

# - - Add track analyzers
import fiji.plugin.trackmate.features.track.TrackIndexAnalyzer as TrackIndexAnalyzer
settings.addTrackAnalyzer( TrackIndexAnalyzer() )

import fiji.plugin.trackmate.features.track.TrackDurationAnalyzer as TrackDurationAnalyzer
settings.addTrackAnalyzer( TrackDurationAnalyzer() )

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# add some spots by hand
from fiji.plugin.trackmate import SpotCollection,Spot
from math import pi,cos,sin

# add the spots to the collection
spots = SpotCollection()
for t in range(120):
	for i in range(3):
		spot = Spot( (6+i)*100*cos(2*pi*(t+i*10)/400 )+2000, (6+i)*100*sin(2*pi*(t+i*10)/400)+2000,0.,10.,1.)
		spot.putFeature( 'POSITION_T', t )
		spots.add( spot ,t )

# put the spot collection in the model
model.beginUpdate() 		
model.setSpots(spots,True)
model.endUpdate()

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
trackmate = TrackMate(model, settings)
ok = trackmate.execTracking() 
if( ok ):
	print('TrackMate completed successfully.' )
else:
	print(str(trackmate.getErrorMessage()))
print( 'Found %d spots in %d tracks.' % ( model.getSpots().getNSpots( True ) , model.getTrackModel().nTracks( True ) ) )

trackmate.computeSpotFeatures(False)
trackmate.computeEdgeFeatures(False)
trackmate.computeTrackFeatures(False)

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
#  Feature calculator (not sure if this needed
from fiji.plugin.trackmate.features import TrackFeatureCalculator
tf = TrackFeatureCalculator( model, settings) 
ok = tf.checkInput()
if( ok ):
	print( "input OK")
else:
	print(str(trackmate.getErrorMessage()))
tf.process()
fm = model.getFeatureModel()


# Look to see if the duration is there
outputTrack=True
if( outputTrack ):
	for id in model.getTrackModel().trackIDs(True):
		dtrack = model.getTrackModel().trackSpots(id)
		print(id,fm.getTrackFeature(id, 'TRACK_DURATION'))

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Color the trajectories
from fiji.plugin.trackmate import SelectionModel
import fiji.plugin.trackmate.visualization.PerTrackFeatureColorGenerator as PerTrackFeatureColorGenerator
sm = SelectionModel(model)
#color = PerTrackFeatureColorGenerator(model, 'TRACK_INDEX')
color = PerTrackFeatureColorGenerator(model, 'TRACK_DURATION')


# You can create an hyperstack viewer without specifying any ImagePlus.
# It will then create a dummy one tuned to display the model content.
import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer as HyperStackDisplayer
view = HyperStackDisplayer(model, sm)
# Display tracks as comets
view.setDisplaySettings('TrackDisplaymode', 1)
view.setDisplaySettings('TrackDisplayDepth', 20)
view.setDisplaySettings('TrackColoring', color)
view.render()
2 Likes