| # Gaudi Framework, version v21r11 |

Home |  | Generated: 30 Sep 2010

# H3D.cpp

Go to the documentation of this file.

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