private void fitDataUpdate(FitPeak fit, double[] deltas) { // update sign and clamp solution if appears to be oscillating for (int i = 0; i < deltas.length; i++) { if (fit.sign[i] != 0) { if ((fit.sign[i] == 1) && (deltas[i] < 0.0)) { fit.clamp[i] *= 0.5; } else if ((fit.sign[i] == -1) && (deltas[i] > 0.0)) { fit.clamp[i] *= 0.5; } } if (deltas[i] > 0.0) { fit.sign[i] = (byte) +1; } else { fit.sign[i] = (byte) -1; } // update values based on delta and clamp if (deltas[i] != 0.0) { final double update = deltas[i] / (1.0 + Math.abs(deltas[i]) / fit.clamp[i]); fit.peak.addToParameter(i, -update); } } // update peak center with HYSTERESIS if (Math.abs(fit.peak.getXCenter() - ((double) fit.xc) - 0.5) > this.HYSTERESIS) { fit.xc = (int) fit.peak.getXCenter(); } if (Math.abs(fit.peak.getYCenter() - ((double) fit.yc) - 0.5) > this.HYSTERESIS) { fit.yc = (int) fit.peak.getYCenter(); } // check that the peak has not moved too close of the // edge of the image, flag peak as bad if it has int xc = fit.xc; int yc = fit.yc; if ((xc < this.MARGIN) || (xc >= (imgSizeX - this.MARGIN)) || (yc < this.MARGIN) || (yc >= (imgSizeY - this.MARGIN))) { fit.peak.setStatus(PeakStatus.BADPEAK); } // check for negative background or height if ((fit.peak.getBackground() < 0.0) || (fit.peak.getHeight() < 0.0)) { fit.peak.setStatus(PeakStatus.ERROR); } // check for negative widths if ((fit.peak.getXWidth() < 0.0) || (fit.peak.getYWidth() < 0.0)) { fit.peak.setStatus(PeakStatus.ERROR); } // Opt 1 : peak errors if z is out of range /* if ((cur.peak.zCenter < this.minZ) || (cur.peak.zCenter > this.maxZ)) { cur.status = PeakStatus.Error; } */ // Opt 2: Clamp Z value Range if (fit.peak.getZCenter() < this.minZ) fit.peak.setZCenter(this.minZ); if (fit.peak.getZCenter() > this.maxZ) fit.peak.setZCenter(this.maxZ); }
// ------------------------------------------- // Constructor // ------------------------------------------- public MultiFit( double[] image, ArrayList<Peak> params, double tolerance, int imageSizeX, int imageSizeY, boolean zFitting) { assert (tolerance < 1.0e-1); assert (image != null && image.length == (imageSizeX * imageSizeY)); this.tolerance = tolerance; this.imgData = image; this.imgSizeX = imageSizeX; this.imgSizeY = imageSizeY; this.fgData = new double[image.length]; this.bgData = new double[image.length]; this.bgCounts = new int[image.length]; this.fits = new ArrayList<FitPeak>(params.size()); for (Peak p : params) { FitPeak newFit = new FitPeak(p, 10); if (newFit.peak.hasStatus(PeakStatus.RUNNING)) { newFit.error = 0.0; newFit.errorOld = 0.0; } else { newFit.error = newFit.peak.getIError(); newFit.errorOld = newFit.error; } if (zFitting) { calcWidthsFromZ(newFit); } else { newFit.peak.setXWidth(1.0 / (2.0 * Math.pow(newFit.peak.getXWidth(), 2))); newFit.peak.setYWidth(1.0 / (2.0 * Math.pow(newFit.peak.getYWidth(), 2))); } newFit.xc = (int) newFit.peak.getXCenter(); newFit.yc = (int) newFit.peak.getYCenter(); // possible bug casting fromm double to int in original version newFit.wx = calcWidth(newFit.peak.getXWidth(), -10); newFit.wy = calcWidth(newFit.peak.getYWidth(), -10); // todo these are annoying constants newFit.setClampHeight(1000.0); newFit.setClampBackground(100.0); newFit.setClampXCenter(1.0); newFit.setClampYCenter(1.0); newFit.setClampXWidth(0.3); newFit.setClampYWidth(0.3); newFit.setClampZCenter(0.1); this.fits.add(newFit); } calcFit(); calcError(); }