use of uk.ac.sussex.gdsc.core.utils.LocalList in project GDSC-SMLM by aherbert.
the class DynamicMultipleTargetTracingTest method testTrajectory.
@Test
void testTrajectory() {
final PeakResult p1 = new PeakResult(0, 1, 2);
final PeakResult p2 = new PeakResult(1, 2, 3);
final PeakResult p3 = new PeakResult(2, 3, 4);
final PeakResult p4 = new PeakResult(3, 4, 5);
final Trajectory t = new Trajectory(42, p1, true);
Assertions.assertEquals(42, t.getId());
Assertions.assertSame(p1, t.getLast(-1));
Assertions.assertEquals(1, t.size());
Assertions.assertEquals(1, t.onSize());
t.add(p2, false);
t.add(p3, false);
t.add(p4, true);
Assertions.assertSame(p4, t.getLast(-1));
Assertions.assertSame(p3, t.getLast(-2));
Assertions.assertSame(p2, t.getLast(-3));
Assertions.assertSame(p1, t.getLast(-4));
Assertions.assertEquals(4, t.size());
Assertions.assertEquals(2, t.onSize());
final LocalList<PeakResult> list = new LocalList<>();
t.forLast(2, list::add);
Assertions.assertEquals(2, list.size());
Assertions.assertSame(p3, list.pop());
Assertions.assertSame(p4, list.pop());
t.forLastOn(2, list::add);
Assertions.assertEquals(2, list.size());
Assertions.assertSame(p1, list.pop());
Assertions.assertSame(p4, list.pop());
final Trace trace = t.toTrace();
Assertions.assertEquals(4, trace.size());
Assertions.assertEquals(42, trace.getId());
// Test setting the gap
final int frame = t.getLast(-1).getFrame();
for (int i = 1; i <= 3; i++) {
t.reset(frame + i);
Assertions.assertEquals(i - 1, t.gap);
}
// Test setting the local statistics
t.setLocalIntensity(10, 0);
Assertions.assertEquals(10, t.meanI);
Assertions.assertEquals(0, t.sdI);
Assertions.assertFalse(t.isLocalIntensity);
t.setLocalIntensity(9, 1);
Assertions.assertEquals(9, t.meanI);
Assertions.assertEquals(1, t.sdI);
Assertions.assertTrue(t.isLocalIntensity);
t.setLocalDiffusion(10, 9);
Assertions.assertEquals(10, t.r2);
Assertions.assertFalse(t.isLocalDiffusion);
t.setLocalDiffusion(9, 10);
Assertions.assertEquals(9, t.r2);
Assertions.assertTrue(t.isLocalDiffusion);
}
use of uk.ac.sussex.gdsc.core.utils.LocalList in project GDSC-SMLM by aherbert.
the class ErfGaussian2DFunctionTest method functionIsFasterThanEquivalentGaussian2DFunction.
// Speed test verses equivalent Gaussian2DFunction
@SpeedTag
@Test
void functionIsFasterThanEquivalentGaussian2DFunction() {
Assumptions.assumeTrue(TestSettings.allow(TestComplexity.MEDIUM));
final int flags = this.flags & ~GaussianFunctionFactory.FIT_ERF;
final Gaussian2DFunction gf = GaussianFunctionFactory.create2D(1, maxx, maxy, flags, zModel);
final boolean zDepth = (flags & GaussianFunctionFactory.FIT_Z) != 0;
final LocalList<double[]> params1 = new LocalList<>();
final LocalList<double[]> params2 = new LocalList<>();
for (final double background : testbackground) {
// Peak 1
for (final double signal1 : testsignal1) {
for (final double cx1 : testcx1) {
for (final double cy1 : testcy1) {
for (final double cz1 : testcz1) {
for (final double[] w1 : testw1) {
for (final double angle1 : testangle1) {
double[] params = createParameters(background, signal1, cx1, cy1, cz1, w1[0], w1[1], angle1);
params1.add(params);
if (zDepth) {
// Change to a standard free circular function
params = params.clone();
params[Gaussian2DFunction.X_SD] *= zModel.getSx(params[Gaussian2DFunction.Z_POSITION]);
params[Gaussian2DFunction.Y_SD] *= zModel.getSy(params[Gaussian2DFunction.Z_POSITION]);
params[Gaussian2DFunction.Z_POSITION] = 0;
params2.add(params);
}
}
}
}
}
}
}
}
final double[][] x = params1.toArray(new double[0][]);
final double[][] x2 = (zDepth) ? params2.toArray(new double[0][]) : x;
final int runs = 10000 / x.length;
final TimingService ts = new TimingService(runs);
ts.execute(new FunctionTimingTask(gf, x2, 1));
ts.execute(new FunctionTimingTask(gf, x2, 0));
ts.execute(new FunctionTimingTask(f1, x, 2));
ts.execute(new FunctionTimingTask(f1, x, 1));
ts.execute(new FunctionTimingTask(f1, x, 0));
final int size = ts.getSize();
ts.repeat(size);
if (logger.isLoggable(Level.INFO)) {
logger.info(ts.getReport());
}
for (int i = 1; i <= 2; i++) {
final TimingResult slow = ts.get(-i - 3);
final TimingResult fast = ts.get(-i);
logger.log(TestLogUtils.getTimingRecord(slow, fast));
}
}
use of uk.ac.sussex.gdsc.core.utils.LocalList in project GDSC-SMLM by aherbert.
the class CameraModelFisherInformationAnalysis method getAlpha.
private double[] getAlpha(final double[] photons, double[] exp, final BasePoissonFisherInformation fi, FiKey key) {
final CameraType type = key.getType();
final double[] alpha = new double[photons.length];
if (!type.isFast()) {
final int[] index;
// Try and load from the cache
final PoissonFisherInformationData data = load(key);
if (data != null) {
// Dump the samples
final TDoubleArrayList meanList = new TDoubleArrayList(data.getAlphaSampleCount());
final TDoubleArrayList alphalist = new TDoubleArrayList(data.getAlphaSampleCount());
for (final AlphaSample sample : data.getAlphaSampleList()) {
meanList.add(sample.getLog10Mean());
alphalist.add(sample.getAlpha());
}
final double[] exp2 = meanList.toArray();
final double[] alphas = alphalist.toArray();
SortUtils.sortData(alphas, exp2, true, false);
// Find any exponent not in the array
final TIntArrayList list = new TIntArrayList(exp.length);
for (int i = 0; i < exp.length; i++) {
// Assume exp2 is sorted
final int j = Arrays.binarySearch(exp2, exp[i]);
if (j < 0) {
// Add to indices to compute
list.add(i);
} else {
// Get alpha
alpha[i] = alphas[j];
}
}
index = list.toArray();
} else {
// Compute all
index = SimpleArrayUtils.natural(alpha.length);
}
if (index.length > 0) {
IJ.showStatus("Computing " + getName(key));
final int nThreads = Prefs.getThreads();
if (es == null) {
es = Executors.newFixedThreadPool(nThreads);
}
final Ticker ticker = ImageJUtils.createTicker(index.length, nThreads);
final int nPerThread = (int) Math.ceil((double) index.length / nThreads);
final LocalList<Future<?>> futures = new LocalList<>(nThreads);
for (int i = 0; i < index.length; i += nPerThread) {
final int start = i;
final int end = Math.min(index.length, i + nPerThread);
futures.add(es.submit(() -> {
final BasePoissonFisherInformation fi2 = fi.copy();
for (int ii = start; ii < end; ii++) {
final int j = index[ii];
alpha[j] = fi2.getAlpha(photons[j]);
ticker.tick();
}
}));
}
ConcurrencyUtils.waitForCompletionUnchecked(futures);
ImageJUtils.finished();
save(key, exp, alpha);
}
} else {
// Simple single threaded method.
for (int i = 0; i < alpha.length; i++) {
alpha[i] = fi.getAlpha(photons[i]);
}
}
return alpha;
}
use of uk.ac.sussex.gdsc.core.utils.LocalList in project GDSC-SMLM by aherbert.
the class CameraModelFisherInformationAnalysis method save.
/**
* Save the data to the cache.
*
* @param key the key
* @param log10photons the log 10 photons
* @param alpha the alpha
*/
private static void save(FiKey key, double[] log10photons, double[] alpha) {
final CameraType type = key.getType();
if (type.isFast()) {
return;
}
PoissonFisherInformationData data = cache.get(key);
if (data != null) {
// This should only be called if new values have been computed.
// so assume we must merge the lists.
// Note: The lists must be sorted.
final AlphaSample[] list1 = data.getAlphaSampleList().toArray(new AlphaSample[0]);
final LocalList<AlphaSample> list = new LocalList<>(list1.length + log10photons.length);
int i1 = 0;
int i2 = 0;
final AlphaSample.Builder a2 = AlphaSample.newBuilder();
while (i1 < list1.length && i2 < log10photons.length) {
final AlphaSample a1 = list1[i1];
final double mean = log10photons[i2];
if (a1.getLog10Mean() == mean) {
list.add(a1);
i1++;
i2++;
} else if (a1.getLog10Mean() < mean) {
list.add(a1);
i1++;
} else {
// (a1.getLog10Mean() > mean)
a2.setLog10Mean(mean);
a2.setAlpha(alpha[i2++]);
list.add(a2.build());
}
}
while (i1 < list1.length) {
list.add(list1[i1++]);
}
while (i2 < log10photons.length) {
a2.setLog10Mean(log10photons[i2]);
a2.setAlpha(alpha[i2++]);
list.add(a2.build());
}
final PoissonFisherInformationData.Builder b = data.toBuilder();
b.clearAlphaSample();
b.addAllAlphaSample(list);
data = b.build();
} else {
final PoissonFisherInformationData.Builder b = PoissonFisherInformationData.newBuilder();
final AlphaSample.Builder sample = AlphaSample.newBuilder();
b.setType(key.type);
b.setGain(key.gain);
b.setNoise(key.noise);
for (int i = 0; i < log10photons.length; i++) {
sample.setLog10Mean(log10photons[i]);
sample.setAlpha(alpha[i]);
b.addAlphaSample(sample);
}
data = b.build();
}
cache.put(key, data);
// Also save EM-CCD data to file
if (type == CameraType.EM_CCD) {
final int t = type.ordinal();
// Get the EM-CCD keys
final LocalList<FiKey> list = new LocalList<>(cache.size());
for (final FiKey k : cache.keySet()) {
if (k.type == t) {
list.add(k);
}
}
if (list.size() > MAX_DATA_TO_FILE) {
// Sort by age - Youngest first
list.sort((o1, o2) -> Long.compare(o2.timeStamp, o1.timeStamp));
}
final PoissonFisherInformationCache.Builder cacheData = PoissonFisherInformationCache.newBuilder();
for (int i = Math.min(list.size(), MAX_DATA_TO_FILE); i-- > 0; ) {
cacheData.addData(cache.get(list.unsafeGet(i)));
}
SettingsManager.writeSettings(cacheData);
}
}
use of uk.ac.sussex.gdsc.core.utils.LocalList in project GDSC-SMLM by aherbert.
the class DensityEstimator method run.
@Override
public void run(String arg) {
SmlmUsageTracker.recordPlugin(this.getClass(), arg);
// Require some fit results and selected regions
if (MemoryPeakResults.countMemorySize() == 0) {
IJ.error(TITLE, "There are no fitting results in memory");
return;
}
if (!showDialog()) {
return;
}
// Currently this only supports pixel distance units
final MemoryPeakResults results = ResultsManager.loadInputResults(settings.inputOption, false, DistanceUnit.PIXEL, null);
if (MemoryPeakResults.isEmpty(results)) {
IJ.error(TITLE, "No results could be loaded");
IJ.showStatus("");
return;
}
final long start = System.currentTimeMillis();
IJ.showStatus("Calculating density ...");
// Scale to um^2 from px^2
final double scale = Math.pow(results.getDistanceConverter(DistanceUnit.UM).convertBack(1), 2);
results.sort();
final FrameCounter counter = results.newFrameCounter();
final double localisationsPerFrame = (double) results.size() / (results.getLastFrame() - counter.currentFrame() + 1);
final Rectangle bounds = results.getBounds(true);
final double globalDensity = localisationsPerFrame / bounds.width / bounds.height;
final int border = settings.border;
final boolean includeSingles = settings.includeSingles;
final int size = 2 * border + 1;
final double minDensity = Math.pow(size, -2);
ImageJUtils.log("%s : %s : Global density %s. Minimum density in %dx%d px = %s um^-2", TITLE, results.getName(), MathUtils.rounded(globalDensity * scale), size, size, MathUtils.rounded(minDensity * scale));
final TIntArrayList x = new TIntArrayList();
final TIntArrayList y = new TIntArrayList();
final ExecutorService es = Executors.newFixedThreadPool(Prefs.getThreads());
final LocalList<FrameDensity> densities = new LocalList<>();
final LocalList<Future<?>> futures = new LocalList<>();
results.forEach((PeakResultProcedure) (peak) -> {
if (counter.advance(peak.getFrame())) {
final FrameDensity fd = new FrameDensity(peak.getFrame(), x.toArray(), y.toArray(), border, includeSingles);
densities.add(fd);
futures.add(es.submit(fd));
x.resetQuick();
y.resetQuick();
}
x.add((int) peak.getXPosition());
y.add((int) peak.getYPosition());
});
densities.add(new FrameDensity(counter.currentFrame(), x.toArray(), y.toArray(), border, includeSingles));
futures.add(es.submit(densities.get(densities.size() - 1)));
es.shutdown();
// Wait
ConcurrencyUtils.waitForCompletionUnchecked(futures);
densities.sort((o1, o2) -> Integer.compare(o1.frame, o2.frame));
final int total = densities.stream().mapToInt(fd -> fd.counts.length).sum();
// Plot density
final Statistics stats = new Statistics();
final float[] frame = new float[total];
final float[] density = new float[total];
densities.stream().forEach(fd -> {
for (int i = 0; i < fd.counts.length; i++) {
final double d = (fd.counts[i] / fd.values[i]) * scale;
frame[stats.getN()] = fd.frame;
density[stats.getN()] = (float) d;
stats.add(d);
}
});
final double mean = stats.getMean();
final double sd = stats.getStandardDeviation();
final String label = String.format("Density = %s +/- %s um^-2", MathUtils.rounded(mean), MathUtils.rounded(sd));
final Plot plot = new Plot("Frame vs Density", "Frame", "Density (um^-2)");
plot.addPoints(frame, density, Plot.CIRCLE);
plot.addLabel(0, 0, label);
final WindowOrganiser wo = new WindowOrganiser();
ImageJUtils.display(plot.getTitle(), plot, wo);
// Histogram density
new HistogramPlotBuilder("Local", StoredData.create(density), "Density (um^-2)").setPlotLabel(label).show(wo);
wo.tile();
// Log the number of singles
final int singles = densities.stream().mapToInt(fd -> fd.singles).sum();
ImageJUtils.log("Singles %d / %d (%s%%)", singles, results.size(), MathUtils.rounded(100.0 * singles / results.size()));
IJ.showStatus(TITLE + " complete : " + TextUtils.millisToString(System.currentTimeMillis() - start));
}
Aggregations