use of uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TcPalmAnalysisSettings in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method runSelection.
/**
* Run selection of the current clusters.
*
* @param work the current work
*/
private void runSelection(Work work) {
// Support square ROI
// - Map image ROI bounds to the data
// - Check if the cluster is inside the rectangle bounds
final Roi roi = work.roi;
final TcPalmAnalysisSettings settings = work.settings;
final Rectangle2D scaledBounds = createScaledBounds(roi);
final BiPredicate<ClusterData, Rectangle2D> filter = createSelectionFilter(roi, settings);
clusters = new LocalList<>();
clusterData.forEach(c -> {
if (filter.test(c, scaledBounds)) {
clusters.add(c);
}
});
// Build total activations data
countData = createCumulativeCountData(clusters, true);
// Add a table of the clusters.
final ClusterDataTableModelFrame clustersTable = createGroupsTable();
clustersTable.getModel().setData(clusters, dataCalibration);
// Allow a configurable action that accepts the array of ClusterData that is selected.
clustersTable.selectedAction = clusterSelectedListener;
// Extract the localisations into a loop view
final MemoryPeakResults subset = new MemoryPeakResults();
subset.copySettings(results);
clusters.forEach(c -> {
c.results.forEach(peak -> {
if (scaledBounds.contains(peak.getXPosition(), peak.getYPosition())) {
subset.add(peak);
}
});
});
// Clear bounds to force a recompute
subset.setBounds(null);
loopImage.setSettings(settings).setResults(subset).update();
}
use of uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TcPalmAnalysisSettings in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method analyseRois.
/**
* Analyses all the ROIs in the ROI manager.
*
* @param event the event
*/
private void analyseRois(ActionEvent event) {
final RoiManager manager = RoiManager.getInstance();
if (manager == null) {
IJ.error(TITLE, "ROI manager is not open");
return;
}
final LocalList<Roi> rois = Arrays.stream(manager.getRoisAsArray()).filter(Roi::isArea).collect(LocalCollectors.toLocalList());
if (rois.isEmpty()) {
IJ.error(TITLE, "No area ROIs");
return;
}
// Check for overlaps.
if (!settings.getDisableOverlapCheck() && anyOverlap(rois)) {
final GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage(TextUtils.wrap("WARNING - Bounding rectangles of ROIs overlap. You can verify " + "the ROIs on the image using the ROI manager 'Show all' function.", 80));
gd.setOKLabel("Continue");
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
}
// For each ROI:
// - Extract the current groups
// - Build the cumulative count plot
// - Identify the bursts
// - Extract ClusterData for each burst
final TcPalmAnalysisSettings settings = this.settings.build();
final LocalList<ClusterData> allClusters = rois.parallelStream().map(roi -> {
final Rectangle2D scaledBounds = createScaledBounds(roi);
final BiPredicate<ClusterData, Rectangle2D> filter = createSelectionFilter(roi, settings);
// Filter all cluster groups
final LocalList<ClusterData> clusters = new LocalList<>();
clusterData.forEach(c -> {
if (filter.test(c, scaledBounds)) {
clusters.add(c);
}
});
// Extract activation bursts
final CumulativeCountData countData = createCumulativeCountData(clusters, false);
final LocalList<int[]> bursts = runBurstAnalysis(settings, countData);
final LocalList<LocalList<PeakResult>> burstLocalisations = createBurstLocalisations(clusters, bursts);
clusters.clear();
burstLocalisations.forEach(list -> {
final ClusterData d = new ClusterData(clusters.size() + 1, list);
// Save this for analysis
d.sourceRoi = roi;
d.getArea();
clusters.add(d);
});
return clusters;
}).collect(LocalList::new, LocalList::addAll, LocalList::addAll);
// Reorder
final Counter count = new Counter();
allClusters.forEach(c -> c.id = count.incrementAndGet());
// Display in a table
final ClusterDataTableModelFrame frame = createAllClustersTable();
frame.getModel().setData(allClusters, dataCalibration);
// Allow the results to be repeated
frame.selectedAction = clusters -> {
// Expecting a single cluster. No clusters occurs when the table (and selection) is cleared.
if (clusters.size() == 1) {
final ClusterData c = clusters.get(0);
// Push the correct ROI and settings to the analysis action.
// We do not directly update the ROI or dialog settings as
// these trigger events that are processed to add work with a delay.
// Updating them at the end should generate events that are
// ignored when finally executed as the ROI/settings should be the same.
addWork(0, c.sourceRoi, settings, () -> {
// When analysis has finished update the settings and image ROI.
image.getImagePlus().setRoi(c.sourceRoi);
darkTimeToleranceTextField.setText(Integer.toString(settings.getDarkTimeTolerance()));
minClusterSizeTextField.setText(Integer.toString(settings.getMinClusterSize()));
// When analysis has finished the cluster should be selected in the
// current clusters table.
final ClusterDataTableModelFrame currentClusters = currentClustersTable.get();
if (currentClusters != null) {
currentClusters.select(c);
}
});
}
};
// Show histogram of cluster size/duration
reportAnalysis(settings, allClusters, dataCalibration);
// Save clusters to memory
final Trace[] traces = allClusters.stream().map(c -> {
final Trace t = new Trace();
t.setId(c.id);
c.results.forEach(t::add);
return t;
}).toArray(Trace[]::new);
TraceMolecules.saveResults(results, traces, "TC PALM");
IJ.showStatus(TITLE + ": " + TextUtils.pleural(allClusters.size(), "cluster"));
}
use of uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TcPalmAnalysisSettings in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method createSelectionFilter.
/**
* Creates the selection filter to identify all cluster groups using a custom filter.
*
* @param roi the roi
* @param settings the settings
* @return the bi predicate
*/
private BiPredicate<ClusterData, Rectangle2D> createSelectionFilter(final Roi roi, final TcPalmAnalysisSettings settings) {
// Filter on time first as this is simple.
BiPredicate<ClusterData, Rectangle2D> test = null;
if (settings.getMinFrame() > minT) {
final int min = settings.getMinFrame();
test = (c, r) -> c.start >= min;
}
if (settings.getMaxFrame() < maxT) {
final int max = settings.getMaxFrame();
test = and(test, (c, r) -> c.end <= max);
}
// Add square bounds check
test = and(test, settings.getIntersects() ? ClusterData::intersects : ClusterData::isWithin);
// -- Check if the cluster is inside the ROI using a CoordinatePredicate
if (roi.getType() != Roi.RECTANGLE || roi.getCornerDiameter() != 0) {
final CoordinatePredicate pred = CoordinatePredicateUtils.createContainsPredicate(roi);
if (settings.getIntersects()) {
test = and(test, (c, r) -> c.intersects(pred, image::mapX, image::mapY));
} else {
test = and(test, (c, r) -> c.isWithin(pred, image::mapX, image::mapY));
}
}
return test;
}
use of uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TcPalmAnalysisSettings in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method runAnalysis.
/**
* Run the analysis of clusters inside the bounds with the provided analysis settings.
*
* @param last the last work
* @param current the current work
*/
private void runAnalysis(Work last, Work current) {
final TcPalmAnalysisSettings lastSettings = last.settings;
final TcPalmAnalysisSettings settings = current.settings;
final boolean selectionChanged = selectionChanged(last, current);
if (selectionChanged) {
runSelection(current);
} else if (loopSettingsChanged(lastSettings, settings)) {
loopImage.setSettings(settings).update();
}
final boolean plotChanged = selectionChanged || plotSettingsChanged(lastSettings, settings);
if (plotChanged) {
runPlot(settings);
}
final boolean analysisChanged = selectionChanged || analysisSettingsChanged(lastSettings, settings);
if (analysisChanged) {
clearClustersTableSelection();
bursts = runBurstAnalysis(settings, countData);
runBurstOverlay(createBurstLocalisations(clusters, bursts));
}
if (plotChanged || analysisChanged) {
runBurstPlotSelection(bursts);
}
}
use of uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TcPalmAnalysisSettings 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();
}
Aggregations