use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class DiffusionRateTest method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (IJ.controlKeyDown()) {
simpleTest();
return;
}
extraOptions = Utils.isExtraOptions();
if (!showDialog())
return;
lastSimulatedDataset[0] = lastSimulatedDataset[1] = "";
lastSimulatedPrecision = 0;
final int totalSteps = (int) Math.ceil(settings.seconds * settings.stepsPerSecond);
conversionFactor = 1000000.0 / (settings.pixelPitch * settings.pixelPitch);
// Diffusion rate is um^2/sec. Convert to pixels per simulation frame.
final double diffusionRateInPixelsPerSecond = settings.diffusionRate * conversionFactor;
final double diffusionRateInPixelsPerStep = diffusionRateInPixelsPerSecond / settings.stepsPerSecond;
final double precisionInPixels = myPrecision / settings.pixelPitch;
final boolean addError = myPrecision != 0;
Utils.log(TITLE + " : D = %s um^2/sec, Precision = %s nm", Utils.rounded(settings.diffusionRate, 4), Utils.rounded(myPrecision, 4));
Utils.log("Mean-displacement per dimension = %s nm/sec", Utils.rounded(1e3 * ImageModel.getRandomMoveDistance(settings.diffusionRate), 4));
if (extraOptions)
Utils.log("Step size = %s, precision = %s", Utils.rounded(ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep)), Utils.rounded(precisionInPixels));
// Convert diffusion co-efficient into the standard deviation for the random walk
final double diffusionSigma = (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) ? // Q. What should this be? At the moment just do 1D diffusion on a random vector
ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep) : ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep);
Utils.log("Simulation step-size = %s nm", Utils.rounded(settings.pixelPitch * diffusionSigma, 4));
// Move the molecules and get the diffusion rate
IJ.showStatus("Simulating ...");
final long start = System.nanoTime();
final long seed = System.currentTimeMillis() + System.identityHashCode(this);
RandomGenerator[] random = new RandomGenerator[3];
RandomGenerator[] random2 = new RandomGenerator[3];
for (int i = 0; i < 3; i++) {
random[i] = new Well19937c(seed + i * 12436);
random2[i] = new Well19937c(seed + i * 678678 + 3);
}
Statistics[] stats2D = new Statistics[totalSteps];
Statistics[] stats3D = new Statistics[totalSteps];
StoredDataStatistics jumpDistances2D = new StoredDataStatistics(totalSteps);
StoredDataStatistics jumpDistances3D = new StoredDataStatistics(totalSteps);
for (int j = 0; j < totalSteps; j++) {
stats2D[j] = new Statistics();
stats3D[j] = new Statistics();
}
SphericalDistribution dist = new SphericalDistribution(settings.confinementRadius / settings.pixelPitch);
Statistics asymptote = new Statistics();
// Save results to memory
MemoryPeakResults results = new MemoryPeakResults(totalSteps);
Calibration cal = new Calibration(settings.pixelPitch, 1, 1000.0 / settings.stepsPerSecond);
results.setCalibration(cal);
results.setName(TITLE);
int peak = 0;
// Store raw coordinates
ArrayList<Point> points = new ArrayList<Point>(totalSteps);
StoredData totalJumpDistances1D = new StoredData(settings.particles);
StoredData totalJumpDistances2D = new StoredData(settings.particles);
StoredData totalJumpDistances3D = new StoredData(settings.particles);
for (int i = 0; i < settings.particles; i++) {
if (i % 16 == 0) {
IJ.showProgress(i, settings.particles);
if (Utils.isInterrupted())
return;
}
// Increment the frame so that tracing analysis can distinguish traces
peak++;
double[] origin = new double[3];
final int id = i + 1;
MoleculeModel m = new MoleculeModel(id, origin.clone());
if (addError)
origin = addError(origin, precisionInPixels, random);
if (useConfinement) {
// Note: When using confinement the average displacement should asymptote
// at the average distance of a point from the centre of a ball. This is 3r/4.
// See: http://answers.yahoo.com/question/index?qid=20090131162630AAMTUfM
// The equivalent in 2D is 2r/3. However although we are plotting 2D distance
// this is a projection of the 3D position onto the plane and so the particles
// will not be evenly spread (there will be clustering at centre caused by the
// poles)
final double[] axis = (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) ? nextVector() : null;
for (int j = 0; j < totalSteps; j++) {
double[] xyz = m.getCoordinates();
double[] originalXyz = xyz.clone();
for (int n = confinementAttempts; n-- > 0; ) {
if (settings.getDiffusionType() == DiffusionType.GRID_WALK)
m.walk(diffusionSigma, random);
else if (settings.getDiffusionType() == DiffusionType.LINEAR_WALK)
m.slide(diffusionSigma, axis, random[0]);
else
m.move(diffusionSigma, random);
if (!dist.isWithin(m.getCoordinates())) {
// Reset position
for (int k = 0; k < 3; k++) xyz[k] = originalXyz[k];
} else {
// The move was allowed
break;
}
}
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
asymptote.add(distance(m.getCoordinates()));
} else {
if (settings.getDiffusionType() == DiffusionType.GRID_WALK) {
for (int j = 0; j < totalSteps; j++) {
m.walk(diffusionSigma, random);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
} else if (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) {
final double[] axis = nextVector();
for (int j = 0; j < totalSteps; j++) {
m.slide(diffusionSigma, axis, random[0]);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
} else {
for (int j = 0; j < totalSteps; j++) {
m.move(diffusionSigma, random);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
}
}
// Debug: record all the particles so they can be analysed
// System.out.printf("%f %f %f\n", m.getX(), m.getY(), m.getZ());
final double[] xyz = m.getCoordinates();
double d2 = 0;
totalJumpDistances1D.add(d2 = xyz[0] * xyz[0]);
totalJumpDistances2D.add(d2 += xyz[1] * xyz[1]);
totalJumpDistances3D.add(d2 += xyz[2] * xyz[2]);
}
final double time = (System.nanoTime() - start) / 1000000.0;
IJ.showProgress(1);
MemoryPeakResults.addResults(results);
lastSimulatedDataset[0] = results.getName();
lastSimulatedPrecision = myPrecision;
// Convert pixels^2/step to um^2/sec
final double msd2D = (jumpDistances2D.getMean() / conversionFactor) / (results.getCalibration().getExposureTime() / 1000);
final double msd3D = (jumpDistances3D.getMean() / conversionFactor) / (results.getCalibration().getExposureTime() / 1000);
Utils.log("Raw data D=%s um^2/s, Precision = %s nm, N=%d, step=%s s, mean2D=%s um^2, MSD 2D = %s um^2/s, mean3D=%s um^2, MSD 3D = %s um^2/s", Utils.rounded(settings.diffusionRate), Utils.rounded(myPrecision), jumpDistances2D.getN(), Utils.rounded(results.getCalibration().getExposureTime() / 1000), Utils.rounded(jumpDistances2D.getMean() / conversionFactor), Utils.rounded(msd2D), Utils.rounded(jumpDistances3D.getMean() / conversionFactor), Utils.rounded(msd3D));
aggregateIntoFrames(points, addError, precisionInPixels, random2);
IJ.showStatus("Analysing results ...");
if (showDiffusionExample) {
showExample(totalSteps, diffusionSigma, random);
}
// Plot a graph of mean squared distance
double[] xValues = new double[stats2D.length];
double[] yValues2D = new double[stats2D.length];
double[] yValues3D = new double[stats3D.length];
double[] upper2D = new double[stats2D.length];
double[] lower2D = new double[stats2D.length];
double[] upper3D = new double[stats3D.length];
double[] lower3D = new double[stats3D.length];
SimpleRegression r2D = new SimpleRegression(false);
SimpleRegression r3D = new SimpleRegression(false);
final int firstN = (useConfinement) ? fitN : totalSteps;
for (int j = 0; j < totalSteps; j++) {
// Convert steps to seconds
xValues[j] = (double) (j + 1) / settings.stepsPerSecond;
// Convert values in pixels^2 to um^2
final double mean2D = stats2D[j].getMean() / conversionFactor;
final double mean3D = stats3D[j].getMean() / conversionFactor;
final double sd2D = stats2D[j].getStandardDeviation() / conversionFactor;
final double sd3D = stats3D[j].getStandardDeviation() / conversionFactor;
yValues2D[j] = mean2D;
yValues3D[j] = mean3D;
upper2D[j] = mean2D + sd2D;
lower2D[j] = mean2D - sd2D;
upper3D[j] = mean3D + sd3D;
lower3D[j] = mean3D - sd3D;
if (j < firstN) {
r2D.addData(xValues[j], yValues2D[j]);
r3D.addData(xValues[j], yValues3D[j]);
}
}
// TODO - Fit using the equation for 2D confined diffusion:
// MSD = 4s^2 + R^2 (1 - 0.99e^(-1.84^2 Dt / R^2)
// s = localisation precision
// R = confinement radius
// D = 2D diffusion coefficient
// t = time
final PolynomialFunction fitted2D, fitted3D;
if (r2D.getN() > 0) {
// Do linear regression to get diffusion rate
final double[] best2D = new double[] { r2D.getIntercept(), r2D.getSlope() };
fitted2D = new PolynomialFunction(best2D);
final double[] best3D = new double[] { r3D.getIntercept(), r3D.getSlope() };
fitted3D = new PolynomialFunction(best3D);
// For 2D diffusion: d^2 = 4D
// where: d^2 = mean-square displacement
double D = best2D[1] / 4.0;
String msg = "2D Diffusion rate = " + Utils.rounded(D, 4) + " um^2 / sec (" + Utils.timeToString(time) + ")";
IJ.showStatus(msg);
Utils.log(msg);
D = best3D[1] / 6.0;
Utils.log("3D Diffusion rate = " + Utils.rounded(D, 4) + " um^2 / sec (" + Utils.timeToString(time) + ")");
} else {
fitted2D = fitted3D = null;
}
// Create plots
plotMSD(totalSteps, xValues, yValues2D, lower2D, upper2D, fitted2D, 2);
plotMSD(totalSteps, xValues, yValues3D, lower3D, upper3D, fitted3D, 3);
plotJumpDistances(TITLE, jumpDistances2D, 2, 1);
plotJumpDistances(TITLE, jumpDistances3D, 3, 1);
if (idCount > 0)
new WindowOrganiser().tileWindows(idList);
if (useConfinement)
Utils.log("3D asymptote distance = %s nm (expected %.2f)", Utils.rounded(asymptote.getMean() * settings.pixelPitch, 4), 3 * settings.confinementRadius / 4);
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class DensityImage method plotResults.
/**
* Draw an image of the density for each localisation. Optionally filter results below a threshold.
*
* @param results
* @param density
* @param scoreCalculator
* @return
*/
private int plotResults(MemoryPeakResults results, float[] density, ScoreCalculator scoreCalculator) {
// Filter results using 5x higher than average density of the sample in a 150nm radius:
// Annibale, et al (2011). Identification of clustering artifacts in photoactivated localization microscopy.
// Nature Methods, 8, pp527-528
MemoryPeakResults newResults = null;
// No filtering
float densityThreshold = Float.NEGATIVE_INFINITY;
if (filterLocalisations) {
densityThreshold = scoreCalculator.getThreshold();
newResults = new MemoryPeakResults();
newResults.copySettings(results);
newResults.setName(results.getName() + " Density Filter");
}
// Draw an image - Use error so that a floating point value can be used on a single pixel
List<PeakResult> peakResults = results.getResults();
IJImagePeakResults image = ImagePeakResultsFactory.createPeakResultsImage(ResultsImage.ERROR, false, false, results.getName() + " Density", results.getBounds(), results.getNmPerPixel(), results.getGain(), imageScale, 0, (cumulativeImage) ? ResultsMode.ADD : ResultsMode.MAX);
image.setDisplayFlags(image.getDisplayFlags() | IJImagePeakResults.DISPLAY_NEGATIVES);
image.setLutName("grays");
image.begin();
for (int i = 0; i < density.length; i++) {
if (density[i] < densityThreshold)
continue;
PeakResult r = peakResults.get(i);
image.add(0, 0, 0, 0, density[i], 0, r.params, null);
if (newResults != null)
newResults.add(r);
}
image.end();
// Add to memory
if (newResults != null && newResults.size() > 0)
MemoryPeakResults.addResults(newResults);
return image.size();
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class DensityImage method cropWithBorder.
/**
* Crop the results to the ROI. Add a border using the sampling radius so that counts do not have to be approximated
* (i.e. all spots around the edge of the ROI will have a complete image to sample from). The results are modified
* in place.
*
* @param results
* @param isWithin
* Set to true if the added border is within the original bounds (i.e. no adjustment for missing counts
* is required)
* @return
*/
private MemoryPeakResults cropWithBorder(MemoryPeakResults results, boolean[] isWithin) {
isWithin[0] = false;
if (roiBounds == null)
return results;
// Adjust bounds relative to input results image:
// Use the ROI relative to the frame the ROI is drawn on.
// Map those fractional coordinates back to the original data bounds.
Rectangle bounds = results.getBounds();
double xscale = (double) roiImageWidth / bounds.width;
double yscale = (double) roiImageHeight / bounds.height;
// Compute relative to the results bounds (if present)
scaledRoiMinX = bounds.x + roiBounds.x / xscale;
scaledRoiMaxX = scaledRoiMinX + roiBounds.width / xscale;
scaledRoiMinY = bounds.y + roiBounds.y / yscale;
scaledRoiMaxY = scaledRoiMinY + roiBounds.height / yscale;
// Allow for the border
final float minX = (int) (scaledRoiMinX - radius);
final float maxX = (int) Math.ceil(scaledRoiMaxX + radius);
final float minY = (int) (scaledRoiMinY - radius);
final float maxY = (int) Math.ceil(scaledRoiMaxY + radius);
// Create a new set of results within the bounds
MemoryPeakResults newResults = new MemoryPeakResults();
newResults.begin();
for (PeakResult peakResult : results.getResults()) {
float x = peakResult.params[Gaussian2DFunction.X_POSITION];
float y = peakResult.params[Gaussian2DFunction.Y_POSITION];
if (x < minX || x > maxX || y < minY || y > maxY)
continue;
newResults.add(peakResult);
}
newResults.end();
newResults.copySettings(results);
newResults.setBounds(new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)));
isWithin[0] = minX >= bounds.x && minY >= bounds.y && maxX <= (bounds.x + bounds.width) && maxY <= (bounds.y + bounds.height);
return newResults;
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class DrawClusters method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "No localisations in memory");
return;
}
if (!showDialog())
return;
// Load the results
MemoryPeakResults results = ResultsManager.loadInputResults(inputOption, false);
if (results == null || results.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
return;
}
// Get the traces
Trace[] traces = TraceManager.convert(results);
if (traces == null || traces.length == 0) {
IJ.error(TITLE, "No traces could be loaded");
return;
}
// Filter traces to a min size
int maxFrame = 0;
int count = 0;
final int myMaxSize = (maxSize < minSize) ? Integer.MAX_VALUE : maxSize;
final boolean myDrawLines = (myMaxSize < 2) ? false : drawLines;
for (int i = 0; i < traces.length; i++) {
if (expandToSingles)
traces[i].expandToSingles();
if (traces[i].size() >= minSize && traces[i].size() <= myMaxSize) {
traces[count++] = traces[i];
traces[i].sort();
if (maxFrame < traces[i].getTail().getFrame())
maxFrame = traces[i].getTail().getFrame();
}
}
if (count == 0) {
IJ.error(TITLE, "No traces achieved the size limits");
return;
}
String msg = String.format(TITLE + ": %d / %s (%s)", count, Utils.pleural(traces.length, "trace"), Utils.pleural(results.size(), "localisation"));
IJ.showStatus(msg);
//Utils.log(msg);
Rectangle bounds = results.getBounds(true);
ImagePlus imp = WindowManager.getImage(title);
boolean isUseStackPosition = useStackPosition;
if (imp == null) {
// Create a default image using 100 pixels as the longest edge
double maxD = (bounds.width > bounds.height) ? bounds.width : bounds.height;
int w, h;
if (maxD == 0) {
// Note that imageSize can be zero (for auto sizing)
w = h = (imageSize == 0) ? 20 : imageSize;
} else {
// Note that imageSize can be zero (for auto sizing)
if (imageSize == 0) {
w = bounds.width;
h = bounds.height;
} else {
w = (int) (imageSize * bounds.width / maxD);
h = (int) (imageSize * bounds.height / maxD);
}
}
ByteProcessor bp = new ByteProcessor(w, h);
if (isUseStackPosition) {
ImageStack stack = new ImageStack(w, h, maxFrame);
for (int i = 1; i <= maxFrame; i++) // Do not clone as the image is empty
stack.setPixels(bp.getPixels(), i);
imp = Utils.display(TITLE, stack);
} else
imp = Utils.display(TITLE, bp);
// Enlarge
ImageWindow iw = imp.getWindow();
for (int i = 9; i-- > 0 && iw.getWidth() < 500 && iw.getHeight() < 500; ) {
iw.getCanvas().zoomIn(imp.getWidth() / 2, imp.getHeight() / 2);
}
} else {
// Check if the image has enough frames for all the traces
if (maxFrame > imp.getNFrames())
isUseStackPosition = false;
}
final float xScale = (float) (imp.getWidth() / bounds.getWidth());
final float yScale = (float) (imp.getHeight() / bounds.getHeight());
// Create ROIs and store data to sort them
Roi[] rois = new Roi[count];
int[][] frames = (isUseStackPosition) ? new int[count][] : null;
int[] indices = Utils.newArray(count, 0, 1);
double[] values = new double[count];
for (int i = 0; i < count; i++) {
Trace trace = traces[i];
int nPoints = trace.size();
float[] xPoints = new float[nPoints];
float[] yPoints = new float[nPoints];
int j = 0;
if (isUseStackPosition)
frames[i] = new int[nPoints];
for (PeakResult result : trace.getPoints()) {
xPoints[j] = (result.getXPosition() - bounds.x) * xScale;
yPoints[j] = (result.getYPosition() - bounds.y) * yScale;
if (isUseStackPosition)
frames[i][j] = result.getFrame();
j++;
}
Roi roi;
if (myDrawLines) {
roi = new PolygonRoi(xPoints, yPoints, nPoints, Roi.POLYLINE);
if (splineFit)
((PolygonRoi) roi).fitSpline();
} else {
roi = new PointRoi(xPoints, yPoints, nPoints);
((PointRoi) roi).setShowLabels(false);
}
rois[i] = roi;
switch(sort) {
case 0:
default:
break;
case // Sort by ID
1:
values[i] = traces[i].getId();
break;
case // Sort by time
2:
values[i] = traces[i].getHead().getFrame();
break;
case // Sort by size descending
3:
values[i] = -traces[i].size();
break;
case // Sort by length descending
4:
values[i] = -roi.getLength();
break;
case // Mean Square Displacement
5:
values[i] = -traces[i].getMSD();
break;
case // Mean / Frame
6:
values[i] = -traces[i].getMeanPerFrame();
break;
}
}
if (sort > 0)
Sort.sort(indices, values);
// Draw the traces as ROIs on an overlay
Overlay o = new Overlay();
LUT lut = LUTHelper.createLUT(DrawClusters.lut);
final double scale = 256.0 / count;
if (isUseStackPosition) {
// Add the tracks on the frames containing the results
final boolean isHyperStack = imp.isDisplayedHyperStack();
for (int i = 0; i < count; i++) {
final int index = indices[i];
final Color c = LUTHelper.getColour(lut, (int) (i * scale));
final PolygonRoi roi = (PolygonRoi) rois[index];
roi.setFillColor(c);
roi.setStrokeColor(c);
final FloatPolygon fp = roi.getNonSplineFloatPolygon();
// For each frame in the track, add the ROI track and a point ROI for the current position
for (int j = 0; j < frames[index].length; j++) {
addToOverlay(o, (Roi) roi.clone(), isHyperStack, frames[index][j]);
//PointRoi pointRoi = new PointRoi(pos.x + fp.xpoints[j], pos.y + fp.ypoints[j]);
PointRoi pointRoi = new PointRoi(fp.xpoints[j], fp.ypoints[j]);
pointRoi.setPointType(3);
pointRoi.setFillColor(c);
pointRoi.setStrokeColor(Color.black);
addToOverlay(o, pointRoi, isHyperStack, frames[index][j]);
}
}
} else {
// Add the tracks as a single overlay
for (int i = 0; i < count; i++) {
final Roi roi = rois[indices[i]];
roi.setStrokeColor(new Color(lut.getRGB((int) (i * scale))));
o.add(roi);
}
}
imp.setOverlay(o);
IJ.showStatus(msg);
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class DriftCalculator method applyDriftCorrection.
private void applyDriftCorrection(MemoryPeakResults results, double[][] drift) {
ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Apply drift correction to in-memory results?");
gd.addChoice("Update_method", UPDATE_METHODS, UPDATE_METHODS[updateMethod]);
// Option to save the drift unless it was loaded from file
if (method != DRIFT_FILE)
gd.addCheckbox("Save_drift", saveDrift);
gd.showDialog();
if (gd.wasCanceled())
return;
updateMethod = gd.getNextChoiceIndex();
if (method != DRIFT_FILE) {
saveDrift = gd.getNextBoolean();
saveDrift(calculatedTimepoints, lastdx, lastdy);
}
if (updateMethod == 0)
return;
final double[] dx = drift[0];
final double[] dy = drift[1];
if (updateMethod == 1) {
// Update the results in memory
Utils.log("Applying drift correction to the results set: " + results.getName());
for (PeakResult r : results) {
r.params[Gaussian2DFunction.X_POSITION] += dx[r.getFrame()];
r.params[Gaussian2DFunction.Y_POSITION] += dy[r.getFrame()];
}
} else {
// Create a new set of results
MemoryPeakResults newResults = new MemoryPeakResults(results.size());
newResults.copySettings(results);
newResults.setName(results.getName() + " (Corrected)");
MemoryPeakResults.addResults(newResults);
final boolean truncate = updateMethod == 3;
Utils.log("Creating %sdrift corrected results set: " + newResults.getName(), (truncate) ? "truncated " : "");
for (PeakResult r : results) {
if (truncate) {
if (r.getFrame() < interpolationStart || r.getFrame() > interpolationEnd)
continue;
}
float[] params = Arrays.copyOf(r.params, r.params.length);
params[Gaussian2DFunction.X_POSITION] += dx[r.getFrame()];
params[Gaussian2DFunction.Y_POSITION] += dy[r.getFrame()];
newResults.addf(r.getFrame(), r.origX, r.origY, r.origValue, r.error, r.noise, params, r.paramsStdDev);
}
}
}
Aggregations