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 GAUDI_API 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
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
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
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
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
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
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
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
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
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
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
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
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
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
00241
00242 m_rep->SetEntries(h.allEntries());
00243
00244
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 }