00001 #ifndef BOOK_FOR_ROOT_HISTOGRAMS 00002 #define BOOK_FOR_ROOT_HISTOGRAMS 00003 00004 #include <map> 00005 #include <string> 00006 #include "poly.h" 00007 #include "TDirectory.h" 00008 #include "TH1.h" 00009 #include "TH1D.h" 00010 #include "TH2D.h" 00011 #include "TProfile.h" 00012 #include "TH3D.h" 00013 #include <boost/regex.hpp> 00014 #include <boost/iterator/filter_iterator.hpp> 00015 00016 class Book { 00017 00018 typedef const double double_t; 00019 typedef const unsigned long uint_t; 00020 typedef const std::string string_t; 00021 typedef std::map<std::string, TH1*> book_t; 00022 00023 book_t book_; 00024 std::string title_; 00025 TDirectory* directory; 00026 00027 struct match_name { 00028 match_name(string_t re) : expression(re) {} 00029 bool operator()(const book_t::const_iterator::value_type& p) { return regex_match( p.first, expression); } 00030 private: boost::regex expression; 00031 }; 00032 00033 public: 00034 00035 Book() : title_(""), directory(0) {} 00036 Book(string_t t) : title_(t), directory(new TDirectory(t.c_str(),t.c_str())) {} 00037 00038 string_t& title() const { return title_;} 00039 bool empty() const { return book_.empty(); } 00040 long size () const { return book_.size(); } 00041 00042 TH1* book(string_t name, TH1*const hist) { book_[name]=hist; hist->SetDirectory(directory); if(!hist->GetSumw2N()) hist->Sumw2(); return hist;} 00043 TH1*& operator[](string_t name) { return book_[name]; } 00044 const TH1* operator[](string_t name) const { book_t::const_iterator it = book_.find(name); return it==book_.end() ? 0 : it->second;} 00045 00046 typedef boost::filter_iterator<match_name,book_t::iterator> iterator; 00047 typedef boost::filter_iterator<match_name,book_t::const_iterator> const_iterator; 00048 iterator begin(string_t re = ".*") {book_t::iterator b(book_.begin()), e(book_.end()); return boost::make_filter_iterator(match_name(re),b,e);} 00049 const_iterator begin(string_t re = ".*") const {book_t::const_iterator b(book_.begin()), e(book_.end()); return boost::make_filter_iterator(match_name(re),b,e);} 00050 iterator end( string_t re = ".*") {book_t::iterator e(book_.end()); return boost::make_filter_iterator(match_name(re),e,e);} 00051 const_iterator end( string_t re = ".*") const {book_t::const_iterator e(book_.end()); return boost::make_filter_iterator(match_name(re),e,e);} 00052 iterator find (string_t name, string_t re = ".*") { return boost::make_filter_iterator(match_name(re),book_.find(name),book_.end()); } 00053 const_iterator find (string_t name, string_t re = ".*") const { return boost::make_filter_iterator(match_name(re),book_.find(name),book_.end()); } 00054 std::pair<iterator,iterator> filter_range(string_t re = ".*") { return std::make_pair(begin(re), end(re) ); } 00055 std::pair<const_iterator,const_iterator> filter_range(string_t re = ".*") const { return std::make_pair(begin(re), end(re) ); } 00056 00057 void erase(string_t name) { book_t::iterator it = book_.find(name); if(it!=book_.end()) {delete it->second; book_.erase(it); } } 00058 void erase(iterator it) { delete it->second; book_.erase(it.base()); } 00059 00060 void fill( double_t X, const char* name, 00061 uint_t NbinsX, double_t Xlow, double_t Xup, double_t W=1 ) { fill(X,std::string(name),NbinsX,Xlow,Xup,W);} 00062 void fill( double_t X, const poly<std::string>& names, 00063 uint_t NbinsX, double_t Xlow, double_t Xup, double_t W=1 ) 00064 { 00065 BOOST_FOREACH(string_t name, std::make_pair(names.begin(),names.end())) { 00066 book_t::const_iterator current = book_.find(name); 00067 if( current == book_.end() ) 00068 book(name, new TH1D(name.c_str(), "", NbinsX, Xlow, Xup))->Fill(X,W); 00069 else current->second->Fill(X,W); 00070 } 00071 } 00072 void fill( double_t X, double_t Y, const char* name, 00073 uint_t NbinsX, double_t Xlow, double_t Xup, double_t W=1 ) {fill(X,Y,std::string(name),NbinsX,Xlow,Xup,W);} 00074 void fill( double_t X, double_t Y, const poly<std::string>& names, 00075 uint_t NbinsX, double_t Xlow, double_t Xup, double_t W=1 ) 00076 { 00077 BOOST_FOREACH(string_t name, std::make_pair(names.begin(),names.end())) { 00078 book_t::const_iterator current = book_.find(name); 00079 if( current == book_.end() ) 00080 static_cast<TProfile*>(book(name, new TProfile(name.c_str(), "", NbinsX, Xlow, Xup)))->Fill(X,Y,W); 00081 else static_cast<TProfile*>(current->second)->Fill(X,Y,W); 00082 } 00083 } 00084 void fill( double_t X, double_t Y, const char* name, 00085 uint_t NbinsX, double_t Xlow, double_t Xup, 00086 uint_t NbinsY, double_t Ylow, double_t Yup, double_t W=1 ) { fill(X,Y,std::string(name),NbinsX,Xlow,Xup,NbinsY,Ylow,Yup,W);} 00087 void fill( double_t X, double_t Y, const poly<std::string>& names, 00088 uint_t NbinsX, double_t Xlow, double_t Xup, 00089 uint_t NbinsY, double_t Ylow, double_t Yup, double_t W=1 ) 00090 { 00091 BOOST_FOREACH(string_t name, std::make_pair(names.begin(),names.end())) { 00092 book_t::const_iterator current = book_.find(name); 00093 if( current == book_.end() ) 00094 static_cast<TH2*>(book(name, new TH2D(name.c_str(), "", NbinsX, Xlow, Xup, NbinsY, Ylow, Yup)))->Fill(X,Y,W); 00095 else static_cast<TH2*>(current->second)->Fill(X,Y,W); 00096 } 00097 } 00098 void fill( double_t X, double_t Y, double_t Z, const char* name, 00099 uint_t NbinsX, double_t Xlow, double_t Xup, 00100 uint_t NbinsY, double_t Ylow, double_t Yup, 00101 uint_t NbinsZ, double_t Zlow, double_t Zup, double_t W=1 ) {fill(X,Y,Z,std::string(name),NbinsX,Xlow,Xup,NbinsY,Ylow,Yup,NbinsZ,Zlow,Zup);} 00102 void fill( double_t X, double_t Y, double_t Z, const poly<std::string>& names, 00103 uint_t NbinsX, double_t Xlow, double_t Xup, 00104 uint_t NbinsY, double_t Ylow, double_t Yup, 00105 uint_t NbinsZ, double_t Zlow, double_t Zup, double_t W=1 ) 00106 { 00107 BOOST_FOREACH(string_t name, std::make_pair(names.begin(),names.end())) { 00108 book_t::const_iterator current = book_.find(name); 00109 if( current == book_.end() ) 00110 static_cast<TH3*>(book(name, new TH3D(name.c_str(), "", NbinsX, Xlow, Xup, NbinsY, Ylow, Yup, NbinsZ, Zlow, Zup)))->Fill(X,Y,Z,W); 00111 else static_cast<TH3*>(current->second)->Fill(X,Y,Z,W); 00112 } 00113 } 00114 00115 }; 00116 00117 #endif