use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.
the class FilterAnalysis method run.
private ClassificationResult run(Filter filter, List<MemoryPeakResults> resultsList) {
ClassificationResult s = filter.score(resultsList);
if (showResultsTable) {
StringBuilder sb = new StringBuilder();
sb.append(filter.getName()).append("\t");
sb.append(s.getTP() + s.getFP()).append("\t");
sb.append(s.getTP()).append("\t");
sb.append(s.getFP()).append("\t");
sb.append(s.getTN()).append("\t");
sb.append(s.getFN()).append("\t");
sb.append(s.getJaccard()).append("\t");
sb.append(s.getPrecision()).append("\t");
sb.append(s.getRecall()).append("\t");
sb.append(s.getF1Score());
if (isHeadless) {
IJ.log(sb.toString());
} else {
resultsWindow.append(sb.toString());
}
}
return s;
}
use of gdsc.core.match.ClassificationResult 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.
*
* @param resultsList
* a list of results to analyse
* @return the score
*/
public ClassificationResult score(List<MemoryPeakResults> resultsList) {
int tp = 0, fp = 0, tn = 0, fn = 0;
for (MemoryPeakResults peakResults : resultsList) {
setup(peakResults);
for (PeakResult peak : peakResults.getResults()) {
final boolean isTrue = peak.origValue != 0;
boolean isPositive = accept(peak);
if (isTrue) {
if (isPositive)
// true positive
tp++;
else
// false negative
fn++;
} else {
if (isPositive)
// false positive
fp++;
else
// true negative
tn++;
}
}
end();
}
return new ClassificationResult(tp, fp, tn, fn);
}
use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.
the class BenchmarkFilterAnalysis method score.
private ComplexFilterScore score(DirectFilter f, int i, int size, int[] combinations, boolean[] enable, int[] uniqueIds1, int uniqueIdCount1) {
setupFractionScoreStore();
// Score them
long time = System.nanoTime();
FilterScoreResult r = scoreFilter(f);
time = System.nanoTime() - time;
endFractionScoreStore();
ClassificationResult r2 = null;
if (uniqueIds1 != null) {
// Build an overlap between the results created by this filter and the best filter.
// Note that the overlap may be very low given the number of different ways we can generate
// fit results (i.e. it is not as simple as just single-fitting on each candidate)
// To do this we assign a unique ID to each possible result.
// The two sets can be compared to produce a Precision, Recall, Jaccard, etc.
// PreprocessedPeakResult will need an additional mutable Id field.
// Sort by Id then iterate through both arrays concurrently counting the matching Ids.
int[] uniqueIds2 = uniqueIds;
int uniqueIdCount2 = uniqueIdCount;
int tp = 0, fp = 0, fn = 0;
// Compare Ids (must be sorted in ascending order)
int i1 = 0, i2 = 0;
while (i1 < uniqueIdCount1 && i2 < uniqueIdCount2) {
final int result = uniqueIds1[i1] - uniqueIds2[i2];
if (result > 0) {
i2++;
fp++;
} else if (result < 0) {
i1++;
fn++;
}
i1++;
i2++;
tp++;
}
// Count the remaining ids
fn += (uniqueIdCount1 - i1);
fp += (uniqueIdCount2 - i2);
r2 = new ClassificationResult(tp, fp, 0, fn);
}
// These scores are used when the same filter type so set allSameType to true
return new ComplexFilterScore(r, true, i, time, r2, size, combinations, enable);
}
use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.
the class BenchmarkFilterAnalysis method createResult.
public StringBuilder createResult(DirectFilter filter, FractionClassificationResult r, String resultsPrefix2) {
StringBuilder sb = new StringBuilder(resultsPrefix);
sb.append(filter.getName()).append(resultsPrefix2).append(resultsPrefix3);
int i = 0;
// TODO - Fix the scores that we show since we no longer have TN results
// We could set:
// TN as any candidate that does not match a true result.
// FN as any candidate that does match a true result (that is not matched by any fit result)
// To do this properly would require that we store all the matches of candidates to the data.
// These can then be totalled up given the candidates that have not been used to create a positive.
// Integer results
final ClassificationResult r2 = (requireIntegerResults) ? createIntegerResult(r) : null;
add(sb, r2.getTP(), i++);
add(sb, r2.getFP(), i++);
add(sb, r2.getFN(), i++);
add(sb, r2.getPrecision(), i++);
add(sb, r2.getRecall(), i++);
add(sb, r2.getF1Score(), i++);
add(sb, r2.getJaccard(), i++);
addCount(sb, r.getTP(), i++);
addCount(sb, r.getFP(), i++);
addCount(sb, r.getFN(), i++);
add(sb, r.getPrecision(), i++);
add(sb, r.getRecall(), i++);
add(sb, r.getF1Score(), i++);
add(sb, r.getJaccard(), i++);
return sb;
}
use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.
the class FilterAnalysis method calculateSensitivity.
private void calculateSensitivity(List<MemoryPeakResults> resultsList) {
if (!calculateSensitivity)
return;
if (!bestFilter.isEmpty()) {
IJ.showStatus("Calculating sensitivity ...");
createSensitivityWindow();
int currentIndex = 0;
for (String type : bestFilterOrder) {
IJ.showProgress(currentIndex++, bestFilter.size());
Filter filter = bestFilter.get(type).filter;
ClassificationResult s = filter.score(resultsList);
String message = type + "\t\t\t" + Utils.rounded(s.getJaccard(), 4) + "\t\t" + Utils.rounded(s.getPrecision(), 4) + "\t\t" + Utils.rounded(s.getRecall(), 4);
if (isHeadless) {
IJ.log(message);
} else {
sensitivityWindow.append(message);
}
// List all the parameters that can be adjusted.
final int parameters = filter.getNumberOfParameters();
for (int index = 0; index < parameters; index++) {
// For each parameter compute as upward + downward delta and get the average gradient
Filter higher = filter.adjustParameter(index, delta);
Filter lower = filter.adjustParameter(index, -delta);
ClassificationResult sHigher = higher.score(resultsList);
ClassificationResult sLower = lower.score(resultsList);
StringBuilder sb = new StringBuilder();
sb.append("\t").append(filter.getParameterName(index)).append("\t");
sb.append(Utils.rounded(filter.getParameterValue(index), 4)).append("\t");
double dx1 = higher.getParameterValue(index) - filter.getParameterValue(index);
double dx2 = filter.getParameterValue(index) - lower.getParameterValue(index);
addSensitivityScore(sb, s.getJaccard(), sHigher.getJaccard(), sLower.getJaccard(), dx1, dx2);
addSensitivityScore(sb, s.getPrecision(), sHigher.getPrecision(), sLower.getPrecision(), dx1, dx2);
addSensitivityScore(sb, s.getRecall(), sHigher.getRecall(), sLower.getRecall(), dx1, dx2);
if (isHeadless) {
IJ.log(sb.toString());
} else {
sensitivityWindow.append(sb.toString());
}
}
}
String message = "-=-=-=-";
if (isHeadless) {
IJ.log(message);
} else {
sensitivityWindow.append(message);
}
IJ.showProgress(1);
IJ.showStatus("");
}
}
Aggregations