// ---------------------------------------------------------------------- // // HepRootHistProf.cc - implementation of Root profile histogram // // HepRootHistProf is the implementation of the Root profile // histogram. It is derived from HepHistProf (the generic interface) and // HepRootHist. It is mainly a C++ wrapper around the Root // C++ histogramming libraries. // // No HepRootHistProf objects are ever directly // instantiated by the programmer. When creating new HepHist* objects, // the manager is in charge of creating the appropriate HepRoot object. // // To use generate Root histograms, HepRootFileManager must be used: // // int lunit = 10; // HepFileManager* m = new HepRootFileManager("filename.rz", lunit); // : // : // HepHistProf* h(m->histProf("Title", 100, 0.0, 23.0, 0.0, 23.0)); // float x, y, weight; // : // [gather data] // : // h->accumulate(x, y, weight); // // // // // 12-Dec-1998 Philippe Canal Creation // 25-Feb-1999 J. Marraffino Added increment operators for histograms // // ---------------------------------------------------------------------- #ifndef HEPTRACE_H #include "HepTuple/HepTrace.h" #endif #ifndef HEPROOTFILEMANAGER_H #include "HepTuple/HepRootFileManager.h" #endif #ifndef HEPROOTHISTPROF_H #include "HepTuple/HepRootHistProf.h" #endif #ifndef HEPRAWHIST_H #include "HepTuple/HepRawHist.h" #endif #ifndef HEPTH1P_H #include "HepTuple/HepTH1P.h" #endif #include "ZMutility/iostream" #include USING( std::string ) #include #include #include "HepTuple/HepTH1P.h" ZM_BEGIN_NAMESPACE( zmht ) /* namespace zmht { */ // Create a profile plot from an existing TProfile HepRootHistProf::HepRootHistProf( HepRootFileManager * manager , TProfile* histo ) : HepHistProf( manager, histo->GetTitle(), histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax(), // wrong for now: histo->GetYaxis()->GetXmin(), histo->GetYaxis()->GetXmax(), ((HepTH1P*)histo)->GetYmin(), ((HepTH1P*)histo)->GetYmax(), histo->GetErrorOption(), histo->GetUniqueID() ), HepRootObj(histo) { HEP_DEBUG( "HepRootHistProf::constructor( TProfile* " << histo << " )" ); } // create a profile plot with the given title and binning HepRootHistProf::HepRootHistProf( HepRootFileManager * manager , const string& title , const int nBinsX, const float lowX, const float highX , const float lowY, const float highY , const string& chopt , const int idReq ) : HepHistProf( manager, title.c_str(), nBinsX, lowX, highX, lowY, highY, chopt.c_str(), idReq ) { HEP_DEBUG( "HepRootHistProf::constructor( \"" << title << "\", " << *id_ << " )" ); string name = mkname(title, *id_); // error= sigma/sqrt(N) data( new TProfile( name.c_str(), title.c_str(), nBinsX, lowX, highX, lowY, highY, chopt.c_str() ) ); if ( data() == 0 ) { ZMthrow(ZMxHepCantMakeHist(string("Root failed to create the hist 1d: ") + title ) ); isValid(false); } } // HepRootHistProf::HepRootHistProf() HepRootHistProf::HepRootHistProf( HepRootFileManager * manager , const string& title , const int nBinsX, const float lowX, const float highX , const float lowY, const float highY , const int idReq ) : HepHistProf( manager, title.c_str(), nBinsX, lowX, highX, lowY, highY, idReq ) { // Create a 1-D profile root histo with default error calculation: HEP_DEBUG( "HepRootHist1D::constructor( \"" << title << "\", " << id_ << " )" ); string name = mkname(title, *id_); // error= sigma/sqrt(N) data( new TProfile( name.c_str(), title.c_str(), nBinsX, lowX, highX, lowY, highY ) ); if ( data() == 0 ) { ZMthrow(ZMxHepCantMakeHist(string("Root failed to create the hist 1d: ") + title ) ); isValid(false); } else { data()->SetUniqueID( idReq ); } } // HepRootHistProf::HepRootHistProf() HepRootHistProf::HepRootHistProf( HepRootHistProf * original , const string& title , const int idReq ) : HepHistProf( original->manager(), title.c_str(), original->nBinsX(), original->minX(), original->maxX(), original->minY(), original->maxY(), idReq ) { data( (TNamed*)( original->data()->Clone() ) ); if ( data() == 0 ) { ZMthrow(ZMxHepCantMakeHist(string("Root failed to create the hist 1d: ") + title ) ); isValid(false); } else { data()->SetTitle( title.c_str() ); data()->SetUniqueID( idReq ); } } // HepRootHistProf::HepRootHistProf() // Used for dummy construction ... // the object is then not valid ... HepRootHistProf::HepRootHistProf() : HepHistProf() { HEP_DEBUG( "HepRootHistProf::constructor( )" ); } HepRootHistProf::~HepRootHistProf() { HEP_DEBUG( "HepRootHistProf::destructor( \"" << *title_ << "\", " << *id_ << " )" ); } void HepRootHistProf::accumulate( const float x , const float y , const float weight ) { if ( mayUse() ) { _accumulate( x, y, weight ); ((TProfile*)data())->Fill( x, y, weight); } else { ZMthrow(ZMxHepUnmanagedItem("attempt to accumulate() to unmanaged histogram.")); return; } } #define CHECK(name) \ if (! mayUse() ) { \ ZMthrow(ZMxHepUnmanagedItem( \ string("attempt to " #name "() an unmanaged histogram ") \ +title()+string("."))); \ return 0; \ } int HepRootHistProf::entries() const { // number of entries CHECK(entries); // call histo function return (int) ((TH1*)data())->GetEntries(); } int HepRootHistProf::entries( const int binNumX) const { // number of entries in X-bin ZMthrow(ZMxHepUnsupported("Root's Histogram Profiles do not have access to the number of entries by bin")); CHECK(entries); return 0; } float HepRootHistProf::weight() const { // sum of all weight CHECK(weight); float result = 0.0; for(int i=1; iGetBinCenter(i))*weight(i); } return result; } float HepRootHistProf::sumX2() const { // retrieve weighted sum of square (X^2) if (! mayUse() ) { ZMthrow(ZMxHepUnmanagedItem( string("attempt to sum() an unmanaged histogram ") +title()+string("."))); return 0.0; } TH1 * hist = (TH1*)data(); float result = 0.0; float tempX; for(int i=1; iGetBinCenter(i); result += tempX*tempX*weight(i); } return result; } float HepRootHistProf::sumY() const { // retrieve weighted sum of Y CHECK(sumY); TProfile * hist = (TProfile*) data(); float sumY = 0; for(int i=1; iGetBinContent(i); } return sumY; } float HepRootHistProf::sumY2() const { // retrieve weighted sum of Y^2 CHECK(sumY2); TProfile * hist = (TProfile*) data(); float sumY2 = 0; for(int i=1; iGetBinContent(i) * weight(i) * hist->GetBinContent(i); } return sumY2; } float HepRootHistProf::sumY( const int binNumX) const { // retrieve sum of Y in X-bin CHECK(sumY); TProfile * hist = (TProfile*) data(); if ( binNumX < 0 || binNumX > nBinsX() ) { return 0.0; } return weight(binNumX) * hist->GetBinContent(binNumX); } float HepRootHistProf::sumY2( const int binNumX) const{ // retrieve sum of Y^2 in X-bin CHECK(sumY2); TProfile * hist = (TProfile*) data(); if ( binNumX < 0 || binNumX > nBinsX() ) { return 0.0; } return weight(binNumX) * hist->GetBinContent(binNumX) * weight(binNumX) * hist->GetBinContent(binNumX); } void HepRootHistProf::reset() { if ( mayUse() ) { ((TH1*) data())->Reset(); } else { ZMthrow(ZMxHepUnmanagedItem("attempt to reset() unmanaged histogram.")); return; } } float HepRootHistProf::bin( // retrieve contents of given bin const int binNum ) const { if ( mayUse() ) { return (float)(((TH1*)data())->GetBinContent(binNum)); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access to unmanaged histogram ") +title()+string("."))); return 0.0; } } float HepRootHistProf::binError( // retrieve error of given bin const int binNum ) const { if ( mayUse() ) { return (float)(((TH1*)data())->GetBinError(binNum)); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access to unmanaged histogram ") +title()+string("."))); return 0.0; } } float HepRootHistProf::getWeight( // get sum of weights for specified bin int numBin ) const { if ( mayUse() ) { return ((HepTH1P*)data())->fetchWeight( numBin ); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); return 0.0; } } void HepRootHistProf::getSumW( // get sum of weights per bin for all bins float * values ) const { if ( mayUse() ) { ((HepTH1P*)data())->fetchSumW( values ); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); } } void HepRootHistProf::getSumWY( // get sum of weighted Y per bin for all bins float * values ) const { if ( mayUse() ) { ((HepTH1P*)data())->fetchSumWY( values ); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); } } void HepRootHistProf::getSumWY2( // get sum of weighted Y^2 per bin for all bins float * values ) const { if ( mayUse() ) { ((HepTH1P*)data())->fetchSumWY2( values ); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); } } void HepRootHistProf::getStatistics( // get histogram-wide statistics int & numEntries , float & sumW , float & sumW2 , double & sumWX , double & sumWX2 ) const { if ( mayUse() ) { numEntries = entries(); sumW = weight(); sumW2 = weight2(); sumWX = (double)sumX(); sumWX2 = (double)sumX2(); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); } } void HepRootHistProf::getOverflows( // get over/under-flow count float * numOver , float * numUnder ) const { if ( mayUse() ) { *numUnder = this->bin( 0 ); *numOver = this->bin( nBinsX()+1 ); } else { ZMthrow(ZMxHepUnmanagedItem( string("attempt to access an unmanaged histogram ") +title()+string("."))); } } HepRawHist HepRootHistProf::importHistProf( const HepHistProf & h ) { // Manufacture a temporary Root histogram with all the characteristics of h. // Make it a HepTH1P object so we can get to the protected data. HepTH1P * tmpHist = new HepTH1P( h ); // Instantiate a HepRawHist object to pass back to say where the // Raw Histogram lives and what it's called HepRawHist temp( tmpHist ); return temp; } void HepRootHistProf::addHistProf( const HepRawHist & temp ) { // If we got here, the temporary histogram object referred to by temp is // known to be valid. On the other hand, it's worth being careful. TH1 * tmpHist = temp.HepTH1Pptr; if( tmpHist != 0 ) ((TH1*)data())->Add( tmpHist, 1.0 ); } void HepRootHistProf::subtractHistProf( const HepRawHist & temp ) { // If we got here, the temporary histogram object referred to by temp is // known to be valid. On the other hand, it's worth being careful. TH1 * tmpHist = temp.HepTH1Pptr; if( tmpHist != 0 ) ((TH1*)data())->Add( tmpHist, -1.0 ); } void HepRootHistProf::multiplyHistProf( const HepRawHist & temp ) { // If we got here, the temporary histogram object referred to by temp is // known to be valid. On the other hand, it's worth being careful. ZMthrow(ZMxHepUnsupported("Root's Profile histograms have only a dummy Multiply method")); TH1 * tmpHist = temp.HepTH1Pptr; if( tmpHist != 0 ) ((TH1*)data())->Multiply( tmpHist ); } void HepRootHistProf::divideHistProf( const HepRawHist & temp ) { // If we got here, the temporary histogram object referred to by temp is // known to be valid. On the other hand, it's worth being careful. TH1 * tmpHist = temp.HepTH1Pptr; if( tmpHist != 0 ) ((TH1*)data())->Divide( tmpHist ); } void HepRootHistProf::removeImportedHistProf( const HepRawHist & temp ) { // If we got here, the temporary histogram object referred to by temp is // known to be valid. On the other hand, it's worth being careful. HepTH1P * tmpHist = temp.HepTH1Pptr; if( tmpHist != 0 ) delete tmpHist; } ZM_END_NAMESPACE( zmht ) /* } // namespace zmht */