use of uk.ac.sussex.gdsc.core.annotation.Nullable in project gdsc-smlm by aherbert.
the class ImageJ3DResultsViewer method createSphereSizeFromDeviations.
@Nullable
private static Point3f[] createSphereSizeFromDeviations(MemoryPeakResults results) {
if (!results.hasDeviations()) {
IJ.error(TITLE, "The results have no deviations");
return null;
}
// Currently the rendering is in nm
final TypeConverter<DistanceUnit> dc = results.getDistanceConverter(DistanceUnit.NM);
final Point3f[] size = new Point3f[results.size()];
final boolean failed = results.forEach(new PeakResultProcedureX() {
int index;
@Override
public boolean execute(PeakResult peakResult) {
final float x = peakResult.getParameterDeviation(PeakResult.X);
final float y = peakResult.getParameterDeviation(PeakResult.Y);
// This should be OK as 2D fitting should provide these.
if (x == 0 || y == 0) {
return true;
}
float z = peakResult.getParameterDeviation(PeakResult.Z);
if (z == 0) {
// Mean variance
z = (float) Math.sqrt((x * x + y * y) / 2);
}
// z = (x + y) / 2; // Mean Std Dev
size[index++] = new Point3f(dc.convert(x), dc.convert(y), dc.convert(z));
return false;
}
});
return (failed) ? null : size;
}
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 ImageJ3DResultsViewer method createAlphaFromSize.
@Nullable
private static float[] createAlphaFromSize(double minA, double maxA, Point3f[] sphereSize) {
if (sphereSize == null) {
return null;
}
final double[] d = new double[sphereSize.length];
for (int i = 0; i < d.length; i++) {
final Point3f p = sphereSize[i];
if (p.x == p.y && p.y == p.z) {
d[i] = 3.0 * p.x * p.x;
} else {
// Use the squared distance. This is the equivalent of the area of the shape projected to
// 2D.
d[i] = (double) p.x * p.x + p.y * p.y + p.z * p.z;
}
// Use the average radius. This is the equivalent of the mean radius of an enclosing
// ellipsoid.
// d[i] = Math.sqrt(d[i] / 3);
}
final double[] limits = MathUtils.limits(d);
final double min = limits[0];
final double max = limits[1];
if (min == max) {
ImageJUtils.log("No per-item transparency as size is fixed");
return null;
}
final double range = (maxA - minA) / (max - min);
final float[] alpha = new float[d.length];
for (int i = 0; i < alpha.length; i++) {
// Largest distance has lowest alpha (more transparent)
alpha[i] = (float) (minA + range * (max - d[i]));
}
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 List<List<Localisation>> blocks = p.blocks;
if (blocks.size() <= 1) {
tracker.log("ERROR : Require at least 2 images for drift calculation");
return null;
}
// Check the final block has enough localisations
final List<Localisation> nextBlock = p.nextBlock;
if (nextBlock.size() < settings.minimimLocalisations) {
blocks.remove(blocks.size() - 1);
if (blocks.size() <= 1) {
tracker.log("ERROR : Require at least 2 images for drift calculation");
return null;
}
final List<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 List<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 calculateUsingMarkers.
/**
* Calculates drift using the feducial markers within ROI.
*
* <p>Adapted from the drift calculation method in QuickPALM.
*
* @param results the results
* @param limits the limits
* @param rois the rois
* @return the drift { dx[], dy[] }
*/
@Nullable
private double[][] calculateUsingMarkers(MemoryPeakResults results, int[] limits, Roi[] rois) {
final Spot[][] roiSpots = findSpots(results, rois, limits);
// Check we have enough data
if (roiSpots.length == 0) {
IJ.error("No peak fit results in the selected ROIs");
return null;
}
final double[] dx = new double[limits[1] + 1];
final double[] dy = new double[dx.length];
final double[] sum = new double[roiSpots.length];
final double[] weights = calculateWeights(roiSpots, dx.length, sum);
final double smoothing = updateSmoothingParameter(weights);
lastdx = null;
double change = calculateDriftUsingMarkers(roiSpots, weights, sum, dx, dy, smoothing, settings.iterations);
if (Double.isNaN(change) || tracker.isEnded()) {
return null;
}
ImageJUtils.log("Drift Calculator : Initial drift " + MathUtils.rounded(change));
for (int i = 1; i <= settings.maxIterations; i++) {
change = calculateDriftUsingMarkers(roiSpots, weights, sum, dx, dy, smoothing, settings.iterations);
if (Double.isNaN(change)) {
return null;
}
if (converged(i, change, getTotalDrift(dx, dy, weights))) {
break;
}
}
if (tracker.isEnded()) {
return null;
}
interpolate(dx, dy, weights);
plotDrift(limits, dx, dy);
saveDrift(weights, dx, dy);
return new double[][] { dx, dy };
}
Aggregations