Search in sources :

Example 11 with ImagePlus

use of ij.ImagePlus in project GDSC-SMLM by aherbert.

the class SpotAnalysis method createProfile.

private void createProfile(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();
    ImageStack rawSpot = new ImageStack(bounds.width, bounds.height, nSlices);
    double[][] profile = extractSpotProfile(imp, bounds, rawSpot);
    // Retain the existing display range
    double min = 0, max = Double.POSITIVE_INFINITY;
    if (rawImp != null) {
        min = rawImp.getDisplayRangeMin();
        max = rawImp.getDisplayRangeMax();
    }
    rawImp = showSpot(rawSpotTitle, 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 ...");
        ImageStack stack = imp.getImageStack();
        ImageStack newStack = new ImageStack(stack.getWidth(), stack.getHeight(), stack.getSize());
        // Multi-thread the blur stage
        ExecutorService threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
        List<Future<?>> futures = new LinkedList<Future<?>>();
        Utils.setShowProgress(false);
        blurCount = 0;
        // TODO - See if this is faster if processing multiple slices in each worker
        int slices = 5;
        for (int n = 1; n <= nSlices; n += slices) {
            futures.add(threadPool.submit(new BlurWorker(stack, n, slices, bounds, blur * psfWidth, newStack)));
        }
        IJ.showStatus("Calculating blur ... Finishing");
        Utils.waitForCompletion(futures);
        threadPool.shutdown();
        Utils.setShowProgress(false);
        IJ.showStatus("Calculating blur ... Drawing");
        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(blurSpotTitle, blurSpot);
        if (max != Double.POSITIVE_INFINITY) {
            blurImp.setDisplayRange(min, max);
        }
        IJ.showStatus("");
    } else {
        blurImp = null;
    }
    // Add a z-projection of the blur/original image
    ZProjector project = new ZProjector((blurImp == null) ? rawImp : blurImp);
    project.setMethod(ZProjector.AVG_METHOD);
    project.doProjection();
    showSpot(avgSpotTitle, project.getProjection().getImageStack());
    if (!candidateFrames.isEmpty())
        // Set the first candidate frame
        rawImp.setSlice(candidateFrames.get(0));
    else
        updateCurrentSlice(rawImp.getCurrentSlice());
    IJ.showStatus("");
}
Also used : ImageStack(ij.ImageStack) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) ImagePlus(ij.ImagePlus) Point(java.awt.Point) LinkedList(java.util.LinkedList) ZProjector(ij.plugin.ZProjector)

Example 12 with ImagePlus

use of ij.ImagePlus in project GDSC-SMLM by aherbert.

the class CreateData method getImageHWHM.

/**
	 * Get the PSF half-width at half-maxima from the Image PSF
	 * 
	 * @return
	 */
private double getImageHWHM() {
    ImagePlus imp = WindowManager.getImage(settings.psfImageName);
    if (imp == null) {
        IJ.error(TITLE, "Unable to create the PSF model from image: " + settings.psfImageName);
        return -1;
    }
    Object o = XmlUtils.fromXML(imp.getProperty("Info").toString());
    if (!(o != null && o instanceof PSFSettings)) {
        IJ.error(TITLE, "Unknown PSF settings for image: " + imp.getTitle());
        return -1;
    }
    PSFSettings psfSettings = (PSFSettings) o;
    if (psfSettings.fwhm <= 0) {
        IJ.error(TITLE, "Unknown PSF FWHM setting for image: " + imp.getTitle());
        return -1;
    }
    if (psfSettings.nmPerPixel <= 0) {
        IJ.error(TITLE, "Unknown PSF nm/pixel setting for image: " + imp.getTitle());
        return -1;
    }
    // output image
    return 0.5 * psfSettings.fwhm * psfSettings.nmPerPixel / settings.pixelPitch;
}
Also used : ImagePlus(ij.ImagePlus) PSFSettings(gdsc.smlm.ij.settings.PSFSettings)

