use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class PcPalmMolecules method traceMolecules.
/**
* Trace localisations.
*
* @param results The results
* @param precisions the precisions
* @param distance The distance threshold (nm)
* @param time The time threshold (frames)
* @param singles a list of the singles (not grouped into molecules)
* @return a list of molecules
*/
private static ArrayList<Molecule> traceMolecules(MemoryPeakResults results, double[] precisions, double distance, int time, ArrayList<Molecule> singles) {
// These plugins are not really supported so just leave them to throw an exception if
// the data cannot be handled
final TypeConverter<IntensityUnit> ic = results.getCalibrationReader().getIntensityConverter(IntensityUnit.PHOTON);
final TypeConverter<DistanceUnit> dc = results.getCalibrationReader().getDistanceConverter(DistanceUnit.NM);
// Create a new dataset with the precision
final MemoryPeakResults results2 = new MemoryPeakResults(results.size());
for (int i = 0, size = results.size(); i < size; i++) {
final AttributePeakResult peak2 = new AttributePeakResult(results.get(i));
peak2.setPrecision(precisions[i]);
results2.add(peak2);
}
final TraceManager tm = new TraceManager(results2);
final double distanceThreshold = dc.convertBack(distance);
tm.traceMolecules(distanceThreshold, time);
final Trace[] traces = tm.getTraces();
final ArrayList<Molecule> molecules = new ArrayList<>(traces.length);
for (final Trace t : traces) {
final double p = t.getLocalisationPrecision(dc);
final float[] centroid = t.getCentroid();
final List<Molecule> list = t.size() == 1 ? singles : molecules;
list.add(new Molecule(dc.convert(centroid[0]), dc.convert(centroid[1]), p, ic.convert(t.getSignal())));
}
log(" %d localisations traced to %d molecules (%d singles, %d traces) using d=%.2f nm," + " t=%d frames (%s s)", results.size(), molecules.size() + singles.size(), singles.size(), molecules.size(), distance, time, MathUtils.rounded(time * results.getCalibrationReader().getExposureTime() / 1000.0));
return molecules;
}
use of uk.ac.sussex.gdsc.smlm.results.Trace 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.results.Trace in project GDSC-SMLM by aherbert.
the class PulseActivationAnalysis method createActivations.
/**
* Creates the activations. This splits the input traces into continuous chains of localisations.
* Each chain is an activation. A new activation is created if there are more than the configured
* number of dark frames since the last localisation. The start frame for the activation defines
* the channel the activation is assigned to (this may be channel 0 if the start frame is not in a
* pulse start frame).
*/
@SuppressWarnings("null")
private void createActivations() {
final LocalList<Activation> activations = new LocalList<>(traces.length);
// Activations are only counted if there are at least
// n frames between localisations.
final int n = settings.darkFramesForNewActivation + 1;
for (final Trace trace : traces) {
// Time-order
trace.sort();
final PeakResultStoreList points = trace.getPoints();
// Define the frame for a new activation
int nextActivationStartFrame = Integer.MIN_VALUE;
Trace current = null;
int channel = 0;
for (int j = 0; j < points.size(); j++) {
final PeakResult p = points.get(j);
// Check if this is an activation
if (p.getFrame() >= nextActivationStartFrame) {
if (current != null) {
// Store the last
activations.add(new Activation(current, channel));
}
// Create a new activation
current = new Trace(p);
channel = getChannel(p);
} else {
// This is the same chain of localisations
current.add(p);
}
nextActivationStartFrame = p.getEndFrame() + n;
}
if (current != null) {
activations.add(new Activation(current, channel));
}
}
save(activations);
}
use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class NeighbourAnalysis 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;
}
final TraceManager manager = new TraceManager(results);
// Run the tracing
manager.setTracker(SimpleImageJTrackProgress.getInstance());
final Trace[] traces = manager.findNeighbours(settings.distanceThreshold, settings.timeThreshold);
saveTraces(traces);
}
use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class NeighbourAnalysis method saveTraces.
private void saveTraces(Trace[] traces) {
final String[] path = ImageJUtils.decodePath(settings.filename);
final OpenDialog chooser = new OpenDialog("Traces_File", path[0], path[1]);
if (chooser.getFileName() != null) {
settings.filename = chooser.getDirectory() + chooser.getFileName();
// Remove extension and replace with .xls
final int index = settings.filename.lastIndexOf('.');
if (index > 0) {
settings.filename = settings.filename.substring(0, index);
}
settings.filename += ".xls";
final boolean showDeviations = results.hasDeviations();
final TextFilePeakResults traceResults = new TextFilePeakResults(settings.filename, showDeviations);
traceResults.copySettings(results);
traceResults.begin();
if (!traceResults.isActive()) {
IJ.error(TITLE, "Failed to write to file: " + settings.filename);
return;
}
traceResults.addComment(createSettingsComment());
for (final Trace trace : traces) {
// addTrace(...) does a sort on the results
traceResults.addCluster(trace);
}
traceResults.end();
}
}
Aggregations