Search in sources :

Example 1 with CubicSplineData

use of uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineData in project GDSC-SMLM by aherbert.

the class CubicSplineManager method loadFromFile.

private static CubicSplinePsf loadFromFile(String name, String filename) {
    // Try to load from file
    try (InputStream is = new BufferedInputStream(new FileInputStream(filename))) {
        IJ.showStatus("Loading cubic spline: " + name);
        final ImagePSF imagePsf = ImagePSF.parseDelimitedFrom(is);
        final CubicSplineData function = CubicSplineData.read(is, SimpleImageJTrackProgress.getInstance());
        return new CubicSplinePsf(imagePsf, function);
    } catch (final Exception ex) {
        ImageJUtils.log("Failed to load spline model %s from file: %s. %s", name, filename, ex.getMessage());
    } finally {
        IJ.showStatus("");
    }
    return null;
}
Also used : BufferedInputStream(java.io.BufferedInputStream) ImagePSF(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.ImagePSF) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) CubicSplineData(uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineData) FileInputStream(java.io.FileInputStream)

Example 2 with CubicSplineData

use of uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineData in project GDSC-SMLM by aherbert.

the class CubicSplineManager method createCubicSpline.

/**
 * Creates the cubic spline.
 *
 * @param imagePsf the image PSF details
 * @param image the image
 * @param singlePrecision Set to true to use single precision (float values) to store the cubic
 *        spline coefficients
 * @return the cubic spline PSF
 */
public static CubicSplinePsf createCubicSpline(ImagePSFOrBuilder imagePsf, ImageStack image, final boolean singlePrecision) {
    final int maxx = image.getWidth();
    final int maxy = image.getHeight();
    final int maxz = image.getSize();
    final float[][] psf = new float[maxz][];
    for (int z = 0; z < maxz; z++) {
        psf[z] = ImageJImageConverter.getData(image.getPixels(z + 1), null);
    }
    // We reduce by a factor of 3
    final int maxi = (maxx - 1) / 3;
    final int maxj = (maxy - 1) / 3;
    final int maxk = (maxz - 1) / 3;
    final int size = maxi * maxj;
    final CustomTricubicFunction[][] splines = new CustomTricubicFunction[maxk][size];
    final int threadCount = Prefs.getThreads();
    final Ticker ticker = ImageJUtils.createTicker((long) maxi * maxj * maxk, threadCount);
    final ExecutorService threadPool = Executors.newFixedThreadPool(threadCount);
    final LocalList<Future<?>> futures = new LocalList<>(maxk);
    // spline node along each dimension, i.e. dimension length = n*3 + 1 with n the number of nodes.
    for (int k = 0; k < maxk; k++) {
        final int kk = k;
        futures.add(threadPool.submit(() -> {
            final CubicSplineCalculator calc = new CubicSplineCalculator();
            final double[] value = new double[64];
            final int zz = 3 * kk;
            for (int j = 0, index = 0; j < maxj; j++) {
                // 4x4 block origin in the XY data
                int index0 = 3 * j * maxx;
                for (int i = 0; i < maxi; i++, index++) {
                    ticker.tick();
                    int count = 0;
                    for (int z = 0; z < 4; z++) {
                        final float[] data = psf[zz + z];
                        for (int y = 0; y < 4; y++) {
                            for (int x = 0, ii = index0 + y * maxx; x < 4; x++) {
                                value[count++] = data[ii++];
                            }
                        }
                    }
                    splines[kk][index] = CustomTricubicFunctionUtils.create(calc.compute(value));
                    if (singlePrecision) {
                        splines[kk][index] = splines[kk][index].toSinglePrecision();
                    }
                    index0 += 3;
                }
            }
        }));
    }
    ticker.stop();
    threadPool.shutdown();
    ConcurrencyUtils.waitForCompletionUnchecked(futures);
    // Normalise
    double maxSum = 0;
    for (int k = 0; k < maxk; k++) {
        double sum = 0;
        for (int i = 0; i < size; i++) {
            sum += splines[k][i].value000();
        }
        if (maxSum < sum) {
            maxSum = sum;
        }
    }
    if (maxSum == 0) {
        throw new IllegalStateException("The cubic spline has no maximum signal");
    }
    final double scale = 1.0 / maxSum;
    for (int k = 0; k < maxk; k++) {
        for (int i = 0; i < size; i++) {
            splines[k][i] = splines[k][i].scale(scale);
        }
    }
    // Create on an integer scale
    final CubicSplineData f = new CubicSplineData(maxi, maxj, splines);
    // Create a new info with the PSF details
    final ImagePSF.Builder b = ImagePSF.newBuilder();
    b.setImageCount(imagePsf.getImageCount());
    // Reducing the image has the effect of enlarging the pixel size
    b.setPixelSize(imagePsf.getPixelSize() * 3.0);
    b.setPixelDepth(imagePsf.getPixelDepth() * 3.0);
    // The centre has to be moved as we reduced the image size by 3.
    // In the ImagePSF the XY centre puts 0.5 at the centre of the pixel.
    // The spline puts 0,0 at the centre of each pixel for convenience.
    double cx = maxi / 2.0;
    if (imagePsf.getXCentre() != 0) {
        cx = (imagePsf.getXCentre() - 0.5) / 3;
    }
    double cy = maxj / 2.0;
    if (imagePsf.getYCentre() != 0) {
        cy = (imagePsf.getYCentre() - 0.5) / 3;
    }
    double cz = maxk / 2.0;
    if (imagePsf.getZCentre() != 0) {
        cz = imagePsf.getZCentre() / 3;
    } else if (imagePsf.getCentreImage() != 0) {
        cz = (imagePsf.getCentreImage() - 1) / 3.0;
    }
    b.setXCentre(cx);
    b.setYCentre(cy);
    b.setZCentre(cz);
    return new CubicSplinePsf(b.build(), f);
}
Also used : CubicSplineCalculator(uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineCalculator) Ticker(uk.ac.sussex.gdsc.core.logging.Ticker) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) ImagePSF(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.ImagePSF) CubicSplineData(uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineData) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) CustomTricubicFunction(uk.ac.sussex.gdsc.core.math.interpolation.CustomTricubicFunction)

Aggregations

ImagePSF (uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.ImagePSF)2 CubicSplineData (uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineData)2 BufferedInputStream (java.io.BufferedInputStream)1 FileInputStream (java.io.FileInputStream)1 InputStream (java.io.InputStream)1 ExecutorService (java.util.concurrent.ExecutorService)1 Future (java.util.concurrent.Future)1 Ticker (uk.ac.sussex.gdsc.core.logging.Ticker)1 CustomTricubicFunction (uk.ac.sussex.gdsc.core.math.interpolation.CustomTricubicFunction)1 LocalList (uk.ac.sussex.gdsc.core.utils.LocalList)1 CubicSplineCalculator (uk.ac.sussex.gdsc.smlm.function.cspline.CubicSplineCalculator)1