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")));
}
Aggregations