package org.jlab.groot.fitter;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import org.jlab.groot.data.GraphErrors;
import org.jlab.groot.data.H1F;
import org.jlab.groot.data.H2F;
import org.jlab.groot.data.IDataSet;
import org.jlab.groot.graphics.EmbeddedCanvas;
import org.jlab.groot.graphics.EmbeddedCanvasGroup;
import org.jlab.groot.math.Axis;
import org.jlab.groot.math.F1D;
import org.jlab.groot.ui.ProgressBar;
public class ParallelSliceFitter {
H2F originalhistogram = null;
H2F fithistogram = null;
int nthreads = Runtime.getRuntime().availableProcessors();
ArrayList slices = null;
ArrayList threads = new ArrayList();
ArrayList fitResults = new ArrayList();
double min = 0.0;
double max = 0.0;
int minBin = 0;
int maxBin = 0;
double maxChiSquare = Double.MAX_VALUE;
int minEvents = 10;
boolean autorangemin = true;
boolean autorangemax = true;
boolean autorangeminbin = true;
boolean autorangemaxbin = true;
boolean showProgress = true;
String fitMode = "N";
public String getFitMode() {
return fitMode;
}
public void setFitMode(String fitMode) {
this.fitMode = fitMode;
}
Axis axis = null;
String[] modes = {"[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]+x*x*x[p3]",};
public static final int NO_BG = -1;
public static final int P0_BG = 0;
public static final int P1_BG = 1;
public static final int P2_BG = 2;
public static final int P3_BG = 3;
int mode = 0;
public H2F getHistogram() {
return fithistogram;
}
public void setHistogram(H2F histogram) {
this.originalhistogram = histogram;
this.fithistogram = histogram;
}
public int getNthreads() {
return nthreads;
}
public void setNthreads(int nthreads) {
this.nthreads = nthreads;
}
public void setBackgroundOrder(int mode) {
this.mode = mode + 1;
}
public ParallelSliceFitter() {
}
public ParallelSliceFitter(H2F histogram) {
this.originalhistogram = histogram;
this.fithistogram = histogram;
}
public void fitSlicesY(){
fitSlicesY(1);
}
public void fitSlicesY(int nbins) {
fithistogram = originalhistogram.rebinY(nbins);
slices = fithistogram.getSlicesY();
axis = fithistogram.getYAxis();
if (autorangemin && slices.size() > 0) {
min = slices.get(0).getxAxis().min();
}
if (autorangemax && slices.size() > 0) {
max = slices.get(0).getxAxis().max();
}
if (autorangeminbin && slices.size() > 0) {
minBin = 0;
}
if (autorangemaxbin) {
maxBin = slices.size();
}
fit();
}
public void fitSlicesX(){
fitSlicesX(1);
}
public void fitSlicesX(int nbins) {
fithistogram = originalhistogram.rebinX(nbins);
slices = fithistogram.getSlicesX();
axis = fithistogram.getXAxis();
if (autorangemin && slices.size() > 0) {
min = slices.get(0).getxAxis().min();
}
if (autorangemax && slices.size() > 0) {
max = slices.get(0).getxAxis().max();
}
if (autorangeminbin && slices.size() > 0) {
minBin = 0;
}
if (autorangemaxbin ) {
maxBin = slices.size();
}
fit();
}
public GraphErrors getChi2Slices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getChiSq(), 0, 0);
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("#chi^2/ndf from SliceFitter");
}
}
return graph;
}
public GraphErrors getMeanSlices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(1), 0,
result.getFunction().parameter(1).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Gaussian Mean from SliceFitter");
}
}
return graph;
}
public GraphErrors getSigmaSlices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(2), 0,
result.getFunction().parameter(2).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Gaussian #sigma from SliceFitter");
}
}
return graph;
}
public GraphErrors getAmpSlices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(0), 0,
result.getFunction().parameter(0).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Gaussian Amplitude from SliceFitter");
}
}
return graph;
}
public GraphErrors getP0Slices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(3), 0,
result.getFunction().parameter(3).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Background P0 from SliceFitter");
}
}
return graph;
}
public GraphErrors getP1Slices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(4), 0,
result.getFunction().parameter(4).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Background P1 from SliceFitter");
}
}
return graph;
}
public GraphErrors getP2Slices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(5), 0,
result.getFunction().parameter(5).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Background P2 from SliceFitter");
}
}
return graph;
}
public GraphErrors getP3Slices() {
GraphErrors graph = new GraphErrors();
for (FitResults result : fitResults) {
if (result.getChiSq() < this.maxChiSquare && result.getData().getIntegral() > this.minEvents) {
graph.addPoint(result.getPoint(), result.getFunction().getParameter(6), 0,
result.getFunction().parameter(6).error());
graph.setTitleX(this.slices.get(0).getTitleX());
graph.setTitleY("Background P3 from SliceFitter");
}
}
return graph;
}
public void setMin(double min) {
this.min = min;
this.autorangemin = false;
}
public void setMax(double max) {
this.max = max;
this.autorangemax = false;
}
public void setRange(double min, double max) {
this.min = min;
this.max = max;
this.autorangemin = false;
this.autorangemax = false;
}
public void setMinBin(int min) {
this.minBin = min;
this.autorangeminbin = false;
}
public void setMaxBin(int max) {
this.maxBin = max;
this.autorangemaxbin = false;
}
public void setBinRange(int min, int max) {
this.minBin = min;
this.maxBin = max;
this.autorangemin = false;
this.autorangemax = false;
}
public double getMaxChiSquare() {
return maxChiSquare;
}
public void setMaxChiSquare(double maxChiSquare) {
this.maxChiSquare = maxChiSquare;
}
public int getMinEvents() {
return minEvents;
}
public void setMinEvents(int minEvents) {
this.minEvents = minEvents;
}
public boolean isShowProgress() {
return showProgress;
}
public void setShowProgress(boolean showProgress) {
this.showProgress = showProgress;
}
public void inspectFits() {
JFrame frame = new JFrame("Fit Inspector");
frame.add(getInspectFitsPane());
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
frame.pack();
frame.setSize((int) (screensize.getHeight() * .75 * 1.618), (int) (screensize.getHeight() * .75));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public JTabbedPane getInspectFitsPane() {
int nHistograms = slices.size();
int cols = 4;
int rows = 4;
// int pages = nHistograms/(cols*rows) +
// ((nHistograms%(cols*rows)==0)?0:1);
int pages = nHistograms / (cols * rows);
if (nHistograms - pages * cols * rows > 0)
pages++;
JTabbedPane pane = new JTabbedPane();
EmbeddedCanvas fitSummary = new EmbeddedCanvas();
int nPlots = mode + 5;
fitSummary.divide(3, 2);
if (nPlots > 6) {
fitSummary.divide(3, 3);
} else if (nPlots > 9) {
fitSummary.divide(4, 3);
} else if (nPlots > 12) {
fitSummary.divide(4, 4);
}
int counter = 0;
fitSummary.cd(counter++);
fitSummary.draw(this.fithistogram);
fitSummary.cd(counter++);
fitSummary.draw(this.getMeanSlices());
fitSummary.cd(counter++);
fitSummary.draw(this.getSigmaSlices());
fitSummary.cd(counter++);
fitSummary.draw(this.getAmpSlices());
if (mode > 0) {
fitSummary.cd(counter++);
fitSummary.draw(this.getP0Slices());
if (mode > 1) {
fitSummary.cd(counter++);
fitSummary.draw(this.getP1Slices());
}
if (mode > 2) {
fitSummary.cd(counter++);
fitSummary.draw(this.getP2Slices());
}
if (mode > 3) {
fitSummary.cd(counter++);
fitSummary.draw(this.getP3Slices());
}
}
fitSummary.cd(counter++);
fitSummary.draw(this.getChi2Slices());
pane.addTab("Summary", fitSummary);
EmbeddedCanvasGroup group = new EmbeddedCanvasGroup();
for(int i=0; i data = new ArrayList(slices);
group.setData(data);
pane.add("Individual Fits", group);
return pane;
}
private void fit() {
List> taskList = new ArrayList>(slices.size());
ArrayList> tasks = new ArrayList>();
for (int i = 0; i < slices.size(); i++) {
System.out.println(i+" "+minBin+" "+maxBin);
if (i >= minBin && i < maxBin) {
H1F slice = slices.get(i);
if (slice.getIntegral() > minEvents) {
ResultSetter setter = new ResultSetter() {
public void setResult(H1F histogram, F1D fit, int fitNumber) {
FitResults result = new FitResults();
result.setData(histogram);
result.setFunction(fit);
result.setPoint(axis.getBinCenter(fitNumber));
if ((fit.getChiSquare() / (double) fit.getNDF()) < maxChiSquare) {
fitResults.add(result);
}
}
};
FitThread temp = new FitThread();
temp.setN(i);
temp.setHistogram(slice);
temp.setResultSetter(setter);
temp.setOptions("RQ" + this.fitMode);
temp.setFitter(new F1D("f1", modes[mode], min, max));
threads.add(temp);
}
}
}
ExecutorService threadPool = Executors.newFixedThreadPool(nthreads);
for (FitThread thread : threads) {
taskList.add(Executors.callable(thread));
@SuppressWarnings("unchecked")
Future
Ads help maintain this website.