use of ij.ImagePlus in project GDSC-SMLM by aherbert.
the class CMOSAnalysis method run.
private void run() {
long start = System.currentTimeMillis();
// Avoid all the file saves from updating the progress bar and status line
Utils.setShowProgress(false);
Utils.setShowStatus(false);
JLabel statusLine = Utils.getStatusLine();
progressBar = Utils.getProgressBar();
// Create thread pool and workers
ExecutorService executor = Executors.newFixedThreadPool(getThreads());
TurboList<Future<?>> futures = new TurboList<Future<?>>(nThreads);
TurboList<ImageWorker> workers = new TurboList<ImageWorker>(nThreads);
double[][][] data = new double[subDirs.size()][2][];
double[] pixelOffset = null, pixelVariance = null;
Statistics statsOffset = null, statsVariance = null;
// For each sub-directory compute the mean and variance
final int nSubDirs = subDirs.size();
boolean error = false;
for (int n = 0; n < nSubDirs; n++) {
SubDir sd = subDirs.getf(n);
statusLine.setText("Analysing " + sd.name);
// Open the series
SeriesImageSource source = new SeriesImageSource(sd.name, sd.path.getPath());
//source.setLogProgress(true);
if (!source.open()) {
error = true;
IJ.error(TITLE, "Failed to open image series: " + sd.path.getPath());
break;
}
// So the bar remains at 99% when workers have finished
totalProgress = source.getFrames() + 1;
stepProgress = Utils.getProgressInterval(totalProgress);
progress = 0;
progressBar.show(0);
ArrayMoment moment = (rollingAlgorithm) ? new RollingArrayMoment() : new SimpleArrayMoment();
final BlockingQueue<ImageJob> jobs = new ArrayBlockingQueue<ImageJob>(nThreads * 2);
for (int i = 0; i < nThreads; i++) {
final ImageWorker worker = new ImageWorker(jobs, moment);
workers.add(worker);
futures.add(executor.submit(worker));
}
// Process the data
for (float[] pixels = source.next(); pixels != null; pixels = source.next()) {
put(jobs, new ImageJob(pixels));
}
// Finish all the worker threads by passing in a null job
for (int i = 0; i < nThreads; i++) {
put(jobs, new ImageJob(null));
}
// Wait for all to finish
for (int t = futures.size(); t-- > 0; ) {
try {
// The future .get() method will block until completed
futures.get(t).get();
} catch (Exception e) {
// This should not happen.
e.printStackTrace();
}
}
// Create the final aggregate statistics
for (ImageWorker w : workers) moment.add(w.moment);
data[n][0] = moment.getFirstMoment();
data[n][1] = moment.getVariance();
// Reset
futures.clear();
workers.clear();
Statistics s = new Statistics(data[n][0]);
if (n != 0) {
// Compute mean ADU
Statistics signal = new Statistics();
double[] mean = data[n][0];
for (int i = 0; i < pixelOffset.length; i++) signal.add(mean[i] - pixelOffset[i]);
Utils.log("%s Mean = %s +/- %s. Signal = %s +/- %s ADU", sd.name, Utils.rounded(s.getMean()), Utils.rounded(s.getStandardDeviation()), Utils.rounded(signal.getMean()), Utils.rounded(signal.getStandardDeviation()));
// TODO - optionally save
ImageStack stack = new ImageStack(source.getWidth(), source.getHeight());
stack.addSlice("Mean", Utils.toFloat(data[n][0]));
stack.addSlice("Variance", Utils.toFloat(data[n][1]));
IJ.save(new ImagePlus("PerPixel", stack), new File(directory, "perPixel" + sd.name + ".tif").getPath());
} else {
pixelOffset = data[0][0];
pixelVariance = data[0][1];
statsOffset = s;
statsVariance = new Statistics(pixelVariance);
Utils.log("%s Offset = %s +/- %s. Variance = %s +/- %s", sd.name, Utils.rounded(s.getMean()), Utils.rounded(s.getStandardDeviation()), Utils.rounded(statsVariance.getMean()), Utils.rounded(statsVariance.getStandardDeviation()));
}
}
Utils.setShowStatus(true);
Utils.setShowProgress(true);
IJ.showProgress(1);
executor.shutdown();
if (error)
return;
// Compute the gain
statusLine.setText("Computing gain");
double[] pixelGain = new double[pixelOffset.length];
// Ignore first as this is the 0 exposure image
for (int i = 0; i < pixelGain.length; i++) {
// Use equation 2.5 from the Huang et al paper.
double bibiT = 0;
double biaiT = 0;
for (int n = 1; n < nSubDirs; n++) {
double bi = data[n][0][i] - pixelOffset[i];
double ai = data[n][1][i] - pixelVariance[i];
bibiT += bi * bi;
biaiT += bi * ai;
}
pixelGain[i] = biaiT / bibiT;
}
Statistics statsGain = new Statistics(pixelGain);
Utils.log("Gain Mean = %s +/- %s", Utils.rounded(statsGain.getMean()), Utils.rounded(statsGain.getStandardDeviation()));
// Histogram of offset, variance and gain
int bins = Utils.getBinsSturges(pixelGain.length);
WindowOrganiser wo = new WindowOrganiser();
showHistogram("Offset", pixelOffset, bins, statsOffset, wo);
showHistogram("Variance", pixelVariance, bins, statsVariance, wo);
showHistogram("Gain", pixelGain, bins, statsGain, wo);
wo.tile();
// Save
measuredStack = new ImageStack(size, size);
measuredStack.addSlice("Offset", Utils.toFloat(pixelOffset));
measuredStack.addSlice("Variance", Utils.toFloat(pixelVariance));
measuredStack.addSlice("Gain", Utils.toFloat(pixelGain));
IJ.save(new ImagePlus("PerPixel", measuredStack), new File(directory, "perPixel.tif").getPath());
// Remove the status from the ij.io.ImageWriter class
IJ.showStatus("");
Utils.log("Analysis time = " + Utils.timeToString(System.currentTimeMillis() - start));
}
use of ij.ImagePlus in project GDSC-SMLM by aherbert.
the class CMOSAnalysis method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
extraOptions = Utils.isExtraOptions();
// Avoid the status bar talking to the current image
WindowManager.setTempCurrentImage(null);
//@formatter:off
IJ.log(TextUtils.wrap(TITLE + ": Analyse the per-pixel offset, variance and gain of sCMOS images. " + "See Huang et al (2013) Video-rate nanoscopy using sCMOS camera–specific " + "single-molecule localization algorithms. Nature Methods 10, 653-658 " + "(Supplementary Information).", 80));
//@formatter:on
String dir = Utils.getDirectory(TITLE, directory);
if (Utils.isNullOrEmpty(dir))
return;
directory = dir;
boolean simulate = "simulate".equals(arg);
if (simulate || extraOptions) {
if (!showSimulateDialog())
return;
simulate();
}
if (!showDialog())
return;
run();
if (simulationImp == null) {
// Just in case an old simulation is in the directory
ImagePlus imp = IJ.openImage(new File(directory, "perPixelSimulation.tif").getPath());
if (imp != null && imp.getStackSize() == 3 && imp.getWidth() == measuredStack.getWidth() && imp.getHeight() == measuredStack.getHeight())
simulationImp = imp;
}
if (simulationImp != null)
computeError();
}
use of ij.ImagePlus in project GDSC-SMLM by aherbert.
the class CreateData method createBackgroundPixels.
private synchronized void createBackgroundPixels() {
// Cache illumination background
if (backgroundPixels == null) {
backgroundPixels = new float[settings.size * settings.size];
ImagePlus imp = WindowManager.getImage(settings.backgroundImage);
if (imp != null) {
// Use an image for the background
ImageProcessor ip = imp.getProcessor().duplicate().toFloat(0, null);
ip.setInterpolationMethod(ImageProcessor.BILINEAR);
ip = ip.resize(settings.size, settings.size);
float[] data = (float[]) ip.getPixels();
final double max = FastMath.max(0, Maths.max(data));
if (max != 0) {
final double scale = settings.background / max;
for (int i = 0; i < backgroundPixels.length; i++) {
// Ignore pixels below zero
backgroundPixels[i] = (float) (FastMath.max(0, data[i]) * scale);
}
return;
}
}
// Use the illumination (this is the fall-back method if the background image has no
// maximum)
SpatialIllumination illumination = createIllumination(settings.background, 0);
double[] xyz = new double[3];
for (int y = 0, i = 0; y < settings.size; y++) {
xyz[1] = y - settings.size / 2;
for (int x = 0, x2 = -settings.size / 2; x < settings.size; x++, x2++, i++) {
xyz[0] = x2;
backgroundPixels[i] = (float) illumination.getPhotons(xyz);
}
}
}
}
use of ij.ImagePlus in project GDSC-SMLM by aherbert.
the class ConfigurationTemplate method updateResults.
/**
* Update the results window using the current selected slice from the template image.
*
* @param slice
* the slice
* @return the text window
*/
public TextWindow updateResults(int slice) {
if (slice == currentSlice || text == null)
return resultsWindow;
currentSlice = slice;
if (resultsWindow == null || !resultsWindow.isVisible()) {
resultsWindow = new TextWindow(TITLE + " Results", headings, "", 450, 250);
// Put next to the image
ImagePlus imp = WindowManager.getImage(templateId);
if (imp != null && imp.getWindow() != null) {
ImageWindow iw = imp.getWindow();
Point p = iw.getLocation();
p.x += iw.getWidth();
resultsWindow.setLocation(p);
}
}
resultsWindow.getTextPanel().clear();
String data = text.get(slice);
if (!Utils.isNullOrEmpty(data))
resultsWindow.append(data);
return resultsWindow;
}
use of ij.ImagePlus in project GDSC-SMLM by aherbert.
the class ConfigurationTemplate method showTemplateImage.
private void showTemplateImage(String name) {
ImagePlus imp = getTemplateImage(name);
if (imp == null) {
IJ.error(TITLE, "Failed to load example image for template: " + name);
} else {
this.imp = displayTemplate(TITLE, imp);
if (Utils.isNewWindow()) {
// Zoom a bit
ImageWindow iw = this.imp.getWindow();
for (int i = 7; i-- > 0 && Math.max(iw.getWidth(), iw.getHeight()) < 512; ) {
iw.getCanvas().zoomIn(0, 0);
}
}
createResults(this.imp);
showTemplateInfo(name);
}
}
Aggregations