#ifndef _BINNEDEFFICIENCY_HPP #define _BINNEDEFFICIENCY_HPP #include "eff_utils/EffExceptions.hpp" #include "eff_utils/Efficiency.hpp" #include "eff_utils/EffVal.hpp" #include #include #include class TH1; class TH1F; class TAxis ; namespace eff_utils { struct BinnedEffUnderflow : public EffException { BinnedEffUnderflow(const std::string & mess = "") : EffException( "BinnedEfficiency : underflow in bin lookup" + mess) {;} }; struct BinnedEffOverflow : public EffException { BinnedEffOverflow( const std::string & mess = "") : EffException( "BinnedEfficiency : overflow in bin lookup" + mess) {;} }; struct BinnedMalformed : public EffException { BinnedMalformed( const std::string & mess = "" ) : EffException("Malformed BinInfo line :" + mess ) {;} }; struct BinnedBadDimension : public EffException { BinnedBadDimension( const std::string & mess = "") : EffException("BinnedEfficiency : Dimension of Eff call does not match dimension of Efficiency : " +mess) {;} }; /* BinnedEfficiency class is a class to used by eff_util package to keep histogram with any values (not only efficiency). It also can be used as a historam class (the number of event in each bin could be increased one by one). Any number of dimensions with uniform or non-uniform bins are supported. */ class BinnedEfficiency : public Efficiency { public: enum MODE {DEFAULT, IGNORE_UNDERFLOW, IGNORE_OVERFLOW, IGNORE_UNDEROVERFLOW} ; enum FINDBINMODE {INCLUDELOWBOUND, INCLUDEHIGHBOUND} ; BinnedEfficiency() : Efficiency(), _flowMode(DEFAULT) {} BinnedEfficiency( std::istream & ist, const EffInfo* request=0 ); // initialise efficiency with Root TH1, TH2 or TH3 histograms BinnedEfficiency( const TH1 * h); // support for different up and down errors: BinnedEfficiency( const TH1 * h_el, const TH1 * h_eh); // add bin axis with non-uniform bin structure void DefineBins( const std::vector& edges) ; // add bin axis with uniform bins void DefineBins( int nbins, float xlo, float xhi) ; // add bins from ROOT TAxis void addTAxis(const TAxis* axis) ; // increase event counter by one in the bins with axis values specified by the vector // passed flag should be true for events which pass the selection or fire the trigger // The return value is the efficiency object in the current bin const EffVal& Fill(const std::vector& axis, bool passed) ; // set bin content using internal bin number void Val( int ibin, float val, float elo, float ehi); // set bin content using bins number void Val(const std::vector& ibins, float val, float elo, float ehi); // set bin content using axis values void Val(const std::vector& axis, float val, float elo, float ehi); // set bin content from EffVal object void Val( int binno, const EffVal& eff) ; // set bin content from Value object void Val(int binno, const Value& eff) ; // number of bins of axis number n (starting from 0). // Default value -1 corresponds to the total number of bins int GetNbins(int n=-1) const ; // return historgram dimension (number of axis) int dimension() const { return _axisEdges.size();} // get internal bin index using axis values. int BinIndex( const std::vector& value) const; // return internal bin index using axis bin index. // for example, for 3d index = z + nz*y + nz*ny*x int BinIndex( const std::vector& value) const ; // get bin edges for axis with number axis_n float LowBinEdge( int axis_n, int n) const ; float HighBinEdge( int axis_n, int n) const ; // get bin content by bin index, bin index started at 0 at finished at nbins-1 /// bin index >= number of nbins throw overflow exeption const EffVal& GetBinContent( int nx, int ny =-1, int nz = -1 ) const ; // get bin content by axes value // 1D only EffVal Eff(float x) const; // 2D only EffVal Eff(float x, float y) const; // 3D only EffVal Eff(float x, float y, float z) const; // any number of dimensions EffVal Eff( const std::vector& value) const; // any number of dimensions EffVal Eff( const std::vector& value) const; // int find bin index (number) using axis value int FindBin( const std::vector< float >& loEdges, float x, FINDBINMODE mode = INCLUDELOWBOUND) const; // int find bin index (number) using axis value and number int FindBin(int axis_n, float x, FINDBINMODE mode = INCLUDELOWBOUND) const { return FindBin(_axisEdges.at(axis_n), x, mode);} bool ValidateInput() const { return _eff.size() >0 ; } // remove all bin axis and bin contents information void Clear() ; /// if mode set to IGNORE_UNDERFLOW will substitute the underflow with the lowest bin value /// if mode set to IGNORE_OVERFLOW will substitute the overrflow with the highest bin value /// IGNORE_UNDEROVERFLOW will substitue both underflow and overflow void setExeptionMode(MODE mode) const {_flowMode = mode ;} // create 1D projection of nD histogram TH1F* projection(int axis_number) const ; // create root histogram void makeEfficiencyHistogram(const EffInfo* request, const std::string& hname="", bool useCurrentDir=false ) const; // add another efficiency with the same binning void add(const BinnedEfficiency* eff) ; //scale efficiency by a float void Scale(float sc) ; //scale efficiency by a float in a bin i void Scale(float sc, int ibin) ; protected: bool ParseInputLine( const std::string &key, const std::vector< std::string > & line); private: std::vector > _axisEdges ; // The order of axes is x, y, z ... std::vector< EffVal > _eff; mutable MODE _flowMode ; // ignore or not over/undo flow // write efficiency information to the output stream void stream( std::ostream &) const; // initialize efficiencies void initEff() ; }; } #endif