use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class HysteresisFilter method setup.
@Override
public void setup(MemoryPeakResults peakResults) {
ok = new HashSet<>();
// Create a set of candidates and valid peaks
final MemoryPeakResults traceResults = new MemoryPeakResults();
// Initialise peaks to check
final LinkedList<PeakResult> candidates = new LinkedList<>();
peakResults.forEach((PeakResultProcedure) result -> {
switch(getStatus(result)) {
case OK:
ok.add(result);
traceResults.add(result);
break;
case CANDIDATE:
candidates.add(result);
traceResults.add(result);
break;
default:
break;
}
});
if (candidates.isEmpty()) {
// No candidates for tracing so just return
return;
}
double distanceThreshold;
switch(searchDistanceMode) {
case 1:
distanceThreshold = searchDistance / peakResults.getNmPerPixel();
break;
case 0:
default:
distanceThreshold = getSearchDistanceUsingCandidates(peakResults, candidates);
}
if (distanceThreshold <= 0) {
return;
}
// This must be in frames
int myTimeThreshold;
if (timeThresholdMode == 1) {
// time threshold is in Seconds.
// Default to 1 frame if not calibrated.
myTimeThreshold = 1;
if (peakResults.hasCalibration()) {
// Convert time threshold in seconds to frames
final CalibrationReader cr = peakResults.getCalibrationReader();
final double et = cr.getExposureTime();
if (et > 0) {
myTimeThreshold = (int) Math.round((this.timeThreshold / et));
}
}
} else {
// frames
myTimeThreshold = (int) this.timeThreshold;
}
if (myTimeThreshold <= 0) {
return;
}
// Trace through candidates
final TraceManager tm = new TraceManager(traceResults);
tm.setTraceMode(TraceMode.LATEST_FORERUNNER);
tm.traceMolecules(distanceThreshold, myTimeThreshold);
final Trace[] traces = tm.getTraces();
for (final Trace trace : traces) {
if (trace.size() > 1) {
// Check if the trace touches a valid point
boolean isOk = false;
for (int i = 0; i < trace.size(); i++) {
if (ok.contains(trace.get(i))) {
isOk = true;
break;
}
}
// Add the entire trace to the OK points
if (isOk) {
for (int i = 0; i < trace.size(); i++) {
ok.add(trace.get(i));
}
}
}
}
}
use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class TraceDiffusion method filterTraces.
/**
* Split traces to contiguous traces and filter traces that are not the minimum length. Re-assigns
* the ID for the output traces.
*
* @param name the name
* @param traces the traces
* @param minimumTraceLength the minimum trace length
* @param ignoreEnds the ignore ends
* @return The new traces
*/
private static Trace[] filterTraces(String name, Trace[] traces, int minimumTraceLength, boolean ignoreEnds) {
final LocalList<Trace> list = new LocalList<>(traces.length);
final int minLength = (ignoreEnds) ? minimumTraceLength + 2 : minimumTraceLength;
final Consumer<Trace> action = (ignoreEnds) ? t -> {
if (t.size() >= minLength) {
t.removeEnds();
list.add(t);
t.setId(list.size());
}
} : t -> {
if (t.size() >= minLength) {
list.add(t);
t.setId(list.size());
}
};
final Consumer<ArrayPeakResultStore> action2 = (ignoreEnds) ? r -> {
if (r.size() >= minLength) {
r.remove(0);
r.remove(r.size() - 1);
final Trace t = new Trace(r);
list.add(t);
t.setId(list.size());
}
} : r -> {
if (r.size() >= minLength) {
final Trace t = new Trace(r);
list.add(t);
t.setId(list.size());
}
};
final ArrayPeakResultStore results = new ArrayPeakResultStore(11);
for (final Trace trace : traces) {
if (trace.size() < minLength) {
// Too short
continue;
}
if (trace.size() == trace.getTail().getFrame() - trace.getHead().getFrame() + 1) {
// Contiguous
action.accept(trace);
} else {
// Split the trace
int t1 = trace.getHead().getFrame();
for (int i = 0; i < trace.size(); i++) {
final PeakResult peak = trace.get(i);
final int t2 = peak.getFrame();
if (t2 - t1 > 1) {
// Non-contiguous
action2.accept(results);
results.clear();
}
t1 = t2;
results.add(peak);
}
// Final trace
action2.accept(results);
results.clear();
}
}
ImageJUtils.log("Filtered results '%s' : %s split and filtered to %d using " + "minimum length %d (Ignore ends = %b)", name, TextUtils.pleural(traces.length, "trace"), list.size(), minimumTraceLength, ignoreEnds);
return list.toArray(new Trace[0]);
}
use of uk.ac.sussex.gdsc.smlm.results.Trace 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.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class TraceMolecules method saveTraces.
/**
* Save the traces to the file. A File open dialog is presented and the selected filename
* returned.
*
* <p>If the id is above zero then the file open dialog title will have the id appended and the
* filename is searched for .[0-9]+. and it is replaced with .id.
*
* @param sourceResults the source results
* @param traces the traces
* @param comment the comment
* @param filename The initial filename
* @param id The traces id (used if above 0)
* @return The select filename (or null)
*/
static String saveTraces(MemoryPeakResults sourceResults, Trace[] traces, String comment, String filename, int id) {
IJ.showStatus("Saving traces");
String title = "Traces_File";
if (id > 0) {
title += id;
final String regex = "\\.[0-9]+\\.";
if (filename.matches(regex)) {
filename = filename.replaceAll(regex, "." + (id) + ".");
} else {
filename = FileUtils.replaceExtension(filename, id + ".xls");
}
}
filename = ImageJUtils.getFilename(title, filename);
if (filename != null) {
filename = FileUtils.replaceExtension(filename, "xls");
final boolean showDeviations = sourceResults.hasDeviations();
// Assume that are results are from a single frame but store the trace ID
final TextFilePeakResults traceResults = new TextFilePeakResults(filename, showDeviations, false, true);
traceResults.copySettings(sourceResults);
traceResults.begin();
if (!traceResults.isActive()) {
IJ.error("Failed to write to file: " + filename);
} else {
traceResults.addComment(comment);
for (final Trace trace : traces) {
traceResults.addTrace(trace);
}
traceResults.end();
}
}
IJ.showStatus("");
return filename;
}
use of uk.ac.sussex.gdsc.smlm.results.Trace in project GDSC-SMLM by aherbert.
the class TraceMolecules method run.
@Override
public void run(String arg) {
SmlmUsageTracker.recordPlugin(this.getClass(), arg);
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(pluginTitle, "No localisations in memory");
return;
}
altKeyDown = ImageJUtils.isExtraOptions();
Trace[] traces = null;
int totalFiltered = 0;
if ("dynamic".equals(arg)) {
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Dynamic Mutliple Target Tracing
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
outputName = "Dynamic Trace";
if (!showDynamicTraceDialog()) {
return;
}
final DmttConfiguration config = createDmttConfiguration();
traces = new DynamicMultipleTargetTracing(results).traceMolecules(config).toArray(new Trace[0]);
} else if ("cluster".equals(arg)) {
// -=-=-=-=-=
// Clustering
// -=-=-=-=-=
outputName = "Cluster";
if (!showClusterDialog()) {
return;
}
final ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), getClusteringAlgorithm(settings.getClusteringAlgorithm()), SimpleImageJTrackProgress.getInstance());
if (settings.getSplitPulses()) {
engine.setPulseInterval(settings.getPulseInterval());
limitTimeThreshold(settings.getPulseInterval());
}
final List<Cluster> clusters = engine.findClusters(convertToClusterPoints(), getDistance(settings.getDistanceThreshold(), results.getCalibration()), timeThresholdInFrames());
if (clusters == null) {
ImageJUtils.log("Aborted");
return;
}
traces = convertToTraces(clusters);
} else {
// -=-=-=-
// Tracing
// -=-=-=-
outputName = "Trace";
if (!showDialog()) {
return;
}
final TraceManager manager = new TraceManager(results);
manager.setTraceMode(getTraceMode(settings.getTraceMode()));
manager.setActivationFrameInterval(settings.getPulseInterval());
manager.setActivationFrameWindow(settings.getPulseWindow());
manager.setDistanceExclusion(getDistance(settings.getDistanceExclusion(), results.getCalibration()));
if (settings.getOptimise()) {
// Optimise before configuring for a pulse interval
runOptimiser(manager);
}
if (settings.getSplitPulses()) {
manager.setPulseInterval(settings.getPulseInterval());
limitTimeThreshold(settings.getPulseInterval());
}
manager.setTracker(SimpleImageJTrackProgress.getInstance());
manager.traceMolecules(getDistance(settings.getDistanceThreshold(), results.getCalibration()), timeThresholdInFrames());
traces = manager.getTraces();
totalFiltered = manager.getTotalFiltered();
}
// --=-=-=-=-=-
// Results processing
// --=-=-=-=-=-
outputName += (outputName.endsWith("e") ? "" : "e") + "d";
saveResults(results, traces, outputName);
// Save singles + single localisations in a trace
saveCentroidResults(results, getSingles(traces), outputName + " Singles");
final Trace[] multiTraces = getTraces(traces);
saveResults(results, multiTraces, outputName + " Multi");
// Save centroids
outputName += " Centroids";
final MemoryPeakResults tracedResults = saveCentroidResults(results, traces, outputName);
// Save traces separately
saveCentroidResults(results, multiTraces, outputName + " Multi");
// Sort traces by time to assist the results source in extracting frames sequentially.
// Do this before saving to assist in debugging using the saved traces file.
sortByTime(traces);
if (settings.getSaveTraces()) {
saveTraces(traces);
}
summarise(createSummaryTable(), traces, totalFiltered, settings.getDistanceThreshold(), timeThresholdInSeconds());
IJ.showStatus(String.format("%d localisations => %d traces (%d filtered)", results.size(), tracedResults.size(), totalFiltered));
}
Aggregations