Setting TrackFilter values dynamically

Hi guys!

I’m using TrackMate from MATLAB script where I’m applying two filters to the tracks…

  1. NUMBER_SPOTS
  2. NUMBER_GAPS

with this code:
filter2 = fiji.plugin.trackmate.features.FeatureFilter(‘NUMBER_SPOTS’, 69.06093189964157, true);
settings.addTrackFilter(filter2);
filter3 = fiji.plugin.trackmate.features.FeatureFilter(‘NUMBER_GAPS’, 2.2636746143057502, false);
settings.addTrackFilter(filter3);

As one can see, those filters require a numerical parameter. Those crazy values I’ve got from processing manually the same dataset using TrackMate/Fiji GUI and clicking in ‘Auto’ button.

My question is: How can I get those values in the code?

A quick search for “auto threshold button in the TrackMate repository led me to these lines in FilterPanel.java:

… suggesting that you can get the automatic threshold value in a similar way using fiji.plugin.trackmate.util.TMUtils, along these lines:

threshold = fiji.plugin.trackmate.util.TMUtils.otsuThreshold( values );

Hi @imagejan, thank you for answer me.

When I posted the question I already knew about that autoThreshold method.
I’ve got stucked on it because to call the otsuThreshold method I have to pass the valuesMap corresponding to the feature I want to apply Otsu, right?
So I dug into the code to see how/where get those values but, so far I couldn’t find where they come from.

I suppose it should be available when I add a TrackFilter to settings, but I was successful on that…

Anyone have any thoughts?

Ok, I found something maybe useful.
I supposed could use the code below.

The problem is the method getTrackFeatureValues() returns NULL. It will return what I want only after I call trackmate.process().

Now, how can I update the model to get those values? I believe there is a way, since the ImageJ GUI cand update the threshold values without process everything.

Here is the code mentioned before:

trackFeatureValues = model.getFeatureModel.getTrackFeatureValues();

featureValues = trackFeatureValues.get('NUMBER_SPOTS');
optimalNumberSpots = fiji.plugin.trackmate.util.TMUtils.otsuThreshold(featureValues)

featureValues = trackFeatureValues.get('NUMBER_GAPS');
optimalNumberGaps = fiji.plugin.trackmate.util.TMUtils.otsuThreshold(featureValues)

% Configure track filters
filter2 = fiji.plugin.trackmate.features.FeatureFilter('NUMBER_SPOTS', optimalNumberSpots, true);
settings.addTrackFilter(filter2);

filter3 = fiji.plugin.trackmate.features.FeatureFilter('NUMBER_GAPS', optimalNumberGaps, false);
settings.addTrackFilter(filter3);

The call of trackmate.process() is in fact a sequence of several steps that can also be accessed separately via the methods of the TrackMate class. See the source code:

I guess, you could first run:

trackmate.execDetection();
trackmate.execInitialSpotFiltering();
trackmate.computeSpotFeatures(false);
trackmate.execSpotFiltering(false);
trackmate.execTracking();
trackmate.computeTrackFeatures(false);

then get the track features and add your FeatureFilters, and finally run:

trackmate.execTrackFiltering(false);
1 Like

Hi again @imagejan, thank you very much!

Five minutes ago I did the same thing you suggested except for the last part.

%% Instantiate the TrackMate only to get the optimla values of the features.
trackmate = fiji.plugin.trackmate.TrackMate(model, settings);
trackmate.setNumThreads(1); 

% Part of trackmate.process(), that will be done later mus to be done now
% to get the optimal values.
trackmate.execDetection();
trackmate.execInitialSpotFiltering();
trackmate.computeSpotFeatures(false);
trackmate.execSpotFiltering(false);
trackmate.execTracking();
trackmate.computeTrackFeatures(false);

%% Process necessary to get optimal values of the features
trackFeatureValues = model.getFeatureModel.getTrackFeatureValues();

featureValues = trackFeatureValues.get('NUMBER_SPOTS');
optimalNumberSpots = fiji.plugin.trackmate.util.TMUtils.otsuThreshold(featureValues);

featureValues = trackFeatureValues.get('NUMBER_GAPS');
optimalNumberGaps = fiji.plugin.trackmate.util.TMUtils.otsuThreshold(featureValues);

% Configure track filters
filter2 = fiji.plugin.trackmate.features.FeatureFilter('NUMBER_SPOTS', optimalNumberSpots, true);
settings.addTrackFilter(filter2);

filter3 = fiji.plugin.trackmate.features.FeatureFilter('NUMBER_GAPS', optimalNumberGaps, false);
settings.addTrackFilter(filter3);

Later I call trackmate.process() to redo everything again.
Ok, this solve my problem but I have some doubts about this and other things I saw in the code:

1- Does TrackMate really calculate all features for all filters even though the used dont want it?
2- Is this the only way to solve my problem? I mean, having to calculate almost everything just to get two values?
3- If I do not set the filter2 and filter3 the trackmate will run normally, since I’m setting the automic values?

PS: I checked the third question. The result will be totally different without those filters.

Thank you @imagejan and all people in the forum…