Exemple #1
0
  // -------------------------------------------
  // 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();
  }
Exemple #2
0
  public void update2D() {
    double[] delta = new double[Peak.NFITPARAMS];
    double[] jt = new double[5];
    double[] jacobian = new double[5];
    double[][] hessian = new double[5][5];

    for (FitPeak fit : this.fits) {
      if (fit.peak.hasStatus(PeakStatus.RUNNING)) {

        for (int i = 0; i < 5; i++) {
          jacobian[i] = 0.0;
          hessian[i][0] = 0.0;
          hessian[i][1] = 0.0;
          hessian[i][2] = 0.0;
          hessian[i][3] = 0.0;
          hessian[i][4] = 0.0;
        }

        final int offset = fit.offset;
        final int wx = fit.wx;
        final int wy = fit.wy;
        final double height = fit.peak.getHeight();
        final double width = fit.peak.getXWidth();

        for (int i = -wy; i <= +wy; i++) {
          final double yt = fit.yt[i + wy];
          final double eyt = fit.eyt[i + wy];

          for (int j = -wx; j <= +wx; j++) {
            final double xt = fit.xt[j + wx];
            final double ext = fit.ext[j + wx];

            final int idx = (i * this.imgSizeX) + (j + offset);
            final double xi = this.imgData[idx];
            final double fi = this.fgData[idx] + (this.bgData[idx] / ((double) this.bgCounts[idx]));

            final double et = ext * eyt;
            jt[0] = et;
            jt[1] = 2.0 * height * width * xt * et;
            jt[2] = 2.0 * height * width * yt * et;
            jt[3] = (-height * xt * xt * et) - (height * yt * yt * et);
            jt[4] = 1.0;

            // calculate jacobian
            final double t1 = 2.0 * (1.0 - xi / fi);
            jacobian[0] += t1 * jt[0];
            jacobian[1] += t1 * jt[1];
            jacobian[2] += t1 * jt[2];
            jacobian[3] += t1 * jt[3];
            jacobian[4] += t1 * jt[4];

            // calculate hessian
            final double t2 = 2.0 * xi / (fi * fi);

            // calculate hessian without second derivative terms.
            // (symmetric upper triangular)
            hessian[0][0] += t2 * jt[0] * jt[0];
            hessian[0][1] += t2 * jt[0] * jt[1];
            hessian[0][2] += t2 * jt[0] * jt[2];
            hessian[0][3] += t2 * jt[0] * jt[3];
            hessian[0][4] += t2 * jt[0] * jt[4];

            hessian[1][1] += t2 * jt[1] * jt[1];
            hessian[1][2] += t2 * jt[1] * jt[2];
            hessian[1][3] += t2 * jt[1] * jt[3];
            hessian[1][4] += t2 * jt[1] * jt[4];

            hessian[2][2] += t2 * jt[2] * jt[2];
            hessian[2][3] += t2 * jt[2] * jt[3];
            hessian[2][4] += t2 * jt[2] * jt[4];

            hessian[3][3] += t2 * jt[3] * jt[3];
            hessian[3][4] += t2 * jt[3] * jt[4];

            hessian[4][4] += t2 * jt[4] * jt[4];
          }
        }

        // subtract the old peak out of the foreground and background arrays
        subtractPeak(fit);

        // use lapack to solve Ax=B to calculate update vector;
        boolean error = false;
        final RealMatrix hessianMatrix = MatrixUtils.createRealMatrix(hessian);
        RealVector jacobianVector = MatrixUtils.createRealVector(jacobian);

        try {
          MatrixUtils.solveUpperTriangularSystem(hessianMatrix, jacobianVector);
        } catch (Exception ex) {
          fit.peak.setStatus(PeakStatus.ERROR);
          error = true;
        }
        if (!error) {
          // TODO: Rearranged the jacobian vector entries
          delta[Peak.HEIGHT] = jacobianVector.getEntry(0); // height
          delta[Peak.XCENTER] = jacobianVector.getEntry(1); // x center
          delta[Peak.YCENTER] = jacobianVector.getEntry(2); // y center
          delta[Peak.XWIDTH] = jacobianVector.getEntry(3); // width
          delta[Peak.YWIDTH] = jacobianVector.getEntry(3); // width
          delta[Peak.BACKGROUND] = jacobianVector.getEntry(4); // background

          // update fits data
          fitDataUpdate(fit, delta);

          // add the peak to the foreground and background arrays
          // recalculate peak fit area as the peak width may have changed
          if (!fit.peak.hasStatus(PeakStatus.ERROR)) {
            fit.wx = calcWidth(fit.peak.getXWidth(), fit.wx);
            fit.wy = fit.wx;
            addPeak(fit);
          }
        }
      }
    }
  }