Example 13 with ImagePlus

use of ij.ImagePlus in project GDSC-SMLM by aherbert.

the class CreateData method drawImage.

//StoredDataStatistics rawPhotons = new StoredDataStatistics();
//StoredDataStatistics drawPhotons = new StoredDataStatistics();
//	private synchronized void addRaw(double d)
//	{
//		//rawPhotons.add(d);
//	}
//
//	private synchronized void addDraw(double d)
//	{
//		//drawPhotons.add(d);
//	}
/**
	 * Create an image from the localisations using the configured PSF width. Draws a new stack
	 * image.
	 * <p>
	 * Note that the localisations are filtered using the signal. The input list of localisations will be updated.
	 * 
	 * @param localisationSets
	 * @return The localisations
	 */
private List<LocalisationModel> drawImage(final List<LocalisationModelSet> localisationSets) {
    if (localisationSets.isEmpty())
        return null;
    // Create a new list for all localisation that are drawn (i.e. pass the signal filters)
    List<LocalisationModelSet> newLocalisations = Collections.synchronizedList(new ArrayList<LocalisationModelSet>(localisationSets.size()));
    photonsRemoved = new AtomicInteger();
    t1Removed = new AtomicInteger();
    tNRemoved = new AtomicInteger();
    photonStats = new SummaryStatistics();
    // Add drawn spots to memory
    results = new MemoryPeakResults();
    Calibration c = new Calibration(settings.pixelPitch, settings.getTotalGain(), settings.exposureTime);
    c.setEmCCD((settings.getEmGain() > 1));
    c.setBias(settings.bias);
    c.setReadNoise(settings.readNoise * ((settings.getCameraGain() > 0) ? settings.getCameraGain() : 1));
    c.setAmplification(settings.getAmplification());
    results.setCalibration(c);
    results.setSortAfterEnd(true);
    results.begin();
    maxT = localisationSets.get(localisationSets.size() - 1).getTime();
    // Display image
    ImageStack stack = new ImageStack(settings.size, settings.size, maxT);
    final double psfSD = getPsfSD();
    if (psfSD <= 0)
        return null;
    ImagePSFModel imagePSFModel = null;
    if (imagePSF) {
        // Create one Image PSF model that can be copied
        imagePSFModel = createImagePSF(localisationSets);
        if (imagePSFModel == null)
            return null;
    }
    IJ.showStatus("Drawing image ...");
    // Multi-thread for speed
    // Note that the default Executors.newCachedThreadPool() will continue to make threads if
    // new tasks are added. We need to limit the tasks that can be added using a fixed size
    // blocking queue.
    // http://stackoverflow.com/questions/1800317/impossible-to-make-a-cached-thread-pool-with-a-size-limit
    // ExecutorService threadPool = Executors.newCachedThreadPool();
    ExecutorService threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
    List<Future<?>> futures = new LinkedList<Future<?>>();
    // Count all the frames to process
    frame = 0;
    totalFrames = maxT;
    // Collect statistics on the number of photons actually simulated
    // Process all frames
    int i = 0;
    int lastT = -1;
    for (LocalisationModelSet l : localisationSets) {
        if (Utils.isInterrupted())
            break;
        if (l.getTime() != lastT) {
            lastT = l.getTime();
            futures.add(threadPool.submit(new ImageGenerator(localisationSets, newLocalisations, i, lastT, createPSFModel(imagePSFModel), results, stack, poissonNoise, new RandomDataGenerator(createRandomGenerator()))));
        }
        i++;
    }
    // Finish processing data
    Utils.waitForCompletion(futures);
    futures.clear();
    if (Utils.isInterrupted()) {
        IJ.showProgress(1);
        return null;
    }
    // Do all the frames that had no localisations
    for (int t = 1; t <= maxT; t++) {
        if (Utils.isInterrupted())
            break;
        if (stack.getPixels(t) == null) {
            futures.add(threadPool.submit(new ImageGenerator(localisationSets, newLocalisations, maxT, t, null, results, stack, poissonNoise, new RandomDataGenerator(createRandomGenerator()))));
        }
    }
    // Finish
    Utils.waitForCompletion(futures);
    threadPool.shutdown();
    IJ.showProgress(1);
    if (Utils.isInterrupted()) {
        return null;
    }
    results.end();
    // Clear memory
    imagePSFModel = null;
    threadPool = null;
    futures.clear();
    futures = null;
    if (photonsRemoved.get() > 0)
        Utils.log("Removed %d localisations with less than %.1f rendered photons", photonsRemoved.get(), settings.minPhotons);
    if (t1Removed.get() > 0)
        Utils.log("Removed %d localisations with no neighbours @ SNR %.2f", t1Removed.get(), settings.minSNRt1);
    if (tNRemoved.get() > 0)
        Utils.log("Removed %d localisations with valid neighbours @ SNR %.2f", tNRemoved.get(), settings.minSNRtN);
    if (photonStats.getN() > 0)
        Utils.log("Average photons rendered = %s +/- %s", Utils.rounded(photonStats.getMean()), Utils.rounded(photonStats.getStandardDeviation()));
    //System.out.printf("rawPhotons = %f\n", rawPhotons.getMean());
    //System.out.printf("drawPhotons = %f\n", drawPhotons.getMean());
    //Utils.showHistogram("draw photons", drawPhotons, "photons", true, 0, 1000);
    // Update with all those localisation that have been drawn
    localisationSets.clear();
    localisationSets.addAll(newLocalisations);
    newLocalisations = null;
    IJ.showStatus("Displaying image ...");
    ImageStack newStack = stack;
    if (!settings.rawImage) {
        // Get the global limits and ensure all values can be represented
        Object[] imageArray = stack.getImageArray();
        float[] limits = Maths.limits((float[]) imageArray[0]);
        for (int j = 1; j < imageArray.length; j++) limits = Maths.limits(limits, (float[]) imageArray[j]);
        // Leave bias in place
        limits[0] = 0;
        // Check if the image will fit in a 16-bit range
        if ((limits[1] - limits[0]) < 65535) {
            // Convert to 16-bit
            newStack = new ImageStack(stack.getWidth(), stack.getHeight(), stack.getSize());
            // Account for rounding
            final float min = (float) (limits[0] - 0.5);
            for (int j = 0; j < imageArray.length; j++) {
                float[] image = (float[]) imageArray[j];
                short[] pixels = new short[image.length];
                for (int k = 0; k < pixels.length; k++) {
                    pixels[k] = (short) (image[k] - min);
                }
                newStack.setPixels(pixels, j + 1);
                // Free memory
                imageArray[j] = null;
                // Attempt to stay within memory (check vs 32MB)
                if (MemoryPeakResults.freeMemory() < 33554432L)
                    MemoryPeakResults.runGCOnce();
            }
        } else {
            // Keep as 32-bit but round to whole numbers
            for (int j = 0; j < imageArray.length; j++) {
                float[] pixels = (float[]) imageArray[j];
                for (int k = 0; k < pixels.length; k++) {
                    pixels[k] = Math.round(pixels[k]);
                }
            }
        }
    }
    // Show image
    ImagePlus imp = Utils.display(CREATE_DATA_IMAGE_TITLE, newStack);
    ij.measure.Calibration cal = new ij.measure.Calibration();
    String unit = "nm";
    double unitPerPixel = settings.pixelPitch;
    if (unitPerPixel > 100) {
        unit = "um";
        unitPerPixel /= 1000.0;
    }
    cal.setUnit(unit);
    cal.pixelHeight = cal.pixelWidth = unitPerPixel;
    imp.setCalibration(cal);
    imp.setDimensions(1, 1, newStack.getSize());
    imp.resetDisplayRange();
    imp.updateAndDraw();
    saveImage(imp);
    results.setSource(new IJImageSource(imp));
    results.setName(CREATE_DATA_IMAGE_TITLE + " (" + TITLE + ")");
    results.setConfiguration(createConfiguration((float) psfSD));
    results.setBounds(new Rectangle(0, 0, settings.size, settings.size));
    MemoryPeakResults.addResults(results);
    setBenchmarkResults(imp, results);
    if (benchmarkMode && benchmarkParameters != null)
        benchmarkParameters.setPhotons(results);
    List<LocalisationModel> localisations = toLocalisations(localisationSets);
    savePulses(localisations, results, CREATE_DATA_IMAGE_TITLE);
    // Saved the fixed and moving localisations into different datasets
    saveFixedAndMoving(results, CREATE_DATA_IMAGE_TITLE);
    return localisations;
}
Also used : Rectangle(java.awt.Rectangle) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ImagePSFModel(gdsc.smlm.model.ImagePSFModel) ImageStack(ij.ImageStack) RandomDataGenerator(org.apache.commons.math3.random.RandomDataGenerator) SummaryStatistics(org.apache.commons.math3.stat.descriptive.SummaryStatistics) Calibration(gdsc.smlm.results.Calibration) ImagePlus(ij.ImagePlus) LinkedList(java.util.LinkedList) IJImageSource(gdsc.smlm.ij.IJImageSource) LocalisationModel(gdsc.smlm.model.LocalisationModel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) LocalisationModelSet(gdsc.smlm.model.LocalisationModelSet)

