use of gdsc.smlm.ij.plugins.BenchmarkSpotFilter.FilterResult in project GDSC-SMLM by aherbert.
the class BenchmarkSpotFit method subsetFilterResults.
/**
* Extract all the filter candidates in order until the desired number of positives have been reached and the number
* of negatives matches the configured parameters.
*
* @param filterResults
* @return The filter candidates
*/
private TIntObjectHashMap<FilterCandidates> subsetFilterResults(TIntObjectHashMap<FilterResult> filterResults, int fitting) {
// Convert fractions from percent
final double f1 = Math.min(1, fractionPositives / 100.0);
final double f2 = fractionNegativesAfterAllPositives / 100.0;
final int[] counter = new int[2];
final TIntObjectHashMap<FilterCandidates> subset = new TIntObjectHashMap<FilterCandidates>();
fP = fN = 0;
nP = nN = 0;
final double[] fX = new double[2];
final int[] nX = new int[2];
filterResults.forEachEntry(new TIntObjectProcedure<FilterResult>() {
public boolean execute(int frame, FilterResult r) {
// Determine the number of positives to find. This score may be fractional.
fX[0] += r.result.getTP();
fX[1] += r.result.getFP();
// Q. Is r.result.getTP() not the same as the total of r.spots[i].match?
// A. Not if we used fractional scoring.
int c = 0;
for (int i = r.spots.length; i-- > 0; ) {
if (r.spots[i].match)
c++;
}
nX[0] += c;
nX[1] += (r.spots.length - c);
// Make the target use the fractional score
final double np2 = r.result.getTP() * f1;
double targetP = np2;
// Set the target using the closest
if (f1 < 1) {
double np = 0;
double min = r.result.getTP();
for (ScoredSpot spot : r.spots) {
if (spot.match) {
np += spot.getScore();
double d = np2 - np;
if (d < min) {
min = d;
targetP = np;
} else {
break;
}
}
}
//if (targetP < np2)
// System.out.printf("np2 = %.2f, targetP = %.2f\n", np2, targetP);
}
// Count the number of positive & negatives
int p = 0, n = 0;
double np = 0, nn = 0;
boolean reachedTarget = false;
int nAfter = 0;
int count = 0;
for (ScoredSpot spot : r.spots) {
count++;
nn += spot.antiScore();
if (spot.match) {
np += spot.getScore();
p++;
if (!reachedTarget) {
reachedTarget = np >= targetP;
}
} else {
n++;
if (reachedTarget) {
nAfter++;
}
}
if (reachedTarget) {
// Check if we have reached both the limits
if (nAfter >= negativesAfterAllPositives && (double) n / (n + p) >= f2)
break;
}
}
counter[0] += count;
counter[1] += r.spots.length;
// Debug
//System.out.printf("Frame %d : %.1f / (%.1f + %.1f). p=%d, n=%d, after=%d, f=%.1f\n", result.getKey().intValue(),
// r.result.getTP(), r.result.getTP(), r.result.getFP(), p, n,
// nAfter, (double) n / (n + p));
// We can use all the candidates but only fit up to count
subset.put(frame, new FilterCandidates(p, n, np, nn, r.spots, count));
return true;
}
});
fP = fX[0];
fN = fX[1];
nP = nX[0];
nN = nX[1];
// We now add all the candidates but only fit the first N
int target = counter[0];
int total = counter[1];
int added = total - target;
if (extraOptions && added > target)
Utils.log("Added %s to %s (total = %d)", Utils.pleural(added, "neighbour"), Utils.pleural(target, "candidate"), total);
return subset;
}
Aggregations