Search in sources :

Example 1 with SplittableUniformRandomProvider

use of uk.ac.sussex.gdsc.core.utils.rng.SplittableUniformRandomProvider in project GDSC-SMLM by aherbert.

the class PulseActivationAnalysis method runAnalysis.

/**
 * Run the analysis. This modifies state and so should be synchronized.
 *
 * <p>Note: We check against the last settings and only repeat what is necessary.
 *
 * @param runSettings the run settings
 */
private void runAnalysis(RunSettings runSettings) {
    if (runSettings == null) {
        lastRunSettings = null;
        return;
    }
    IJ.showStatus("Analysing ...");
    SplittableUniformRandomProvider rng = null;
    // Assign all activations to a channel.
    // This is only necessary when we have more than 1 channel. If we have 1 channel then
    // no correction method is specified.
    boolean changed = false;
    if (runSettings.newUnmixSettings(lastRunSettings)) {
        changed = true;
        // Reset
        for (int i = specificActivations.length; i-- > 0; ) {
            final Activation result = specificActivations[i];
            result.currentChannel = result.channel;
        }
        if (runSettings.specificCorrection != Correction.NONE) {
            // Use a density counter that can put all the activations on a grid.
            // It has a method to count the number of activations within a radius that
            // belong to each channel.
            // Add only those with specific activations. Non-specific activations are ignored.
            createDensityCounter((float) runSettings.densityRadius);
            // Do this all together: it uses a faster algorithm and we can cache the results
            if (density == null) {
                IJ.showStatus("Computing observed density");
                density = dc.countAll(settings.channels);
            }
            rng = Optional.fromNullable(rng).or(UniformRandomProviders::createSplittable);
            // -=-=-=--=-=-
            // Unmix the specific activations to their correct channel.
            // -=-=-=--=-=-
            IJ.showStatus("Unmixing");
            createThreadPool();
            final int[] newChannel = new int[specificActivations.length];
            final int nPerThread = (int) Math.ceil((double) specificActivations.length / numberOfThreads);
            for (int from = 0; from < specificActivations.length; ) {
                final int to = Math.min(from + nPerThread, specificActivations.length);
                futures.add(executor.submit(new SpecificUnmixWorker(runSettings, density, newChannel, from, to, rng.split())));
                from = to;
            }
            waitToFinish();
            // Update the channel assignment
            for (int i = specificActivations.length; i-- > 0; ) {
                specificActivations[i].currentChannel = newChannel[i];
            }
        }
    }
    // -=-=-=--=-=-
    if (changed || runSettings.newNonSpecificCorrectionSettings(lastRunSettings)) {
        // Reset
        for (int i = nonSpecificActivations.length; i-- > 0; ) {
            final Activation result = nonSpecificActivations[i];
            result.currentChannel = result.channel;
        }
        if (runSettings.nonSpecificCorrection != Correction.NONE) {
            createDensityCounter((float) runSettings.densityRadius);
            rng = Optional.fromNullable(rng).or(UniformRandomProviders::createSplittable);
            IJ.showStatus("Non-specific assignment");
            createThreadPool();
            final int[] newChannel = new int[nonSpecificActivations.length];
            final int nPerThread = (int) Math.ceil((double) nonSpecificActivations.length / numberOfThreads);
            for (int from = 0; from < nonSpecificActivations.length; ) {
                final int to = Math.min(from + nPerThread, nonSpecificActivations.length);
                futures.add(executor.submit(new NonSpecificUnmixWorker(runSettings, dc, newChannel, from, to, rng.split())));
                from = to;
            }
            waitToFinish();
            // Update the channel assignment
            for (int i = nonSpecificActivations.length; i-- > 0; ) {
                nonSpecificActivations[i].currentChannel = newChannel[i];
            }
        }
    }
    // Set-up outputs for each channel
    IJ.showStatus("Creating outputs");
    output = new PeakResultsList[settings.channels];
    for (int c = 0; c < settings.channels; c++) {
        output[c] = createOutput(c + 1);
    }
    // Create a results set with only those molecules assigned to a channel
    int count = write(output, specificActivations, 0);
    count = write(output, nonSpecificActivations, count);
    int size = 0;
    for (int c = 0; c < settings.channels; c++) {
        output[c].end();
        size += output[c].size();
    }
    // Collate image into a stack
    if (settings.channels > 1 && runSettings.resultsSettings.getResultsImageSettings().getImageType() != ResultsImageType.DRAW_NONE) {
        final ImageProcessor[] images = new ImageProcessor[settings.channels];
        for (int c = 0; c < settings.channels; c++) {
            images[c] = getImage(output[c]);
        }
        displayComposite(images, results.getName() + " " + title);
    }
    lastRunSettings = runSettings;
    IJ.showStatus(String.format("%d/%s, %d/%s", count, TextUtils.pleural(traces.length, "Trace"), size, TextUtils.pleural(results.size(), "Result")));
}
Also used : ImageProcessor(ij.process.ImageProcessor) SplittableUniformRandomProvider(uk.ac.sussex.gdsc.core.utils.rng.SplittableUniformRandomProvider)

Aggregations

ImageProcessor (ij.process.ImageProcessor)1 SplittableUniformRandomProvider (uk.ac.sussex.gdsc.core.utils.rng.SplittableUniformRandomProvider)1