use of uk.ac.sussex.gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class PeakResultTableModelFrameDemo method main.
/**
* Launch the application.
*
* @param args the arguments
*/
public static void main(String[] args) {
final SplitMix r = SplitMix.new64(System.currentTimeMillis());
final int n = 20;
final ListSelectionModel selectionModel = new DefaultListSelectionModel();
EventQueue.invokeLater((Runnable) () -> {
try {
final PeakResultStoreList store = new ArrayPeakResultStore(10);
for (int i = n; i-- > 0; ) {
store.add(new PeakResult(r.nextInt(), r.nextInt(), r.nextInt(), r.nextFloat(), r.nextDouble(), r.nextFloat(), r.nextFloat(), PeakResult.createParams(r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat()), null));
}
final CalibrationWriter cw = new CalibrationWriter();
cw.setNmPerPixel(100);
cw.setCountPerPhoton(10);
cw.setDistanceUnit(DistanceUnit.PIXEL);
cw.setIntensityUnit(IntensityUnit.COUNT);
final ResultsTableSettings.Builder tableSettings = ResultsTableSettings.newBuilder();
tableSettings.setDistanceUnit(DistanceUnit.NM);
tableSettings.setIntensityUnit(IntensityUnit.PHOTON);
tableSettings.setShowFittingData(true);
tableSettings.setShowNoiseData(true);
tableSettings.setShowPrecision(true);
tableSettings.setRoundingPrecision(4);
final PeakResultTableModel model = new PeakResultTableModel(store, cw.getCalibration(), null, tableSettings.build());
final PeakResultTableModelFrame d = new PeakResultTableModelFrame(model, null, selectionModel);
d.setTitle("D");
d.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
d.setVisible(true);
// Selecting in one list activates the other list
final PeakResultTableModelFrame d2 = new PeakResultTableModelFrame(model, null, selectionModel);
d2.setTitle("D2");
// Since we have the same selection model we need the same row sorter,
// otherwise the selection is scrambled by sorting.
// The alternative would be to get the source for the selection event (the table)
// and get the row sorter to do the mapping.
// However this breaks deletion of data as the row sorter double processes the deletion.
// Basically only one table can use the same selection model when sorting is desired.
// d2.table.setRowSorter(d.table.getRowSorter())
d2.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
d2.setVisible(true);
} catch (final Exception ex) {
ex.printStackTrace();
}
});
}
use of uk.ac.sussex.gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class ResultsManagerTest method checkEqual.
private static void checkEqual(Spot[] spots, int channel, int slice, int position, int type, MemoryPeakResults actualResults) {
Assertions.assertNotNull(actualResults, "Input results are null");
final MemoryPeakResults expectedResults = extract(spots, channel, slice, position, type);
Assertions.assertEquals(expectedResults.size(), actualResults.size(), "Size differ");
final PeakResult[] expected = expectedResults.toArray();
final PeakResult[] actual = actualResults.toArray();
for (int i = 0; i < actualResults.size(); i++) {
final int ii = i;
final PeakResult p1 = expected[i];
final PeakResult p2 = actual[i];
Assertions.assertEquals(p1.getFrame(), p2.getFrame(), () -> "Peak mismatch @ " + ii);
Assertions.assertEquals(p1.getOrigX(), p2.getOrigX(), () -> "Orig X mismatch @ " + ii);
Assertions.assertEquals(p1.getOrigY(), p2.getOrigY(), () -> "Orig Y mismatch @ " + ii);
Assertions.assertEquals(p1.getOrigValue(), p2.getOrigValue(), () -> "Orig value mismatch @ " + ii);
Assertions.assertEquals(p1.getError(), p2.getError(), 1e-6, () -> "Error mismatch @ " + ii);
Assertions.assertEquals(p1.getNoise(), p2.getNoise(), () -> "Noise mismatch @ " + ii);
Assertions.assertNotNull(p2.getParameters(), () -> "Params is null @ " + ii);
Assertions.assertEquals(p1.getBackground(), p2.getBackground(), () -> "Background mismatch @ " + ii);
Assertions.assertEquals(p1.getIntensity(), p2.getIntensity(), () -> "Signal mismatch @ " + ii);
Assertions.assertEquals(p1.getXPosition(), p2.getXPosition(), () -> "XPosition mismatch @ " + ii);
Assertions.assertEquals(p1.getYPosition(), p2.getYPosition(), () -> "YPosition mismatch @ " + ii);
Assertions.assertEquals(p1.getZPosition(), p2.getZPosition(), () -> "ZPosition mismatch @ " + ii);
for (int j = PeakResult.STANDARD_PARAMETERS, size = p1.getNumberOfParameters(); j < size; j++) {
Assertions.assertEquals(p1.getParameter(j), p2.getParameter(j), 1e-6, () -> "Parameter mismatch @ " + ii);
}
Assertions.assertEquals(p1.getId(), p2.getId(), () -> "ID mismatch @ " + ii);
}
}
use of uk.ac.sussex.gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class ImageJImagePeakResults method addAll.
@Override
public void addAll(PeakResult[] results) {
if (!imageActive) {
return;
}
final int[] indices = new int[5];
final float[] values = new float[4];
int npoints = 0;
int nvalues = 0;
// Buffer output in batches
final int[] allIndices = new int[100];
final float[] allValues = new float[allIndices.length];
// We add at most 4 indices for each peak
final int limit = allIndices.length - 4;
for (final PeakResult result : results) {
final float x = mapX(result.getXPosition());
final float y = mapY(result.getYPosition());
// Check bounds
if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight) {
continue;
}
if (shouldUpdate(result.getFrame())) {
addData(npoints, nvalues, allIndices, allValues);
npoints = 0;
nvalues = 0;
updateToFrame(result.getFrame());
}
getValue(result.getFrame(), result.getId(), result.getParameters(), result.getError(), x, y, indices, values);
for (int i = indices[4]; i-- > 0; ) {
allIndices[nvalues] = indices[i];
allValues[nvalues] = values[i];
nvalues++;
}
npoints++;
if (nvalues > limit) {
addData(npoints, nvalues, allIndices, allValues);
npoints = 0;
nvalues = 0;
updateImage();
if (!imageActive) {
return;
}
}
}
// Now add the values to the configured indices
addData(npoints, nvalues, allIndices, allValues);
updateImage();
}
use of uk.ac.sussex.gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class ResultsImageSampler method getSample.
/**
* Gets the sample image. The image is a stack of the samples with an overlay of the localisation
* positions. The info property is set with details of the localisations and the image is
* calibrated.
*
* @param countNo the number of samples with no localisations
* @param countLow the number of samples with low localisations
* @param countHigh the number of samples with high localisations
* @return the sample image (could be null if no samples were made)
*/
public ImagePlus getSample(int countNo, int countLow, int countHigh) {
final ImageStack out = new ImageStack(size, size);
if (!isValid()) {
return null;
}
sampleList.clear();
// empty
for (final int i : RandomUtils.sample(countNo, no.length, rng)) {
sampleList.add(ResultsSample.createEmpty(no[i]));
}
// low
for (final int i : RandomUtils.sample(countLow, lower, rng)) {
sampleList.add(data[i]);
}
// high
for (final int i : RandomUtils.sample(countHigh, upper, rng)) {
sampleList.add(data[i + lower]);
}
if (sampleList.isEmpty()) {
return null;
}
double nmPerPixel = 1;
if (results.hasCalibration()) {
final CalibrationReader calibration = results.getCalibrationReader();
if (calibration.hasNmPerPixel()) {
nmPerPixel = calibration.getNmPerPixel();
}
}
// Sort descending by number in the frame
final ResultsSample[] samples = sampleList.toArray(new ResultsSample[0]);
Arrays.sort(samples, ReverseCountComparator.INSTANCE);
final int[] xyz = new int[3];
final Rectangle stackBounds = new Rectangle(stack.getWidth(), stack.getHeight());
final Overlay overlay = new Overlay();
final StringBuilder sb = new StringBuilder();
if (nmPerPixel == 1) {
sb.append("Sample X Y Z Signal\n");
} else {
sb.append("Sample X(nm) Y(nm) Z(nm) Signal\n");
}
for (final ResultsSample sample : samples) {
getXyz(sample.index, xyz);
// Construct the region to extract
Rectangle target = new Rectangle(xyz[0], xyz[1], size, size);
target = target.intersection(stackBounds);
if (target.width == 0 || target.height == 0) {
continue;
}
// Extract the frame
final int slice = xyz[2];
final ImageProcessor ip = stack.getProcessor(slice);
// Cut out the desired pixels (some may be blank if the block overruns the source image)
final ImageProcessor ip2 = ip.createProcessor(size, size);
for (int y = 0; y < target.height; y++) {
for (int x = 0, i = y * size, index = (y + target.y) * ip.getWidth() + target.x; x < target.width; x++, i++, index++) {
ip2.setf(i, ip.getf(index));
}
}
final int sampleSize = sample.size();
if (sampleSize > 0) {
final float[] ox = new float[sampleSize];
final float[] oy = new float[sampleSize];
final int position = out.getSize() + 1;
// Create an ROI with the localisations
for (int i = 0; i < sampleSize; i++) {
final PeakResult p = sample.list.get(i);
ox[i] = p.getXPosition() - xyz[0];
oy[i] = p.getYPosition() - xyz[1];
sb.append(position).append(' ');
sb.append(MathUtils.rounded(ox[i] * nmPerPixel)).append(' ');
sb.append(MathUtils.rounded(oy[i] * nmPerPixel)).append(' ');
sb.append(MathUtils.rounded(p.getZPosition() * nmPerPixel)).append(' ');
sb.append(MathUtils.rounded(p.getIntensity())).append('\n');
}
final PointRoi roi = new OffsetPointRoi(ox, oy, sampleSize);
roi.setPosition(position);
overlay.add(roi);
}
out.addSlice(String.format("Frame=%d @ %d,%d px (n=%d)", slice, xyz[0], xyz[1], sampleSize), ip2.getPixels());
}
if (out.getSize() == 0) {
return null;
}
final ImagePlus imp = new ImagePlus("Sample", out);
imp.setOverlay(overlay);
// Note: Only the info property can be saved to a TIFF file
imp.setProperty("Info", sb.toString());
if (nmPerPixel != 1) {
final ij.measure.Calibration cal = new ij.measure.Calibration();
cal.setUnit("nm");
cal.pixelHeight = cal.pixelWidth = nmPerPixel;
imp.setCalibration(cal);
}
return imp;
}
use of uk.ac.sussex.gdsc.smlm.results.PeakResult 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;
}
Aggregations