use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.
the class ImageJ3DResultsViewer method createAlphaFromIntensity.
@Nullable
private static float[] createAlphaFromIntensity(MemoryPeakResults results, double minA, double maxA) {
final RawResultProcedure p = new RawResultProcedure(results);
p.getI();
final float[] intensity = p.intensity;
final float[] limits = MathUtils.limits(intensity);
final float min = limits[0];
final float max = limits[1];
if (min == max) {
ImageJUtils.log("No per-item transparency as intensity is fixed");
return null;
}
final double range = (maxA - minA) / (max - min);
final float[] alpha = new float[intensity.length];
for (int i = 0; i < alpha.length; i++) {
// Lowest intensity has lowest alpha (more transparent)
alpha[i] = (float) (minA + range * (intensity[i] - min));
}
return alpha;
}
use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.
the class DriftCalculator method calculateUsingFrames.
/**
* Calculates drift using images from N consecutive frames aligned to the overall image.
*
* @param results the results
* @param limits the limits
* @param reconstructionSize the reconstruction size
* @return the drift { dx[], dy[] }
*/
@Nullable
private double[][] calculateUsingFrames(MemoryPeakResults results, int[] limits, int reconstructionSize) {
// Extract the localisations into blocks of N consecutive frames
final BlockPeakResultProcedure p = new BlockPeakResultProcedure(settings);
results.sort();
results.forEach(p);
final ArrayList<ArrayList<Localisation>> blocks = p.blocks;
final ArrayList<Localisation> nextBlock = p.nextBlock;
if (blocks.size() < 2) {
tracker.log("ERROR : Require at least 2 images for drift calculation");
return null;
}
// Check the final block has enough localisations
if (nextBlock.size() < settings.minimimLocalisations) {
blocks.remove(blocks.size() - 1);
if (blocks.size() < 2) {
tracker.log("ERROR : Require at least 2 images for drift calculation");
return null;
}
final ArrayList<Localisation> combinedBlock = blocks.get(blocks.size() - 1);
combinedBlock.addAll(nextBlock);
}
// Find the average time point for each block
final int[] blockT = new int[blocks.size()];
int time = 0;
for (final ArrayList<Localisation> block : blocks) {
long sum = 0;
for (final Localisation r : block) {
sum += r.time;
}
blockT[time++] = (int) (sum / block.size());
}
// Calculate a scale to use when constructing the images for alignment
final Rectangle bounds = results.getBounds(true);
final ResultsImageSettings.Builder builder = ResultsImageSettings.newBuilder().setImageSizeMode(ResultsImageSizeMode.IMAGE_SIZE).setImageSize(reconstructionSize);
final float scale = ImagePeakResultsFactory.getScale(builder, bounds, 1);
executor = Executors.newFixedThreadPool(Prefs.getThreads());
final double[] dx = new double[limits[1] + 1];
final double[] dy = new double[dx.length];
final double[] originalDriftTimePoints = getOriginalDriftTimePoints(dx, blockT);
lastdx = null;
final double smoothing = updateSmoothingParameter(originalDriftTimePoints);
double change = calculateDriftUsingFrames(blocks, blockT, bounds, scale, dx, dy, originalDriftTimePoints, smoothing, settings.iterations);
if (Double.isNaN(change) || tracker.isEnded()) {
return null;
}
plotDrift(limits, dx, dy);
ImageJUtils.log("Drift Calculator : Initial drift " + MathUtils.rounded(change));
for (int i = 1; i <= settings.maxIterations; i++) {
change = calculateDriftUsingFrames(blocks, blockT, bounds, scale, dx, dy, originalDriftTimePoints, smoothing, settings.iterations);
if (Double.isNaN(change)) {
return null;
}
plotDrift(limits, dx, dy);
if (converged(i, change, getTotalDrift(dx, dy, originalDriftTimePoints))) {
break;
}
}
if (tracker.isEnded()) {
return null;
}
plotDrift(limits, dx, dy);
return new double[][] { dx, dy };
}
use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.
the class DriftCalculator method createStackImageList.
/**
* Build a list of suitable stack images.
*
* @return the list of suitable stack images.
*/
@Nullable
private static String[] createStackImageList() {
final int[] idList = WindowManager.getIDList();
if (idList != null) {
final String[] list = new String[idList.length];
int count = 0;
for (final int id : idList) {
final ImagePlus imp = WindowManager.getImage(id);
if (imp != null && imp.getStackSize() > 1) {
list[count++] = imp.getTitle();
}
}
return Arrays.copyOf(list, count);
}
return null;
}
use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.
the class PeakResultsReader method createNStormResult.
/**
* Creates the NStorm result.
*
* @param line the line
* @param readPhotons Set to {@code true} if there is a Photons field
* @return the peak result
*/
@Nullable
private static PeakResult createNStormResult(String line, boolean readPhotons) {
// Ywc
try (Scanner scanner = new Scanner(line)) {
scanner.useDelimiter(tabPattern);
scanner.useLocale(Locale.US);
// channelName
scanner.next();
// x
scanner.nextFloat();
// y
scanner.nextFloat();
final float xc = scanner.nextFloat();
final float yc = scanner.nextFloat();
final float height = scanner.nextFloat();
final float area = scanner.nextFloat();
final float width = scanner.nextFloat();
// phi
scanner.nextFloat();
final float ax = scanner.nextFloat();
final float bg = scanner.nextFloat();
// intensity
scanner.nextFloat();
final int frame = scanner.nextInt();
final int length = scanner.nextInt();
double photons = 0;
if (readPhotons) {
// These are not needed
// Link
scanner.next();
// Valid
scanner.next();
// Z
scanner.next();
// Zc
scanner.next();
photons = scanner.nextDouble();
}
// The coordinates are in nm
// The values are in ADUs. The area value is the signal.
// The following relationship holds when length == 1:
// Area = Height * 2 * pi * (Width / (pixel_pitch*2) )^2
// => Pixel_pitch = 0.5 * Width / sqrt(Area / (Height * 2 * pi))
final float[] params = new float[SIZE_TWO_AXIS];
params[PeakResult.BACKGROUND] = bg;
params[PeakResult.INTENSITY] = area;
params[PeakResult.X] = xc;
params[PeakResult.Y] = yc;
// Convert width (2*SD) to SD
final float sd = width / 2f;
// Convert to separate XY widths using the axial ratio
if (ax == 1) {
params[INDEX_SX] = sd;
params[INDEX_SY] = sd;
} else {
// Ensure the axial ratio is long/short
final double a = Math.sqrt((ax < 1) ? 1.0 / ax : ax);
params[INDEX_SX] = (float) (sd * a);
params[INDEX_SY] = (float) (sd / a);
}
// Store the photons in the error value
return new ExtendedPeakResult(frame, (int) xc, (int) yc, height, photons, 0.0f, 0, params, null, frame + length - 1, 0);
} catch (final NoSuchElementException ex) {
// Ignore
}
return null;
}
use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.
the class MultiPathFilter method filter.
/**
* Create a subset of multi-path results, i.e. all those that pass the filter.
*
* <p>The results are processed in order. Results are only processed if the fail counter
* {@link FailCounter#isOk() isOK}.
*
* <p>If the subset flag is set to true the candidate Id will be used to determine the number of
* failed fits before the current candidate, assuming candidates start at zero and increment.
*
* @param multiPathResults the multi path results
* @param failCounter the counter to track the failures to allow per frame before all peaks are
* rejected
* @param setup Set to true to run the {@link #setup()} method
* @param subset True if a subset (the candidate Id will be used to determine the number of failed
* fits before the current candidate)
* @return the filtered results
*/
@Nullable
private MultiPathFitResult[] filter(final IMultiPathFitResults multiPathResults, final FailCounter failCounter, boolean setup, boolean subset) {
if (setup) {
setup();
}
failCounter.reset();
int lastId = -1;
int size = 0;
final MultiPathFitResult[] newMultiPathResults = new MultiPathFitResult[multiPathResults.getNumberOfResults()];
final SimpleSelectedResultStore store = new SimpleSelectedResultStore(multiPathResults.getTotalCandidates());
// System.out.println("Debug");
for (int c = 0; c < newMultiPathResults.length; c++) {
final MultiPathFitResult multiPathResult = multiPathResults.getResult(c);
// Include the number of failures before this result from the larger set
if (subset) {
incrementFailures(failCounter, lastId, multiPathResult);
lastId = multiPathResult.getCandidateId();
}
final boolean evaluateFit = failCounter.isOk();
if (evaluateFit || store.isValid(multiPathResult.getCandidateId())) {
// Evaluate the result.
// This allows storing more estimates in the store even if we are past the failures limit.
final PreprocessedPeakResult[] result = accept(multiPathResult, false, store);
// Note: Even if the actual result failed, the candidate may have passed and so
// the entire multi-path result should be retained.
// Also note that depending on the filter, different results can be selected and pushed
// through
// the store to set them valid. So we must push everything through the store to ensure
// nothing
// is removed that could be used.
checkIsValid(multiPathResult.getSingleFitResult(), store);
checkIsValid(multiPathResult.getMultiFitResult(), store);
setupFilter(FilterValidationOption.NO_SHIFT);
checkIsValid(multiPathResult.getDoubletFitResult(), store);
// Fix to only disable shift filtering for the doublet results...
final FitResult multiDoubletFitResult = multiPathResult.getMultiDoubletFitResult();
if (multiDoubletFitResult != null && multiDoubletFitResult.getResults() != null) {
// Note: Only disable shift for the doublet results.
// doublets = len(multi-doublet) - len(multi) + 1
final PreprocessedPeakResult[] results = multiDoubletFitResult.getResults();
final int nDoublets = results.length - multiPathResult.getMultiFitResult().getResults().length + 1;
checkIsValid(results, store, 0, nDoublets);
restoreFilterState();
checkIsValid(results, store, nDoublets, results.length);
} else {
restoreFilterState();
}
// This has valid results so add to the output subset
newMultiPathResults[size++] = multiPathResult;
if (evaluateFit) {
if (isNewResult(result)) {
// More results were accepted so reset the fail count
failCounter.pass();
} else {
// Nothing was accepted, increment fail count
failCounter.fail();
}
}
} else {
// This was rejected, increment fail count
failCounter.fail();
}
multiPathResults.complete(c);
}
if (size != 0) {
return Arrays.copyOf(newMultiPathResults, size);
}
return null;
}
Aggregations