use of uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure in project GDSC-SMLM by aherbert.
the class Filter method filter2.
/**
* Filter the results.
*
* <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 #filter(MemoryPeakResults, int)}
*
* @param results the results
* @param failures the number of failures to allow per frame before all peaks are rejected
* @return the filtered results
*/
public MemoryPeakResults filter2(MemoryPeakResults results, final int failures) {
final MemoryPeakResults newResults = new MemoryPeakResults();
final FrameCounter counter = new FrameCounter();
newResults.copySettings(results);
setup(results);
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) {
counter.reset();
newResults.add(peak);
} else {
counter.increment();
}
});
end();
return newResults;
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure in project GDSC-SMLM by aherbert.
the class Filter method scoreSubset.
/**
* Filter the results and return the performance score. Allows benchmarking the filter by marking
* the results as true or false.
*
* <p>Any input PeakResult with an original value that is not zero will be treated as a true
* result, all other results are false. The filter is run and the results are marked as true
* positive, false negative and false positive.
*
* <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 subset that was generated using
* {@link #filterSubset(MemoryPeakResults, int, double[])} since the number of consecutive
* failures before each peak are expected to be stored in the origX property.
*
* @param resultsList a list of results to analyse
* @param failures the number of failures to allow per frame before all peaks are rejected
* @param tn The initial true negatives (used when the results have been pre-filtered)
* @param fn The initial false negatives (used when the results have been pre-filtered)
* @return the score
*/
public ClassificationResult scoreSubset(List<MemoryPeakResults> resultsList, final int failures, int tn, int fn) {
final int[] s = new int[4];
s[TN] = tn;
s[FN] = fn;
for (final MemoryPeakResults peakResults : resultsList) {
setup(peakResults);
final FrameCounter counter = new FrameCounter();
peakResults.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
final boolean isTrue = peak.getOrigValue() != 0;
counter.increment(peak.getOrigX());
final boolean isPositive;
if (counter.getCount() > failures) {
isPositive = false;
} else {
isPositive = accept(peak);
}
if (isPositive) {
counter.reset();
} else {
counter.increment();
}
if (isTrue) {
if (isPositive) {
s[TP]++;
} else {
s[FN]++;
}
} else if (isPositive) {
s[FP]++;
} else {
s[TN]++;
}
});
end();
}
return new ClassificationResult(s[TP], s[FP], s[TN], s[FN]);
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure 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.procedures.PeakResultProcedure in project GDSC-SMLM by aherbert.
the class Filter method score.
/**
* Filter the results and return the performance score. Allows benchmarking the filter by marking
* the results as true or false.
*
* <p>Any input PeakResult with an original value that is not zero will be treated as a true
* result, all other results are false. The filter is run and the results are marked as true
* positive, false negative and false positive.
*
* <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.
*
* @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 ClassificationResult score(List<MemoryPeakResults> resultsList, final int failures) {
final int[] s = new int[4];
for (final MemoryPeakResults peakResults : resultsList) {
setup(peakResults);
final FrameCounter counter = new FrameCounter();
peakResults.forEach((PeakResultProcedure) peak -> {
counter.advanceAndReset(peak.getFrame());
final boolean isTrue = peak.getOrigValue() != 0;
final boolean isPositive;
if (counter.getCount() > failures) {
isPositive = false;
} else {
isPositive = accept(peak);
}
if (isPositive) {
counter.reset();
} else {
counter.increment();
}
if (isTrue) {
if (isPositive) {
s[TP]++;
} else {
s[FN]++;
}
} else if (isPositive) {
s[FP]++;
} else {
s[TN]++;
}
});
end();
}
return new ClassificationResult(s[TP], s[FP], s[TN], s[FN]);
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure in project GDSC-SMLM by aherbert.
the class PeakResultsReaderTest method writeMatchesRead.
// -=-=-=-=-
private static void writeMatchesRead(RandomSeed seed, boolean sequential, ResultsFileFormat fileFormat, boolean showDeviations, boolean showEndFrame, boolean showId, boolean showPrecision, boolean showCategory, boolean sort) {
final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
final MemoryPeakResults out = createResults(rg, 200, showDeviations, showEndFrame, showId, showPrecision, showCategory);
if (fileFormat == ResultsFileFormat.MALK) {
final CalibrationWriter cal = new CalibrationWriter(out.getCalibration());
cal.setDistanceUnit(DistanceUnit.NM);
cal.setIntensityUnit(IntensityUnit.PHOTON);
out.setCalibration(cal.getCalibration());
out.setPsf(PsfHelper.create(PSFType.CUSTOM));
}
if (fileFormat == ResultsFileFormat.TSF) {
final CalibrationWriter cal = new CalibrationWriter(out.getCalibration());
// For now just support using the native float TSF datatype
cal.setNmPerPixel((float) cal.getNmPerPixel());
out.setCalibration(cal.getCalibration());
// TSF converts the width parameters so make sure they are not zero
out.forEach(new PeakResultProcedure() {
@Override
public void execute(PeakResult peakResult) {
check(peakResult.getParameters());
if (showDeviations) {
check(peakResult.getParameterDeviations());
}
}
private void check(float[] parameters) {
for (int i = 0; i < parameters.length; i++) {
if (parameters[i] == 0) {
parameters[i] = 0.1f;
}
}
}
});
}
// System.out.println(out.getCalibration());
// System.out.println(out.getPSF().toString());
//
// System.out.println(TextFormat.shortDebugString(out.getCalibration()));
//
// try
// {
// Printer printer = JsonFormat.printer()
// .omittingInsignificantWhitespace()
// //.includingDefaultValueFields()
// ;
// System.out.println(printer.print(out.getCalibration()));
// System.out.println(printer.print(out.getPSF()));
// }
// catch (InvalidProtocolBufferException e)
// {
// // This shouldn't happen so throw it
// }
final String filename = createFile();
writeFile(sequential, fileFormat, showDeviations, showEndFrame, showId, showPrecision, showCategory, sort, out, filename);
final MemoryPeakResults in = readFile(filename, false);
checkEqual(fileFormat, showDeviations, showEndFrame, showId, showPrecision, showCategory, sort, out, in);
}
Aggregations