• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/Users/jmonk/Physics/ForIA/src/D3PD/RootHistogrammer.cxx

Go to the documentation of this file.
00001 #include "ForIA/D3PD/RootHistogrammer.hh"
00002 
00003 #include "TH1D.h"
00004 #include "TH2D.h"
00005 #include "TH3D.h"
00006 #include "TFile.h"
00007 #include "TDirectory.h"
00008 #include "TProfile.h"
00009 
00010 #include <iostream>
00011 
00012 namespace ForIA {
00013 
00014   RootHistogrammer::RootHistogrammer(const string &rootFileName) : IHistogrammer(), m_rootFileName(rootFileName), m_rootDir("/"){
00015     m_directories["/"] = &m_rootDir;
00016     TH1::AddDirectory(false);
00017   }
00018   
00020   const string &RootHistogrammer::outputName()const{
00021     return m_rootFileName;
00022   }
00023   
00025   void RootHistogrammer::bookHistogram1D(const string &path, const string &name, 
00026                                          const string &title, 
00027                                          int nBins, double xMin, double xMax,
00028                                          bool divideBinWidths){
00029     
00030     if(xMin > xMax){
00031       throw BinError(xMin, xMax);
00032     }
00033     
00034     TH1D *histo = new TH1D(name.c_str(), title.c_str(), nBins, xMin, xMax);
00035     histo->Sumw2();
00036     histo->ResetStats();
00037     histo->Reset();
00038     
00039     try{
00040       addHisto(path, name, histo, divideBinWidths);
00041     }catch(DuplicateHistogramException er){
00042       delete histo;
00043       throw er;
00044     }
00045         
00046     return; 
00047   }
00048   
00050   void RootHistogrammer::bookHistogram1D(const string &path, const string &name, 
00051                                          const string &title, const vector<double> &bins,
00052                                          bool divideBinWidths){
00053 
00054     TH1D *histo = new TH1D(name.c_str(), title.c_str(), bins.size() - 1, &(bins[0]));
00055     histo->Sumw2();
00056     histo->ResetStats();
00057     histo->Reset();
00058     
00059     try{
00060       addHisto(path, name, histo, divideBinWidths);
00061     }catch(DuplicateHistogramException er){
00062       delete histo;
00063       throw er;
00064     }
00065     
00066     return;
00067   }
00068 
00070   void RootHistogrammer::bookProfile1D(const string &path, const string &name, 
00071                                        const string &title, int nBins, 
00072                                        double xMin, double xMax){
00073     
00074     TProfile *prof = new TProfile(name.c_str(), title.c_str(), nBins, xMin, xMax);
00075     prof->Sumw2();    
00076     try{
00077       addProfile(path, name, prof);
00078     }catch(DuplicateHistogramException er){
00079       delete prof;
00080       throw er;
00081     }
00082     
00083     return;
00084   }
00085   
00087   void RootHistogrammer::bookHistogram2D(const string &path, const string &name, const string &title, 
00088                                          int nBinsX, double xMin, double xMax,
00089                                          int nBinsY, double yMin, double yMax,
00090                                          bool divideBinWidths){
00091    
00092     if(xMin > xMax){
00093       throw BinError(xMin, xMax);
00094     }
00095     
00096     if(yMin > yMax){
00097       throw BinError(xMin, xMax);
00098     }
00099     
00100     TH2D *histo = new TH2D(name.c_str(), title.c_str(), nBinsX, xMin, xMax, nBinsY, yMin, yMax);
00101     histo->Sumw2();
00102     
00103     try{
00104       addHisto(path, name, histo, divideBinWidths);
00105     }catch(DuplicateHistogramException er){
00106       delete histo;
00107       throw er;
00108     }
00109         
00110     return ;
00111   }
00112   
00114   void RootHistogrammer::bookHistogram2D(const string &path, const string &name, const string &title,
00115                                          const vector<double> &xbins, const vector<double> &ybins,
00116                                          bool divideBinWidths){
00117    
00118     TH2D *histo = new TH2D(name.c_str(), title.c_str(), 
00119                            xbins.size() - 1, &(xbins[0]), ybins.size() - 1, &(ybins[0]));
00120     histo->Sumw2();
00121     
00122     try{
00123       addHisto(path, name, histo, divideBinWidths);
00124     }catch(DuplicateHistogramException er){
00125     
00126       delete histo;
00127       throw er;
00128     }
00129     return;
00130   }
00131   
00133   void RootHistogrammer::bookHistogram3D(const string &path, const string &name, const string &title, 
00134                           int nBinsX, double xMin, double xMax,
00135                           int nBinsY, double yMin, double yMax,
00136                           int nBinsZ, double zMin, double zMax,
00137                           bool divideBinWidths){
00138     
00139     if(xMin > xMax){
00140       throw BinError(xMin, xMax);
00141     }
00142     
00143     if(yMin > yMax){
00144       throw BinError(xMin, xMax);
00145     }
00146   
00147     if(zMin > zMax){
00148       throw BinError(zMin, zMax);
00149     }
00150     
00151     TH3D *histo = new TH3D(name.c_str(), title.c_str(), 
00152                            nBinsX, xMin, xMax, 
00153                            nBinsY, yMin, yMax,
00154                            nBinsZ, zMin, zMax);
00155     histo->Sumw2();
00156     
00157     try{
00158       addHisto(path, name, histo, divideBinWidths);
00159     }catch(DuplicateHistogramException er){
00160       
00161       delete histo;
00162       throw er;
00163     }
00164     return;
00165   }
00167   void RootHistogrammer::fillHistogram1D(const string &path, const string &name, 
00168                                          double value, double weight){
00169     
00170     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00171     
00172     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name, this);
00173     
00174     TH1D *histo = dir->second->histogram(name);
00175     
00176     if(histo == 0) throw NoSuchHistogramException(path, name, this);
00177     
00178     histo->Fill(value, weight);
00179     
00180     return;
00181   }
00182 
00184   void RootHistogrammer::fillProfile1D(const string &path, const string &name,
00185                                        double xVal, double yVal, double weight){
00186   
00187     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00188     
00189     if(dir == m_directories.end())throw NoSuchHistogramException(path, name, this);
00190     
00191     TProfile *prof = dir->second->profile(name);
00192     
00193     if(prof == 0) throw NoSuchHistogramException(path, name, this);
00194 
00195     prof->Fill(xVal, yVal, weight);
00196     
00197     return;
00198   }
00199   
00201   void RootHistogrammer::fillHistogram2D(const string &path, const string &name, 
00202                                          double xVal, double yVal, double weight){
00203     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00204     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name, this);
00205     
00206     TH2D *histo = dir->second->histogram2D(name);
00207     if(histo ==0) throw NoSuchHistogramException(path, name, this);
00208       
00209     histo->Fill(xVal, yVal, weight);
00210     return;
00211   }
00212   
00214   void RootHistogrammer::fillHistogram3D(const string &path, const string &name, 
00215                                          double xVal, double yVal, double zVal,
00216                                          double weight){
00217   
00218     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00219     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name, this);
00220     
00221     TH3D *histo = dir->second->histogram3D(name);
00222     if(histo ==0) throw NoSuchHistogramException(path, name, this);
00223     
00224     histo->Fill(xVal, yVal, zVal, weight);
00225     return;
00226   }
00228   void RootHistogrammer::finalise(){
00229    
00230     
00231     for(boost::unordered_map<string, Directory*>::iterator dir = m_directories.begin();
00232         dir != m_directories.end(); ++dir){
00233             
00234       for(Directory::iterator histo = dir->second->begin(); histo != dir->second->end(); ++histo){
00235         
00236         if(histo->second == 0) throw NoSuchHistogramException(dir->first, histo->first);
00237         
00238         if(! dir->second->doDivideBinWidths(histo->second)){
00239           std::cout<<"Histogram "<< histo->first<<" is not normalised by bin widths"<<std::endl;
00240           continue;
00241         }
00242         
00243         double nEntries = histo->second->GetEntries();
00244         
00245         int nBins = histo->second->GetNbinsX() +1;
00246         for(int bin=1; bin != nBins; ++bin){
00247           double area = histo->second->GetBinContent(bin);
00248           double width = histo->second->GetBinWidth(bin);
00249           double error = histo->second->GetBinError(bin) / width;
00250           double height = area / width;
00251           histo->second->SetBinContent(bin, height);
00252           histo->second->SetBinError(bin, error);
00253         }
00254         
00255         histo->second->SetEntries(nEntries);
00256         
00257       }
00258       
00259       for(Directory::iterator2D histo = dir->second->begin2D(); histo != dir->second->end2D(); ++histo){
00260         
00261         if(histo->second == 0) throw NoSuchHistogramException(dir->first, histo->first);
00262         
00263         if(! dir->second->doDivideBinWidths(histo->second)){
00264           std::cout<<"Histogram "<< histo->first<<" is not normalised by bin widths"<<std::endl;
00265           continue;
00266         }
00267         
00268         int nBinsX = histo->second->GetNbinsX() + 1;
00269         int nBinsY = histo->second->GetNbinsY() + 1;
00270         
00271         double nEntries = histo->second->GetEntries();
00272         
00273         for(int xbin =1; xbin != nBinsX; ++xbin){
00274           for(int ybin = 1; ybin != nBinsY; ++ybin){
00275             int bin = histo->second->GetBin(xbin, ybin);
00276             double volume = histo->second->GetBinContent(bin);
00277             double xWidth = histo->second->GetXaxis()->GetBinWidth(xbin);
00278             double yWidth = histo->second->GetYaxis()->GetBinWidth(ybin);
00279             double area = xWidth * yWidth;
00280             double height = volume / area;
00281             double error = histo->second->GetBinError(bin) / area;
00282             histo->second->SetBinContent(bin, height);
00283             histo->second->SetBinError(bin, error);
00284           }
00285         }
00286         histo->second->SetEntries(nEntries);
00287       }
00288      
00289       for(Directory::iterator3D histo = dir->second->begin3D(); histo != dir->second->end3D(); ++histo){
00290         
00291         if(histo->second == 0) throw NoSuchHistogramException(dir->first, histo->first);
00292         
00293         if(! dir->second->doDivideBinWidths(histo->second)){
00294           std::cout<<"Histogram "<<histo->first<<" is not normalised by bin widths"<<std::endl;
00295           continue;
00296         }
00297         
00298         int nBinsX = histo->second->GetNbinsX() + 1;
00299         int nBinsY = histo->second->GetNbinsY() + 1;
00300         int nBinsZ = histo->second->GetNbinsZ() + 1;
00301         
00302         double nEntries = histo->second->GetEntries();
00303         
00304         for(int xbin = 1; xbin != nBinsX; ++xbin){
00305           for(int ybin = 1; ybin != nBinsY; ++ybin){
00306             for(int zbin = 1; zbin != nBinsZ; ++zbin){
00307               int bin = histo->second->GetBin(xbin, ybin, zbin);
00308               double volume = histo->second->GetBinContent(bin);
00309               double xWidth = histo->second->GetXaxis()->GetBinWidth(bin);
00310               double yWidth = histo->second->GetYaxis()->GetBinWidth(bin);
00311               double zWidth = histo->second->GetZaxis()->GetBinWidth(bin);
00312               double dxdydz = xWidth * yWidth * zWidth;
00313               double height = volume / dxdydz;
00314               double error = histo->second->GetBinError(bin) / dxdydz;
00315               histo->second->SetBinContent(bin, height);
00316               histo->second->SetBinError(bin, error);
00317             }
00318           }
00319         }
00320         histo->second->SetEntries(nEntries);
00321       }
00322       
00323     }
00324     
00325     string filename = m_rootFileName + ".root";
00326     
00327     TFile *file = new TFile(filename.c_str(), "RECREATE");
00328     
00329     m_rootDir.write(file);
00330     
00331     file->Close();
00332     return;
00333   }
00334   
00336   void RootHistogrammer::normaliseHistogram1D(const string &path, const string &name, double norm){
00337     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00338     
00339     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name);
00340     
00341     TH1D *histo = dir->second->histogram(name);
00342     
00343     if(histo == 0) throw NoSuchHistogramException(path, name);
00344 
00345     double intgl = histo->Integral();//"width");
00346     histo->Scale(norm / intgl);
00347     
00348     return;
00349   }
00350   
00352   void RootHistogrammer::scaleHistogram1D(const string &path, const string &name, double scale){
00353     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00354     
00355     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name);
00356     
00357     TH1D *histo = dir->second->histogram(name);
00358     
00359     if(histo == 0) throw NoSuchHistogramException(path, name);
00360     
00361     histo->Scale(scale);
00362     
00363     return;
00364   }
00366   void RootHistogrammer::normaliseHistogram2D(const string &path, const string &name, double norm){
00367     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00368     
00369     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name);
00370     
00371     TH2D *histo = dir->second->histogram2D(name);
00372     
00373     if(histo == 0) throw NoSuchHistogramException(path, name);
00374     
00375     double intgl = histo->Integral();//"width");
00376     histo->Scale(norm / intgl);
00377     
00378     return;
00379   }
00381   void RootHistogrammer::scaleHistogram2D(const string &path, const string &name, double scale){
00382     boost::unordered_map<string, Directory*>::iterator dir = m_directories.find(path);
00383     
00384     if(dir == m_directories.end()) throw NoSuchHistogramException(path, name);
00385     
00386     TH2D *histo = dir->second->histogram2D(name);
00387     
00388     if(histo == 0) throw NoSuchHistogramException(path, name);
00389     
00390     histo->Scale(scale);
00391     
00392     return;
00393   }
00394   
00396   void RootHistogrammer::showHistograms(std::ostream &out)const{
00397   
00398     for(boost::unordered_map<string, Directory*>::const_iterator dir = m_directories.begin();
00399         dir != m_directories.end(); ++dir){
00400       
00401       for(Directory::const_iterator histo = dir->second->begin();
00402           histo != dir->second->end(); ++histo){
00403         out<<dir->first<<histo->first<<std::endl;
00404       }
00405       
00406       for(Directory::const_iterator2D histo = dir->second->begin2D();
00407           histo != dir->second->end2D(); ++histo){
00408         out<<dir->first<<histo->first<<std::endl;
00409       }
00410       
00411     }
00412         
00413     return;
00414   }
00415   
00417   Directory::Directory(const string &name): 
00418   m_name(name){
00419     stripSlash(m_name);
00420   }
00421   
00423   const string &Directory::name()const{
00424     return m_name;
00425   }
00426   
00428   pair<string, Directory*> Directory::addDirectory(string path){
00429    
00430     stripSlash(path);
00431     
00432     size_t pos = path.find("/");
00433     
00434     string dirName;
00435     
00436     bool addMore = false;
00437     string nextDir = "";
00438     
00439     if(pos == string::npos){
00440       dirName = path;
00441     }else{
00442       dirName = path.substr(0, pos);
00443       nextDir = path.substr(pos);
00444       addMore = true;
00445     }
00446     
00447     map<string, Directory>::iterator dir = m_dirs.find(dirName);
00448     if(dir==m_dirs.end()){
00449       Directory newDir(dirName);
00450       dir = m_dirs.insert(std::pair<string, Directory>(dirName, newDir)).first;
00451     }
00452     
00453     string resultName = "/" + dirName;
00454     Directory *resultDir = &(dir->second);
00455     
00456     if(addMore){
00457       pair<string, Directory*> added = dir->second.addDirectory(nextDir);
00458       resultName = resultName + added.first;
00459       resultDir =  added.second;
00460     }
00461     
00462     return pair<string, Directory*>(resultName, resultDir);
00463   }
00464   
00466   string &Directory::stripSlash(string &path){
00467     string::iterator c = path.begin();
00468     
00469     if(strncmp(&(*c), "/", 1) == 0){
00470       path.erase(c);
00471     }
00472     
00473     return path;
00474   }
00475   
00477   void Directory::addHistogram(const string &name, TH1D *histo, bool divideBinWidths){
00478    
00479     if(m_histos[name]!=0) throw DuplicateHistogramException(this->name(), name);
00480     
00481     m_histos[name] = histo;
00482     
00483     if(!divideBinWidths){
00484       m_noDivideBinWidths.insert(histo);
00485     }
00486     
00487     return;
00488   }
00489   
00491   void Directory::addProfile(const string &name, TProfile *prof){
00492     if(m_profile1Ds[name]!=0) throw DuplicateHistogramException(this->name(), name);
00493     
00494     m_profile1Ds[name] = prof;
00495     
00496     return;
00497   }
00498   
00500   void Directory::addHistogram(const string &name, TH2D *histo, bool divideBinWidths){
00501     
00502     if(m_2dHistos[name] !=0) throw DuplicateHistogramException(this->name(), name);
00503 
00504     m_2dHistos[name] = histo;
00505     
00506     if(!divideBinWidths){
00507       m_noDivideBinWidths.insert(histo);
00508     }
00509     
00510     return;
00511   }
00512   
00513   void Directory::addHistogram(const string &name, TH3D *histo, bool divideBinWidths){
00514     if(m_3dHistos[name] != 0) throw DuplicateHistogramException(this->name(), name);
00515     
00516     m_3dHistos[name] = histo;
00517     
00518     if(!divideBinWidths){
00519       m_noDivideBinWidths.insert(histo);
00520     }
00521     
00522     return;
00523   }
00524   
00526   TH1D *Directory::histogram(const string &name){
00527     return m_histos[name];
00528   }
00529   
00531   TProfile *Directory::profile(const string &name){
00532     return m_profile1Ds[name];
00533   }
00534   
00536   TH2D *Directory::histogram2D(const string &name){
00537     return m_2dHistos[name];
00538   }
00539   
00541   TH3D *Directory::histogram3D(const string &name){
00542     return m_3dHistos[name];
00543   }
00544   
00546   bool Directory::doDivideBinWidths(const TH1 *histo)const{
00547     
00548     if(m_noDivideBinWidths.count(histo) != 0) return false;
00549       
00550     return true;
00551   }
00552   
00554   bool Directory::write(TDirectory *dir) const{
00555 
00556     if(dir==0) return false;
00557     
00558     dir->cd();
00559         
00560     for(boost::unordered_map<string, TH1D*>::const_iterator histo = m_histos.begin();
00561         histo != m_histos.end(); ++histo){
00562       histo->second->Write();
00563     }
00564     
00565     for(boost::unordered_map<string, TProfile*>::const_iterator prof = m_profile1Ds.begin();
00566         prof != m_profile1Ds.end(); ++prof){
00567       prof->second->Write();
00568     }
00569     
00570     for(boost::unordered_map<string, TH2D*>::const_iterator histo = m_2dHistos.begin();
00571         histo != m_2dHistos.end(); ++histo){
00572       histo->second->Write();
00573     }
00574     
00575     for(boost::unordered_map<string, TH3D*>::const_iterator histo = m_3dHistos.begin();
00576         histo != m_3dHistos.end(); ++histo){
00577       histo->second->Write();
00578     }
00579     
00580     for(map<string, Directory>::const_iterator dirIt = m_dirs.begin();
00581         dirIt != m_dirs.end(); ++dirIt){
00582       TDirectory *newDir = dir->mkdir(dirIt->second.m_name.c_str());
00583       dirIt->second.write(newDir);
00584     }
00585     
00586     return true;
00587   }
00588  
00589 }

Generated on Mon Jul 30 2012 16:56:35 for ForIA by  doxygen 1.7.2