use of uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method reportAnalysis.
/**
* Report statistics on the analysis results.
*
* @param settings the settings
* @param clusters the clusters
* @param calibration the data calibration
*/
private static void reportAnalysis(TcPalmAnalysisSettings settings, LocalList<ClusterData> clusters, DataCalibration calibration) {
final WindowOrganiser wo = new WindowOrganiser();
final Consumer<HistogramPlotBuilder> action = builder -> {
/* noop. */
};
plotHistogram(settings.getShowSizeHistogram(), wo, clusters, "Size", c -> c.results.size(), null, action);
plotHistogram(settings.getShowDurationHistogram(), wo, clusters, "Duration (" + calibration.getTimeUnitName() + ")", c -> calibration.timeConverter.convert(c.getDuration()), null, action);
plotHistogram(settings.getShowAreaHistogram(), wo, clusters, "Area (" + calibration.getDistanceUnitName() + "^2)", c -> calibration.convertArea(c.getArea()), null, action);
plotHistogram(settings.getShowDensityHistogram(), wo, clusters, "Density (" + calibration.getDistanceUnitName() + "^-2)", c -> c.results.size() / calibration.convertArea(c.getArea()), Double::isFinite, action);
wo.tile();
}
use of uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder in project GDSC-SMLM by aherbert.
the class SpotInspector method plotHistogram.
private void plotHistogram(float[] data) {
if (settings.plotHistogram) {
final String title = TITLE + " Histogram";
new HistogramPlotBuilder(title, StoredDataStatistics.create(data), Settings.SORT_ORDER[settings.sortOrderIndex]).setRemoveOutliersOption((settings.removeOutliers) ? 1 : 0).setNumberOfBins(settings.histogramBins).show();
}
}
use of uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder in project GDSC-SMLM by aherbert.
the class TraceLengthAnalysis method run.
@Override
public void run(String arg) {
SmlmUsageTracker.recordPlugin(this.getClass(), arg);
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "No localisations in memory");
return;
}
if (!showDialog()) {
return;
}
// Load the results
MemoryPeakResults results = ResultsManager.loadInputResults(settings.inputOption, false, null, null);
if (MemoryPeakResults.isEmpty(results)) {
IJ.error(TITLE, "No results could be loaded");
return;
}
try {
distanceConverter = results.getDistanceConverter(DistanceUnit.UM);
timeConverter = results.getTimeConverter(TimeUnit.SECOND);
} catch (final Exception ex) {
IJ.error(TITLE, "Cannot convert units to um or seconds: " + ex.getMessage());
return;
}
// Get the localisation error (4s^2) in raw units^2
double precision = 0;
try {
final PrecisionResultProcedure p = new PrecisionResultProcedure(results);
p.getPrecision();
// Precision in nm using the median
precision = new Percentile().evaluate(p.precisions, 50);
// Convert from nm to um to raw units
final double rawPrecision = distanceConverter.convertBack(precision / 1e3);
// Get the localisation error (4s^2) in units^2
error = 4 * rawPrecision * rawPrecision;
} catch (final Exception ex) {
ImageJUtils.log(TITLE + " - Unable to compute precision: " + ex.getMessage());
}
// Analyse the track lengths
results = results.copy();
results.sort(IdFramePeakResultComparator.INSTANCE);
// Ensure the first result triggers an id change
lastid = results.getFirst().getId() - 1;
results.forEach(this::processTrackLength);
// For the final track
store();
msds = msdList.toArray();
lengths = lengthList.toArray();
ids = idList.toArray();
final int[] limits = MathUtils.limits(lengths);
h1 = new int[limits[1] + 1];
h2 = new int[h1.length];
x1 = SimpleArrayUtils.newArray(h1.length, 0, 1f);
y1 = new float[x1.length];
y2 = new float[x1.length];
// Sort by MSD
final int[] indices = SimpleArrayUtils.natural(msds.length);
SortUtils.sortIndices(indices, msds, false);
final double[] msds2 = msds.clone();
final int[] lengths2 = lengths.clone();
final int[] ids2 = ids.clone();
for (int i = 0; i < indices.length; i++) {
msds[i] = msds2[indices[i]];
lengths[i] = lengths2[indices[i]];
ids[i] = ids2[indices[i]];
}
// Interactive analysis
final NonBlockingExtendedGenericDialog gd = new NonBlockingExtendedGenericDialog(TITLE);
ImageJUtils.addMessage(gd, "Split traces into fixed or moving using the track diffusion coefficient (D).\n" + "Localisation error has been subtracted from jumps (%s nm).", MathUtils.rounded(precision));
final Statistics s = Statistics.create(msds);
final double av = s.getMean();
final String msg = String.format("Average D per track = %s um^2/s", MathUtils.rounded(av));
gd.addMessage(msg);
// Histogram the diffusion coefficients
final WindowOrganiser wo = new WindowOrganiser();
final HistogramPlot histogramPlot = new HistogramPlotBuilder("Trace diffusion coefficient", StoredData.create(msds), "D (um^2/s)").setRemoveOutliersOption(1).setPlotLabel(msg).build();
histogramPlot.show(wo);
final double[] xvalues = histogramPlot.getPlotXValues();
final double min = xvalues[0];
final double max = xvalues[xvalues.length - 1];
// see if we can build a nice slider range from the histogram limits
if (max - min < 5) {
// Because sliders are used when the range is <5 and floating point
gd.addSlider("D_threshold", min, max, settings.msdThreshold);
} else {
gd.addNumericField("D_threshold", settings.msdThreshold, 2, 6, "um^2/s");
}
gd.addCheckbox("Normalise", settings.normalise);
gd.addDialogListener((gd1, event) -> {
settings.msdThreshold = gd1.getNextNumber();
settings.normalise = gd1.getNextBoolean();
update();
return true;
});
if (ImageJUtils.isShowGenericDialog()) {
draw(wo);
wo.tile();
}
gd.setOKLabel("Save datasets");
gd.setCancelLabel("Close");
gd.addHelp(HelpUrls.getUrl("trace-length-analysis"));
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
// Sort by ID
final PeakResult[] list = results.toArray();
Arrays.sort(list, IdFramePeakResultComparator.INSTANCE);
createResults(results, "Fixed", 0, lastIndex, list);
createResults(results, "Moving", lastIndex, msds.length, list);
}
use of uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder in project GDSC-SMLM by aherbert.
the class TraceMolecules method summarise.
private void summarise(Consumer<String> output, Trace[] traces, int filtered, double distanceThreshold, double timeThreshold) {
IJ.showStatus("Calculating summary ...");
final Statistics[] stats = new Statistics[NAMES.length];
for (int i = 0; i < stats.length; i++) {
stats[i] = (settings.getShowHistograms() || settings.getSaveTraceData()) ? new StoredDataStatistics() : new Statistics();
}
int singles = 0;
for (final Trace trace : traces) {
final int nBlinks = trace.getBlinks() - 1;
stats[BLINKS].add(nBlinks);
final int[] onTimes = trace.getOnTimes();
final int[] offTimes = trace.getOffTimes();
double timeOn = 0;
for (final int t : onTimes) {
stats[T_ON].add(t * exposureTime);
timeOn += t * exposureTime;
}
stats[TOTAL_T_ON].add(timeOn);
if (offTimes != null) {
double timeOff = 0;
for (final int t : offTimes) {
stats[T_OFF].add(t * exposureTime);
timeOff += t * exposureTime;
}
stats[TOTAL_T_OFF].add(timeOff);
}
final double signal = trace.getSignal() / results.getGain();
stats[TOTAL_SIGNAL].add(signal);
stats[SIGNAL_PER_FRAME].add(signal / trace.size());
stats[DWELL_TIME].add((trace.getTail().getEndFrame() - trace.getHead().getFrame() + 1) * exposureTime);
if (trace.size() == 1) {
singles++;
}
}
// Add to the summary table
final StringBuilder sb = new StringBuilder();
sb.append(results.getName()).append('\t');
sb.append(outputName.equals("Cluster") ? getClusteringAlgorithm(settings.getClusteringAlgorithm()) : getTraceMode(settings.getTraceMode())).append('\t');
sb.append(MathUtils.rounded(getExposureTimeInMilliSeconds(), 3)).append('\t');
sb.append(MathUtils.rounded(distanceThreshold, 3)).append('\t');
sb.append(MathUtils.rounded(timeThreshold, 3));
if (settings.getSplitPulses()) {
sb.append(" *");
}
sb.append('\t');
sb.append(convertSecondsToFrames(timeThreshold)).append('\t');
sb.append(traces.length).append('\t');
sb.append(filtered).append('\t');
sb.append(singles).append('\t');
sb.append(traces.length - singles).append('\t');
for (int i = 0; i < stats.length; i++) {
sb.append(MathUtils.rounded(stats[i].getMean(), 3)).append('\t');
}
if (java.awt.GraphicsEnvironment.isHeadless()) {
IJ.log(sb.toString());
return;
}
output.accept(sb.toString());
if (settings.getShowHistograms()) {
IJ.showStatus("Calculating histograms ...");
final WindowOrganiser windowOrganiser = new WindowOrganiser();
final HistogramPlotBuilder builder = new HistogramPlotBuilder(pluginTitle).setNumberOfBins(settings.getHistogramBins());
for (int i = 0; i < NAMES.length; i++) {
if (pluginSettings.displayHistograms[i]) {
builder.setData((StoredDataStatistics) stats[i]).setName(NAMES[i]).setIntegerBins(integerDisplay[i]).setRemoveOutliersOption((settings.getRemoveOutliers() || alwaysRemoveOutliers[i]) ? 2 : 0).show(windowOrganiser);
}
}
windowOrganiser.tile();
}
if (settings.getSaveTraceData()) {
saveTraceData(stats);
}
IJ.showStatus("");
}
use of uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder in project GDSC-SMLM by aherbert.
the class CmosAnalysis method showHistogram.
private static void showHistogram(String name, double[] values, int bins, Statistics stats, WindowOrganiser wo) {
final DoubleData data = DoubleData.wrap(values);
final double minWidth = 0;
final int removeOutliers = 0;
final int shape = Plot.CIRCLE;
final String label = String.format("Mean = %s +/- %s", MathUtils.rounded(stats.getMean()), MathUtils.rounded(stats.getStandardDeviation()));
final HistogramPlot histogramPlot = new HistogramPlotBuilder(TITLE, data, name).setMinBinWidth(minWidth).setRemoveOutliersOption(removeOutliers).setNumberOfBins(bins).setPlotShape(shape).setPlotLabel(label).build();
histogramPlot.show(wo);
// Redraw using a log scale. This requires a non-zero y-min
final Plot plot = histogramPlot.getPlot();
final double[] limits = plot.getLimits();
plot.setLimits(limits[0], limits[1], 1, limits[3]);
plot.setAxisYLog(true);
plot.updateImage();
}
Aggregations