package hep.aida.ref.histogram;
/**
* Implementation of IHistogram3D.
* @author The AIDA Team at SLAC.
* @version $Id: Histogram3D.java 9095 2006-10-06 17:53:30Z serbo $
*
*/
import hep.aida.IAxis;
import hep.aida.IHistogram3D;
import hep.aida.ref.histogram.binner.BasicBinner3D;
import hep.aida.ref.histogram.binner.Binner3D;
import hep.aida.ref.histogram.binner.EfficiencyBinner3D;
import java.io.Serializable;
import java.util.Map;
public class Histogram3D extends Histogram implements IHistogram3D, Serializable {
/**
* Create a 3-dimensional Histogram.
*/
public Histogram3D(){
super("","",3, "");
}
/**
* Create a 3-dimensional Histogram.
* @param name The name of the Histogram as a ManagedObject.
* @param title The title of the Histogram.
* @param xAxis The x-axis of the Histogram.
* @param yAxis The y-axis of the Histogram.
* @param zAxis The z-axis of the Histogram.
*
*/
public Histogram3D(String name, String title, IAxis xAxis, IAxis yAxis, IAxis zAxis) {
this(name,title,xAxis,yAxis,zAxis,"");
}
/**
* Create a 3-dimensional Histogram.
* @param name The name of the Histogram as a ManagedObject.
* @param title The title of the Histogram.
* @param xAxis The x-axis of the Histogram.
* @param yAxis The y-axis of the Histogram.
* @param zAxis The z-axis of the Histogram.
* @param options The options of the Histogram.
*
*/
public Histogram3D(String name, String title, IAxis xAxis, IAxis yAxis, IAxis zAxis, String options) {
super(name, title, 3, options);
initHistogram3D(xAxis,yAxis,zAxis,options);
}
/**
* Fill the Histogram with unit weight.
* @param x The x value to be filled.
* @param y The y value to be filled.
* @param z The z value to be filled.
*
*/
public void fill(double x, double y, double z) {
fill(x, y, z, 1.);
}
/**
* Fill the Histogram.
* @param x The x value to be filled.
* @param y The y value to be filled.
* @param z The z value to be filled.
* @param weight The weight for this entry.
*
*/
public void fill( double x, double y, double z, double weight) {
if ( ! isFillable() ) throw new UnfillableHistogramException();
allEntries++;
if ( (! Double.isNaN(x)) && (!Double.isNaN(y)) && (!Double.isNaN(z)) && (!Double.isNaN(weight))) {
int xCoordToIndex = xAxis.coordToIndex(x);
int yCoordToIndex = yAxis.coordToIndex(y);
int zCoordToIndex = zAxis.coordToIndex(z);
int xBin = mapBinNumber(xCoordToIndex, xAxis());
int yBin = mapBinNumber(yCoordToIndex, yAxis());
int zBin = mapBinNumber(zCoordToIndex, zAxis());
binner3D.fill(xBin,yBin,zBin,x,y,z,weight);
if ( ( xCoordToIndex >= 0 && yCoordToIndex >= 0 && zCoordToIndex >= 0) || useOutflows() ) {
validEntries++;
meanX += x*weight;
rmsX += x*x*weight;
meanY += y*weight;
rmsY += y*y*weight;
meanZ += z*weight;
rmsZ += z*z*weight;
sumOfWeights += weight;
sumOfWeightsSquared += weight*weight;
}
}
if (isValid) fireStateChanged();
}
/**
* Reset the Histogram. After calling this method the Histogram
* is as it was just created.
*
*/
public void reset() {
binner3D.clear();
meanX = 0;
rmsX = 0;
meanY = 0;
rmsY = 0;
meanZ = 0;
rmsZ = 0;
super.reset();
}
/**
* Get the number of entries in the underflow and overflow bins.
* @return The number of entries outside the range of the Histogram.
*
*/
public int extraEntries() {
int n = 0;
for (int i=xAxis.bins(); --i >= -2;)
for (int j=yAxis.bins(); --j >= -2;)
for (int k=zAxis.bins(); --k >= -2;) {
if ( i<0 || j<0 || k<0 ) n += binEntries(i,j,k);
}
return n;
}
/**
* Get the sum of the bin heights for all the entries, in-range and out-range ones.
* @return The sum of all the bin's heights.
*
*/
public double sumAllBinHeights() {
double sum = 0;
for (int i=xAxis.bins(); --i >= -2;)
for (int j=yAxis.bins(); --j >= -2;)
for (int k=zAxis.bins(); --k >= -2;)
sum += binHeight(i,j,k);
return sum;
}
/**
* Get the sum of the bin heights for all the entries outside the Histogram's range.
* @return The sum of the out of range bin's heights.
*
*/
public double sumExtraBinHeights() {
int sum = 0;
for (int i=xAxis.bins(); --i >= -2;)
for (int j=yAxis.bins(); --j >= -2;)
for (int k=zAxis.bins(); --k >= -2;)
if ( i<0 || j<0 || k<0 ) sum += binHeight(i,j,k);
return sum;
}
/**
* Get the minimum height of in-range bins in the Histogram.
* @return The minimum bin height for in range bins.
*
*/
public double minBinHeight() {
double min=Double.NaN;
for(int i=1; i<=xAxis.bins(); i++)
for(int j=1; j<=yAxis.bins(); j++)
for(int k=1; k<=zAxis.bins(); k++)
if(Double.isNaN(min) || binHeight(i,j,k) <= min) min=binHeight(i,j,k);
return min;
}
/**
* Get the maximum height of in-range bins in the Histogram.
* @return The maximum bin height for in range bins.
*
*/
public double maxBinHeight() {
double max=Double.NaN;
for(int i=1; i<=xAxis.bins(); i++)
for(int j=1; j<=yAxis.bins(); j++)
for(int k=1; k<=zAxis.bins(); k++)
if(Double.isNaN(max) || binHeight(i,j,k) >= max) max=binHeight(i,j,k);
return max;
}
/**
* Number of entries in the corresponding bin (ie the number of times fill was called for this bin).
* @param indexX The x bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @param indexY The y bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @param indexZ The z bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The number of entries for the corresponding bin.
*
*/
public int binEntries(int indexX, int indexY, int indexZ) {
return binner3D.entries(mapBinNumber(indexX, xAxis()),mapBinNumber(indexY, yAxis()),mapBinNumber(indexZ,zAxis()));
}
/**
* Number of entries with a given x bin number (ie the number of times fill was called for these bins).
* Equivalent to projectionXY().binEntriesX(indexX).
* @param indexX the x bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The number of entries for the corresponding bins.
*/
public int binEntriesX(int indexX) {
int n = 0;
for (int j=IAxis.UNDERFLOW_BIN; jprojectionXY().binEntriesY(indexY).
* @param indexY the y bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The number of entries for the corresponding bins.
*/
public int binEntriesY(int indexY) {
int n = 0;
for (int i=IAxis.UNDERFLOW_BIN; iprojectionXZ().binEntriesZ(indexZ).
* @param indexZ the z bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The number of entries for the corresponding bins.
*/
public int binEntriesZ(int indexZ) {
int n = 0;
for (int i=IAxis.UNDERFLOW_BIN; iprojectionXY().binHeightX(indexX).
* @param indexX The x bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The bin height for the corresponding bin.
*
*/
public double binHeightX(int indexX) {
double d = 0;
for (int j=IAxis.UNDERFLOW_BIN; jprojectionXY().binHeightY(indexY).
* @param indexY The y bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The bin height for the corresponding bin.
*
*/
public double binHeightY(int indexY) {
double d = 0;
for (int i=IAxis.UNDERFLOW_BIN; iprojectionXZ().binHeightZ(indexZ).
* @param indexZ The y bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The bin height for the corresponding bin.
*
*/
public double binHeightZ(int indexZ) {
double d = 0;
for (int i=IAxis.UNDERFLOW_BIN; ixAxis().coordToIndex(coord).
* @see IAxis#coordToIndex(double)
* @return The bin's index along the x axis corresponding to the position coordX.
*
*/
public int coordToIndexX(double coordX) {
return xAxis().coordToIndex(coordX);
}
/**
* Convenience method, equivalent to yAxis().coordToIndex(coord).
* @see IAxis#coordToIndex(double)
* @return The bin's index along the y axis corresponding to the position coordY.
*
*/
public int coordToIndexY(double coordY) {
return yAxis().coordToIndex(coordY);
}
/**
* Convenience method, equivalent to zAxis().coordToIndex(coord).
* @see IAxis#coordToIndex(double)
* @return The bin's index along the z axis corresponding to the position coordY.
*
*/
public int coordToIndexZ(double coordZ) {
return zAxis().coordToIndex(coordZ);
}
/**
* Scale the weights and the errors by a given factor.
*
*/
public void scale(double scaleFactor) throws IllegalArgumentException {
if ( scaleFactor <= 0 ) throw new IllegalArgumentException("Illegal scale factor "+scaleFactor+" it has to be positive");
binner3D.scale(scaleFactor);
meanX *= scaleFactor;
rmsX *= scaleFactor;
meanY *= scaleFactor;
rmsY *= scaleFactor;
meanZ *= scaleFactor;
rmsZ *= scaleFactor;
sumOfWeights *= scaleFactor;
sumOfWeightsSquared *= scaleFactor*scaleFactor;
if (isValid) fireStateChanged();
}
/**
* Modifies this histogram by adding the contents of h to it.
*
* @param hist The histogram to be added to this histogram
* @throws IllegalArgumentException if histogram binnings are incompatible
*/
public void add(IHistogram3D hist) throws IllegalArgumentException {
HistMath.checkCompatibility(xAxis(), hist.xAxis());
HistMath.checkCompatibility(yAxis(), hist.yAxis());
HistMath.checkCompatibility(zAxis(), hist.zAxis());
int xbins = xAxis().bins()+2;
int ybins = yAxis().bins()+2;
int zbins = zAxis().bins()+2;
double[][][] newHeights=new double[xbins][ybins][zbins];
double[][][] newErrors=new double[xbins][ybins][zbins];
double[][][] newMeanXs = new double[xbins][ybins][zbins];
double[][][] newRmsXs = new double[xbins][ybins][zbins];
double[][][] newMeanYs = new double[xbins][ybins][zbins];
double[][][] newRmsYs = new double[xbins][ybins][zbins];
double[][][] newMeanZs = new double[xbins][ybins][zbins];
double[][][] newRmsZs = new double[xbins][ybins][zbins];
double rmsx2 = 0;
double rmsy2 = 0;
double rmsz2 = 0;
boolean h1Aida = !(hist instanceof Histogram3D);
int[][][] newEntries = new int[xbins][ybins][zbins];
for(int i=IAxis.UNDERFLOW_BIN; i= 0 && mj >= 0 && mk >=0 ) || useOutflows() ) {
if ( ! Double.isNaN(mx) && ! Double.isNaN(my) && ! Double.isNaN(mz) && ! Double.isInfinite(mx) && ! Double.isInfinite(my) && ! Double.isInfinite(mz) ) {
meanX += mx*h;
rmsX += rx*rx*h+mx*mx*h;
meanY += my*h;
rmsY += ry*ry*h+my*my*h;
meanZ += mz*h;
rmsZ += rz*rz*h+mz*mz*h;
}
validEntries += e;
sumOfWeights += h;
sumOfWeightsSquared = h*h;
}
}
}
}
}
public void initHistogram3D( IAxis xAxis, IAxis yAxis, IAxis zAxis, String options ) {
this.xAxis = xAxis;
this.yAxis = yAxis;
this.zAxis = zAxis;
Map optionMap = hep.aida.ref.AidaUtils.parseOptions( options );
String type = (String) optionMap.get("type");
if ( type == null || type.equals("default"))
binner3D = new BasicBinner3D( xAxis.bins()+2, yAxis.bins()+2, zAxis.bins()+2);
else if ( type.equals("efficiency") )
binner3D = new EfficiencyBinner3D( xAxis.bins()+2, yAxis.bins()+2, zAxis.bins()+2);
else
throw new IllegalArgumentException("Wrong histogram type "+type);
String useOutflowsString = (String) optionMap.get("useOutflowsInStatistics");
if ( useOutflowsString != null )
setUseOutflows( Boolean.valueOf(useOutflowsString).booleanValue() );
reset();
}
private double meanX = 0, rmsX = 0;
private double meanY = 0, rmsY = 0;
private double meanZ = 0, rmsZ = 0;
private IAxis xAxis, yAxis, zAxis;
private Binner3D binner3D;
}
Ads help maintain this website.