![]() |
|
|
Generated: 8 Jan 2009 |
00001 #include "GaudiKernel/DataObject.h" 00002 #include "GaudiKernel/ObjectFactory.h" 00003 #include "GaudiPI.h" 00004 #include "Generic3D.h" 00005 #include "TH3D.h" 00006 00007 namespace Gaudi { 00008 00015 class Histogram3D : public DataObject, public Generic3D<AIDA::IHistogram3D,TH3D> { 00016 public: 00018 Histogram3D(); 00020 Histogram3D(TH3D* rep); 00022 virtual ~Histogram3D() {} 00024 bool fill ( double x, double y, double z, double weight); 00026 virtual bool setBinContents( int i, int j, int k, int entries,double height,double error,double centreX, double centreY, double centreZ ); 00028 virtual bool setRms(double rmsX, double rmsY, double rmsZ); 00029 // overwrite reset 00030 virtual bool reset(); 00032 void* cast(const std::string & className) const; 00034 void copyFromAida(const AIDA::IHistogram3D & h); 00036 virtual const CLID& clID() const { return Gaudi::Histogram3D::classID(); } 00037 static const CLID& classID() { return CLID_H3D; } 00038 00039 protected: 00040 // cache sumwx and sumwy when setting contents since I don't have bin mean 00041 double m_sumwx; 00042 double m_sumwy; 00043 double m_sumwz; 00044 }; 00045 } 00046 typedef Gaudi::Histogram3D H3D; 00047 DECLARE_DATAOBJECT_FACTORY(H3D) 00048 00049 namespace Gaudi { 00050 template <> 00051 void Generic3D<AIDA::IHistogram3D,TH3D>::adoptRepresentation(TObject* rep) { 00052 TH3D* imp = dynamic_cast<TH3D*>(rep); 00053 if ( imp ) { 00054 if ( m_rep ) delete m_rep; 00055 m_rep = imp; 00056 m_xAxis.initialize(m_rep->GetXaxis(),true); 00057 m_yAxis.initialize(m_rep->GetYaxis(),true); 00058 m_zAxis.initialize(m_rep->GetZaxis(),true); 00059 const TArrayD* a = m_rep->GetSumw2(); 00060 if ( 0 == a || (a && a->GetSize()==0) ) m_rep->Sumw2(); 00061 setTitle(m_rep->GetTitle()); 00062 return; 00063 } 00064 throw std::runtime_error("Cannot adopt native histogram representation."); 00065 } 00066 } 00067 00069 std::pair<DataObject*,AIDA::IHistogram3D*> 00070 Gaudi::createH3D(const std::string& title,int nBinsX,double xlow,double xup,int nBinsY,double ylow,double yup,int nBinsZ,double zlow,double zup) { 00071 Histogram3D* p = new Histogram3D(new TH3D(title.c_str(),title.c_str(),nBinsX,xlow,xup,nBinsY,ylow,yup,nBinsZ,zlow,zup)); 00072 return std::pair<DataObject*,AIDA::IHistogram3D*>(p,p); 00073 } 00074 00076 std::pair<DataObject*,AIDA::IHistogram3D*> 00077 Gaudi::createH3D(const std::string& title, const Edges& eX,const Edges& eY,const Edges& eZ) { 00078 Histogram3D* p = new Histogram3D(new TH3D(title.c_str(),title.c_str(),eX.size()-1,&eX.front(), eY.size()-1,&eY.front(), eZ.size()-1,&eZ.front())); 00079 return std::pair<DataObject*,AIDA::IHistogram3D*>(p,p); 00080 } 00081 00082 std::pair<DataObject*,AIDA::IHistogram3D*> Gaudi::createH3D(const AIDA::IHistogram3D& hist) { 00083 TH3D *h = getRepresentation<AIDA::IHistogram3D,TH3D>(hist); 00084 Histogram3D *n = h ? new Histogram3D(new TH3D(*h)) : 0; 00085 return std::pair<DataObject*,AIDA::IHistogram3D*>(n,n); 00086 } 00087 00088 Gaudi::Histogram3D::Histogram3D() { 00089 m_rep = new TH3D(); 00090 setTitle(""); 00091 m_rep->Sumw2(); 00092 m_sumEntries = 0; 00093 m_sumwx = 0; 00094 m_sumwy = 0; 00095 m_sumwz = 0; 00096 m_rep->SetDirectory(0); 00097 } 00098 00099 Gaudi::Histogram3D::Histogram3D(TH3D* rep) { 00100 m_rep = 0; 00101 adoptRepresentation(rep); 00102 m_sumEntries = 0; 00103 m_sumwx = 0; 00104 m_sumwy = 0; 00105 m_sumwz = 0; 00106 m_rep->SetDirectory(0); 00107 } 00108 00109 // set bin content (entries and centre are not used ) 00110 bool Gaudi::Histogram3D::setBinContents(int i,int j,int k,int entries,double height,double error,double centreX, double centreY, double centreZ ) { 00111 m_rep->SetBinContent(rIndexX(i), rIndexY(j), rIndexZ(k), height); 00112 m_rep->SetBinError(rIndexX(i), rIndexY(j), rIndexZ(k), error); 00113 // accumulate sum bin centers 00114 if (i >=0 && j >= 0 && k >= 0) { 00115 m_sumwx += centreX*height; 00116 m_sumwy += centreY*height; 00117 m_sumwz += centreZ*height; 00118 } 00119 m_sumEntries += entries; 00120 return true; 00121 } 00122 00123 bool Gaudi::Histogram3D::setRms(double rmsX, double rmsY, double rmsZ ) { 00124 m_rep->SetEntries(m_sumEntries); 00125 std::vector<double> stat(11); 00126 // sum weights 00127 stat[0] = sumBinHeights(); 00128 stat[1] = 0; 00129 if (equivalentBinEntries() != 0) 00130 stat[1] = ( sumBinHeights() * sumBinHeights() ) / equivalentBinEntries(); 00131 stat[2] = m_sumwx; 00132 double meanX = 0; 00133 if ( sumBinHeights() != 0 ) meanX = m_sumwx/ sumBinHeights(); 00134 stat[3] = ( meanX*meanX + rmsX*rmsX )* sumBinHeights(); 00135 stat[4] = m_sumwy; 00136 double meanY = 0; 00137 if ( sumBinHeights() != 0 ) meanY = m_sumwy/ sumBinHeights(); 00138 stat[5] = ( meanY*meanY + rmsY*rmsY )* sumBinHeights(); 00139 stat[6] = 0; 00140 stat[7] = m_sumwz; 00141 double meanZ = 0; 00142 if ( sumBinHeights() != 0 ) meanZ = m_sumwz/ sumBinHeights(); 00143 stat[8] = ( meanZ*meanZ + rmsZ*rmsZ )* sumBinHeights(); 00144 // do not need to use sumwxy sumwxz and sumwyz 00145 00146 m_rep->PutStats(&stat.front()); 00147 return true; 00148 } 00149 00150 bool Gaudi::Histogram3D::reset ( ) { 00151 m_sumwx = 0; 00152 m_sumwy = 0; 00153 m_sumwz = 0; 00154 m_sumEntries = 0; 00155 m_rep->Reset ( ); 00156 return true; 00157 } 00158 00159 bool Gaudi::Histogram3D::fill ( double x, double y, double z, double weight) { 00160 m_rep->Fill ( x , y, z, weight ); 00161 return true; 00162 } 00163 00164 void* Gaudi::Histogram3D::cast(const std::string & className) const { 00165 if (className == "AIDA::IHistogram3D") { 00166 return (AIDA::IHistogram3D*)this; 00167 } 00168 else if (className == "AIDA::IHistogram") { 00169 return (AIDA::IHistogram*)this; 00170 } 00171 return 0; 00172 } 00173 00174 void Gaudi::Histogram3D::copyFromAida(const AIDA::IHistogram3D & h) { 00175 delete m_rep; 00176 // implement here the copy 00177 const char* tit = h.title().c_str(); 00178 if (h.xAxis().isFixedBinning() && h.yAxis().isFixedBinning() && h.zAxis().isFixedBinning() ) { 00179 m_rep = new TH3D(tit,tit, 00180 h.xAxis().bins(), h.xAxis().lowerEdge(), h.xAxis().upperEdge(), 00181 h.yAxis().bins(), h.yAxis().lowerEdge(), h.yAxis().upperEdge(), 00182 h.zAxis().bins(), h.zAxis().lowerEdge(), h.zAxis().upperEdge() ); 00183 } 00184 else { 00185 Edges eX, eY, eZ; 00186 for (int i =0; i < h.xAxis().bins(); ++i) 00187 eX.push_back(h.xAxis().binLowerEdge(i)); 00188 // add also upperedges at the end 00189 eX.push_back(h.xAxis().upperEdge() ); 00190 for (int i =0; i < h.yAxis().bins(); ++i) 00191 eY.push_back(h.yAxis().binLowerEdge(i)); 00192 // add also upperedges at the end 00193 eY.push_back(h.yAxis().upperEdge() ); 00194 for (int i =0; i < h.zAxis().bins(); ++i) 00195 eZ.push_back(h.zAxis().binLowerEdge(i)); 00196 // add also upperedges at the end 00197 eZ.push_back(h.zAxis().upperEdge() ); 00198 m_rep = new TH3D(tit,tit,eX.size()-1,&eX.front(),eY.size()-1,&eY.front(),eZ.size()-1,&eZ.front()); 00199 } 00200 m_xAxis.initialize(m_rep->GetXaxis(),true); 00201 m_yAxis.initialize(m_rep->GetYaxis(),true); 00202 m_zAxis.initialize(m_rep->GetZaxis(),true); 00203 const TArrayD* a = m_rep->GetSumw2(); 00204 if ( 0 == a || (a && a->GetSize()==0) ) m_rep->Sumw2(); 00205 m_sumEntries = 0; 00206 m_sumwx = 0; 00207 m_sumwy = 0; 00208 m_sumwz = 0; 00209 00210 // statistics 00211 double sumw = h.sumBinHeights(); 00212 double sumw2 = 0; 00213 if (h.equivalentBinEntries() != 0) 00214 sumw2 = ( sumw * sumw ) /h.equivalentBinEntries(); 00215 double sumwx = h.meanX()*h.sumBinHeights(); 00216 double sumwx2 = (h.meanX()*h.meanX() + h.rmsX()*h.rmsX() )*h.sumBinHeights(); 00217 double sumwy = h.meanY()*h.sumBinHeights(); 00218 double sumwy2 = (h.meanY()*h.meanY() + h.rmsY()*h.rmsY() )*h.sumBinHeights(); 00219 double sumwz = h.meanZ()*h.sumBinHeights(); 00220 double sumwz2 = (h.meanZ()*h.meanZ() + h.rmsZ()*h.rmsZ() )*h.sumBinHeights(); 00221 double sumwxy = 0; 00222 double sumwxz = 0; 00223 double sumwyz = 0; 00224 00225 // copy the contents in (AIDA underflow/overflow are -2,-1) 00226 for (int i=-2; i < xAxis().bins(); ++i) { 00227 for (int j=-2; j < yAxis().bins(); ++j) { 00228 for (int k=-2; k < zAxis().bins(); ++k) { 00229 m_rep->SetBinContent(rIndexX(i), rIndexY(j), rIndexZ(k), h.binHeight(i,j,k) ); 00230 m_rep->SetBinError(rIndexX(i), rIndexY(j), rIndexZ(k), h.binError(i,j,k) ); 00231 // calculate statistics 00232 if ( i >= 0 && j >= 0 && k >= 0) { 00233 sumwxy += h.binHeight(i,j,k)*h.binMeanX(i,j,k)*h.binMeanY(i,j,k); 00234 sumwxz += h.binHeight(i,j,k)*h.binMeanX(i,j,k)*h.binMeanZ(i,j,k); 00235 sumwyz += h.binHeight(i,j,k)*h.binMeanY(i,j,k)*h.binMeanZ(i,j,k); 00236 } 00237 } 00238 } 00239 } 00240 // need to do set entries after setting contents otherwise root will recalulate them 00241 // taking into account how many time SetBinContents() has been called 00242 m_rep->SetEntries(h.allEntries()); 00243 00244 // fill stat vector 00245 std::vector<double> stat(11); 00246 stat[0] = sumw; 00247 stat[1] = sumw2; 00248 stat[2] = sumwx; 00249 stat[3] = sumwx2; 00250 stat[4] = sumwy; 00251 stat[5] = sumwy2; 00252 stat[6] = sumwxy; 00253 stat[7] = sumwz; 00254 stat[8] = sumwz2; 00255 stat[9] = sumwxz; 00256 stat[10] = sumwyz; 00257 m_rep->PutStats(&stat.front()); 00258 }