// ---------------------------------------------------------------------- // // HepTH2F.cc - implementation of class HepTH2F // // Intended to gain access to the protected members of the Root TH2F class. // // This class is used to import an existing histogram object from possibly // some other manager and manufacture a temporary TH2F object with all the // same characteristics as the original. That way, we can use the existing // Root methods to implement the increment operators. // // Because of the eccentricities of the various managers, we do NOT manage // to get some of the statistical sums quite right - in particular the // sum of the squared weights - so the overall statistics should not be taken // too seriously. // // 25-Feb-1999 J. Marraffino Initial definition // // // ---------------------------------------------------------------------- #include "HepTuple/HepTH2F.h" #ifndef HEPTRACE_H #include "HepTuple/HepTrace.h" #endif #ifndef HEPFILEMANAGER_H #include "HepTuple/HepFileManager.h" #endif #ifndef HEPHIST2D_H #include "HepTuple/HepHist2D.h" #endif #ifndef HEPRAWHIST_H #include "HepTuple/HepRawHist.h" #endif ZM_BEGIN_NAMESPACE( zmht ) /* namespace zmht { */ // Constructor HepTH2F::HepTH2F( const HepHist2D & h ) : TH2F("Temporary", h.title().c_str(), h.nBinsX(), h.minX(), h.maxX(), h.nBinsY(), h.minY(), h.maxY() ) { // Gather up all the data we need from h. Do type conversions as necessary. // First get the over/under-flow counts int numBinsX = h.nBinsX(); int numBinsY = h.nBinsY(); float numXOverYOver; float numXOverYUnder; float numXUnderYUnder; float numXUnderYOver; float * numTop = new float[numBinsX]; float * numRight = new float[numBinsY]; float * numBottom = new float[numBinsX]; float * numLeft = new float[numBinsY]; h.getOverflows( &numXOverYOver, &numXOverYUnder, &numXUnderYUnder, &numXUnderYOver, numTop, numRight, numBottom, numLeft ); // Then the bin contents. int numBins = numBinsX*numBinsY; float * contents = new float[numBins]; float * errors = new float[numBins]; h.getContents( contents ); h.getErrors( errors ); // Finally, the overall statistics int numEntries; float sumW, sumW2; double sumWX, sumWX2; h.getStatistics( numEntries, sumW, sumW2, sumWX, sumWX2 ); // Move the bin contents and bin errors float * tempp = contents; for( int i=0; iSetCellContent( i+1, j+1, (Stat_t)*tempp ); tempp++; } } tempp = errors; for( int i=0; iSetCellError( i+1, j+1, (Stat_t)*tempp ); tempp++; } } delete [] contents; delete [] errors; // Then underflows and overflows int binno; if( numXOverYOver > 0 ) { binno = GetBin( numBinsX+1, numBinsY+1 ); this->SetBinContent( binno, (Stat_t)numXOverYOver ); } if( numXOverYUnder > 0 ) { binno = GetBin( numBinsX+1, 0 ); this->SetBinContent( binno, (Stat_t)numXOverYUnder ); } if( numXUnderYUnder > 0 ) { binno = GetBin( 0, 0 ); this->SetBinContent( binno, (Stat_t)numXUnderYUnder ); } if( numXUnderYOver > 0 ) { binno = GetBin( 0, numBinsY+1 ); this->SetBinContent( binno, (Stat_t)numXUnderYOver ); } for(int i = 0; i < numBinsX; ++i ) { binno = GetBin( i+1, numBinsY+1 ); this->SetBinContent( binno, (Stat_t)numTop[i] ); binno = GetBin( i+1, 0 ); this->SetBinContent( binno, (Stat_t)numBottom[i] ); } for(int i = 0; i < numBinsY; ++i ) { binno = GetBin( numBinsX+1, i+1 ); this->SetBinContent( binno, (Stat_t)numRight[i] ); binno = GetBin( 0, i+1 ); this->SetBinContent( binno, (Stat_t)numLeft[i] ); } delete [] numTop; delete [] numBottom; delete [] numRight; delete [] numLeft; // Now set the overall statistics this->fEntries = (Stat_t)numEntries; this->fTsumw = (Stat_t)sumW; this->fTsumw2 = (Stat_t)sumW2; this->fTsumwx = (Stat_t)sumWX; this->fTsumwx2 = (Stat_t)sumWX2; this->fTsumwy = (Stat_t)(h.sumY()); this->fTsumwy2 = (Stat_t)(h.sumY2()); this->fTsumwxy = (Stat_t)(h.sumXY()); } void HepTH2F::finishStat2D( HepRootHist2D * h ) { // This bit of foolishness is needed because the TH1::Divide and Multiply // methods attempt to update the x sums and get it wrong. this->fEntries = h->entries(); this->fTsumwx = h->sumX(); this->fTsumwx2 = h->sumX2(); this->fTsumw = h->weight(); this->fTsumw2 = h->weight2(); // This bit of foolishness is needed because the TH1::Add, Divide and Multiply // methods only update the x sums. There probably should be TH2::Add, Divide // and Multiply methods that do that but there aren't. this->fTsumwy = h->sumY(); this->fTsumwy2 = h->sumY2(); this->fTsumwxy = h->sumXY(); } // destructor HepTH2F::~HepTH2F() { } ZM_END_NAMESPACE( zmht ) /* } // namespace zmht */