use of uk.ac.sussex.gdsc.core.ij.ImageJTrackProgress in project GDSC-SMLM by aherbert.
the class ImageJ3DResultsViewer method createMesh.
@SuppressWarnings("unused")
private static CustomMesh createMesh(final ImageJ3DResultsViewerSettingsOrBuilder settings, LocalList<Point3f> points, final Point3f[] sphereSize, float transparency, float[] alpha) {
// Coordinates + color
int stride = 3 + 3;
if (alpha != null) {
// add color alpha
stride++;
}
// Support drawing as points ...
if (settings.getRendering() == 0) {
final long arraySize = (long) points.size() * stride;
if (arraySize > CustomContentHelper.MAX_ARRAY_SIZE) {
final double capacity = (double) arraySize / CustomContentHelper.MAX_ARRAY_SIZE;
// @formatter:off
IJ.error(TITLE, TextUtils.wrap(String.format("The results will generate data of %d values. " + "This is amount of data is not supported (%.2fx capacity). " + "Please choose a different dataset with fewer points.", arraySize, capacity), 80));
// @formatter:on
return null;
}
CustomPointMesh mesh;
if (alpha != null) {
final TransparentItemPointMesh mesh2 = new TransparentItemPointMesh(points, null, transparency);
mesh = mesh2;
mesh2.setItemAlpha(alpha);
} else {
mesh = new ItemPointMesh(points, null, transparency);
}
mesh.setPointSize(sphereSize[0].x);
return mesh;
}
final Rendering r = Rendering.forNumber(settings.getRendering());
// Repeated mesh creation is much faster as the normals are cached.
// There does not appear to be a difference in the speed the image responds
// to user interaction between indexed or standard triangles.
// Currently the RepeatedIndexedTriangleMesh computes the normals a different way to
// the super class to preserve the orientation of the normals. So if the coordinates
// are modified through the mesh then the appearance will change. For now just use
// the RepeatedTriangleMesh.
// TODO - check this. It may not be true if the shading mode is flat...
// Also the IndexedTriangleMesh has one normal per vertex and this causes a colour fall-off
// on the triangle plane towards the edges. The TriangleMesh colours the entire surface
// of each triangle the same which looks 'normal'.
final List<Point3f> point = Shape3DHelper.createLocalisationObject(r);
// + normals
stride += 3;
final int singlePointSize = point.size();
final long size = (long) points.size() * singlePointSize;
final long arraySize = size * stride;
if (arraySize > CustomContentHelper.MAX_ARRAY_SIZE) {
final double capacity = (double) arraySize / CustomContentHelper.MAX_ARRAY_SIZE;
// @formatter:off
IJ.error(TITLE, TextUtils.wrap(String.format("The results will generate data of %d values. " + "This is amount of data is not supported (%.2fx capacity). " + "Please choose a different rendering model with fewer vertices.", arraySize, capacity), 80));
// @formatter:on
return null;
}
if (size > 10000000L) {
final ExtendedGenericDialog egd = new ExtendedGenericDialog(TITLE);
egd.addMessage("The results will generate a large mesh of " + size + " vertices.\nThis may take a long time to render and may run out of memory.");
egd.setOKLabel("Continue");
egd.showDialog();
if (egd.wasCanceled()) {
return null;
}
}
IJ.showStatus("Creating 3D mesh ...");
final double creaseAngle = (r.isHighResolution()) ? 44 : 0;
// Used for debugging construction time
final ImageJTrackProgress progress = null;
if (alpha != null) {
final TransparentItemTriangleMesh mesh = new TransparentItemTriangleMesh(point.toArray(new Point3f[singlePointSize]), points.toArray(new Point3f[0]), sphereSize, null, transparency, creaseAngle, progress);
mesh.setItemAlpha(alpha);
return mesh;
}
return new ItemTriangleMesh(point.toArray(new Point3f[singlePointSize]), points.toArray(new Point3f[0]), sphereSize, null, transparency, creaseAngle, progress);
}
use of uk.ac.sussex.gdsc.core.ij.ImageJTrackProgress in project GDSC-SMLM by aherbert.
the class CmosAnalysis method simulate.
private void simulate() throws IOException {
// Create the offset, variance and gain for each pixel
final int n = settings.size * settings.size;
final float[] pixelOffset = new float[n];
final float[] pixelVariance = new float[n];
final float[] pixelGain = new float[n];
IJ.showStatus("Creating random per-pixel readout");
final long start = System.currentTimeMillis();
final UniformRandomProvider rg = UniformRandomProviders.create();
final DiscreteSampler pd = PoissonSamplerUtils.createPoissonSampler(rg, settings.offset);
final ContinuousSampler ed = SamplerUtils.createExponentialSampler(rg, settings.variance);
final SharedStateContinuousSampler gauss = SamplerUtils.createGaussianSampler(rg, settings.gain, settings.gainStdDev);
Ticker ticker = ImageJUtils.createTicker(n, 0);
for (int i = 0; i < n; i++) {
// Q. Should these be clipped to a sensible range?
pixelOffset[i] = pd.sample();
pixelVariance[i] = (float) ed.sample();
pixelGain[i] = (float) gauss.sample();
ticker.tick();
}
IJ.showProgress(1);
// Save to the directory as a stack
final ImageStack simulationStack = new ImageStack(settings.size, settings.size);
simulationStack.addSlice("Offset", pixelOffset);
simulationStack.addSlice("Variance", pixelVariance);
simulationStack.addSlice("Gain", pixelGain);
simulationImp = new ImagePlus("PerPixel", simulationStack);
// Only the info property is saved to the TIFF file
simulationImp.setProperty("Info", String.format("Offset=%s; Variance=%s; Gain=%s +/- %s", MathUtils.rounded(settings.offset), MathUtils.rounded(settings.variance), MathUtils.rounded(settings.gain), MathUtils.rounded(settings.gainStdDev)));
IJ.save(simulationImp, new File(settings.directory, "perPixelSimulation.tif").getPath());
// Create thread pool and workers
final int threadCount = getThreads();
final ExecutorService executor = Executors.newFixedThreadPool(threadCount);
final LocalList<Future<?>> futures = new LocalList<>(numberOfThreads);
// Simulate the exposure input.
final int[] photons = settings.getPhotons();
// For saving stacks
final int blockSize = 10;
int numberPerThread = (int) Math.ceil((double) settings.frames / numberOfThreads);
// Convert to fit the block size
numberPerThread = (int) Math.ceil((double) numberPerThread / blockSize) * blockSize;
final Pcg32 rng = Pcg32.xshrs(start);
// Note the bias is increased by 3-fold so add 2 to the length
ticker = Ticker.createStarted(new ImageJTrackProgress(true), (long) (photons.length + 2) * settings.frames, threadCount > 1);
for (final int p : photons) {
ImageJUtils.showStatus(() -> "Simulating " + TextUtils.pleural(p, "photon"));
// Create the directory
final Path out = Paths.get(settings.directory, String.format("photon%03d", p));
Files.createDirectories(out);
// Increase frames for bias image
final int frames = settings.frames * (p == 0 ? 3 : 1);
for (int from = 0; from < frames; ) {
final int to = Math.min(from + numberPerThread, frames);
futures.add(executor.submit(new SimulationWorker(ticker, rng.split(), out.toString(), simulationStack, from, to, blockSize, p)));
from = to;
}
ConcurrencyUtils.waitForCompletionUnchecked(futures);
futures.clear();
}
final String msg = "Simulation time = " + TextUtils.millisToString(System.currentTimeMillis() - start);
IJ.showStatus(msg);
ImageJUtils.clearSlowProgress();
executor.shutdown();
ImageJUtils.log(msg);
}
use of uk.ac.sussex.gdsc.core.ij.ImageJTrackProgress in project GDSC-SMLM by aherbert.
the class SpotAnalysis method runCreateProfile.
private void runCreateProfile(ImagePlus imp, Rectangle bounds, double psfWidth, double blur) {
areaBounds = bounds;
this.imp = imp;
area = bounds.width * bounds.height;
clearSelectedFrames();
// Get a profile through the images
IJ.showStatus("Calculating raw profile");
final int nSlices = imp.getStackSize();
final ImageStack rawSpot = new ImageStack(bounds.width, bounds.height, nSlices);
final double[][] profile = extractSpotProfile(imp, bounds, rawSpot);
// Retain the existing display range
double min = 0;
double max = Double.POSITIVE_INFINITY;
if (rawImp != null) {
min = rawImp.getDisplayRangeMin();
max = rawImp.getDisplayRangeMax();
}
rawImp = showSpot(RAW_SPLOT_TITLE, rawSpot);
if (max != Double.POSITIVE_INFINITY) {
rawImp.setDisplayRange(min, max);
}
rawMean = profile[0];
rawSd = profile[1];
// Check if there are fitted results in memory
addCandidateFrames(imp.getTitle());
updateProfilePlots();
if (blur > 0) {
IJ.showStatus("Calculating blur ...");
final ImageStack stack = imp.getImageStack();
final ImageStack newStack = new ImageStack(stack.getWidth(), stack.getHeight(), stack.getSize());
// Multi-thread the blur stage
final ExecutorService threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
final List<Future<?>> futures = new LinkedList<>();
final Ticker ticker = Ticker.create(new ImageJTrackProgress(true), nSlices, true);
blurCount = 0;
final int slices = 5;
ImageJUtils.showSlowProgress(0, nSlices);
for (int n = 1; n <= nSlices; n += slices) {
futures.add(threadPool.submit(new BlurWorker(ticker, stack, n, slices, bounds, blur * psfWidth, newStack)));
}
IJ.showStatus("Calculating blur ... Finishing");
threadPool.shutdown();
ConcurrencyUtils.waitForCompletionUnchecked(futures);
ImageJUtils.clearSlowProgress();
IJ.showStatus("Calculating blur ... Drawing");
final ImageStack blurSpot = new ImageStack(bounds.width, bounds.height, nSlices);
extractSpotProfile(new ImagePlus("Blur", newStack), bounds, blurSpot);
// Retain the existing display range
max = Double.POSITIVE_INFINITY;
if (blurImp != null) {
min = blurImp.getDisplayRangeMin();
max = blurImp.getDisplayRangeMax();
}
blurImp = showSpot(BLUR_SPOT_TITLE, blurSpot);
if (max != Double.POSITIVE_INFINITY) {
blurImp.setDisplayRange(min, max);
}
IJ.showStatus("");
} else {
blurImp = null;
}
// Add a z-projection of the blur/original image
final ZProjector project = new ZProjector((blurImp == null) ? rawImp : blurImp);
project.setMethod(ZProjector.AVG_METHOD);
project.doProjection();
showSpot(AVG_SPOT_TITLE, project.getProjection().getImageStack());
if (!candidateFrames.isEmpty()) {
// Set the first candidate frame
rawImp.setSlice(candidateFrames.get(0));
} else {
updateCurrentSlice(rawImp.getCurrentSlice());
}
IJ.showStatus("");
}
Aggregations