Skip to content

Commit

Permalink
Added basic motility plotting
Browse files Browse the repository at this point in the history
  • Loading branch information
sjcross committed Jun 6, 2024
1 parent 9f8a1f6 commit 84192b7
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import fiji.plugin.trackmate.tracking.SpotTracker;
import fiji.plugin.trackmate.util.Threads;
import io.github.mianalysis.mia.MIA;
import io.github.mianalysis.mia.module.Module;
import io.github.mianalysis.mia.object.Objs;
import io.github.mianalysis.mia.object.coordinates.volume.Volume;
import net.imglib2.algorithm.MultiThreadedBenchmarkAlgorithm;
Expand Down Expand Up @@ -73,7 +74,8 @@ public class OverlapTracker3D extends MultiThreadedBenchmarkAlgorithm implements
* CONSTRUCTOR
*/

public OverlapTracker3D(final SpotCollection spots, final Objs objs, final double minIoU, final boolean allowTrackSplitting, final boolean allowTrackMerging) {
public OverlapTracker3D(final SpotCollection spots, final Objs objs, final double minIoU,
final boolean allowTrackSplitting, final boolean allowTrackMerging) {
this.spots = spots;
this.objs = objs;
this.minIoU = minIoU;
Expand Down Expand Up @@ -150,6 +152,7 @@ public boolean process() {

logger.setStatus("Frame to frame linking...");
int progress = 0;
int count = 0;
while (frameIterator.hasNext()) {
if (!ok.get() || isCanceled())
break;
Expand Down Expand Up @@ -205,6 +208,9 @@ public boolean process() {

sourceGeometries = targetGeometries;
logger.setProgress((double) progress++ / spots.keySet().size());

Module.writeProgressStatus(++count,spots.keySet().size(),"frames","Overlap tracker 3D");

}

logger.setProgress(1d);
Expand Down Expand Up @@ -266,7 +272,7 @@ private static final class FindBestSourcesTask implements Callable<ArrayList<IoU
private final boolean allowTrackMerging;

public FindBestSourcesTask(final Spot target, final Volume targetVolume,
final Map<Spot, Volume> sourceGeometries, final double minIoU,
final Map<Spot, Volume> sourceGeometries, final double minIoU,
final boolean allowTrackMerging) {
this.target = target;
this.targetVolume = targetVolume;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import io.github.mianalysis.mia.object.parameters.SeparatorP;
import io.github.mianalysis.mia.object.parameters.text.DoubleP;
import io.github.mianalysis.mia.process.ColourFactory;
import java_cup.parse_reduce_row;

public abstract class AbstractOverlay extends Module {
public static final String COLOUR_SEPARATOR = "Overlay colour";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
package io.github.mianalysis.mia.module.visualise.plots;

import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;

import org.scijava.Priority;
import org.scijava.plugin.Plugin;

import com.google.common.primitives.Doubles;

import ij.gui.Plot;
import io.github.mianalysis.mia.module.Categories;
import io.github.mianalysis.mia.module.Category;
import io.github.mianalysis.mia.module.Module;
import io.github.mianalysis.mia.module.Modules;
import io.github.mianalysis.mia.module.visualise.overlays.AbstractOverlay;
import io.github.mianalysis.mia.object.Obj;
import io.github.mianalysis.mia.object.Objs;
import io.github.mianalysis.mia.object.Workspace;
import io.github.mianalysis.mia.object.image.Image;
import io.github.mianalysis.mia.object.image.ImageFactory;
import io.github.mianalysis.mia.object.parameters.ChoiceP;
import io.github.mianalysis.mia.object.parameters.ObjectMeasurementP;
import io.github.mianalysis.mia.object.parameters.ObjectMetadataP;
import io.github.mianalysis.mia.object.parameters.Parameters;
import io.github.mianalysis.mia.object.parameters.ParentObjectsP;
import io.github.mianalysis.mia.object.parameters.PartnerObjectsP;
import io.github.mianalysis.mia.object.parameters.ChildObjectsP;
import io.github.mianalysis.mia.object.parameters.InputObjectsP;
import io.github.mianalysis.mia.object.parameters.OutputImageP;
import io.github.mianalysis.mia.object.parameters.SeparatorP;
import io.github.mianalysis.mia.object.parameters.text.DoubleP;
import io.github.mianalysis.mia.object.refs.collections.ImageMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.MetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ParentChildRefs;
import io.github.mianalysis.mia.object.refs.collections.PartnerRefs;
import io.github.mianalysis.mia.object.system.Status;
import io.github.mianalysis.mia.process.ColourFactory;

@Plugin(type = Module.class, priority = Priority.LOW, visible = true)
public class PlotTrackMotility extends AbstractOverlay {
public static final String INPUT_SEPARATOR = "Object input/image output";
public static final String INPUT_TRACKS = "Input tracks";
public static final String INPUT_OBJECTS = "Input objects";
public static final String OUTPUT_IMAGE = "Output image";

public static final String PLOT_SEPARATOR = "Plot controls";
public static final String LINE_WIDTH = "Line width";

// public static final String AXIS_SEPARATOR = "Axis controls";
// public static final String X_RANGE_MODE = "X-range mode";
// public static final String X_RANGE_MIN = "X-range min";
// public static final String X_RANGE_MAX = "X-range max";
// public static final String Y_RANGE_MODE = "Y-range mode";
// public static final String Y_RANGE_MIN = "Y-range min";
// public static final String Y_RANGE_MAX = "Y-range max";


public PlotTrackMotility(Modules modules) {
super("Plot track motility", modules);
}

@Override
public Category getCategory() {
return Categories.VISUALISATION_PLOTS;
}

@Override
public String getVersionNumber() {
return "1.0.0";
}

@Override
public String getDescription() {
return "";

}

public static double[][] getPositionValues(Obj trackObject, String objectsName) {
Objs childObjects = trackObject.getChildren(objectsName);

// Find first object in track
int minT = Integer.MAX_VALUE;
Obj currObj = null;
for (Obj childObject:childObjects.values()) {
if (childObject.getT() < minT) {
minT = childObject.getT();
currObj = childObject;
}
}

// Creating stores for the coordinates
ArrayList<Double> x = new ArrayList<>();
ArrayList<Double> y = new ArrayList<>();
x.add(0d);
y.add(0d);

// Iterating over each timepoint instance, adding a link to the previous object
double x0 = currObj.getXMean(true);
double y0 = currObj.getYMean(true);

Objs nextObjects = currObj.getNextPartners(objectsName);
while (nextObjects.size() > 0) {
Obj nextObject = nextObjects.getFirst();

x.add(nextObject.getXMean(true)-x0);
y.add(nextObject.getYMean(true)-y0);

nextObjects = nextObject.getNextPartners(objectsName);

}

double[][] positions = new double[2][x.size()];
positions[0] = Doubles.toArray(x);
positions[1] = Doubles.toArray(y);

return positions;

}


@Override
protected Status process(Workspace workspace) {
// Getting parameters
String inputTracksName = parameters.getValue(INPUT_TRACKS, workspace);
String inputObjectsName = parameters.getValue(INPUT_OBJECTS, workspace);
String outputImageName = parameters.getValue(OUTPUT_IMAGE, workspace);
double lineWidth = parameters.getValue(LINE_WIDTH, workspace);

Objs trackObjects = workspace.getObjects(inputTracksName);

// Creating plot
Plot plot = new Plot("Motility", "x-position (px)", "y-position (px)");

// Generating colours for each object
HashMap<Integer, Color> colours = getColours(trackObjects, workspace);

// Iterating over each track, creating the plot
int count = 0;
double extreme = 0;

for (Obj trackObject : trackObjects.values()) {
// Getting values to plot
double[][] posDouble = getPositionValues(trackObject, inputObjectsName);

for (int i=0;i<posDouble[0].length;i++) {
if (Math.abs(posDouble[0][i]) > extreme)
extreme = Math.abs(posDouble[0][i]);
if (Math.abs(posDouble[1][i]) > extreme)
extreme = Math.abs(posDouble[1][i]);
}

plot.setLineWidth((float) lineWidth);
plot.setColor(colours.get(trackObject.getID()));
plot.add("Line", posDouble[0], posDouble[1]);

writeProgressStatus(count, trackObjects.size(), "tracks");

}

plot.setLimits(-extreme,extreme,-extreme,extreme);
plot.setSize(640,640);

Image outputImage = ImageFactory.createImage(outputImageName, plot.getImagePlus());
workspace.addImage(outputImage);

if (showOutput)
outputImage.show();

return Status.PASS;

}

@Override
protected void initialiseParameters() {
super.initialiseParameters();

parameters.add(new SeparatorP(INPUT_SEPARATOR, this));
parameters.add(new InputObjectsP(INPUT_TRACKS, this));
parameters.add(new ChildObjectsP(INPUT_OBJECTS, this));
parameters.add(new OutputImageP(OUTPUT_IMAGE, this));

parameters.add(new SeparatorP(PLOT_SEPARATOR, this));
parameters.add(new DoubleP(LINE_WIDTH, this, 1.0));

// parameters.add(new SeparatorP(AXIS_SEPARATOR, this));
// parameters.add(new IntegerP(X_RANGE_MIN, this, 0));
// parameters.add(new IntegerP(X_RANGE_MAX, this, 1));
// parameters.add(new DoubleP(Y_RANGE_MIN, this, 0.0));
// parameters.add(new DoubleP(Y_RANGE_MAX, this, 1.0));

}

@Override
public Parameters updateAndGetParameters() {
Workspace workspace = null;

Parameters returnedParameters = new Parameters();
String inputObjectsName = parameters.getValue(INPUT_OBJECTS, workspace);
String trackObjectsName = parameters.getValue(INPUT_TRACKS, workspace);

returnedParameters.add(parameters.getParameter(INPUT_SEPARATOR));
returnedParameters.add(parameters.getParameter(INPUT_TRACKS));
returnedParameters.add(parameters.getParameter(INPUT_OBJECTS));
((ChildObjectsP) parameters.getParameter(INPUT_OBJECTS)).setParentObjectsName(trackObjectsName);
returnedParameters.add(parameters.getParameter(OUTPUT_IMAGE));

returnedParameters.add(parameters.getParameter(PLOT_SEPARATOR));
returnedParameters.add(parameters.getParameter(LINE_WIDTH));

returnedParameters.addAll(super.updateAndGetParameters(inputObjectsName));

// returnedParameters.add(parameters.getParameter(AXIS_SEPARATOR));
// returnedParameters.add(parameters.getParameter(X_RANGE_MODE));
// switch ((String) parameters.getValue(X_RANGE_MODE, workspace)) {
// case AxisRangeModes.FIXED:
// returnedParameters.add(parameters.getParameter(X_RANGE_MIN));
// returnedParameters.add(parameters.getParameter(X_RANGE_MAX));
// break;
// }

// returnedParameters.add(parameters.getParameter(Y_RANGE_MODE));
// switch ((String) parameters.getValue(Y_RANGE_MODE, workspace)) {
// case AxisRangeModes.FIXED:
// returnedParameters.add(parameters.getParameter(Y_RANGE_MIN));
// returnedParameters.add(parameters.getParameter(Y_RANGE_MAX));
// break;
// }

return returnedParameters;

}

@Override
public ImageMeasurementRefs updateAndGetImageMeasurementRefs() {
return null;
}

@Override
public ObjMeasurementRefs updateAndGetObjectMeasurementRefs() {
return null;
}

@Override
public ObjMetadataRefs updateAndGetObjectMetadataRefs() {
return null;
}

@Override
public MetadataRefs updateAndGetMetadataReferences() {
return null;
}

@Override
public ParentChildRefs updateAndGetParentChildRefs() {
return null;
}

@Override
public PartnerRefs updateAndGetPartnerRefs() {
return null;
}

@Override
public boolean verify() {
return true;
}
}

0 comments on commit 84192b7

Please sign in to comment.