/* * AbstractBinner1D.java * * This class handles everything, except the errors */ package hep.aida.ref.histogram.binner; import hep.aida.ref.histogram.HistUtils; /** * * @author The AIDA team at SLAC * */ public abstract class AbstractBinner1D implements Binner1D{ protected int[] entries; protected double[] binCenter; protected double[] sumW; protected double[] sumWW; protected double[] sumXW; protected double[] sumXXW; protected int bins; /** * Creates a new instance of OneDBinner. * */ public AbstractBinner1D(int bins) { if (bins < 0) throw new IllegalArgumentException("Number of bins cannot be negative!!! "+bins); setNumberOfBins(bins); } public AbstractBinner1D(Binner1D binner) { if (binner.bins() < 0) throw new IllegalArgumentException("Number of bins cannot be negative!!! "+bins); initBinner(binner); } // Service methods public void initBinner(Binner1D binner) { setNumberOfBins(binner.bins()); int e = 0; double h = 0; double er = 0; double m = 0; double w = 0; double r = 0; for (int i=0; i<bins; i++) { setBinCenter(i, binner.binCenter(i)); e = binner.entries(i); h = binner.height(i); w = binner.sumWW(i); m = binner.sumXW(i); r = binner.sumXXW(i); entries[i] = e; if ( HistUtils.isValidDouble(h) ) sumW[i] = h; if ( HistUtils.isValidDouble(w) ) sumWW[i] = w; if ( HistUtils.isValidDouble(m) ) sumXW[i] = m; if ( HistUtils.isValidDouble(r) ) sumXXW[i] = r; } } protected void createArrays( int n ) { entries = new int[n]; binCenter = new double[n]; sumW = new double[n]; sumWW = new double[n]; sumXW = new double[n]; sumXXW = new double[n]; } private void setNumberOfBins( int bins ) { this.bins = bins; createArrays(bins); } public String toString() { String tmp = ""; for (int i=0; i<bins; i++) { tmp += i+" b="+binCenter(i)+", e="+entries(i)+", h="+height(i)+", m="+mean(i)+", r="+rms(i)+"\n"; } tmp += "\n"; return tmp; } // Binner1D methods /** * This method sets new center of the bin and * initializes other bin data */ public void setBinCenter(int bin, double x) { binCenter[bin] = x; entries[bin] = 0; sumW[bin] = 0; sumWW[bin] = 0; sumXW[bin] = 0; sumXXW[bin] = 0; } public double binCenter(int bin) { return binCenter[bin]; } public void clear() { for (int i=0; i<bins; i++) { binCenter[i] = 0; entries[i] = 0; sumW[i] = 0; sumWW[i] = 0; sumXW[i] = 0; sumXXW[i] = 0; } } public int bins() { return bins; } public void fill( int bin, double x, double weight) { double delta = x - binCenter[bin]; entries[bin]++; sumW[bin] += weight; sumWW[bin] += weight*weight; sumXW[bin] += delta*weight; sumXXW[bin] += delta*delta*weight; } public int entries(int bin) { return entries[bin]; } public double height(int bin) { return sumW[bin]; } public double mean(int bin) { double h = height(bin); if ( h != 0 ) return sumXW[bin]/h; return Double.NaN; } public double rms(int bin) { double h = height(bin); double m = sumXW[bin]; double r = sumXXW[bin]; if ( h != 0 ) return Math.sqrt( Math.abs( (r - m*m/h)/h ) ); return Double.NaN; } public void scale( double scaleFactor ) { for ( int bin = 0; bin < bins; bin++ ) { sumW[bin] *= scaleFactor; sumWW[bin] *= scaleFactor*scaleFactor; sumXW[bin] *= scaleFactor; sumXXW[bin] *= scaleFactor; } } public double sumWW(int bin) { return sumWW[bin]; } public double sumXW(int bin) { return sumXW[bin]; } public double sumXXW(int bin) { return sumXXW[bin]; } public void setBinContent(int bin, double binCenter, int entries, double height, double plusError, double minusError, double sWW, double sXW, double sXXW) { this.entries[bin] = entries; if ( ! Double.isNaN(height) ) sumW[bin] = height; else sumW[bin] = entries; if ( ! Double.isNaN(sWW) ) this.sumWW[bin] = sWW; else if ( ! Double.isNaN(plusError) ) this.sumWW[bin] = plusError*plusError; else this.sumWW[bin] = entries; double d = binCenter - this.binCenter(bin); if (d != 0) { sXXW = sXXW + d*(2*sXW + d*sumW[bin]); sXW = sXW + d*sumW[bin]; } sumXW[bin] = sXW; sumXXW[bin] = sXXW; } }