00001 #ifndef FORIA_ROOTHISTOGRAMMER_HH 00002 #define FORIA_ROOTHISTOGRAMMER_HH 00003 00004 #include "ForIA/IHistogrammer.hh" 00005 00006 #include "boost/lexical_cast.hpp" 00007 #include "boost/unordered_map.hpp" 00008 00009 #include <map> 00010 #include <string> 00011 #include <set> 00012 00013 class TH1; 00014 class TH1D; 00015 class TProfile; 00016 class TH2D; 00017 class TH3D; 00018 class TDirectory; 00019 00020 namespace ForIA { 00021 00022 using std::map; 00023 using std::string; 00024 using std::pair; 00025 using std::set; 00026 00028 class BinError: public std::runtime_error{ 00029 00030 public: 00031 BinError(double min, double max): std::runtime_error 00032 ("bin minimum " + boost::lexical_cast<string>(min) + 00033 " is above maximum " + boost::lexical_cast<string>(max)){ 00034 00035 } 00036 00037 }; 00038 00040 class Directory { 00041 00042 public: 00043 00044 Directory(const string &name); 00045 00047 void addHistogram(const string &name, TH1D *histo, bool divideBinWidths); 00049 void addProfile(const string &name, TProfile *prof); 00051 void addHistogram(const string &name, TH2D *histo, bool divideBinWidths); 00053 void addHistogram(const string &name, TH3D *histo, bool divideBinWidths); 00054 00056 TH1D *histogram(const string &name); 00058 TProfile *profile(const string &name); 00060 TH2D *histogram2D(const string &name); 00062 TH3D *histogram3D(const string &name); 00063 00073 pair<string, Directory*> addDirectory(string path); 00074 00076 const string &name()const; 00077 00079 bool write(TDirectory *dir) const; 00080 00082 typedef boost::unordered_map<string, TH1D*>::iterator iterator; 00084 typedef boost::unordered_map<string, TH1D*>::const_iterator const_iterator; 00085 00087 iterator begin(){return m_histos.begin();}; 00089 iterator end(){return m_histos.end();}; 00090 00092 typedef boost::unordered_map<string, TH2D*>::iterator iterator2D; 00094 typedef boost::unordered_map<string, TH2D*>::const_iterator const_iterator2D; 00095 00097 iterator2D begin2D(){return m_2dHistos.begin();} 00099 iterator2D end2D(){return m_2dHistos.end();} 00100 00102 typedef boost::unordered_map<string, TH3D*>::iterator iterator3D; 00104 typedef boost::unordered_map<string, TH3D*>::const_iterator const_iterator3D; 00105 00107 iterator3D begin3D(){return m_3dHistos.begin();} 00109 iterator3D end3D(){return m_3dHistos.end();} 00110 00111 bool doDivideBinWidths(const TH1 *histo)const; 00112 00113 private: 00114 00115 00116 string &stripSlash(string &path); 00117 00118 string m_name; 00119 00120 boost::unordered_map<string, TH1D*> m_histos; 00121 boost::unordered_map<string, TProfile*> m_profile1Ds; 00122 boost::unordered_map<string, TH2D*> m_2dHistos; 00123 boost::unordered_map<string, TH3D*> m_3dHistos; 00124 map<string, Directory> m_dirs; 00125 set<const TH1*> m_noDivideBinWidths; 00126 00127 }; 00128 00130 class RootHistogrammer : public IHistogrammer { 00131 00132 public: 00133 00140 RootHistogrammer(const string &rootFileName="ForIA"); 00141 00142 const string & outputName()const; 00143 00144 void bookHistogram1D(const string &path, const string &name, const string &title, int nBins, double xMin, double xMax, bool divideBinWidths); 00145 void bookHistogram1D(const string &path, const string &name, const string &title, const vector<double> &bins, bool divideBinWidths); 00146 00147 void bookProfile1D(const string &path, const string &name, const string &title, int nBins, double xMin, double xMax); 00148 00149 void bookHistogram2D(const string &path, const string &name, const string &title, 00150 int nBinsX, double xMin, double xMax, 00151 int nBinsY, double yMin, double yMax, 00152 bool divideBinWidths); 00153 00154 void bookHistogram2D(const string &path, const string &name, const string &title, 00155 const vector<double> &xbins, const vector<double> &ybins, 00156 bool divideBinWidths); 00157 00158 void bookHistogram3D(const string &path, const string &name, const string &title, 00159 int nBinsX, double xMin, double xMax, 00160 int nBinsY, double yMin, double yMax, 00161 int nBinsZ, double zMin, double zMax, 00162 bool divideBinWidths); 00163 00164 void fillHistogram1D(const string &path, const string &name, double value, double weight); 00165 00166 void fillProfile1D(const string &path, const string &name, double xVal, double yVal, double weight); 00167 00168 void fillHistogram2D(const string &path, const string &name, double xVal, double yVal, double weight); 00169 00170 void fillHistogram3D(const string &path, const string &name, double xVal, double yVal, double zVal, double weight); 00171 00172 void finalise(); 00173 00174 void normaliseHistogram1D(const string &path, const string &name, double norm=1.); 00175 00176 void scaleHistogram1D(const string &path, const string &name, double scale=1.); 00177 00178 void normaliseHistogram2D(const string &path, const string &name, double norm=1.); 00179 00180 void scaleHistogram2D(const string &path, const string &name, double scale=1.); 00181 00182 void showHistograms(std::ostream &out) const; 00183 00184 private: 00185 00186 template <class T> void addHisto(const string &path, const string &name, T *histo, bool divideBinWidths){ 00187 00188 boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path); 00189 00190 if(dir == m_directories.end()){ 00191 00192 pair<string, Directory*> newDir = m_rootDir.addDirectory(path); 00193 00194 newDir.second->addHistogram(name, histo, divideBinWidths); 00195 00196 m_directories.insert(newDir); 00197 }else{ 00198 dir->second->addHistogram(name, histo, divideBinWidths); 00199 } 00200 00201 return; 00202 } 00203 00204 template<class T> void addProfile(const string &path, const string &name, T *prof){ 00205 00206 boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path); 00207 00208 if(dir == m_directories.end()){ 00209 00210 pair<string, Directory*> newDir = m_rootDir.addDirectory(path); 00211 00212 newDir.second->addProfile(name, prof); 00213 00214 m_directories.insert(newDir); 00215 }else{ 00216 dir->second->addProfile(name, prof); 00217 } 00218 00219 return; 00220 } 00221 00222 string m_rootFileName; 00223 boost::unordered_map<string, Directory*> m_directories; 00224 Directory m_rootDir; 00225 00226 }; 00227 } 00228 #endif