use of uk.ac.sussex.gdsc.smlm.results.count.Counter in project GDSC-SMLM by aherbert.
the class Filter method filterSubset.
/**
* Filter the results.
*
* <p>Input PeakResults must be allocated a score for true positive, false positive, true negative
* and false negative (accessed via the object property get methods). The filter is run and
* results that pass accumulate scores for true positive and false positive, otherwise the scores
* are accumulated for true negative and false negative. The simplest scoring scheme is to mark
* valid results as tp=fn=1 and fp=tn=0 and invalid results the opposite.
*
* <p>The number of failures before each peak is stored in the origX property of the PeakResult.
*
* @param results the results
* @param score If not null will be populated with the fraction score [ tp, fp, tn, fn, p, n ]
* @return the filtered results
*/
public MemoryPeakResults filterSubset(MemoryPeakResults results, double[] score) {
final MemoryPeakResults newResults = new MemoryPeakResults();
final FrameCounter counter = new FrameCounter();
newResults.copySettings(results);
setup(results);
final double[] s = new double[4];
final Counter p = new Counter();
results.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
final boolean isPositive = accept(peak);
if (isPositive) {
peak.setOrigX(counter.getCount());
counter.reset();
newResults.add(peak);
} else {
counter.increment();
}
if (isPositive) {
p.increment();
s[TP] += peak.getTruePositiveScore();
s[FP] += peak.getFalsePositiveScore();
} else {
s[FN] += peak.getFalseNegativeScore();
s[TN] += peak.getTrueNegativeScore();
}
});
end();
if (score != null && score.length > 5) {
score[0] = s[TP];
score[1] = s[FP];
score[2] = s[TN];
score[3] = s[FN];
score[4] = p.getCount();
score[5] = (double) results.size() - p.getCount();
}
return newResults;
}
use of uk.ac.sussex.gdsc.smlm.results.count.Counter in project GDSC-SMLM by aherbert.
the class Filter method filterSubset.
/**
* Filter the results.
*
* <p>Input PeakResults must be allocated a score for true positive, false positive, true negative
* and false negative (accessed via the object property get methods). The filter is run and
* results that pass accumulate scores for true positive and false positive, otherwise the scores
* are accumulated for true negative and false negative. The simplest scoring scheme is to mark
* valid results as tp=fn=1 and fp=tn=0 and invalid results the opposite.
*
* <p>The number of consecutive rejections are counted per frame. When the configured number of
* failures is reached all remaining results for the frame are rejected. This assumes the results
* are ordered by the frame.
*
* <p>The number of failures before each peak is stored in the origX property of the PeakResult.
*
* @param results the results
* @param failures the number of failures to allow per frame before all peaks are rejected
* @param score If not null will be populated with the fraction score [ tp, fp, tn, fn, p, n ]
* @return the filtered results
*/
public MemoryPeakResults filterSubset(MemoryPeakResults results, final int failures, double[] score) {
final MemoryPeakResults newResults = new MemoryPeakResults();
final FrameCounter counter = new FrameCounter();
newResults.copySettings(results);
setup(results);
final double[] s = new double[4];
results.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
final boolean isPositive;
if (counter.getCount() > failures) {
isPositive = false;
} else {
isPositive = accept(peak);
}
if (isPositive) {
peak.setOrigX(counter.getCount());
counter.reset();
newResults.add(peak);
} else {
counter.increment();
}
if (isPositive) {
s[TP] += peak.getTruePositiveScore();
s[FP] += peak.getFalsePositiveScore();
} else {
s[FN] += peak.getFalseNegativeScore();
s[TN] += peak.getTrueNegativeScore();
}
});
end();
if (score != null && score.length > 5) {
score[0] = s[TP];
score[1] = s[FP];
score[2] = s[TN];
score[3] = s[FN];
score[4] = newResults.size();
score[5] = (double) results.size() - newResults.size();
}
return newResults;
}
use of uk.ac.sussex.gdsc.smlm.results.count.Counter in project GDSC-SMLM by aherbert.
the class Filter method fractionScore2.
/**
* Filter the results and return the performance score. Allows benchmarking the filter by marking
* the results as true or false.
*
* <p>Input PeakResults must be allocated a score for true positive, false positive, true negative
* and false negative (accessed via the object property get methods). The filter is run and
* results that pass accumulate scores for true positive and false positive, otherwise the scores
* are accumulated for true negative and false negative. The simplest scoring scheme is to mark
* valid results as tp=fn=1 and fp=tn=0 and invalid results the opposite.
*
* <p>The number of consecutive rejections are counted per frame. When the configured number of
* failures is reached all remaining results for the frame are rejected. This assumes the results
* are ordered by the frame.
*
* <p>Note that this method is to be used to score a set of results that may have been extracted
* from a larger set since the number of consecutive failures before each peak are expected to be
* stored in the origY property. Set this to zero and the results should be identical to
* {@link #fractionScore(List, int)}.
*
* @param resultsList a list of results to analyse
* @param failures the number of failures to allow per frame before all peaks are rejected
* @return the score
*/
public FractionClassificationResult fractionScore2(List<MemoryPeakResults> resultsList, final int failures) {
final double[] s = new double[4];
final Counter p = new Counter();
int negatives = 0;
for (final MemoryPeakResults peakResults : resultsList) {
setup(peakResults);
final FrameCounter counter = new FrameCounter();
peakResults.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
counter.increment(peak.getOrigY());
final boolean isPositive;
if (counter.getCount() > failures) {
isPositive = false;
} else {
isPositive = accept(peak);
}
if (isPositive) {
counter.reset();
} else {
counter.increment();
}
if (isPositive) {
p.increment();
s[TP] += peak.getTruePositiveScore();
s[FP] += peak.getFalsePositiveScore();
} else {
s[FN] += peak.getFalseNegativeScore();
s[TN] += peak.getTrueNegativeScore();
}
});
negatives += peakResults.size();
end();
}
negatives -= p.getCount();
return new FractionClassificationResult(s[TP], s[FP], s[TN], s[FN], p.getCount(), negatives);
}
use of uk.ac.sussex.gdsc.smlm.results.count.Counter in project GDSC-SMLM by aherbert.
the class Filter method filterSubset2.
/**
* Filter the results.
*
* <p>Input PeakResults must be allocated a score for true positive, false positive, true negative
* and false negative (accessed via the object property get methods). The filter is run and
* results that pass accumulate scores for true positive and false positive, otherwise the scores
* are accumulated for true negative and false negative. The simplest scoring scheme is to mark
* valid results as tp=fn=1 and fp=tn=0 and invalid results the opposite.
*
* <p>The number of consecutive rejections are counted per frame. When the configured number of
* failures is reached all remaining results for the frame are rejected. This assumes the results
* are ordered by the frame.
*
* <p>Note that this method is to be used to score a set of results that may have been extracted
* from a larger set since the number of consecutive failures before each peak are expected to be
* stored in the origY property. Set this to zero and the results should be identical to
* {@link #filterSubset(MemoryPeakResults, int, double[])}.
*
* <p>The number of failures before each peak is stored in the origX property of the PeakResult.
*
* @param results the results
* @param failures the number of failures to allow per frame before all peaks are rejected
* @param score If not null will be populated with the fraction score [ tp, fp, tn, fn, p, n ]
* @return the filtered results
*/
public MemoryPeakResults filterSubset2(MemoryPeakResults results, final int failures, double[] score) {
final MemoryPeakResults newResults = new MemoryPeakResults();
final FrameCounter counter = new FrameCounter();
newResults.copySettings(results);
setup(results);
final double[] s = new double[4];
results.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
counter.increment(peak.getOrigY());
final boolean isPositive;
if (counter.getCount() > failures) {
isPositive = false;
} else {
isPositive = accept(peak);
}
if (isPositive) {
peak.setOrigX(counter.getCount());
counter.reset();
newResults.add(peak);
} else {
counter.increment();
}
if (isPositive) {
s[TP] += peak.getTruePositiveScore();
s[FP] += peak.getFalsePositiveScore();
} else {
s[FN] += peak.getFalseNegativeScore();
s[TN] += peak.getTrueNegativeScore();
}
});
end();
if (score != null && score.length > 5) {
score[0] = s[TP];
score[1] = s[FP];
score[2] = s[TN];
score[3] = s[FN];
score[4] = newResults.size();
score[5] = (double) results.size() - newResults.size();
}
return newResults;
}
use of uk.ac.sussex.gdsc.smlm.results.count.Counter in project GDSC-SMLM by aherbert.
the class ResultsManager method run.
@Override
public void run(String arg) {
extraOptions = ImageJUtils.isExtraOptions();
SmlmUsageTracker.recordPlugin(this.getClass(), arg);
if ("load".equals(arg)) {
batchLoad();
return;
}
if ("save".equals(arg)) {
batchSave();
return;
}
if (StringUtils.startsWith(arg, "clear")) {
runClearMemory(arg);
return;
}
if (!showDialog()) {
return;
}
final MemoryPeakResults results = loadResults(settings.inputOption);
if (MemoryPeakResults.isEmpty(results)) {
IJ.error(TITLE, "No results could be loaded");
IJ.showStatus("");
return;
}
IJ.showStatus("Loaded " + TextUtils.pleural(results.size(), "result"));
boolean saved = false;
if (resultsSettings.getResultsInMemorySettings().getInMemory() && fileInput) {
if (!addResultsToMemory(results, settings.inputFilename)) {
IJ.showStatus("");
return;
}
saved = true;
}
if (resultsSettings.getResultsTableSettings().getResultsTableFormatValue() <= 0 && resultsSettings.getResultsImageSettings().getImageTypeValue() <= 0 && TextUtils.isNullOrEmpty(resultsSettings.getResultsFileSettings().getResultsFilename())) {
// No outputs. Error if results were not saved to memory
if (!saved) {
IJ.error(TITLE, "No output selected");
}
return;
}
final Rectangle bounds = results.getBounds(true);
final boolean showDeviations = resultsSettings.getShowDeviations() && canShowDeviations(results);
final boolean showEndFrame = canShowEndFrame(results);
final boolean showId = canShowId(results);
final boolean showCategory = canShowCategory(results);
// Display the configured output
final PeakResultsList outputList = new PeakResultsList();
outputList.copySettings(results);
final int tableFormat = resultsSettings.getResultsTableSettings().getResultsTableFormatValue();
if (tableFormat == ResultsTableFormat.IMAGEJ_VALUE) {
addImageJTableResults(outputList, resultsSettings.getResultsTableSettings(), showDeviations, showEndFrame, results.is3D(), showId, showCategory);
} else if (tableFormat == ResultsTableFormat.INTERACTIVE_VALUE) {
showInteractiveTable(results, resultsSettings.getResultsTableSettings());
}
addImageResults(outputList, resultsSettings.getResultsImageSettings(), bounds, (extraOptions) ? FLAG_EXTRA_OPTIONS : 0);
addFileResults(outputList, showDeviations, showEndFrame, showId, showCategory);
if (outputList.numberOfOutputs() == 0) {
// This occurs when only using the interactive table
IJ.showStatus("Processed " + TextUtils.pleural(results.size(), "result"));
return;
}
IJ.showStatus("Processing outputs ...");
// Reduce to single object for speed
final PeakResults output = (outputList.numberOfOutputs() == 1) ? outputList.toArray()[0] : outputList;
output.begin();
// Note: We could add a batch iterator to the MemoryPeakResults.
// However the speed increase will be marginal as the main time
// taken is in processing the outputs.
// Process in batches to provide progress
final Counter progress = new Counter();
final int totalProgress = results.size();
final int batchSize = Math.max(100, totalProgress / 10);
final FixedPeakResultList batch = new FixedPeakResultList(batchSize);
IJ.showProgress(0);
results.forEach((PeakResultProcedureX) result -> {
batch.add(result);
if (batch.size == batchSize) {
if (IJ.escapePressed()) {
batch.clear();
return true;
}
output.addAll(batch.results);
batch.clear();
IJ.showProgress(progress.incrementAndGet(batchSize), totalProgress);
}
return false;
});
// Will be empty if interrupted
if (batch.isNotEmpty()) {
output.addAll(batch.toArray());
}
IJ.showProgress(1);
output.end();
if (output.size() == results.size()) {
IJ.showStatus("Processed " + TextUtils.pleural(results.size(), "result"));
} else {
IJ.showStatus(String.format("A %d/%s", output.size(), TextUtils.pleural(results.size(), "result")));
}
}
Aggregations