package hep.io.root.util;
import hep.io.root.interfaces.TH1;
import hep.io.root.interfaces.TH1D;
import hep.io.root.interfaces.TH1F;
import hep.io.root.interfaces.TH2;
import hep.io.root.interfaces.TH2D;
import hep.io.root.interfaces.TH2F;
import jas.hist.DataSource;
import jas.hist.HasStatistics;
import jas.hist.Rebinnable1DHistogramData;
import jas.hist.Rebinnable2DHistogramData;
import jas.hist.Statistics;
class RootHistogramAdapter
{
static DataSource create(TH1 rootHisto)
{
if (rootHisto instanceof TH1F) return new Root1FHistogramAdapter((TH1F) rootHisto);
else if (rootHisto instanceof TH1D) return new Root1DHistogramAdapter((TH1D) rootHisto);
else if (rootHisto instanceof TH2F) return new Root2FHistogramAdapter((TH2F) rootHisto);
else if (rootHisto instanceof TH2D) return new Root2DHistogramAdapter((TH2D) rootHisto);
else return null;
}
private static class Root1DHistogramAdapter extends Root1HistogramAdapter
{
private TH1D th1d;
Root1DHistogramAdapter(TH1D rootHisto)
{
super(rootHisto);
this.th1d = rootHisto;
}
public double[][] rebin(int bins, double p2, double p3, boolean p4, boolean p5)
{
double[] data = new double[bins];
double[] array = th1d.getArray();
for (int i=0; i<bins; i++) data[i] = array[i+1];
double[] darray = rootHisto.getSumw2();
if (darray != null && darray.length>0)
{
double[] error = new double[bins];
for (int i=0; i<bins; i++) error[i] = Math.sqrt(darray[i+1]);
return new double[][]
{ data, error };
}
else
{
return new double[][]
{data};
}
}
}
private static class Root1FHistogramAdapter extends Root1HistogramAdapter
{
private TH1F th1f;
Root1FHistogramAdapter(TH1F rootHisto)
{
super(rootHisto);
this.th1f = rootHisto;
}
public double[][] rebin(int bins, double p2, double p3, boolean p4, boolean p5)
{
double[] data = new double[bins];
float[] array = th1f.getArray();
for (int i=0; i<bins; i++) data[i] = array[i+1];
double[] darray = rootHisto.getSumw2();
if (darray != null && darray.length>0)
{
double[] error = new double[bins];
for (int i=0; i<bins; i++) error[i] = Math.sqrt(darray[i+1]);
return new double[][]
{ data, error };
}
else
{
return new double[][]
{data};
}
}
}
private static abstract class Root1HistogramAdapter implements Rebinnable1DHistogramData, HasStatistics, Statistics
{
protected TH1 rootHisto;
Root1HistogramAdapter(TH1 rootHisto)
{
this.rootHisto = rootHisto;
}
public double getMin()
{
return rootHisto.getXaxis().getXmin();
}
public double getMax()
{
return rootHisto.getXaxis().getXmax();
}
public int getBins()
{
return rootHisto.getXaxis().getNbins();
}
public boolean isRebinnable()
{
return false;
}
public int getAxisType()
{
return DOUBLE;
}
public String[] getAxisLabels()
{
return null;
}
public String getTitle()
{
return rootHisto.getTitle();
}
public Statistics getStatistics()
{
return this;
}
public String[] getStatisticNames()
{
return new String[]
{"Entries", "Mean", "RMS"};
}
private double mean()
{
return rootHisto.getTsumwx()/rootHisto.getTsumw();
}
public double rms()
{
double sumw = rootHisto.getTsumw();
double sumwx = rootHisto.getTsumwx();
double sumwx2 = rootHisto.getTsumwx2();
return Math.sqrt(sumwx2/sumw - sumwx*sumwx/sumw/sumw);
}
public double getStatistic(String name)
{
if (name.equals("Entries")) return rootHisto.getEntries();
else if (name.equals("Mean")) return mean();
else if (name.equals("RMS")) return rms();
else return 0;
}
}
private static class Root2DHistogramAdapter extends Root2HistogramAdapter
{
private TH2D th2d;
Root2DHistogramAdapter(TH2D rootHisto)
{
super(rootHisto);
this.th2d = rootHisto;
}
public double[][][] rebin(int xbins, double p2, double p3,
int ybins, double p6, double p7,
boolean p4, boolean p5, boolean p8)
{
double[][] data = new double[xbins][ybins];
double[] array = th2d.getArray();
for (int i=0; i<xbins; i++)
for (int j=0; j<ybins; j++)
data[i][j] = array[1+i+(j+1)*(xbins+2)];
double[] darray = rootHisto.getSumw2();
if (darray != null && darray.length > 0)
{
double[][] error = new double[xbins][ybins];
for (int i=0; i<xbins; i++)
for (int j=0; j<ybins; j++)
error[i][j] = darray[1+j+(i+1)*(ybins+2)];
return new double[][][]
{ data, error };
}
else
{
return new double[][][]
{ data };
}
}
}
private static class Root2FHistogramAdapter extends Root2HistogramAdapter
{
private TH2F th2f;
Root2FHistogramAdapter(TH2F rootHisto)
{
super(rootHisto);
this.th2f = rootHisto;
}
public double[][][] rebin(int xbins, double p2, double p3,
int ybins, double p6, double p7,
boolean p4, boolean p5, boolean p8)
{
double[][] data = new double[xbins][ybins];
float[] array = th2f.getArray();
for (int i=0; i<xbins; i++)
for (int j=0; j<ybins; j++)
data[i][j] = array[1+i+(j+1)*(xbins+2)];
double[] darray = rootHisto.getSumw2();
if (darray != null && darray.length > 0)
{
double[][] error = new double[xbins][ybins];
for (int i=0; i<xbins; i++)
for (int j=0; j<ybins; j++)
error[i][j] = darray[1+j+(i+1)*(ybins+2)];
return new double[][][]
{ data, error };
}
else
{
return new double[][][]
{ data };
}
}
}
private static abstract class Root2HistogramAdapter implements Rebinnable2DHistogramData, HasStatistics, Statistics
{
protected TH2 rootHisto;
Root2HistogramAdapter(TH2 rootHisto)
{
this.rootHisto = rootHisto;
}
public double getXMin()
{
return rootHisto.getXaxis().getXmin();
}
public double getXMax()
{
return rootHisto.getXaxis().getXmax();
}
public int getXBins()
{
return rootHisto.getXaxis().getNbins();
}
public double getYMin()
{
return rootHisto.getYaxis().getXmin();
}
public double getYMax()
{
return rootHisto.getYaxis().getXmax();
}
public int getYBins()
{
return rootHisto.getYaxis().getNbins();
}
public boolean isRebinnable()
{
return false;
}
public int getXAxisType()
{
return DOUBLE;
}
public String[] getXAxisLabels()
{
return null;
}
public int getYAxisType()
{
return DOUBLE;
}
public String[] getYAxisLabels()
{
return null;
}
public String getTitle()
{
return rootHisto.getTitle();
}
public Statistics getStatistics()
{
return this;
}
public String[] getStatisticNames()
{
return new String[]
{"Entries"};
}
public double getStatistic(String p1)
{
return rootHisto.getEntries();
}
}
}