Exemple #3
0
  public void updateZ() {

    double[] delta = new double[Peak.NFITPARAMS];
    double[] jt = new double[5];
    double[] jacobian = new double[5];
    double[][] hessian = new double[5][5];

    for (FitPeak fit : this.fits) {
      if (fit.peak.hasStatus(PeakStatus.RUNNING)) {

        for (int i = 0; i < 5; i++) {
          jacobian[i] = 0;
          hessian[i][0] = 0.0;
          hessian[i][1] = 0.0;
          hessian[i][2] = 0.0;
          hessian[i][3] = 0.0;
          hessian[i][4] = 0.0;
        }

        final int offset = fit.offset;
        final int wx = fit.wx;
        final int wy = fit.wy;

        final double height = fit.peak.getHeight();
        final double xwidth = fit.peak.getXWidth();
        final double ywidth = fit.peak.getYWidth();

        // calculate dwx vs z
        final double zCenter = fit.peak.getZCenter();
        double z0 = (zCenter - this.wxZParams[1]) / this.wxZParams[2];
        double z1 = z0 * z0;
        double z2 = z1 * z0;
        double zt = (2.0 * z0) + (3.0 * this.wxZParams[3] * z1) + (4.0 * this.wxZParams[4] * z2);
        final double gx = -2.0 * zt / (this.wxZParams[0] * fit.wxTerm);

        // calculate dwy vs z
        z0 = (zCenter - this.wyZParams[1]) / this.wyZParams[2];
        z1 = z0 * z0;
        z2 = z1 * z0;
        zt = (2.0 * z0) + (3.0 * this.wyZParams[3] * z1) + (4.0 * this.wyZParams[4] * z2);
        final double gy = -2.0 * zt / (this.wyZParams[0] * fit.wyTerm);

        for (int i = -wy; i < +wy; i++) {

          final double yt = fit.yt[i + wy];
          final double eyt = fit.eyt[i + wy];

          for (int j = -wx; j < +wx; j++) {

            final double xt = fit.xt[j + wx];
            final double ext = fit.ext[j + wx];

            final int idx = (i * this.imgSizeX) + (j + offset);
            final double xi = this.imgData[idx];
            final double fi = this.fgData[idx] / (this.bgData[idx] / ((double) this.bgCounts[idx]));

            // first derivatives
            final double et = ext * eyt;
            jt[0] = et;
            jt[1] = 2.0 * height * xwidth * xt * et;
            jt[2] = 2.0 * height * ywidth * yt * et;
            jt[3] = (-height * xt * xt * gx * et) - (height * yt * yt * gy * et);
            jt[4] = 1.0;

            // calculate jacobian
            final double t1 = 2.0 * (1.0 - xi / fi);
            jacobian[0] += t1 * jt[0];
            jacobian[1] += t1 * jt[1];
            jacobian[2] += t1 * jt[2];
            jacobian[3] += t1 * jt[3];
            jacobian[4] += t1 * jt[4];

            // calculate hessian
            final double t2 = 2.0 * xi / (fi * fi);

            // calculate hessian without second derivative terms.
            hessian[0][0] += t2 * jt[0] * jt[0];
            hessian[0][1] += t2 * jt[0] * jt[1];
            hessian[0][2] += t2 * jt[0] * jt[2];
            hessian[0][3] += t2 * jt[0] * jt[3];
            hessian[0][4] += t2 * jt[0] * jt[4];

            hessian[1][1] += t2 * jt[1] * jt[1];
            hessian[1][2] += t2 * jt[1] * jt[2];
            hessian[1][3] += t2 * jt[1] * jt[3];
            hessian[1][4] += t2 * jt[1] * jt[4];

            hessian[2][2] += t2 * jt[2] * jt[2];
            hessian[2][3] += t2 * jt[2] * jt[3];
            hessian[2][4] += t2 * jt[2] * jt[4];

            hessian[3][3] += t2 * jt[3] * jt[3];
            hessian[3][4] += t2 * jt[3] * jt[4];

            hessian[4][4] += t2 * jt[4] * jt[4];
          }
        }

        // subtract the old peak out of the foreground and background arrays
        subtractPeak(fit);

        // use lapack to solve Ax=B to calculate update vector;
        boolean error = false;
        final RealMatrix hessianMatrix = MatrixUtils.createRealMatrix(hessian);
        RealVector jacobianVector = MatrixUtils.createRealVector(jacobian);
        try {
          MatrixUtils.solveUpperTriangularSystem(hessianMatrix, jacobianVector);
        } catch (Exception ex) {
          System.out.println("Fitting ERROR:");
          System.out.println(ex.getMessage());
          fit.peak.setStatus(PeakStatus.ERROR);
          error = true;
        }
        if (!error) {
          // update parameters
          delta[Peak.HEIGHT] = jacobianVector.getEntry(0);
          delta[Peak.XCENTER] = jacobianVector.getEntry(1);
          delta[Peak.YCENTER] = jacobianVector.getEntry(2);
          delta[Peak.ZCENTER] = jacobianVector.getEntry(3);
          delta[Peak.BACKGROUND] = jacobianVector.getEntry(4);

          fitDataUpdate(fit, delta);

          if (!fit.peak.hasStatus(PeakStatus.ERROR)) {
            // calculate new x, y, width and update fit area
            calcWidthsFromZ(fit);
            fit.wx = calcWidth(fit.peak.getXWidth(), fit.wx);
            fit.wy = calcWidth(fit.peak.getYWidth(), fit.wy);
            addPeak(fit);
          }
        }
      }
    }
  }