Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring for Improved Readability and Maintainability #283

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
4 changes: 3 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions src/main/java/fiji/plugin/trackmate/LoadTrackMatePlugIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

public class LoadTrackMatePlugIn extends TrackMatePlugIn
{
private String pluginTitle = TrackMate.PLUGIN_NAME_STR + " v" + TrackMate.PLUGIN_NAME_VERSION;

/**
* Loads a TrackMate file in the GUI.
Expand Down Expand Up @@ -82,13 +83,13 @@ public void run( final String filePath )
file = new File( filePath );
if ( !file.exists() )
{
IJ.error( TrackMate.PLUGIN_NAME_STR + " v" + TrackMate.PLUGIN_NAME_VERSION,
IJ.error( pluginTitle,
"Could not find file with path " + filePath + "." );
return;
}
if ( !file.canRead() )
{
IJ.error( TrackMate.PLUGIN_NAME_STR + " v" + TrackMate.PLUGIN_NAME_VERSION,
IJ.error( pluginTitle,
"Could not read file with path " + filePath + "." );
return;
}
Expand All @@ -98,7 +99,7 @@ public void run( final String filePath )
final TmXmlReader reader = createReader( file );
if ( !reader.isReadingOk() )
{
IJ.error( TrackMate.PLUGIN_NAME_STR + " v" + TrackMate.PLUGIN_NAME_VERSION, reader.getErrorMessage() );
IJ.error( pluginTitle, reader.getErrorMessage() );
return;
}

Expand Down Expand Up @@ -232,7 +233,7 @@ public void run( final String filePath )
}

logger2.log( "File loaded on " + TMUtils.getCurrentTimeString() + '\n', Logger.BLUE_COLOR );
final String welcomeMessage = TrackMate.PLUGIN_NAME_STR + " v" + TrackMate.PLUGIN_NAME_VERSION + '\n';
final String welcomeMessage = pluginTitle + '\n';
// Log GUI processing start
logger2.log( welcomeMessage, Logger.BLUE_COLOR );
logger2.log( "Please note that TrackMate is available through Fiji, and is based on a publication. "
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/fiji/plugin/trackmate/SpotCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public void run()
final double tval = featureFilter.value;
final boolean isAbove = featureFilter.isAbove;

if ( null == val || isAbove && val.compareTo( tval ) < 0 || !isAbove && val.compareTo( tval ) > 0 )
if (isSpotVisible(val, tval, isAbove))
{
shouldNotBeVisible = true;
break;
Expand All @@ -340,6 +340,10 @@ public void run()
}
}

private boolean isSpotVisible(Double val, double tval, boolean isAbove){
return (null == val || isAbove && val.compareTo( tval ) < 0 || !isAbove && val.compareTo( tval ) > 0);
}

/**
* Returns the closest {@link Spot} to the given location (encoded as a
* Spot), contained in the frame <code>frame</code>. If the frame has no
Expand Down
88 changes: 36 additions & 52 deletions src/main/java/fiji/plugin/trackmate/detection/MaskUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,72 +102,56 @@ public static final < T extends RealType< T > > double otsuThreshold( final Rand
return val.getRealDouble();
}

public static final long getThreshold( final Histogram1d< ? > hist )
{
final long[] histogram = hist.toLongArray();
public static final long getThreshold(final Histogram1d<?> histogram) {
final long[] intensityHistogram = histogram.toLongArray();
// Otsu's threshold algorithm
// C++ code by Jordan Bevik <[email protected]>
// ported to ImageJ plugin by G.Landini
int k, kStar; // k = the current threshold; kStar = optimal threshold
final int L = histogram.length; // The total intensity of the image
long N1, N; // N1 = # points with intensity <=k; N = total number of
// points
long Sk; // The total intensity for all histogram points <=k
long S;
double BCV, BCVmax; // The current Between Class Variance and maximum
// BCV
double num, denom; // temporary bookkeeping
int currentThreshold, optimalThreshold; // currentThreshold = the current threshold; optimalThreshold = optimal threshold
final int totalIntensity = intensityHistogram.length; // The total intensity of the image
long pointsBelowThreshold, totalPoints; // pointsBelowThreshold = # points with intensity <= currentThreshold; totalPoints = total number of points
long totalIntensityBelowThreshold; // The total intensity for all histogram points <= currentThreshold
long totalIntensityOverall;
double betweenClassVariance, maxBetweenClassVariance; // The current Between Class Variance and maximum BCV
double numerator, denominator; // temporary bookkeeping

// Initialize values:
S = 0;
N = 0;
for ( k = 0; k < L; k++ )
{
S += k * histogram[ k ]; // Total histogram intensity
N += histogram[ k ]; // Total number of data points
totalIntensityOverall = 0;
totalPoints = 0;
for (currentThreshold = 0; currentThreshold < totalIntensity; currentThreshold++) {
totalIntensityOverall += currentThreshold * intensityHistogram[currentThreshold]; // Total histogram intensity
totalPoints += intensityHistogram[currentThreshold]; // Total number of data points
}

Sk = 0;
N1 = histogram[ 0 ]; // The entry for zero intensity
BCV = 0;
BCVmax = 0;
kStar = 0;
totalIntensityBelowThreshold = 0;
pointsBelowThreshold = intensityHistogram[0]; // The entry for zero intensity
betweenClassVariance = 0;
maxBetweenClassVariance = 0;
optimalThreshold = 0;

// Look at each possible threshold value,
// calculate the between-class variance, and decide if it's a max
for ( k = 1; k < L - 1; k++ )
{ // No need to check endpoints k = 0 or k = L-1
Sk += k * histogram[ k ];
N1 += histogram[ k ];

// The float casting here is to avoid compiler warning about loss of
// precision and
// will prevent overflow in the case of large saturated images
denom = ( double ) ( N1 ) * ( N - N1 ); // Maximum value of denom is
// (N^2)/4 =
// approx. 3E10

if ( denom != 0 )
{
// Float here is to avoid loss of precision when dividing
num = ( ( double ) N1 / N ) * S - Sk; // Maximum value of num =
// 255*N =
// approx 8E7
BCV = ( num * num ) / denom;
for (currentThreshold = 1; currentThreshold < totalIntensity - 1; currentThreshold++) {
totalIntensityBelowThreshold += currentThreshold * intensityHistogram[currentThreshold];
pointsBelowThreshold += intensityHistogram[currentThreshold];

denominator = (double) (pointsBelowThreshold) * (totalPoints - pointsBelowThreshold);

if (denominator != 0) {
numerator = ((double) pointsBelowThreshold / totalPoints) * totalIntensityOverall - totalIntensityBelowThreshold;
betweenClassVariance = (numerator * numerator) / denominator;
} else {
betweenClassVariance = 0;
}
else
BCV = 0;

if ( BCV >= BCVmax )
{ // Assign the best threshold found so far
BCVmax = BCV;
kStar = k;
if (betweenClassVariance >= maxBetweenClassVariance) {
maxBetweenClassVariance = betweenClassVariance;
optimalThreshold = currentThreshold;
}
}
// kStar += 1; // Use QTI convention that intensity -> 1 if intensity >=
// k
// (the algorithm was developed for I-> 1 if I <= k.)
return kStar;
// optimalThreshold += 1; // Use QTI convention that intensity -> 1 if intensity >= optimalThreshold
// (the algorithm was developed for I-> 1 if I <= optimalThreshold.)
return optimalThreshold;
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/fiji/plugin/trackmate/features/Defaults.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fiji.plugin.trackmate.features;

import fiji.plugin.trackmate.Model;
import fiji.plugin.trackmate.Settings;
import fiji.plugin.trackmate.gui.displaysettings.DisplaySettings;

import java.util.*;

public class Defaults extends FeatureUtils {
private static final String USE_UNIFORM_COLOR_NAME = "Uniform color";
private static final String USE_RANDOM_COLOR_NAME = "Random color";

public Map<String, String> collectFeatureKeys(DisplaySettings.TrackMateObject target, Model model, Settings settings) {
final Map<String, String> inverseMap = new HashMap<>();
inverseMap.put(USE_UNIFORM_COLOR_NAME, USE_UNIFORM_COLOR_KEY);
inverseMap.put(USE_RANDOM_COLOR_NAME, USE_RANDOM_COLOR_KEY);

// Sort by feature name.
final List<String> featureNameList = new ArrayList<>(inverseMap.keySet());
featureNameList.sort(null);

final Map<String, String> featureNames = new LinkedHashMap<>(featureNameList.size());
for (final String featureName : featureNameList)
featureNames.put(inverseMap.get(featureName), featureName);

return featureNames;
}
}
34 changes: 34 additions & 0 deletions src/main/java/fiji/plugin/trackmate/features/Edges.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package fiji.plugin.trackmate.features;

import fiji.plugin.trackmate.Model;
import fiji.plugin.trackmate.Settings;
import fiji.plugin.trackmate.features.edges.EdgeAnalyzer;
import fiji.plugin.trackmate.gui.displaysettings.DisplaySettings;

import java.util.*;

public class Edges extends FeatureUtils {


public Map<String, String> collectFeatureKeys(DisplaySettings.TrackMateObject target, Model model, Settings settings) {
final Map<String, String> inverseMap = new HashMap<>();
if (model != null) {
for (final String featureKey : model.getFeatureModel().getEdgeFeatureNames().keySet())
inverseMap.put(model.getFeatureModel().getEdgeFeatureNames().get(featureKey), featureKey);
}
if (settings != null) {
for (final EdgeAnalyzer ea : settings.getEdgeAnalyzers())
for (final String featureKey : ea.getFeatureNames().keySet())
inverseMap.put(ea.getFeatureNames().get(featureKey), featureKey);
}
// Sort by feature name.
final List<String> featureNameList = new ArrayList<>(inverseMap.keySet());
featureNameList.sort(null);

final Map<String, String> featureNames = new LinkedHashMap<>(featureNameList.size());
for (final String featureName : featureNameList)
featureNames.put(inverseMap.get(featureName), featureName);

return featureNames;
}
}
Loading