package hep.aida.ref.histogram;
/**
* Implementation of IHistogram1D.
* @author The AIDA Team at SLAC.
* @version $Id: Histogram1D.java 13479 2008-01-22 19:38:41Z serbo $
*
*/
import hep.aida.IAxis;
import hep.aida.IHistogram1D;
import hep.aida.ref.event.IsObservable;
import hep.aida.ref.histogram.binner.AbstractBinner1D;
import hep.aida.ref.histogram.binner.BasicBinner1D;
import hep.aida.ref.histogram.binner.Binner1D;
import hep.aida.ref.histogram.binner.BinnerMath;
import hep.aida.ref.histogram.binner.EfficiencyBinner1D;
import java.util.Map;
public class Histogram1D extends Histogram implements IHistogram1D, IsObservable {
/**
* Create a 1-dimensional Histogram.
*
*/
public Histogram1D(){
super("","",1, "");
}
/**
* Create a 1-dimensional Histogram.
* @param name The name of the Histogram as a ManagedObject.
* @param title The title of the Histogram.
* @param axis The x-axis of the Histogram.
*
*/
public Histogram1D(String name, String title, IAxis axis) {
this(name,title,axis,"");
}
/**
* Create a 1-dimensional Histogram.
* @param name The name of the Histogram as a ManagedObject.
* @param title The title of the Histogram.
* @param axis The x-axis of the Histogram.
* @param options options of the Histogram.
*
*/
protected Histogram1D(String name, String title, IAxis axis, String options) {
super(name, title, 1, options);
initHistogram1D(axis,options);
}
/**
* Fill the Histogram with unit weight.
* @param x The value to be filled.
*
*/
public void fill(double x) {
fill(x,1.);
}
/**
* Fill the Histogram.
* @param x The value to be filled.
* @param weight The weight for this entry.
*
*/
public void fill(double x, double weight) {
if ( ! isFillable() ) throw new UnfillableHistogramException();
allEntries++;
if ( (! Double.isNaN(x)) && (!Double.isNaN(weight)) ) {
int coordToIndex = xAxis.coordToIndex(x);
int bin = mapBinNumber(coordToIndex, axis());
/*
double x0 = 0d;
if ( coordToIndex == IAxis.UNDERFLOW_BIN ) {
x0 = axis().lowerEdge();
} else if ( coordToIndex == IAxis.OVERFLOW_BIN ) {
x0 = axis().upperEdge();
} else {
x0 = axis().binCenter(coordToIndex);
}
*/
binner1D.fill(bin, x, weight);
if ( coordToIndex >= 0 || useOutflows() ) {
double delata = x - center;
validEntries++;
mean += delata*weight;
rms += delata*delata*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() {
binner1D.clear();
setBinCenters();
mean = 0;
rms = 0;
center = (xAxis.upperEdge() + xAxis.lowerEdge())/2;
super.reset();
}
private void setBinCenters() {
double x0 = 0;
for (int i=0; i= -2; )
sum += binHeight(i);
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() {
return binHeight(IAxis.UNDERFLOW_BIN) + binHeight(IAxis.OVERFLOW_BIN);
}
/**
* 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=0; i= max) max=binHeight(i);
return max;
}
/**
* Number of entries in the corresponding bin (ie the number of times fill was called for this bin).
* @param index the 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 index) {
return binner1D.entries(mapBinNumber(index, axis()));
}
/**
* Total height of the corresponding bin.
* @param index The bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The bin height for the corresponding bin.
*
*/
public double binHeight(int index) {
return binner1D.height(mapBinNumber(index, axis()));
}
/**
* The error on this bin.
* @param index the bin number in the external representation: (0...N-1) or OVERFLOW or UNDERFLOW.
* @return The error on the corresponding bin.
*
*/
public double binError(int index) {
return binner1D.plusError(mapBinNumber(index, axis()));
}
/**
* Get the mean of the whole Histogram. It includes all the entries (in and out of range).
* @return The mean of the Histogram.
*
*/
public double mean() {
if ( validEntries != 0 ) return mean/sumOfWeights + center;
return 0;
}
/**
* Get the RMS of the whole Histogram. It includes all the entries (in and out of range).
* @return The RMS of the Histogram.
*
*/
public double rms(){
if ( validEntries != 0 ) return Math.sqrt((rms - mean*mean/sumOfWeights)/sumOfWeights);
return 0;
}
/**
* Set the rms of the Histogram.
* @param rms The Historam's x rms
*
*/
//public void setRms( double rms ) {
// this.rms = rms*rms*sumOfWeights + mean*mean*sumOfWeights;
//}
/**
* Set the mean of the Histogram.
* @param mean The Histogram's x mean
*
*/
public void setMeanAndRms( double otherMean, double otherRms ) {
this.meanAndRmsIsSet = true;
this.mean = (otherMean - center)*sumOfWeights;
this.rms = otherRms*otherRms*sumOfWeights + (otherMean - center)*(otherMean - center)*sumOfWeights;
}
/**
* Get the X axis.
* @return The x axis.
*
*/
public IAxis axis() {
return xAxis;
}
/**
* Convenience method, equivalent to axis().coordToIndex(coord).
* @see IAxis#coordToIndex(double)
*/
public int coordToIndex(double coord) {
return axis().coordToIndex(coord);
}
/**
* 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");
binner1D.scale(scaleFactor);
mean *= scaleFactor;
rms *= 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(IHistogram1D hist) throws IllegalArgumentException {
HistMath.checkCompatibility(axis(), hist.axis());
int bins = axis().bins()+2;
boolean h1Aida = !(hist instanceof Histogram1D);
if (!h1Aida) {
BinnerMath.add(binner1D, binner1D, ((Histogram1D) hist).binner());
initHistogram1D(binner1D);
} else {
double[] newHeights = new double[bins];
double[] newErrors = new double[bins];
double[] newMeans = new double[bins];
double[] newRmss = new double[bins];
int[] newEntries = new int [bins];
double rms2 = 0;
for(int i=IAxis.UNDERFLOW_BIN; i= 0 || useOutflows() && HistUtils.isValidDouble(h)) {
if ( HistUtils.isValidDouble(m) ) {
double d = b2.binCenter(i) - center;
mean += m + d*h;
rms += r + d*(2*m + d*h);
}
validEntries += b2.entries(i);
sumOfWeights += h;
sumOfWeightsSquared += h*h;
}
}
}
void initHist1D( IAxis xAxis, String options ) {
this.xAxis = xAxis;
Map optionMap = hep.aida.ref.AidaUtils.parseOptions( options );
String type = (String) optionMap.get("type");
if ( type == null || type.equals("default") ) {
binner1D = new BasicBinner1D(xAxis.bins()+2);
} else if ( type.equals("efficiency") ) {
binner1D = new EfficiencyBinner1D(xAxis.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();
}
public AbstractBinner1D binner() {
return binner1D;
}
private double mean = 0;
private double rms = 0;
private double center = 0;
private IAxis xAxis;
private AbstractBinner1D binner1D;
}
Ads help maintain this website.