/* * EfficiencyBinner3D.java * * Created on July 22, 2002, 10:19 AM */ package hep.aida.ref.histogram.binner; /** * * @author The AIDA team at SLAC. * */ public class EfficiencyBinner3D implements Binner3D { private int[][][] entries; private double[][][] heights; private double[][][] meansX; private double[][][] rmssX; private double[][][] meansY; private double[][][] rmssY; private double[][][] meansZ; private double[][][] rmssZ; private int xBins; private int yBins; private int zBins; /** * Creates a new instance of EfficiencyBinner1D. */ public EfficiencyBinner3D(int xBins, int yBins, int zBins) { if (xBins < 0) throw new IllegalArgumentException("Number of bins cannot be negative!!! "+xBins); if (yBins < 0) throw new IllegalArgumentException("Number of bins cannot be negative!!! "+yBins); if (zBins < 0) throw new IllegalArgumentException("Number of bins cannot be negative!!! "+zBins); setNumberOfBins(xBins, yBins, zBins); } public void fill( int xBin, int yBin, int zBin, double x, double y,double z, double weight) { if ( weight < 0 || weight > 1 ) throw new IllegalArgumentException("Wrong weight "+weight+" !! It has to be between 0 and 1"); entries[xBin][yBin][zBin]++; heights[xBin][yBin][zBin] += weight; meansX[xBin][yBin][zBin] += x*weight; rmssX[xBin][yBin][zBin] += x*x*weight; meansY[xBin][yBin][zBin] += y*weight; rmssY[xBin][yBin][zBin] += y*y*weight; meansZ[xBin][yBin][zBin] += z*weight; rmssZ[xBin][yBin][zBin] += z*z*weight; } public void clear() { createArrays( xBins, yBins, zBins); } private void setNumberOfBins(int xBins, int yBins, int zBins) { this.xBins = xBins; this.yBins = yBins; this.zBins = zBins; createArrays(xBins, yBins, zBins); } public int entries(int xBin, int yBin, int zBin) { return entries[xBin][yBin][zBin]; } public double height(int xBin, int yBin, int zBin) { if ( entries(xBin,yBin,zBin) > 0 ) return heights[xBin][yBin][zBin]/entries(xBin,yBin,zBin); return 0; } public double plusError(int xBin, int yBin, int zBin) { return EfficiencyBinnerUtils.H95CL(heights[xBin][yBin][zBin],entries[xBin][yBin][zBin],1); } public double minusError(int xBin, int yBin, int zBin) { return EfficiencyBinnerUtils.H95CL(heights[xBin][yBin][zBin],entries[xBin][yBin][zBin],2); } public double meanX(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; if ( h != 0 ) return meansX[xBin][yBin][zBin]/h; return Double.NaN; } public double meanY(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; if ( h != 0 ) return meansY[xBin][yBin][zBin]/h; return Double.NaN; } public double meanZ(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; if ( h != 0 ) return meansZ[xBin][yBin][zBin]/h; return Double.NaN; } public double rmsX(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; double m = meanX(xBin,yBin,zBin); if ( h != 0 ) return Math.sqrt( Math.abs(rmssX[xBin][yBin][zBin]/h - m*m) ); return Double.NaN; } public double rmsY(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; double m = meanY(xBin,yBin,zBin); if ( h != 0 ) return Math.sqrt( Math.abs(rmssY[xBin][yBin][zBin]/h - m*m) ); return Double.NaN; } public double rmsZ(int xBin, int yBin, int zBin) { double h = heights[xBin][yBin][zBin]; double m = meanZ(xBin,yBin,zBin); if ( h != 0 ) return Math.sqrt( Math.abs(rmssZ[xBin][yBin][zBin]/h - m*m) ); return Double.NaN; } public void setBinContent(int xBin, int yBin, int zBin, int entries, double height, double plusError, double minusError, double meanX, double rmsX, double meanY, double rmsY, double meanZ, double rmsZ) { this.entries[xBin][yBin][zBin] = entries; if ( ! Double.isNaN(height) ) heights[xBin][yBin][zBin] = height*entries; else heights[xBin][yBin][zBin] = entries*entries; meansX[xBin][yBin][zBin] = 0; rmssX[xBin][yBin][zBin] = 0; meansY[xBin][yBin][zBin] = 0; rmssY[xBin][yBin][zBin] = 0; meansZ[xBin][yBin][zBin] = 0; rmssZ[xBin][yBin][zBin] = 0; if ( heights[xBin][yBin][zBin] != 0 ) { meansX[xBin][yBin][zBin] = meanX*heights[xBin][yBin][zBin]; rmssX[xBin][yBin][zBin] = rmsX*rmsX*heights[xBin][yBin][zBin] + meanX*meanX*heights[xBin][yBin][zBin]; meansY[xBin][yBin][zBin] = meanY*heights[xBin][yBin][zBin]; rmssY[xBin][yBin][zBin] = rmsY*rmsY*heights[xBin][yBin][zBin] + meanY*meanY*heights[xBin][yBin][zBin]; meansZ[xBin][yBin][zBin] = meanZ*heights[xBin][yBin][zBin]; rmssZ[xBin][yBin][zBin] = rmsZ*rmsZ*heights[xBin][yBin][zBin] + meanZ*meanZ*heights[xBin][yBin][zBin]; } } public void scale( double scaleFactor ) { for ( int xBin = 0; xBin < xBins; xBin++ ) { for ( int yBin = 0; yBin < yBins; yBin++ ) { for ( int zBin = 0; zBin < zBins; zBin++ ) { heights[xBin][yBin][zBin] *= scaleFactor; meansX[xBin][yBin][zBin] *= scaleFactor; rmssX[xBin][yBin][zBin] *= scaleFactor; meansY[xBin][yBin][zBin] *= scaleFactor; rmssY[xBin][yBin][zBin] *= scaleFactor; meansZ[xBin][yBin][zBin] *= scaleFactor; rmssZ[xBin][yBin][zBin] *= scaleFactor; } } } } private void createArrays(int xBins, int yBins, int zBins) { entries = new int[xBins][yBins][zBins]; heights = new double[xBins][yBins][zBins]; meansX = new double[xBins][yBins][zBins]; rmssX = new double[xBins][yBins][zBins]; meansY = new double[xBins][yBins][zBins]; rmssY = new double[xBins][yBins][zBins]; meansZ = new double[xBins][yBins][zBins]; rmssZ = new double[xBins][yBins][zBins]; } }