Example 14 with ImagePlus

use of ij.ImagePlus in project GDSC-SMLM by aherbert.

the class CreateData method loadBenchmarkData.

/**
	 * Load benchmark data using an open image and a XYZ text file.
	 */
private void loadBenchmarkData() {
    if (!showLoadDialog()) {
        //resetMemory();
        return;
    }
    // Load the image
    ImagePlus imp = WindowManager.getImage(benchmarkImage);
    if (imp == null) {
        IJ.error(TITLE, "No benchmark image: " + benchmarkImage);
        //resetMemory();
        return;
    }
    // Load the results
    MemoryPeakResults results = getSimulationResults();
    if (results == null) {
        IJ.error(TITLE, "No benchmark results: " + benchmarkResultsName);
        //resetMemory();
        return;
    }
    results.setName(imp.getTitle() + " (Results)");
    results.setBounds(new Rectangle(0, 0, imp.getWidth(), imp.getHeight()));
    results.setSource(new IJImageSource(imp));
    // Get the calibration
    simulationParameters = showSimulationParametersDialog(imp, results);
    if (simulationParameters != null) {
        setBackground(results);
        setNoise(results, imp);
        setBenchmarkResults(imp, results);
        IJ.showStatus("Loaded " + Utils.pleural(results.size(), "result"));
    } else {
        resetMemory();
    }
}
Also used : IJImageSource(gdsc.smlm.ij.IJImageSource) Rectangle(java.awt.Rectangle) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ImagePlus(ij.ImagePlus)

