use of ij.gui.Plot in project GDSC-SMLM by aherbert.
the class BenchmarkSpotFit method showDoubleHistogram.
private double[] showDoubleHistogram(StoredDataStatistics[][] stats, final int i, WindowOrganiser wo, double[][] matchScores, double nPredicted) {
String xLabel = filterCriteria[i].name;
LowerLimit lower = filterCriteria[i].lower;
UpperLimit upper = filterCriteria[i].upper;
double[] j = null;
double[] metric = null;
double maxJ = 0;
if (i <= FILTER_PRECISION && (showFilterScoreHistograms || upper.requiresJaccard || lower.requiresJaccard)) {
// Jaccard score verses the range of the metric
Arrays.sort(matchScores, new Comparator<double[]>() {
public int compare(double[] o1, double[] o2) {
if (o1[i] < o2[i])
return -1;
if (o1[i] > o2[i])
return 1;
return 0;
}
});
final int scoreIndex = FILTER_PRECISION + 1;
int n = results.size();
double tp = 0;
double fp = 0;
j = new double[matchScores.length + 1];
metric = new double[j.length];
for (int k = 0; k < matchScores.length; k++) {
final double score = matchScores[k][scoreIndex];
tp += score;
fp += (1 - score);
j[k + 1] = tp / (fp + n);
metric[k + 1] = matchScores[k][i];
}
metric[0] = metric[1];
maxJ = Maths.max(j);
if (showFilterScoreHistograms) {
String title = TITLE + " Jaccard " + xLabel;
Plot plot = new Plot(title, xLabel, "Jaccard", metric, j);
// Remove outliers
double[] limitsx = Maths.limits(metric);
Percentile p = new Percentile();
double l = p.evaluate(metric, 25);
double u = p.evaluate(metric, 75);
double iqr = 1.5 * (u - l);
limitsx[1] = Math.min(limitsx[1], u + iqr);
plot.setLimits(limitsx[0], limitsx[1], 0, Maths.max(j));
PlotWindow pw = Utils.display(title, plot);
if (Utils.isNewWindow())
wo.add(pw);
}
}
// [0] is all
// [1] is matches
// [2] is no match
StoredDataStatistics s1 = stats[0][i];
StoredDataStatistics s2 = stats[1][i];
StoredDataStatistics s3 = stats[2][i];
if (s1.getN() == 0)
return new double[4];
DescriptiveStatistics d = s1.getStatistics();
double median = 0;
Plot2 plot = null;
String title = null;
if (showFilterScoreHistograms) {
median = d.getPercentile(50);
String label = String.format("n = %d. Median = %s nm", s1.getN(), Utils.rounded(median));
int id = Utils.showHistogram(TITLE, s1, xLabel, filterCriteria[i].minBinWidth, (filterCriteria[i].restrictRange) ? 1 : 0, 0, label);
if (id == 0) {
IJ.log("Failed to show the histogram: " + xLabel);
return new double[4];
}
if (Utils.isNewWindow())
wo.add(id);
title = WindowManager.getImage(id).getTitle();
// Reverse engineer the histogram settings
plot = Utils.plot;
double[] xValues = Utils.xValues;
int bins = xValues.length;
double yMin = xValues[0];
double binSize = xValues[1] - xValues[0];
double yMax = xValues[0] + (bins - 1) * binSize;
if (s2.getN() > 0) {
double[] values = s2.getValues();
double[][] hist = Utils.calcHistogram(values, yMin, yMax, bins);
if (hist[0].length > 0) {
plot.setColor(Color.red);
plot.addPoints(hist[0], hist[1], Plot2.BAR);
Utils.display(title, plot);
}
}
if (s3.getN() > 0) {
double[] values = s3.getValues();
double[][] hist = Utils.calcHistogram(values, yMin, yMax, bins);
if (hist[0].length > 0) {
plot.setColor(Color.blue);
plot.addPoints(hist[0], hist[1], Plot2.BAR);
Utils.display(title, plot);
}
}
}
// Do cumulative histogram
double[][] h1 = Maths.cumulativeHistogram(s1.getValues(), true);
double[][] h2 = Maths.cumulativeHistogram(s2.getValues(), true);
double[][] h3 = Maths.cumulativeHistogram(s3.getValues(), true);
if (showFilterScoreHistograms) {
title = TITLE + " Cumul " + xLabel;
plot = new Plot2(title, xLabel, "Frequency");
// Find limits
double[] xlimit = Maths.limits(h1[0]);
xlimit = Maths.limits(xlimit, h2[0]);
xlimit = Maths.limits(xlimit, h3[0]);
// Restrict using the inter-quartile range
if (filterCriteria[i].restrictRange) {
double q1 = d.getPercentile(25);
double q2 = d.getPercentile(75);
double iqr = (q2 - q1) * 2.5;
xlimit[0] = Maths.max(xlimit[0], median - iqr);
xlimit[1] = Maths.min(xlimit[1], median + iqr);
}
plot.setLimits(xlimit[0], xlimit[1], 0, 1.05);
plot.addPoints(h1[0], h1[1], Plot.LINE);
plot.setColor(Color.red);
plot.addPoints(h2[0], h2[1], Plot.LINE);
plot.setColor(Color.blue);
plot.addPoints(h3[0], h3[1], Plot.LINE);
}
// Determine the maximum difference between the TP and FP
double maxx1 = 0;
double maxx2 = 0;
double max1 = 0;
double max2 = 0;
// We cannot compute the delta histogram, or use percentiles
if (s2.getN() == 0) {
upper = UpperLimit.ZERO;
lower = LowerLimit.ZERO;
}
final boolean requireLabel = (showFilterScoreHistograms && filterCriteria[i].requireLabel);
if (requireLabel || upper.requiresDeltaHistogram() || lower.requiresDeltaHistogram()) {
if (s2.getN() != 0 && s3.getN() != 0) {
LinearInterpolator li = new LinearInterpolator();
PolynomialSplineFunction f1 = li.interpolate(h2[0], h2[1]);
PolynomialSplineFunction f2 = li.interpolate(h3[0], h3[1]);
for (double x : h1[0]) {
if (x < h2[0][0] || x < h3[0][0])
continue;
try {
double v1 = f1.value(x);
double v2 = f2.value(x);
double diff = v2 - v1;
if (diff > 0) {
if (max1 < diff) {
max1 = diff;
maxx1 = x;
}
} else {
if (max2 > diff) {
max2 = diff;
maxx2 = x;
}
}
} catch (OutOfRangeException e) {
// Because we reached the end
break;
}
}
} else {
// Switch to percentiles if we have no delta histogram
if (upper.requiresDeltaHistogram())
upper = UpperLimit.NINETY_NINE_PERCENT;
if (lower.requiresDeltaHistogram())
lower = LowerLimit.ONE_PERCENT;
}
// System.out.printf("Bounds %s : %s, pos %s, neg %s, %s\n", xLabel, Utils.rounded(getPercentile(h2, 0.01)),
// Utils.rounded(maxx1), Utils.rounded(maxx2), Utils.rounded(getPercentile(h1, 0.99)));
}
if (showFilterScoreHistograms) {
// We use bins=1 on charts where we do not need a label
if (requireLabel) {
String label = String.format("Max+ %s @ %s, Max- %s @ %s", Utils.rounded(max1), Utils.rounded(maxx1), Utils.rounded(max2), Utils.rounded(maxx2));
plot.setColor(Color.black);
plot.addLabel(0, 0, label);
}
PlotWindow pw = Utils.display(title, plot);
if (Utils.isNewWindow())
wo.add(pw.getImagePlus().getID());
}
// Now compute the bounds using the desired limit
double l, u;
switch(lower) {
case ONE_PERCENT:
l = getPercentile(h2, 0.01);
break;
case MAX_NEGATIVE_CUMUL_DELTA:
l = maxx2;
break;
case ZERO:
l = 0;
break;
case HALF_MAX_JACCARD_VALUE:
l = getValue(metric, j, maxJ * 0.5);
break;
default:
throw new RuntimeException("Missing lower limit method");
}
switch(upper) {
case MAX_POSITIVE_CUMUL_DELTA:
u = maxx1;
break;
case NINETY_NINE_PERCENT:
u = getPercentile(h2, 0.99);
break;
case NINETY_NINE_NINE_PERCENT:
u = getPercentile(h2, 0.999);
break;
case ZERO:
u = 0;
break;
case MAX_JACCARD2:
u = getValue(metric, j, maxJ) * 2;
//System.out.printf("MaxJ = %.4f @ %.3f\n", maxJ, u / 2);
break;
default:
throw new RuntimeException("Missing upper limit method");
}
double min = getPercentile(h1, 0);
double max = getPercentile(h1, 1);
return new double[] { l, u, min, max };
}
use of ij.gui.Plot in project GDSC-SMLM by aherbert.
the class BenchmarkSpotFilter method plot.
private void plot(int i, ArrayList<BatchResult[]> batchResults) {
if (!batchPlot[i])
return;
Color[] colors = new Color[] { Color.red, Color.gray, Color.green, Color.blue, Color.magenta };
String name = batchPlotNames[i];
String title = TITLE + " Performance " + name;
Plot plot = new Plot(title, "Relative width", name);
final double scale = 1.0 / config.getHWHMMin();
for (BatchResult[] batchResult : batchResults) {
if (batchResult == null || batchResult.length == 0)
continue;
float[][] data = extractData(batchResult, i, scale);
int colorIndex = batchResult[0].dataFilter.ordinal();
plot.setColor(colors[colorIndex]);
colors[colorIndex] = colors[colorIndex].darker();
plot.addPoints(data[0], data[1], null, (batchResult.length > 1) ? Plot.LINE : Plot.CIRCLE, batchResult[0].getName());
}
plot.setColor(Color.black);
plot.addLegend(null);
if (name.contains("Time"))
plot.setAxisYLog(true);
PlotWindow pw = Utils.display(title, plot);
// Seems to only work after drawing
plot.setLimitsToFit(true);
if (Utils.isNewWindow())
windowOrganiser.add(pw);
}
use of ij.gui.Plot in project GDSC-SMLM by aherbert.
the class PSFCreator method subtractBackgroundAndWindow.
/**
* Subtract the background from the spot, compute the intensity within half the box region distance from the centre
* and smooth the intensity profile. In interactive mode the user must choose to accept the profile or reject.
* If accepted the smoothed profile is user to normalise the image and then the image is rolled off to zero
* using a Tukey window function.
*
* @param spot
* @param background
* The minimum level, all below this is background and set to zero
* @param spotWidth
* @param spotHeight
* @param n
* The spot number
* @param loess
* The smoothing interpolator
* @return True if accepted
*/
private boolean subtractBackgroundAndWindow(float[][] spot, final float background, final int spotWidth, final int spotHeight, double[] centre, LoessInterpolator loess) {
//ImageWindow imageWindow = new ImageWindow();
for (int i = 0; i < spot.length; i++) {
for (int j = 0; j < spot[i].length; j++) spot[i][j] = FastMath.max(spot[i][j] - background, 0);
}
// Create a distance map from the centre
if (lastWidth != spotWidth || lastHeight != spotHeight) {
final double cx = spotWidth * 0.5;
final double cy = spotHeight * 0.5;
minx = FastMath.max(0, (int) (cx - boxRadius * 0.5));
maxx = FastMath.min(spotWidth, (int) Math.ceil(cx + boxRadius * 0.5));
miny = FastMath.max(0, (int) (cy - boxRadius * 0.5));
maxy = FastMath.min(spotHeight, (int) Math.ceil(cy + boxRadius * 0.5));
// Precompute square distances
double[] dx2 = new double[maxx - minx + 1];
for (int x = minx, i = 0; x < maxx; x++, i++) {
// Use pixel centres with 0.5 offset
final double dx = x + 0.5 - cx;
dx2[i] = dx * dx;
}
dmap = new boolean[dx2.length * (maxy - miny + 1)];
final double d2 = boxRadius * boxRadius / 4;
for (int y = miny, j = 0; y < maxy; y++) {
final double dy = (y + 0.5 - cy);
final double dy2 = dy * dy;
final double limit = d2 - dy2;
for (int x = minx, i = 0; x < maxx; x++, i++, j++) {
dmap[j] = (dx2[i] < limit);
}
}
lastWidth = spotWidth;
lastHeight = spotHeight;
}
// Calculate the intensity profile within half the box radius from the centre
double[] xValues = new double[spot.length];
double[] yValues = new double[spot.length];
for (int i = 0; i < spot.length; i++) {
xValues[i] = i + 1;
double sum = 0;
for (int y = miny, j = 0; y < maxy; y++) {
int index = y * spotWidth + minx;
for (int x = minx; x < maxx; x++, index++, j++) if (dmap[j])
sum += spot[i][index];
}
yValues[i] = sum;
}
double[] newY = loess.smooth(xValues, yValues);
// falls towards zero at the ends)
for (int i = 0; i < newY.length; i++) if (newY[i] < 0)
newY[i] = yValues[i];
if (interactiveMode) {
Utils.hide(TITLE_AMPLITUDE);
Utils.hide(TITLE_PSF_PARAMETERS);
final int n = (int) centre[4];
String title = TITLE_INTENSITY;
Plot plot = new Plot(title, "Slice", "Sum", xValues, yValues);
plot.setColor(Color.red);
plot.addPoints(xValues, newY, Plot.LINE);
plot.setColor(Color.green);
double[] limits = Maths.limits(yValues);
plot.drawLine(centre[2], limits[0], centre[2], limits[1]);
plot.setColor(Color.black);
plot.addLabel(0, 0, "Spot " + n);
Utils.display(title, plot);
GenericDialog gd = new GenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
gd.addMessage(String.format("Add spot %d to the PSF?\n(The intensity profile is the sum within half the box region)", n));
if (yesNoPosition != null) {
gd.centerDialog(false);
gd.setLocation(yesNoPosition);
}
gd.showDialog();
yesNoPosition = gd.getLocation();
if (!gd.wasOKed())
return false;
}
for (int i = 0; i < spot.length; i++) {
// Normalise
final float scale = (float) (newY[i] / yValues[i]);
for (int j = 0; j < spot[i].length; j++) spot[i][j] *= scale;
// Use a Tukey window to roll-off the image edges
//spot[i] = imageWindow.applySeperable(spot[i], spotWidth, spotHeight, ImageWindow.WindowFunction.Tukey);
spot[i] = ImageWindow.applyWindow(spot[i], spotWidth, spotHeight, ImageWindow.WindowFunction.TUKEY);
}
return true;
}
use of ij.gui.Plot in project vcell by virtualcell.
the class PlotCellRegionStats method run.
@Override
public void run() {
Plot plot = new ColorPlot("Cell region mean intensity", "Time", "Mean intensity");
StringBuilder legendLabels = new StringBuilder();
for (int i = 0; i < datasets.size(); i++) {
RandomAccessibleInterval<T> data = datasets.get(i);
if (data instanceof Dataset) {
legendLabels.append(((Dataset) data).getName());
legendLabels.append(": ");
}
RandomAccessibleInterval<T> cropped = ops.transform().crop(data, mask);
displayService.createDisplay(cropped);
}
}
use of ij.gui.Plot in project mcib3d-core by mcib3d.
the class Segment3DSpots method gaussianFit.
/**
* @param x
* @param y
* @param z
* @param plotb
* @return
*/
public double[] gaussianFit(int x, int y, int z, boolean plotb) {
double[] gaussFit;
double[] params;
if (WATERSHED) {
gaussFit = rawImage.radialDistribution(x, y, z, GAUSS_MAXR, Object3D.MEASURE_INTENSITY_AVG, watershedImage);
} else {
gaussFit = rawImage.radialDistribution(x, y, z, GAUSS_MAXR);
}
params = ArrayUtil.fitGaussian(gaussFit, 3, GAUSS_MAXR);
// plot
if (plotb) {
double[] xx = new double[gaussFit.length];
for (int i = 0; i < xx.length; i++) {
xx[i] = i;
}
Plot plot = new Plot("Rad", "X", "Y", xx, gaussFit);
plot.show();
}
return params;
}
Aggregations