package org.jlab.groot.ui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jlab.groot.data.H1F;
import org.jlab.groot.data.IDataSet;
import org.jlab.groot.fitter.DataFitter;
import org.jlab.groot.graphics.EmbeddedCanvas;
import org.jlab.groot.graphics.EmbeddedPad;
import org.jlab.groot.graphics.IDataSetPlotter;
import org.jlab.groot.math.F1D;
import org.jlab.groot.math.Func1D;
import org.jlab.groot.ui.ParameterPanel;
public class FitPanel extends JPanel {
EmbeddedCanvas canvas;
int index;
// double xMin, xMax;
ArrayList datasets = new ArrayList();
ArrayList dataSetNames = new ArrayList();
IDataSet currentDataset = null;
ArrayList fitAllFitFunctions = new ArrayList();
JComboBox paramEstimationMethods;
String predefFunctions[] = {"gaus", "gaus+p0", "gaus+p1", "gaus+p2", "gaus+p3", "p0", "p1", "p2", "p3", "exp",
"a+bcos", "a+bcos+ccos2", "amdahl"};
String predefFunctionsF1D[] = {"[amp]*gaus(x,[mean],[sigma])", "[amp]*gaus(x,[mean],[sigma])+[p0]",
"[amp]*gaus(x,[mean],[sigma])+[p0]+x*[p1]", "[amp]*gaus(x,[mean],[sigma])+[p0]+x*[p1]+x*x*[p2]",
"[amp]*gaus(x,[mean],[sigma])+[p0]+x*[p1]+x*x*[p2]", "[p0]", "[p0]+[p1]*x", "[p0]+[p1]*x+[p2]*x*x",
"[p0]+[p1]*x+[p2]*x*x+[p3]*x*x", "[a]*exp(x,[b])", "[a]+[b]*cos(x*[c])",
"[a]+[b]*cos(x*[d])+[c]*cos(2*x*[e])", "1/((1-[p])+[p]/x)"};
boolean predef = true;
JComboBox predefinedFunctionsSelector;
JPanel fitSettings, fitSwapSettings, fitFunctionPanel, lowerWindow;
Func1D fitFunction;
boolean parameterPanelSwapped = false;
boolean fitSettingsSwapped = false;
JPanel blankPanel = new JPanel();
ArrayList optionCheckBoxes;
double xMin = 0.0;
double xMax = 100.0;
String options = "";
// This mess is due to the slider only working with integer values
int xSliderMin = 0;
int xSliderMax = 1000000;
double currentRangeMin = 0.0;
double currentRangeMax = 100.0;
ParameterPanel parameterPanel;
public FitPanel(EmbeddedCanvas canvas, int index) {
this.canvas = canvas;
this.index = index;
this.fitFunction = new F1D("f1", predefFunctionsF1D[0], xMin, xMax);
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
int gridy = 0;
c.gridy = gridy++;
this.add(initFitFunction(), c);
c.gridy = gridy++;
this.add(initFitSettings(), c);
c.gridy = gridy++;
this.add(initRangeSelector(), c);
if (currentDataset != null) {
if (currentDataset instanceof H1F) {
this.paramEstimationMethods.setSelectedIndex(1);
}
}
}
JTabbedPane initFitSettings() {
JPanel fitMethod = new JPanel(new FlowLayout());
String labs[] = {"Chi-square", "Chi-square (Neyman)", "Chi-square (Pearson)", "Chi-square (All weights=1)",
"Binned Extended-MLE"};
paramEstimationMethods = new JComboBox(labs);
/*
* paramEstimationMethods.addActionListener(new ActionListener() {
* public void actionPerformed(ActionEvent e) {
* if(paramEstimationMethods.getSelectedIndex()==0){ options = "NRQ";
* System.out.print("Option:"+options); }else{ options = "LRQ";
* System.out.print("Option:"+options); }
*
* } });
*/
paramEstimationMethods.setSelectedIndex(0);
fitMethod.add(new JLabel("Method:"));
fitMethod.add(paramEstimationMethods);
JPanel fitOptions = new JPanel(new GridLayout(1, 2));
String[] options = {"Draw Stats", "Quiet"};
optionCheckBoxes = new ArrayList();
for (int i = 0; i < options.length; i++) {
optionCheckBoxes.add(new JCheckBox(options[i]));
fitOptions.add(optionCheckBoxes.get(i));
}
JTabbedPane tabbedPane = new JTabbedPane();
fitSettings = new JPanel(new GridLayout(2, 1));
fitSettings.add(fitMethod);
fitSettings.add(fitOptions);
parameterPanel = new ParameterPanel(this.canvas, this.index, this.fitFunction);
tabbedPane.add("Minimizer Settings", fitSettings);
tabbedPane.add("Parameter Settings", blankPanel);
tabbedPane.setBorder(new TitledBorder("Minimizer Settings"));
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
if (tabbedPane.getSelectedIndex() == 0) {
tabbedPane.setComponentAt(1, blankPanel);
}
if (tabbedPane.getSelectedIndex() == 1) {
tabbedPane.setComponentAt(1, parameterPanel);
}
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(tabbedPane);
topFrame.pack();
}
});
// this.add(tabbedPane, BorderLayout.CENTER);
return tabbedPane;
// System.out.println("YES THIS IS THE CORRECT FILE");
}
private JPanel initFitFunction() {
fitFunctionPanel = new JPanel(new GridLayout(2, 1));
fitFunctionPanel.setBorder(new TitledBorder("Function Settings"));
xMin = canvas.getPad(index).getAxisX().getMin();
xMax = canvas.getPad(index).getAxisX().getMax();
for (IDataSetPlotter plotter : canvas.getPad(index).getDatasetPlotters()) {
datasets.add(plotter.getDataSet());
dataSetNames.add(plotter.getDataSet().getName());
}
JComboBox dataSetBox = new JComboBox(dataSetNames.toArray());
dataSetBox.setSelectedIndex(0);
currentDataset = datasets.get(0);
dataSetBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentDataset = datasets.get(dataSetBox.getSelectedIndex());
}
});
predefinedFunctionsSelector = new JComboBox(predefFunctions);
predefinedFunctionsSelector.setSelectedIndex(0);
parameterPanel = new ParameterPanel(this.canvas, this.index, this.fitFunction);
predefinedFunctionsSelector.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// System.out.println(predefinedFunctionsSelector.getSelectedIndex());
// fitFunction = new
// F1D(predefFunctions[predefinedFunctionsSelector.getSelectedIndex()],currentRangeMin,currentRangeMax);
// fitFunction.setFunction(predefFunctions[predefinedFunctionsSelector.getSelectedIndex()]);
boolean functionSetup = false;
for (int i = 0; i < predefFunctions.length; i++) {
if (predefFunctions[predefinedFunctionsSelector.getSelectedIndex()].equals(predefFunctions[i])) {
fitFunction = new F1D("f1", predefFunctionsF1D[predefinedFunctionsSelector.getSelectedIndex()],
currentRangeMin, currentRangeMax);
functionSetup = true;
predef = true;
}
}
if (predef) {
for (int i = 0; i < fitFunction.getNPars(); i++) {
if (i == 0) {
fitFunction.setParameter(0,
getMaxYIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i == 1) {
fitFunction.setParameter(1,
getMeanIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i == 2) {
fitFunction.setParameter(2,
getRMSIDataSet(currentDataset, currentRangeMin, currentRangeMax));
if (predefinedFunctionsSelector.getSelectedIndex() < 5)
fitFunction.setParLimits(2, 0.0, Double.MAX_VALUE);
} else if (i == 3) {
fitFunction.setParameter(3,
getAverageHeightIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i > 3) {
fitFunction.setParameter(i, 1.0);
}
System.out.println("Paramter " + i + " =" + fitFunction.getParameter(i));
}
}
parameterPanel.updateNewFunction(fitFunction);
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(predefinedFunctionsSelector);
topFrame.pack();
}
});
JLabel labelForFunction = new JLabel("Function:");
JLabel dataSetLabel = new JLabel("Select Dataset:");
fitFunctionPanel.add(dataSetLabel);
fitFunctionPanel.add(dataSetBox);
fitFunctionPanel.add(labelForFunction);
fitFunctionPanel.add(predefinedFunctionsSelector);
return fitFunctionPanel;
}
private JPanel initRangeSelector() {
lowerWindow = new JPanel(new GridLayout(2, 1));
JPanel rangeSelector = new JPanel();
JLabel xLabel = new JLabel("X:");
RangeSlider slider = new RangeSlider();
slider.setMinimum((int) xSliderMin);
slider.setMaximum((int) xSliderMax);
slider.setValue((int) xSliderMin);
slider.setUpperValue((int) xSliderMax);
currentRangeMin = slider.getValue() * (xMax - xMin) / (double) (xSliderMax - xSliderMin) + xMin;
currentRangeMax = slider.getUpperValue() * (xMax - xMin) / (double) (xSliderMax - xSliderMin) + xMin;
JLabel rangeSliderValue1 = new JLabel("" + String.format("%4.2f", currentRangeMin));
JLabel rangeSliderValue2 = new JLabel("" + String.format("%4.2f", currentRangeMax));
fitFunction.setRange(currentRangeMin, currentRangeMax);
rangeSelector.add(xLabel);
rangeSelector.add(rangeSliderValue1);
rangeSelector.add(slider);
rangeSelector.add(rangeSliderValue2);
lowerWindow.add(rangeSelector);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
RangeSlider slider = (RangeSlider) e.getSource();
currentRangeMin = slider.getValue() * (xMax - xMin) / (double) (xSliderMax - xSliderMin) + xMin;
currentRangeMax = slider.getUpperValue() * (xMax - xMin) / (double) (xSliderMax - xSliderMin) + xMin;
rangeSliderValue1.setText(String.valueOf("" + String.format("%4.2f", currentRangeMin)));
rangeSliderValue2.setText(String.valueOf("" + String.format("%4.2f", currentRangeMax)));
// System.out.println("currentRangeMin:"+currentRangeMin+"
// xOffset:"+xOffset);
// fitFunction.setRange(currentRangeMin, currentRangeMax);
}
});
JButton fit = new JButton("Fit");
fit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Construct options
int method = paramEstimationMethods.getSelectedIndex();
if (method == 0) {
options = "ER";
} else if (method == 1) {
options = "NR";
} else if (method == 2) {
options = "PR";
} else if (method == 3) {
options = "R";
} else if (method == 4) {
options = "LR";
}
String drawOption = "";
for (int i = 0; i < optionCheckBoxes.size(); i++) {
if (optionCheckBoxes.get(0).isSelected()) {
drawOption = "S";
}
if (optionCheckBoxes.get(1).isSelected()) {
options = options + "Q";
}
}
fitFunction.setRange(currentRangeMin, currentRangeMax);
if (predef && !parameterPanel.modified()) {
for (int i = 0; i < fitFunction.getNPars(); i++) {
if (i == 0) {
fitFunction.setParameter(0,
getMaxYIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i == 1) {
fitFunction.setParameter(1,
getMeanIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i == 2) {
fitFunction.setParameter(2,
getRMSIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i == 3) {
fitFunction.setParameter(3,
getAverageHeightIDataSet(currentDataset, currentRangeMin, currentRangeMax));
} else if (i > 3) {
fitFunction.setParameter(i, 1.0);
}
System.out.println("Paramter " + i + " =" + fitFunction.getParameter(i));
}
}
System.out.println("Fitting!");
DataFitter.fit(fitFunction, currentDataset, options);
fitFunction.show(); // print on the screen fit results
fitFunction.setLineColor(2);
fitFunction.setLineWidth(5);
fitFunction.setLineStyle(1);
canvas.cd(index);
canvas.draw(fitFunction, "same"+drawOption);
canvas.update();
/*
* ArrayList nonDuplicateDataset = new
* ArrayList(); ArrayList datasets1 = new
* ArrayList(); for(int i=0;
* i canvasPads = canvas.getCanvasPads();
JPanel fitButtons = new JPanel(new GridLayout(1, 2));
if (canvasPads.size() > 1) {
JButton fitAll = new JButton("Fit All");
fitAll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Construct options
int method = paramEstimationMethods.getSelectedIndex();
if (method == 0) {
options = "ER";
} else if (method == 1) {
options = "NR";
} else if (method == 2) {
options = "PR";
} else if (method == 3) {
options = "R";
} else if (method == 4) {
options = "LR";
}
String drawOption = "";
for (int i = 0; i < optionCheckBoxes.size(); i++) {
if (optionCheckBoxes.get(0).isSelected()) {
drawOption = "S";
}
if (optionCheckBoxes.get(1).isSelected()) {
options = options + "Q";
}
}
for (int padCounter = 0; padCounter < canvasPads.size(); padCounter++) {
double min = canvas.getPad(padCounter).getAxisX().getMin();
double max = canvas.getPad(padCounter).getAxisX().getMax();
if (fitAllFitFunctions.size() != canvasPads.size()) {
fitAllFitFunctions.add(new F1D("f1",
predefFunctionsF1D[predefinedFunctionsSelector.getSelectedIndex()], min, max));
} else {
fitAllFitFunctions.set(padCounter, new F1D("f1",
predefFunctionsF1D[predefinedFunctionsSelector.getSelectedIndex()], min, max));
}
ArrayList tempDataset = new ArrayList();
int ndataset = canvas.getPad(padCounter).getDatasetPlotters().size();
for (int i = 0; i < ndataset; i++) {
IDataSet ds = canvas.getPad(padCounter).getDatasetPlotters().get(i).getDataSet();
String name = ds.getName();
dataSetNames.add(name);
tempDataset.add(ds);
}
if (ndataset > 0) {
IDataSet currentDataset = tempDataset.get(0);
fitAllFitFunctions.get(padCounter).setRange(min, max);
if (predef) {
for (int i = 0; i < fitAllFitFunctions.get(padCounter).getNPars(); i++) {
if (i == 0) {
fitAllFitFunctions.get(padCounter).setParameter(0,
getMaxYIDataSet(currentDataset, min, max));
} else if (i == 1) {
fitAllFitFunctions.get(padCounter).setParameter(1,
getMeanIDataSet(currentDataset, min, max));
} else if (i == 2) {
fitAllFitFunctions.get(padCounter).setParameter(2,
getRMSIDataSet(currentDataset, min, max));
if (predefinedFunctionsSelector.getSelectedIndex() < 5)
fitFunction.setParLimits(2, 0.0, Double.MAX_VALUE);
} else if (i == 3) {
fitAllFitFunctions.get(padCounter).setParameter(3,
getAverageHeightIDataSet(currentDataset, min, max));
} else if (i > 3) {
fitAllFitFunctions.get(padCounter).setParameter(i, 1.0);
}
}
}
DataFitter.fit(fitAllFitFunctions.get(padCounter), currentDataset, options);
fitAllFitFunctions.get(padCounter).setLineColor(2);
fitAllFitFunctions.get(padCounter).setLineWidth(5);
fitAllFitFunctions.get(padCounter).setLineStyle(1);
canvas.cd(padCounter);
canvas.draw(fitAllFitFunctions.get(padCounter), "same" + drawOption);
canvas.update();
}
}
}
});
fitButtons.add(fit);
fitButtons.add(fitAll);
lowerWindow.add(fitButtons);
} else {
lowerWindow.add(fit);
}
return lowerWindow;
}
private double getMeanIDataSet(IDataSet data, double min, double max) {
int nsamples = 0;
double sum = 0;
double nEntries = 0;
for (int i = 0; i < data.getDataSize(0); i++) {
double x = data.getDataX(i);
double y = data.getDataY(i);
if (x > min && x < max && y != 0) {
nsamples++;
sum += x * y;
nEntries += y;
}
}
return sum / (double) nEntries;
}
private double getRMSIDataSet(IDataSet data, double min, double max) {
int nsamples = 0;
double mean = getMeanIDataSet(data, min, max);
double sum = 0;
double nEntries = 0;
for (int i = 0; i < data.getDataSize(0); i++) {
double x = data.getDataX(i);
double y = data.getDataY(i);
if (x > min && x < max && y != 0) {
nsamples++;
sum += Math.pow(x - mean, 2) * y;
nEntries += y;
}
}
return Math.sqrt(sum / (double) nEntries);
}
private double getAverageHeightIDataSet(IDataSet data, double min, double max) {
int nsamples = 0;
double sum = 0;
for (int i = 0; i < data.getDataSize(0); i++) {
double x = data.getDataX(i);
double y = data.getDataY(i);
if (x > min && x < max && y != 0) {
nsamples++;
sum += y;
}
}
return sum / (double) nsamples;
}
private double getMaxXIDataSet(IDataSet data, double min, double max) {
double max1 = 0;
double xMax = 0;
for (int i = 0; i < data.getDataSize(0); i++) {
double x = data.getDataX(i);
double y = data.getDataY(i);
if (x > min && x < max && y != 0) {
if (y > max1) {
max1 = y;
xMax = x;
}
}
}
return xMax;
}
private double getMaxYIDataSet(IDataSet data, double min, double max) {
double max1 = 0;
double xMax = 0;
for (int i = 0; i < data.getDataSize(0); i++) {
double x = data.getDataX(i);
double y = data.getDataY(i);
if (x > min && x < max && y != 0) {
if (y > max1) {
max1 = y;
xMax = x;
}
}
}
return max1;
}
}
Ads help maintain this website.