Example 15 with ImagePlus

use of ij.ImagePlus in project GDSC-SMLM by aherbert.

the class CMOSAnalysis method simulate.

private void simulate() {
    // Create the offset, variance and gain for each pixel
    int n = size * size;
    float[] pixelOffset = new float[n];
    float[] pixelVariance = new float[n];
    float[] pixelGain = new float[n];
    IJ.showStatus("Creating random per-pixel readout");
    long start = System.currentTimeMillis();
    RandomGenerator rg = new Well19937c();
    PoissonDistribution pd = new PoissonDistribution(rg, offset, PoissonDistribution.DEFAULT_EPSILON, PoissonDistribution.DEFAULT_MAX_ITERATIONS);
    ExponentialDistribution ed = new ExponentialDistribution(rg, variance, ExponentialDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
    totalProgress = n;
    stepProgress = Utils.getProgressInterval(totalProgress);
    for (int i = 0; i < n; i++) {
        if (i % n == 0)
            IJ.showProgress(i, n);
        // Q. Should these be clipped to a sensible range?
        pixelOffset[i] = (float) pd.sample();
        pixelVariance[i] = (float) ed.sample();
        pixelGain[i] = (float) (gain + rg.nextGaussian() * gainSD);
    }
    IJ.showProgress(1);
    // Avoid all the file saves from updating the progress bar and status line
    Utils.setShowStatus(false);
    Utils.setShowProgress(false);
    JLabel statusLine = Utils.getStatusLine();
    progressBar = Utils.getProgressBar();
    // Save to the directory as a stack
    ImageStack simulationStack = new ImageStack(size, 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", Utils.rounded(offset), Utils.rounded(variance), Utils.rounded(gain), Utils.rounded(gainSD)));
    IJ.save(simulationImp, new File(directory, "perPixelSimulation.tif").getPath());
    // Create thread pool and workers
    ExecutorService executor = Executors.newFixedThreadPool(getThreads());
    TurboList<Future<?>> futures = new TurboList<Future<?>>(nThreads);
    // Simulate the zero exposure input.
    // Simulate 20 - 200 photon images.
    int[] photons = new int[] { 0, 20, 50, 100, 200 };
    totalProgress = photons.length * frames;
    stepProgress = Utils.getProgressInterval(totalProgress);
    progress = 0;
    progressBar.show(0);
    // For saving stacks
    int blockSize = 10;
    int nPerThread = (int) Math.ceil((double) frames / nThreads);
    // Convert to fit the block size
    nPerThread = (int) Math.ceil((double) nPerThread / blockSize) * blockSize;
    long seed = start;
    for (int p : photons) {
        statusLine.setText("Simulating " + Utils.pleural(p, "photon"));
        // Create the directory
        File out = new File(directory, String.format("photon%03d", p));
        if (!out.exists())
            out.mkdir();
        for (int from = 0; from < frames; ) {
            int to = Math.min(from + nPerThread, frames);
            futures.add(executor.submit(new SimulationWorker(seed++, out.getPath(), simulationStack, from, to, blockSize, p)));
            from = to;
        }
        // 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();
            }
        }
        futures.clear();
    }
    Utils.setShowStatus(true);
    Utils.setShowProgress(true);
    IJ.showProgress(1);
    executor.shutdown();
    Utils.log("Simulation time = " + Utils.timeToString(System.currentTimeMillis() - start));
}
Also used : PoissonDistribution(org.apache.commons.math3.distribution.PoissonDistribution) TurboList(gdsc.core.utils.TurboList) ImageStack(ij.ImageStack) ExponentialDistribution(org.apache.commons.math3.distribution.ExponentialDistribution) JLabel(javax.swing.JLabel) Well19937c(org.apache.commons.math3.random.Well19937c) ImagePlus(ij.ImagePlus) PseudoRandomGenerator(gdsc.core.utils.PseudoRandomGenerator) RandomGenerator(org.apache.commons.math3.random.RandomGenerator) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) File(java.io.File)

Aggregations

ImagePlus (ij.ImagePlus)66 ImageStack (ij.ImageStack)13 Rectangle (java.awt.Rectangle)13 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)11 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)11 LinkedList (java.util.LinkedList)10 PeakResult (gdsc.smlm.results.PeakResult)9 Point (java.awt.Point)9 ImageProcessor (ij.process.ImageProcessor)8 ArrayList (java.util.ArrayList)7 Overlay (ij.gui.Overlay)6 PointRoi (ij.gui.PointRoi)6 IJImageSource (gdsc.smlm.ij.IJImageSource)5 GenericDialog (ij.gui.GenericDialog)5 ExecutorService (java.util.concurrent.ExecutorService)5 Future (java.util.concurrent.Future)5 PSFSettings (gdsc.smlm.ij.settings.PSFSettings)4 Calibration (gdsc.smlm.results.Calibration)4 ImageWindow (ij.gui.ImageWindow)4 File (java.io.File)4