private void undoglobalfit() {
   for (int i = 0; i < ncurves; i++) {
     for (int j = 0; j < nparams; j++) {
       globalparams[i][j] = undoparams[i][j];
       globalformulas[i][j] = undoformulas[i][j];
       globalvflmatrix[i][j] = undovflmatrix[i][j];
     }
     for (int j = 0; j < xpts; j++) {
       for (int k = 0; k < ypts; k++) {
         fit[i][j][k] = undofit[i][j][k];
       }
     }
     if (i == dispcurve) {
       pwfit.updateSeries(fit[dispcurve], 1, true);
     }
     c2[i] = undoc2[i];
     c2array[i].setText("" + (float) c2[i]);
   }
   globalc2 = undoglobalc2;
   globalc2label.setText("Global chi^2 = " + (float) globalc2);
 }
  private void fitglobal() {
    int nparams = 11;
    int nsel = 0;
    for (int i = 0; i < ncurves; i++) {
      if (include[i]) {
        nsel++;
      }
    }
    double[][] params = new double[nsel][nparams];
    String[][] tempformulas = new String[nsel][nparams];
    double[][][] constraints = new double[2][nsel][nparams];
    int[][] vflmatrix = new int[nsel][nparams];

    int counter = 0;
    for (int i = 0; i < ncurves; i++) {
      if (include[i]) {
        for (int j = 0; j < nparams; j++) {
          params[counter][j] = globalparams[i][j];
          tempformulas[counter][j] = globalformulas[i][j];
          constraints[0][counter][j] = globalconstraints[0][i][j];
          constraints[1][counter][j] = globalconstraints[1][i][j];
          vflmatrix[counter][j] = globalvflmatrix[i][j];
        }
        counter++;
      }
      for (int j = 0; j < nparams; j++) {
        undoparams[i][j] = globalparams[i][j];
        undoformulas[i][j] = globalformulas[i][j];
        undovflmatrix[i][j] = globalvflmatrix[i][j];
      }
      for (int j = 0; j < xpts; j++) {
        for (int k = 0; k < ypts; k++) {
          undofit[i][j][k] = fit[i][j][k];
        }
      }
      undoc2[i] = c2[i];
    }
    undoglobalc2 = globalc2;
    if (showglobalfitdialog(params, tempformulas, vflmatrix)) {
      counter = 0;
      for (int i = 0; i < ncurves; i++) {
        if (include[i]) {
          for (int j = 0; j < nparams; j++) {
            globalparams[i][j] = params[counter][j];
            globalformulas[i][j] = tempformulas[counter][j];
            globalvflmatrix[i][j] = vflmatrix[counter][j];
          }
          counter++;
        }
      }
      double[] stats = new double[2];
      float[][] tempdata = new float[nsel][xpts * ypts];
      float[][] tempweights = new float[nsel][xpts * ypts];
      counter = 0;
      for (int i = 0; i < ncurves; i++) {
        if (include[i]) {
          for (int j = 0; j < xpts; j++) {
            for (int k = 0; k < ypts; k++) {
              tempdata[counter][j + k * xpts] = (float) ((double) pch[i][j][k] / (double) nmeas[i]);
              tempweights[counter][j + k * xpts] = weights[i][j][k];
            }
          }
          counter++;
        }
      }
      int tempmaxiter = globalfitclass.maxiter;
      if (checkc2) {
        globalfitclass.changemaxiter(0);
      }
      double[] tempc2vals = new double[nsel];
      IJ.showStatus("Fitting Globally");
      float[][] tempfit =
          globalfitclass.fitdata(
              params,
              vflmatrix,
              tempformulas,
              paramsnames,
              constraints,
              tempdata,
              tempweights,
              stats,
              tempc2vals,
              false);
      IJ.showStatus("Fit Complete");
      globalfitclass.changemaxiter(tempmaxiter);
      globalc2 = stats[1];
      globalc2label.setText("Global chi^2 = " + (float) globalc2);
      counter = 0;
      for (int i = 0; i < ncurves; i++) {
        if (include[i]) {
          for (int j = 0; j < xpts; j++) {
            for (int k = 0; k < ypts; k++) {
              fit[i][j][k] = tempfit[counter][j + xpts * k] * (float) nmeas[i];
            }
          }
          if (i == dispcurve) {
            pwfit.updateSeries(fit[dispcurve], 1, true);
          }
          for (int j = 0; j < nparams; j++) {
            globalparams[i][j] = params[counter][j];
          }
          c2[i] = tempc2vals[counter];
          c2array[i].setText("" + (float) c2[i]);
          counter++;
        }
      }
      float[] temp = pwfit.getLimits();
      temp[4] = 1.0f;
      pwfit.setLimits(temp);
    }
  }
  void init(String[] names1, float[][][] pch1, int psfflag1) {
    setLayout(null);
    names = names1;
    pch = pch1;
    psfflag = psfflag1;
    ncurves = pch.length;
    nparams = 11;
    xpts = pch[0].length;
    ypts = pch[0][0].length;

    checkarray = new Checkbox[ncurves];
    include = new boolean[ncurves];
    namearray = new TextField[ncurves + 1];
    int1array = new TextField[ncurves + 1];
    intensity1 = new double[ncurves + 1];
    e1array = new TextField[ncurves + 1];
    n1array = new TextField[ncurves + 1];
    bright1 = new double[ncurves + 1];
    number1 = new double[ncurves + 1];
    int2array = new TextField[ncurves + 1];
    intensity2 = new double[ncurves + 1];
    e2array = new TextField[ncurves + 1];
    n2array = new TextField[ncurves + 1];
    bright2 = new double[ncurves + 1];
    number2 = new double[ncurves + 1];
    eccarray = new TextField[ncurves + 1];
    brightcc = new double[ncurves + 1];
    eminccarray = new TextField[ncurves + 1];
    brightmincc = new double[ncurves + 1];
    c2array = new TextField[ncurves + 1];
    c2 = new double[ncurves + 1];
    nmeas = new int[ncurves + 1];
    avg = new float[xpts][ypts];
    indices = new int[ncurves];
    beta = 0.05;

    getintbright();
    for (int i = 0; i < ncurves; i++) {
      include[i] = true;
      indices[i] = i;
    }
    updateavg();

    int starty = 60;
    int startx = 10;
    int yinc = 25;
    for (int i = 0; i <= ncurves; i++) {
      if (i != ncurves) {
        checkarray[i] = new Checkbox("", include[i]);
        checkarray[i].setBounds(startx, starty + i * yinc, 20, 20);
        checkarray[i].addItemListener(this);
        add(checkarray[i]);
      }

      namearray[i] = new TextField(names[i]);
      namearray[i].setBounds(startx + 30, starty + i * yinc, 200, 20);
      add(namearray[i]);

      int1array[i] = new TextField("" + (float) intensity1[i]);
      int1array[i].setBounds(startx + 30 + 210, starty + i * yinc, 40, 20);
      add(int1array[i]);

      e1array[i] = new TextField("" + (float) bright1[i]);
      e1array[i].setBounds(startx + 30 + 210 + 50, starty + i * yinc, 40, 20);
      add(e1array[i]);

      n1array[i] = new TextField("" + (float) number1[i]);
      n1array[i].setBounds(startx + 30 + 210 + 50 + 50, starty + i * yinc, 40, 20);
      add(n1array[i]);

      int2array[i] = new TextField("" + (float) intensity2[i]);
      int2array[i].setBounds(startx + 30 + 210 + 50 + 50 + 50, starty + i * yinc, 40, 20);
      add(int2array[i]);

      e2array[i] = new TextField("" + (float) bright2[i]);
      e2array[i].setBounds(startx + 30 + 210 + 50 + 50 + 50 + 50, starty + i * yinc, 40, 20);
      add(e2array[i]);

      n2array[i] = new TextField("" + (float) number2[i]);
      n2array[i].setBounds(startx + 30 + 210 + 50 + 50 + 50 + 50 + 50, starty + i * yinc, 40, 20);
      add(n2array[i]);

      eccarray[i] = new TextField("" + (float) brightcc[i]);
      eccarray[i].setBounds(
          startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50, starty + i * yinc, 40, 20);
      add(eccarray[i]);

      eminccarray[i] = new TextField("" + (float) brightmincc[i]);
      eminccarray[i].setBounds(
          startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50 + 50, starty + i * yinc, 40, 20);
      add(eminccarray[i]);

      c2[i] = 0.0;
      c2array[i] = new TextField("" + (float) c2[i]);
      c2array[i].setBounds(
          startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50 + 50 + 50, starty + i * yinc, 80, 20);
      add(c2array[i]);
    }

    namelabel = new Label("Filename");
    namelabel.setBounds(startx + 30, starty - 25, 100, 20);
    add(namelabel);

    intlabel = new Label("<Ig>");
    intlabel.setBounds(startx + 30 + 210, starty - 25, 40, 20);
    add(intlabel);

    brightlabel = new Label("<eg>");
    brightlabel.setBounds(startx + 30 + 210 + 50, starty - 25, 40, 20);
    add(brightlabel);

    nlabel = new Label("<Ng>");
    nlabel.setBounds(startx + 30 + 210 + 50 + 50, starty - 25, 40, 20);
    add(nlabel);

    int2label = new Label("<Ir>");
    int2label.setBounds(startx + 30 + 210 + 50 + 50 + 50, starty - 25, 40, 20);
    add(int2label);

    bright2label = new Label("<er>");
    bright2label.setBounds(startx + 30 + 210 + 50 + 50 + 50 + 50, starty - 25, 40, 20);
    add(bright2label);

    n2label = new Label("<Nr>");
    n2label.setBounds(startx + 30 + 210 + 50 + 50 + 50 + 50 + 50, starty - 25, 40, 20);
    add(n2label);

    brightcclabel = new Label("<ecc>");
    brightcclabel.setBounds(startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50, starty - 25, 40, 20);
    add(brightcclabel);

    brightccminlabel = new Label("min");
    brightccminlabel.setBounds(
        startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50 + 50, starty - 25, 40, 20);
    add(brightccminlabel);

    c2label = new Label("chi^2");
    c2label.setBounds(
        startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50 + 50 + 50, starty - 25, 80, 20);
    add(c2label);

    int buttonsx = startx + 30 + 210 + 50 + 50 + 50 + 50 + 50 + 50 + 50 + 50 + 90;

    fitavgbutton = new Button("Fit Avg");
    fitavgbutton.setBounds(buttonsx, starty - 25, 100, 40);
    fitavgbutton.addActionListener(this);
    add(fitavgbutton);

    fitglobalbutton = new Button("Fit Global");
    fitglobalbutton.setBounds(buttonsx, starty - 25 + 50, 100, 40);
    fitglobalbutton.addActionListener(this);
    add(fitglobalbutton);

    clearparamsbutton = new Button("Reset Fit Params");
    clearparamsbutton.setBounds(buttonsx, starty - 25 + 50 + 50, 100, 40);
    clearparamsbutton.addActionListener(this);
    add(clearparamsbutton);

    checkc2 = false;

    fitclass = new NLLSfit(this, 0.0001, 50, 0.1);
    globalfitclass = new NLLSglobalfit(this, 0.0001, 50, 0.1);
    pchfunc = new pch2D((int) ((double) xpts * 1.5), (int) ((double) ypts * 1.5), psfflag);
    avgfit = new float[xpts][ypts];
    fit = new float[ncurves][xpts][ypts];

    xvals = new float[ncurves][xpts][ypts];
    for (int i = 0; i < ncurves; i++) {
      for (int j = 0; j < xpts; j++) {
        for (int k = 0; k < ypts; k++) {
          xvals[i][j][k] = (float) k;
          fit[i][j][k] = 1.0f;
        }
      }
    }

    globalc2label = new Label("Global chi^2 = " + (float) 0.0);
    globalc2label.setBounds(buttonsx, starty - 25 + 50 + 50 + 50, 140, 20);
    add(globalc2label);

    dispcurvelabel = new Label("Display Fit #");
    dispcurvelabel.setBounds(buttonsx, starty - 25 + 50 + 50 + 50 + 30, 70, 20);
    add(dispcurvelabel);

    dispcurvechoice = new Choice();
    for (int i = 0; i < ncurves; i++) {
      dispcurvechoice.add("" + (i + 1));
    }
    dispcurve = 0;
    dispcurvechoice.select(0);
    dispcurvechoice.setBounds(buttonsx + 80, starty - 25 + 50 + 50 + 50 + 30, 40, 20);
    dispcurvechoice.addItemListener(this);
    add(dispcurvechoice);

    betalabel = new Label("Bleedthrough f");
    betalabel.setBounds(buttonsx, starty - 25 + 50 + 50 + 50 + 30 + 30, 100, 20);
    add(betalabel);
    betaval = new TextField("" + (float) beta);
    betaval.setBounds(buttonsx + 110, starty - 25 + 50 + 50 + 50 + 30 + 30, 40, 20);
    betaval.addActionListener(this);
    add(betaval);

    beta = Double.parseDouble(betaval.getText());
    updatebeta();

    undobutton = new Button("Undo Global Fit");
    undobutton.setBounds(buttonsx, starty - 25 + 50 + 50 + 50 + 30 + 30 + 50, 100, 40);
    undobutton.addActionListener(this);
    add(undobutton);

    geterrorsbutton = new Button("Get Errors");
    geterrorsbutton.setBounds(buttonsx, starty - 25 + 50 + 50 + 50 + 30 + 30 + 50 + 50, 100, 40);
    geterrorsbutton.addActionListener(this);
    add(geterrorsbutton);

    copylabel = new Label("copyright 2009 Jay Unruh ([email protected]) non-profit use only");
    copylabel.setBounds(10, 790, 400, 20);
    add(copylabel);

    n_b_label = new Label("N and B Analysis");
    n_b_label.setBounds(250, 10, 100, 20);
    add(n_b_label);

    pwavg = new PlotWindow3D("Avg", "kg", "kr", "Frequency", avg, 0);
    pwavg.setLogAxes(false, false, true);
    pwavg.draw();
    pwavg.addPoints(avgfit, true, 0);
    float[] temp = pwavg.getLimits();
    temp[4] = 1.0f;
    pwavg.setLimits(temp);

    float[][] temppch = new float[xpts][ypts];
    for (int i = 0; i < xpts; i++) {
      System.arraycopy(pch[dispcurve][i], 0, temppch[i], 0, ypts);
    }
    pwfit = new PlotWindow3D("Selected Curve", "kg", "kr", "Frequency", temppch, 0);
    pwfit.setLogAxes(false, false, true);
    pwfit.draw();
    pwfit.addPoints(fit[dispcurve], true, 0);
    float[] temp2 = pwfit.getLimits();
    temp2[4] = 1.0f;
    pwfit.setLimits(temp2);

    resetparams();
    repaint();
  }