use of org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator in project mastodon-tracking by mastodon-sc.
the class LoGDetectorOp method mutate1.
@Override
public void mutate1(final DetectionCreatorFactory detectionCreatorFactory, final List<SourceAndConverter<?>> sources) {
ok = false;
final long start = System.currentTimeMillis();
final StringBuilder str = new StringBuilder();
if (!DetectionUtil.checkSettingsValidity(settings, str)) {
processingTime = System.currentTimeMillis() - start;
statusService.clearStatus();
errorMessage = str.toString();
return;
}
final int minTimepoint = (int) settings.get(KEY_MIN_TIMEPOINT);
final int maxTimepoint = (int) settings.get(KEY_MAX_TIMEPOINT);
final int setup = (int) settings.get(KEY_SETUP_ID);
// um
final double radius = (double) settings.get(KEY_RADIUS);
final double threshold = (double) settings.get(KEY_THRESHOLD);
final Interval roi = (Interval) settings.get(KEY_ROI);
statusService.showStatus("LoG detection");
for (int tp = minTimepoint; tp <= maxTimepoint; tp++) {
statusService.showProgress(tp - minTimepoint + 1, maxTimepoint - minTimepoint + 1);
// Did we get canceled?
if (isCanceled())
break;
// Check if there is some data at this timepoint.
if (!DetectionUtil.isPresent(sources, setup, tp))
continue;
/*
* Determine optimal level for detection.
*/
final int level = DetectionUtil.determineOptimalResolutionLevel(sources, radius, MIN_SPOT_PIXEL_SIZE / 2., tp, setup);
/*
* Load and extends image data.
*/
@SuppressWarnings("rawtypes") final RandomAccessibleInterval img = DetectionUtil.getImage(sources, tp, setup, level);
if (!DetectionUtil.isReallyPresent(img))
continue;
@SuppressWarnings("unchecked") final RandomAccessibleInterval<?> zeroMin = Views.dropSingletonDimensions(Views.zeroMin(img));
/*
* Transform ROI in higher level.
*/
final Interval interval;
if (null == roi) {
interval = zeroMin;
} else {
final double[] minSource = new double[3];
final double[] maxSource = new double[3];
roi.realMin(minSource);
roi.realMax(maxSource);
final double[] minTarget = new double[3];
final double[] maxTarget = new double[3];
final AffineTransform3D mipmapTransform = DetectionUtil.getMipmapTransform(sources, tp, setup, level);
mipmapTransform.applyInverse(minTarget, minSource);
mipmapTransform.applyInverse(maxTarget, maxSource);
final long[] tmin = new long[zeroMin.numDimensions()];
final long[] tmax = new long[zeroMin.numDimensions()];
for (int d = 0; d < zeroMin.numDimensions(); d++) {
tmin[d] = (long) Math.ceil(minTarget[d]);
tmax[d] = (long) Math.floor(maxTarget[d]);
}
final FinalInterval transformedRoi = new FinalInterval(tmin, tmax);
interval = Intervals.intersect(transformedRoi, zeroMin);
}
/*
* Filter image.
*/
final double[] pixelSize = DetectionUtil.getPixelSize(sources, tp, setup, level);
final RandomAccessibleInterval<FloatType> kernel = createLoGKernel(radius, zeroMin.numDimensions(), pixelSize);
@SuppressWarnings("rawtypes") final IntervalView source = Views.interval(zeroMin, interval);
@SuppressWarnings("unchecked") final RandomAccessibleInterval<FloatType> output = ops().filter().convolve(source, kernel);
/*
* LoG normalization factor, so that the filtered peak have the
* maximal value for spots that have the size this kernel is tuned
* to. With this value, the peak value will be of the same order of
* magnitude than the raw spot (if it has the right size). This
* value also ensures that if the image has its calibration changed,
* one will retrieve the same peak value than before scaling.
* However, I (JYT) could not derive the exact formula if the image
* is scaled differently across X, Y and Z.
*/
final double sigma = radius / Math.sqrt(img.numDimensions());
final double sigmaPixels = sigma / pixelSize[0];
final FloatType C = new FloatType((float) (1. / Math.PI / sigmaPixels / sigmaPixels));
Views.iterable(output).forEach((e) -> e.div(C));
/*
* Detect local maxima.
*/
final AffineTransform3D transform = DetectionUtil.getTransform(sources, tp, setup, level);
final DetectionCreator detectionCreator = detectionCreatorFactory.create(tp);
final List<Point> peaks = DetectionUtil.findLocalMaxima(output, threshold, threadService.getExecutorService());
if (doSubpixelLocalization) {
final int maxNumMoves = 10;
final boolean allowMaximaTolerance = true;
final boolean returnInvalidPeaks = true;
final boolean[] allowedToMoveInDim = new boolean[img.numDimensions()];
Arrays.fill(allowedToMoveInDim, true);
final float maximaTolerance = 0.01f;
final List<RefinedPeak<Point>> refined = SubpixelLocalization.refinePeaks(peaks, output, output, returnInvalidPeaks, maxNumMoves, allowMaximaTolerance, maximaTolerance, allowedToMoveInDim);
final RandomAccess<FloatType> ra = output.randomAccess();
final double[] pos = new double[3];
final RealPoint point = RealPoint.wrap(pos);
final RealPoint p3d = new RealPoint(3);
detectionCreator.preAddition();
try {
for (final RefinedPeak<Point> refinedPeak : refined) {
ra.setPosition(refinedPeak.getOriginalPeak());
final double q = ra.get().getRealDouble();
for (int d = 0; d < refinedPeak.numDimensions(); d++) p3d.setPosition(refinedPeak.getDoublePosition(d), d);
transform.apply(p3d, point);
detectionCreator.createDetection(pos, radius, q);
}
} finally {
detectionCreator.postAddition();
}
} else {
final RandomAccess<FloatType> ra = output.randomAccess();
final double[] pos = new double[3];
final RealPoint point = RealPoint.wrap(pos);
detectionCreator.preAddition();
try {
for (final Point peak : peaks) {
ra.setPosition(peak);
final double q = ra.get().getRealDouble();
transform.apply(peak, point);
detectionCreator.createDetection(pos, radius, q);
}
} finally {
detectionCreator.postAddition();
}
}
}
final long end = System.currentTimeMillis();
processingTime = end - start;
statusService.clearStatus();
ok = true;
}
use of org.mastodon.tracking.detection.DetectionCreatorFactory.DetectionCreator in project mastodon-tracking by mastodon-sc.
the class DoGDetectorOp method mutate1.
@Override
public void mutate1(final DetectionCreatorFactory detectionCreatorFactory, final List<SourceAndConverter<?>> sources) {
ok = false;
final long start = System.currentTimeMillis();
final StringBuilder str = new StringBuilder();
if (!DetectionUtil.checkSettingsValidity(settings, str)) {
processingTime = System.currentTimeMillis() - start;
statusService.clearStatus();
errorMessage = str.toString();
return;
}
final int minTimepoint = (int) settings.get(KEY_MIN_TIMEPOINT);
final int maxTimepoint = (int) settings.get(KEY_MAX_TIMEPOINT);
final int setup = (int) settings.get(KEY_SETUP_ID);
final double radius = (double) settings.get(KEY_RADIUS);
final double threshold = (double) settings.get(KEY_THRESHOLD);
final Interval roi = (Interval) settings.get(KEY_ROI);
final DetectionType detectionType = DetectionType.getOrDefault((String) settings.get(KEY_DETECTION_TYPE), DetectionType.MINIMA);
statusService.showStatus("DoG detection.");
for (int tp = minTimepoint; tp <= maxTimepoint; tp++) {
statusService.showProgress(tp - minTimepoint + 1, maxTimepoint - minTimepoint + 1);
// Did we get canceled?
if (isCanceled())
break;
// Check if there is some data at this timepoint.
if (!DetectionUtil.isPresent(sources, setup, tp))
continue;
/*
* Determine optimal level for detection.
*/
final int level = DetectionUtil.determineOptimalResolutionLevel(sources, radius, MIN_SPOT_PIXEL_SIZE / 2., tp, setup);
/*
* Load and extends image data.
*/
final RandomAccessibleInterval<?> img = DetectionUtil.getImage(sources, tp, setup, level);
if (!DetectionUtil.isReallyPresent(img))
continue;
// If 2D, the 3rd dimension will be dropped here.
final RandomAccessibleInterval<?> zeroMin = Views.dropSingletonDimensions(Views.zeroMin(img));
@SuppressWarnings({ "unchecked", "rawtypes" }) final RandomAccessible<FloatType> source = DetectionUtil.asExtendedFloat((RandomAccessibleInterval) zeroMin);
/*
* Transform ROI in higher level.
*/
final Interval interval;
if (null == roi) {
interval = zeroMin;
} else {
final double[] minSource = new double[3];
final double[] maxSource = new double[3];
roi.realMin(minSource);
roi.realMax(maxSource);
final double[] minTarget = new double[3];
final double[] maxTarget = new double[3];
final AffineTransform3D mipmapTransform = DetectionUtil.getMipmapTransform(sources, tp, setup, level);
mipmapTransform.applyInverse(minTarget, minSource);
mipmapTransform.applyInverse(maxTarget, maxSource);
// Only take 2D or 3D version of the transformed interval.
final long[] tmin = new long[zeroMin.numDimensions()];
final long[] tmax = new long[zeroMin.numDimensions()];
for (int d = 0; d < zeroMin.numDimensions(); d++) {
tmin[d] = (long) Math.ceil(minTarget[d]);
tmax[d] = (long) Math.floor(maxTarget[d]);
}
final FinalInterval transformedRoi = new FinalInterval(tmin, tmax);
interval = Intervals.intersect(transformedRoi, zeroMin);
}
// Ensure that the interval size is at least 3 in all dimensions.
final long[] min = new long[interval.numDimensions()];
interval.min(min);
final long[] max = new long[interval.numDimensions()];
interval.max(max);
for (int d = 0; d < interval.numDimensions(); d++) if (interval.dimension(d) < 3) {
min[d]--;
max[d]++;
}
final FinalInterval minInterval = new FinalInterval(min, max);
/*
* Process image.
*/
final int stepsPerOctave = 4;
final double k = Math.pow(2.0, 1.0 / stepsPerOctave);
final double sigma = radius / Math.sqrt(zeroMin.numDimensions());
final double sigmaSmaller = sigma;
final double sigmaLarger = k * sigmaSmaller;
final double normalization = ((detectionType == DetectionType.MAXIMA) ? 1.0 : -1.0) / (sigmaLarger / sigmaSmaller - 1.0);
final double[] pixelSize = DetectionUtil.getPixelSize(sources, tp, setup, level);
final DogDetection<FloatType> dog = new DogDetection<>(source, minInterval, pixelSize, sigmaSmaller, sigmaLarger, (detectionType == DetectionType.MAXIMA) ? ExtremaType.MAXIMA : ExtremaType.MINIMA, threshold, true);
dog.setExecutorService(threadService.getExecutorService());
final ArrayList<RefinedPeak<Point>> refinedPeaks = dog.getSubpixelPeaks();
final double[] pos = new double[3];
final RealPoint sp = RealPoint.wrap(pos);
final RealPoint p3d = new RealPoint(3);
final AffineTransform3D transform = DetectionUtil.getTransform(sources, tp, setup, level);
final DetectionCreator detectionCreator = detectionCreatorFactory.create(tp);
detectionCreator.preAddition();
try {
for (final RefinedPeak<Point> p : refinedPeaks) {
final double value = p.getValue();
final double normalizedValue = value * normalization;
/*
* In case p is 2D we pass it to a 3D RealPoint to work
* nicely with the 3D transform.
*/
for (int d = 0; d < p.numDimensions(); d++) p3d.setPosition(p.getDoublePosition(d), d);
transform.apply(p3d, sp);
detectionCreator.createDetection(pos, radius, normalizedValue);
}
} finally {
detectionCreator.postAddition();
}
}
final long end = System.currentTimeMillis();
processingTime = end - start;
statusService.clearStatus();
ok = true;
}
Aggregations