CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/MuonAnalysis/MomentumScaleCalibration/interface/Histograms.h

Go to the documentation of this file.
00001 #ifndef Histograms_H
00002 #define Histograms_H
00003 
00012 #include <CLHEP/Vector/LorentzVector.h>
00013 #include "DataFormats/Math/interface/LorentzVector.h"
00014 #include "DataFormats/MuonReco/interface/Muon.h"
00015 #include "MuonAnalysis/MomentumScaleCalibration/interface/MuScleFitUtils.h"
00016 
00017 #include "TH1D.h"
00018 #include "TH1F.h"
00019 #include "TH2F.h"
00020 #include "TH3F.h"
00021 #include "TFile.h"
00022 #include "TString.h"
00023 #include "TProfile.h"
00024 #include "TProfile2D.h"
00025 #include "TF1.h"
00026 #include "TGraphErrors.h"
00027 #include "TFile.h"
00028 #include "TSystem.h"
00029 #include "TCanvas.h"
00030 
00031 #include <vector>
00032 #include <string>
00033 #include <iostream>
00034 #include "TMath.h"
00035 
00036 class Histograms {
00037 public:
00038 
00039   // Constructor
00040   // -----------
00041   Histograms() : theWeight_(1), histoDir_(0) {};
00042   Histograms( const TString & name ) : theWeight_(1), name_(name), histoDir_(0) {}
00043   Histograms( TFile * outputFile, const TString & name ) :
00044     theWeight_(1),
00045     name_(name),
00046     outputFile_(outputFile),
00047     histoDir_( outputFile->GetDirectory(name) )
00048   {
00049     if( histoDir_ == 0 ) {
00050       histoDir_ = outputFile->mkdir(name);
00051     }
00052     histoDir_->cd();
00053   }
00054 
00055   // Destructor
00056   // ----------
00057   virtual ~Histograms() {};
00058 
00059   // Operations
00060   // ----------
00061   //   virtual void Fill( const reco::Particle::LorentzVector & p4 ) {};
00062   //   virtual void Fill( const CLHEP::HepLorentzVector & momentum ) {};
00063   virtual void Fill( const reco::Particle::LorentzVector & p1, const reco::Particle::LorentzVector & p2 ) {};
00064   virtual void Fill( const reco::Particle::LorentzVector & p1, const reco::Particle::LorentzVector & p2, const int charge, const double & weight = 1.) {};
00065   virtual void Fill( const CLHEP::HepLorentzVector & momentum1, const CLHEP::HepLorentzVector & momentum2 ) {};
00066   virtual void Fill( const CLHEP::HepLorentzVector & momentum1, const CLHEP::HepLorentzVector & momentum2, const int charge, const double & weight = 1.) {};
00067   virtual void Fill( const CLHEP::HepLorentzVector & p1, const reco::Particle::LorentzVector & p2 ) {};
00068   virtual void Fill( const reco::Particle::LorentzVector & p4, const double & weight = 1. ) {};
00069   // virtual void Fill( const reco::Particle::LorentzVector & p4, const double & likeValue ) {};
00070   virtual void Fill( const reco::Particle::LorentzVector & p4, const double & resValue, const int charge ) {};
00071   virtual void Fill( const reco::Particle::LorentzVector & p4, const double & genValue, const double recValue, const int charge ) {};
00072   virtual void Fill( const CLHEP::HepLorentzVector & p, const double & likeValue ) {};
00073   virtual void Fill( const unsigned int number ) {};
00074   virtual void Fill( const reco::Particle::LorentzVector & recoP1, const int charge1,
00075                      const reco::Particle::LorentzVector & genP1,
00076                      const reco::Particle::LorentzVector & recoP2, const int charge2,
00077                      const reco::Particle::LorentzVector & genP2,
00078                      const double & recoMass, const double & genMass ) {};
00079   virtual void Fill( const reco::Particle::LorentzVector & recoP1, const int charge1,
00080                      // const reco::Particle::LorentzVector & genP1,
00081                      const reco::Particle::LorentzVector & recoP2, const int charge2,
00082                      // const reco::Particle::LorentzVector & genP2,
00083                      const double & recoMass, const double & genMass ) {};
00084   virtual void Fill( const reco::Particle::LorentzVector & recoP1,
00085                      const reco::Particle::LorentzVector & genP1,
00086                      const reco::Particle::LorentzVector & recoP2,
00087                      const reco::Particle::LorentzVector & genP2 ) {};
00088   virtual void Fill( const double & x, const double & y ) {};
00089   virtual void Fill( const double & x, const double & y, const double & a, const double & b ) {};
00090 
00091   virtual double Get( const reco::Particle::LorentzVector & recoP1, const TString & covarianceName ) { return 0.; };
00092 
00093   virtual void Write() = 0;
00094   virtual void Clear() = 0;
00095 
00096   virtual void SetWeight (double weight) {
00097     theWeight_ = weight;
00098   }
00099 
00100   virtual TString GetName() {
00101     return name_;
00102   }
00103 
00104 protected:
00105   double theWeight_;
00106   TString name_;
00107   TFile * outputFile_;
00108   TDirectory * histoDir_;
00109 
00110 private:
00111 
00112 };
00113 
00115 class HTH2D : public Histograms
00116 {
00117 public:
00118   HTH2D( TFile * outputFile, const TString & name, const TString & title, const TString & dirName,
00119          const int xBins, const double & xMin, const double & xMax,
00120          const int yBins, const double & yMin, const double & yMax ) : Histograms(outputFile, dirName),
00121                                                                        tH2d_( new TH2D(name, title, xBins, xMin, xMax, yBins, yMin, yMax) ),
00122                                                                        tProfile_( new TProfile(name+"Prof", title+" profile", xBins, xMin, xMax, yMin, yMax) ) {}
00123   ~HTH2D() {
00124     delete tH2d_;
00125     delete tProfile_;
00126   }
00127   virtual void Fill( const double & x, const double & y ) {
00128     tH2d_->Fill(x,y);
00129     tProfile_->Fill(x,y);
00130   }
00131   virtual void Write() {
00132     if(histoDir_ != 0) histoDir_->cd();
00133     tH2d_->Write();
00134     tProfile_->Write();
00135   }
00136   virtual void Clear() {
00137     tH2d_->Clear();
00138     tProfile_->Clear();
00139   }
00140   virtual void SetXTitle(const TString & title) {
00141     tH2d_->GetXaxis()->SetTitle(title);
00142     tProfile_->GetXaxis()->SetTitle(title);
00143   }
00144   virtual void SetYTitle(const TString & title) {
00145     tH2d_->GetYaxis()->SetTitle(title);
00146     tProfile_->GetYaxis()->SetTitle(title);
00147   }
00148   TH2D * operator->() { return tH2d_; }
00149   TProfile * getProfile() { return tProfile_; }
00150 protected:
00151   TH2D * tH2d_;
00152   TProfile * tProfile_;
00153 };
00154 
00156 class HTH1D : public Histograms
00157 {
00158 public:
00159   HTH1D( TFile * outputFile, const TString & name, const TString & title,
00160          const int xBins, const double & xMin, const double & xMax ) : Histograms(outputFile, name),
00161                                                                        tH1D_( new TH1D(name, title, xBins, xMin, xMax) ) {}
00162   ~HTH1D() {
00163     delete tH1D_;
00164   }
00165   virtual void Fill( const double & x, const double & y ) {
00166     tH1D_->Fill(x, y);
00167   }
00168   virtual void Write() {
00169     if(histoDir_ != 0) histoDir_->cd();
00170     tH1D_->Write();
00171   }
00172   virtual void Clear() {
00173     tH1D_->Clear();
00174   }
00175   virtual void SetXTitle(const TString & title) {
00176     tH1D_->GetXaxis()->SetTitle(title);
00177   }
00178   virtual void SetYTitle(const TString & title) {
00179     tH1D_->GetYaxis()->SetTitle(title);
00180   }
00181   TH1D * operator->() { return tH1D_; }
00182 protected:
00183   TH1D * tH1D_;
00184 };
00185 
00187 class HTProfile : public Histograms
00188 {
00189 public:
00190   HTProfile( TFile * outputFile, const TString & name, const TString & title,
00191              const int xBins, const double & xMin, const double & xMax,
00192              const double & yMin, const double & yMax ) : Histograms(outputFile, name),
00193                                                           tProfile_( new TProfile(name+"Prof", title+" profile", xBins, xMin, xMax, yMin, yMax) ) {}
00194   ~HTProfile() {
00195     delete tProfile_;
00196   }
00197   virtual void Fill( const double & x, const double & y ) {
00198     tProfile_->Fill(x,y);
00199   }
00200   virtual void Write() {
00201     if(histoDir_ != 0) histoDir_->cd();
00202     tProfile_->Write();
00203   }
00204   virtual void Clear() {
00205     tProfile_->Clear();
00206   }
00207   virtual void SetXTitle(const TString & title) {
00208     tProfile_->GetXaxis()->SetTitle(title);
00209   }
00210   virtual void SetYTitle(const TString & title) {
00211     tProfile_->GetYaxis()->SetTitle(title);
00212   }
00213   TProfile * operator->() { return tProfile_; }
00214 protected:
00215   TProfile * tProfile_;
00216 };
00217 
00218 // -----------------------------------------------------
00219 // A set of histograms of particle kinematical variables
00220 // -----------------------------------------------------
00221 class HParticle : public Histograms {
00222  public:
00223   HParticle( const TString & name, const double & minMass = 0., const double & maxMass = 200., const double & maxPt = 100. ) :
00224     Histograms(name),
00225     // Kinematical variables
00226     hPt_(      new TH1F (name+"_Pt",      "transverse momentum", 100, 0, maxPt) ),
00227     hPtVsEta_( new TH2F (name+"_PtVsEta", "transverse momentum vs #eta", 100, 0, maxPt, 100, -3.0, 3.0) ),
00228     hEta_(     new TH1F (name+"_Eta",     "pseudorapidity", 60, -3.0, 3.0) ),
00229     hPhi_(     new TH1F (name+"_Phi",     "phi angle", 64, -3.2, 3.2) ),
00230     hMass_(    new TH1F (name+"_Mass",    "mass", 10000, minMass, maxMass) ),
00231     // hMass_fine_ = new TH1F (name+"_Mass_fine", "low mass fine binning", 4000, 0., 20. ); //Removed to avoid too many histos (more binning added to hMass)
00232     hNumber_( new TH1F (name+"_Number", "number", 20, -0.5, 19.5) )
00233   {}
00234 
00236   HParticle( TFile* outputFile, const TString & name, const double & minMass = 0., const double & maxMass = 200., const double & maxPt = 100. ) :
00237     Histograms(outputFile, name)
00238   {
00239     // Kinematical variables
00240     hPt_ =      new TH1F (name+"_Pt", "transverse momentum", 100, 0, maxPt);
00241     hPtVsEta_ = new TH2F (name+"_PtVsEta", "transverse momentum vs #eta", 100, 0, maxPt, 100, -3.0, 3.0);
00242     hEta_ =     new TH1F (name+"_Eta", "pseudorapidity", 60, -3.0, 3.0);
00243     hPhi_ =     new TH1F (name+"_Phi", "phi angle", 64, -3.2, 3.2);
00244     hMass_ =    new TH1F (name+"_Mass", "mass", 40000, minMass, maxMass);
00245     // hMass_fine_ = new TH1F (name+"_Mass_fine", "low mass fine binning", 4000, 0., 20. ); //Removed to avoid too many histos (more binning added to hMass)
00246     hNumber_ = new TH1F (name+"_Number", "number", 20, -0.5, 19.5);
00247   }
00248 
00249   HParticle( const TString & name, TFile* file ) :
00250     Histograms(name),
00251     hPt_(      (TH1F *) file->Get(name_+"_Pt") ),
00252     hPtVsEta_( (TH2F *) file->Get(name_+"_PtVsEta") ),
00253     hEta_(     (TH1F *) file->Get(name_+"_Eta") ),
00254     hPhi_(     (TH1F *) file->Get(name_+"_Phi") ),
00255     hMass_(    (TH1F *) file->Get(name_+"_Mass") ),
00256     //hMass_fine_ = (TH1F *) file->Get(name_+"_Mass_fine");
00257     hNumber_( (TH1F *) file->Get(name_+"_Number") )
00258   {}
00259 
00260   ~HParticle()
00261   {
00262     delete hPt_;
00263     delete hPtVsEta_;
00264     delete hEta_;
00265     delete hPhi_;
00266     delete hMass_;
00267     // delete hMass_fine_;
00268     delete hNumber_;
00269   }
00270 
00271   virtual void Fill( const reco::Particle::LorentzVector & p4, const double & weight = 1. )
00272   {
00273     Fill(CLHEP::HepLorentzVector(p4.x(),p4.y(),p4.z(),p4.t()), weight);
00274   }
00275 
00276   virtual void Fill( const CLHEP::HepLorentzVector & momentum, const double & weight = 1. )
00277   {
00278     hPt_->Fill(momentum.perp(), weight);
00279     hPtVsEta_->Fill(momentum.perp(), momentum.eta(), weight);
00280     hEta_->Fill(momentum.eta(), weight);
00281     hPhi_->Fill(momentum.phi(), weight);
00282     hMass_->Fill(momentum.m(), weight);
00283     //hMass_fine_->Fill(momentum.m(), weight);
00284   }
00285   
00286   virtual void Fill( unsigned int number )
00287   {
00288     hNumber_->Fill(number);
00289   }
00290 
00291   virtual void Write()
00292   {
00293     if(histoDir_ != 0) histoDir_->cd();
00294     hPt_->Write();
00295     hPtVsEta_->Write();
00296     hEta_->Write();    
00297     hPhi_->Write();
00298     hMass_->Write();
00299     //hMass_fine_->Write();
00300     hNumber_->Write();
00301   }
00302   
00303   virtual void Clear()
00304   {
00305     hPt_->Clear();
00306     hPtVsEta_->Clear();
00307     hEta_->Clear();    
00308     hPhi_->Clear();
00309     hMass_->Clear();
00310     //hMass_fine_->Clear();
00311     hNumber_->Clear();
00312   }
00313 
00314  protected:
00315   TH1F* hPt_;
00316   TH2F* hPtVsEta_;
00317   TH1F* hEta_;
00318   TH1F* hPhi_;
00319   TH1F* hMass_;
00320   //TH1F* hMass_fine_;
00321   TH1F* hNumber_;
00322 };
00323 
00324 // ---------------------------------------------------
00325 // A set of histograms for distances between particles
00326 // ---------------------------------------------------
00327 class HDelta : public Histograms
00328 {
00329  public:
00330   HDelta (const TString & name) :
00331     Histograms(name),
00332     // Kinematical variables
00333     // ---------------------
00334     hEta_( new TH1F (name+"_DeltaEta", "#Delta#eta", 100, 0, 6) ),
00335     hEtaSign_( new TH1F (name+"_DeltaEtaSign", "#Delta#eta with sign", 100, -6, 6) ),
00336     hPhi_( new TH1F (name+"_DeltaPhi", "#Delta#phi", 100,0,3.2) ),
00337     hTheta_( new TH1F (name+"_DeltaTheta", "#Delta#theta", 100,-3.2,3.2) ),
00338     hCotgTheta_( new TH1F (name+"_DeltaCotgTheta", "#Delta Cotg(#theta )", 100,-3.2,3.2) ),
00339     hDeltaR_( new TH1F (name+"_DeltaR","#Delta R", 400, 0, 4 ) )
00340   {}
00341 
00342   HDelta (TFile* outputFile, const TString & name) :
00343     Histograms(outputFile, name),
00344     // Kinematical variables
00345     // ---------------------
00346     hEta_( new TH1F (name+"_DeltaEta", "#Delta#eta", 100, 0, 6) ),
00347     hEtaSign_( new TH1F (name+"_DeltaEtaSign", "#Delta#eta with sign", 100, -6, 6) ),
00348     hPhi_( new TH1F (name+"_DeltaPhi", "#Delta#phi", 100,0,3.2) ),
00349     hTheta_( new TH1F (name+"_DeltaTheta", "#Delta#theta", 100,-3.2,3.2) ),
00350     hCotgTheta_( new TH1F (name+"_DeltaCotgTheta", "#Delta Cotg(#theta )", 100,-3.2,3.2) ),
00351     hDeltaR_( new TH1F (name+"_DeltaR","#DeltaR", 400, 0, 4 ) )
00352   {}
00353 
00354   HDelta (const TString & name, TFile* file) {
00355     name_ = name;
00356     hEta_       = (TH1F *) file->Get(name+"_DeltaEta");
00357     hEtaSign_   = (TH1F *) file->Get(name+"_DeltaEtaSign");
00358     hPhi_       = (TH1F *) file->Get(name+"_DeltaPhi");
00359     hTheta_     = (TH1F *) file->Get(name+"_DeltaTheta");
00360     hCotgTheta_ = (TH1F *) file->Get(name+"_DeltaCotgTheta");
00361     hDeltaR_    = (TH1F *) file->Get(name+"_DeltaR");
00362    }
00363 
00364   ~HDelta() {
00365     delete hEta_;
00366     delete hEtaSign_;
00367     delete hPhi_;
00368     delete hTheta_;
00369     delete hCotgTheta_;
00370     delete hDeltaR_;
00371   }
00372   
00373   virtual void Fill (const reco::Particle::LorentzVector & p1, const reco::Particle::LorentzVector & p2) {
00374     Fill (CLHEP::HepLorentzVector(p1.x(),p1.y(),p1.z(),p1.t()), 
00375           CLHEP::HepLorentzVector(p2.x(),p2.y(),p2.z(),p2.t()));
00376   }
00377 
00378   virtual void Fill (const CLHEP::HepLorentzVector & p1, const reco::Particle::LorentzVector & p2) {
00379     Fill (p1,CLHEP::HepLorentzVector(p2.x(),p2.y(),p2.z(),p2.t()));
00380   }
00381 
00382   virtual void Fill (const CLHEP::HepLorentzVector & momentum1, const CLHEP::HepLorentzVector & momentum2) {
00383     hEta_->Fill(fabs( momentum1.eta()-momentum2.eta() ));
00384     hEtaSign_->Fill(momentum1.eta()-momentum2.eta());
00385     hPhi_->Fill(MuScleFitUtils::deltaPhi(momentum1.phi(),momentum2.phi()));
00386     hTheta_->Fill(momentum1.theta()-momentum2.theta());
00387     // hCotgTheta->Fill(1/(TMath::Tan(momentum1.theta()))-1/(TMath::Tan(momentum2.theta())));
00388     double theta1 = momentum1.theta();
00389     double theta2 = momentum2.theta();
00390     hCotgTheta_->Fill(TMath::Cos(theta1)/TMath::Sin(theta1) - TMath::Cos(theta2)/TMath::Sin(theta2));
00391     hDeltaR_->Fill(sqrt((momentum1.eta()-momentum2.eta())*(momentum1.eta()-momentum2.eta()) +
00392                         (MuScleFitUtils::deltaPhi(momentum1.phi(),momentum2.phi()))*
00393                         (MuScleFitUtils::deltaPhi(momentum1.phi(),momentum2.phi()))));
00394   }
00395   
00396   virtual void Write() {
00397     if(histoDir_ != 0) histoDir_->cd();
00398 
00399     hEta_->Write();
00400     hEtaSign_->Write();
00401     hPhi_->Write();
00402     hTheta_->Write();
00403     hCotgTheta_->Write();
00404     hDeltaR_->Write();
00405   }
00406   
00407   virtual void Clear() {
00408     hEta_->Clear();
00409     hEtaSign_->Clear();
00410     hPhi_->Clear();
00411     hTheta_->Clear();
00412     hDeltaR_->Clear();
00413     hCotgTheta_->Clear();
00414   }
00415   
00416  public:
00417   TH1F* hEta_;
00418   TH1F* hEtaSign_;
00419   TH1F* hPhi_;
00420   TH1F* hTheta_;
00421   TH1F* hCotgTheta_;
00422   TH1F* hDeltaR_;
00423 };
00424 
00425 // ------------------------------------------------------------
00426 // A set of histograms of particle kinematical variables vs eta
00427 // ------------------------------------------------------------
00428 class HPartVSEta : public Histograms
00429 {
00430  public:
00431   HPartVSEta(const TString & name, const double & minMass = 0., const double & maxMass = 100., const double & maxPt = 100.)
00432   {
00433     name_ = name;
00434     hPtVSEta_ = new TH2F( name+"_PtVSEta", "transverse momentum vs pseudorapidity", 
00435                           64, -3.0, 3.0, 200, 0, maxPt );
00436     hMassVSEta_ = new TH2F( name+"_MassVSEta", "mass vs pseudorapidity", 
00437                             64, -3.0, 3.0, 40, minMass, maxMass );
00438     // TD profile histograms
00439     // ---------------------
00440     hPtVSEta_prof_ = new TProfile( name+"_PtVSEta_prof", "mass vs pseudorapidity", 
00441                                    12, -3, 3, 0, maxPt );
00442     hMassVSEta_prof_ = new TProfile( name+"_MassVSEta_prof", "mass vs pseudorapidity", 
00443                                      12, -3, 3, minMass, maxMass );
00444   }
00445 
00446   ~HPartVSEta() {
00447     delete hPtVSEta_;
00448     delete hMassVSEta_;
00449     delete hPtVSEta_prof_;
00450     delete hMassVSEta_prof_;
00451   }
00452 
00453   virtual void Fill (const reco::Particle::LorentzVector & p4, const double & weight = 1.) {
00454     Fill (CLHEP::HepLorentzVector(p4.x(),p4.y(),p4.z(),p4.t()), weight);
00455   }
00456 
00457   virtual void Fill (const CLHEP::HepLorentzVector & momentum, const double & weight = 1.) {
00458     hPtVSEta_->Fill(momentum.eta(),momentum.perp(), weight);
00459     hPtVSEta_prof_->Fill(momentum.eta(),momentum.perp(), weight);
00460 
00461     hMassVSEta_->Fill(momentum.eta(),momentum.m(), weight);
00462     hMassVSEta_prof_->Fill(momentum.eta(),momentum.m(), weight);
00463   }
00464     
00465   virtual void Write() {
00466     hPtVSEta_->Write();
00467     hPtVSEta_prof_->Write();
00468     hMassVSEta_->Write();
00469     hMassVSEta_prof_->Write();
00470 
00471     //     std::vector<TGraphErrors*> graphs( (MuScleFitUtils::fitMass(hMassVSEta_)) );
00472     //     for (std::vector<TGraphErrors*>::const_iterator graph = graphs.begin(); graph != graphs.end(); graph++) {
00473     //       (*graph)->Write();
00474     //     }
00475   }
00476 
00477   virtual void Clear() {
00478     hPtVSEta_->Clear();
00479     hPtVSEta_prof_->Clear();
00480     hMassVSEta_->Clear();
00481     hMassVSEta_prof_->Clear();
00482   }
00483 
00484  public:
00485 
00486   TH2F *hPtVSEta_;
00487   TH2F *hMassVSEta_; 
00488   TProfile *hMassVSEta_prof_; 
00489   TProfile *hPtVSEta_prof_;  
00490 };
00491 
00492 //---------------------------------------------------------------------------
00493 // A set of histograms of particle kinematical variables vs phi (in eta bins)
00494 // --------------------------------------------------------------------------
00495 class HPartVSPhi : public Histograms
00496 {
00497  public:
00498   HPartVSPhi(const TString & name){
00499     name_ = name;
00500     hPtVSPhi_ = new TH2F (name+"_PtVSPhi", "transverse momentum vs phi angle",
00501                           12, -3.2, 3.2, 200, 0, 200);
00502     hMassVSPhi_ = new TH2F (name+"_MassVSPhi", "mass vs phi angle", 
00503                             7, -3.2, 3.2, 40, 70, 110);
00504     hMassVSPhiF_ = new TH2F (name+"_MassVSPhiF", "mass vs phi F", 
00505                              7, -3.2, 3.2, 40, 70, 110);
00506     hMassVSPhiWp2_ = new TH2F (name+"_MassVSPhiWp2", "mass vs phi Wp2", 
00507                                7, -3.2, 3.2, 40, 70, 110);
00508     hMassVSPhiWp1_ = new TH2F (name+"_MassVSPhiWp1", "mass vs phi Wp1", 
00509                                7, -3.2, 3.2, 40, 70, 110);
00510     hMassVSPhiW0_ = new TH2F (name+"_MassVSPhiW0", "mass vs phi W0", 
00511                               7, -3.2, 3.2, 40, 70, 110);
00512     hMassVSPhiWm1_ = new TH2F (name+"_MassVSPhiWm1", "mass vs phi Wm1", 
00513                                7, -3.2, 3.2, 40, 70, 110);
00514     hMassVSPhiWm2_ = new TH2F (name+"_MassVSPhiWm2", "mass vs phi Wm2", 
00515                                7, -3.2, 3.2, 40, 70, 110);
00516     hMassVSPhiB_ = new TH2F (name+"_MassVSPhiB", "mass vs phi B", 
00517                              7, -3.2, 3.2, 40, 70, 110);  
00518 
00519     // TD profile histograms
00520     hMassVSPhi_prof_ = new TProfile (name+"_MassVSPhi_prof", "mass vs phi angle", 
00521                                      12, -3.2, 3.2, 70, 110);
00522     hPtVSPhi_prof_ = new TProfile (name+"_PtVSPhi_prof", "pt vs phi angle", 
00523                                    12, -3.2, 3.2, 0, 200);
00524   }
00525 
00526   ~HPartVSPhi() {
00527     delete hPtVSPhi_;
00528     delete hMassVSPhi_;
00529     delete hMassVSPhi_prof_;
00530     delete hPtVSPhi_prof_;
00531 
00532     delete hMassVSPhiB_;
00533     delete hMassVSPhiWm2_;
00534     delete hMassVSPhiWm1_;
00535     delete hMassVSPhiW0_;
00536     delete hMassVSPhiWp1_;
00537     delete hMassVSPhiWp2_;
00538     delete hMassVSPhiF_;
00539   }
00540 
00541   void Fill(const reco::Particle::LorentzVector & p4, const double & weight = 1.) {
00542     Fill(CLHEP::HepLorentzVector(p4.x(),p4.y(),p4.z(),p4.t()), weight);
00543   }
00544 
00545   void Fill(const CLHEP::HepLorentzVector & momentum, const double & weight = 1.) {
00546     hPtVSPhi_->Fill(momentum.phi(),momentum.perp(), weight);
00547     hMassVSPhi_->Fill(momentum.phi(),momentum.m(), weight);
00548     hMassVSPhi_prof_->Fill(momentum.phi(),momentum.m(), weight);
00549     hPtVSPhi_prof_->Fill(momentum.phi(),momentum.perp(), weight);
00550  
00551     if (momentum.eta()<-1.2)                             hMassVSPhiB_->Fill(momentum.phi(),momentum.m(), weight);
00552     else if (momentum.eta()<-0.8 && momentum.eta()>-1.2) hMassVSPhiWm2_->Fill(momentum.phi(),momentum.m(), weight);
00553     else if (momentum.eta()<-0.3 && momentum.eta()>-0.8) hMassVSPhiWm1_->Fill(momentum.phi(),momentum.m(), weight);
00554     else if ((fabs(momentum.eta())) < 0.3)               hMassVSPhiW0_->Fill(momentum.phi(),momentum.m(), weight);
00555     else if (momentum.eta()>0.3 && momentum.eta()<0.8)   hMassVSPhiWp1_->Fill(momentum.phi(),momentum.m(), weight);
00556     else if (momentum.eta()>0.8 && momentum.eta()<1.2)   hMassVSPhiWp2_->Fill(momentum.phi(),momentum.m(), weight);
00557     else if (momentum.eta()>1.2)                         hMassVSPhiF_->Fill(momentum.phi(),momentum.m(), weight);
00558   }
00559 
00560   virtual void Write() {
00561     hPtVSPhi_->Write();
00562     hMassVSPhi_->Write();
00563     hMassVSPhi_prof_->Write();
00564     hPtVSPhi_prof_->Write();
00565 
00566     hMassVSPhiB_->Write();
00567     hMassVSPhiWm2_->Write(); 
00568     hMassVSPhiWm1_->Write();
00569     hMassVSPhiW0_->Write();
00570     hMassVSPhiWp1_->Write();
00571     hMassVSPhiWp2_->Write();
00572     hMassVSPhiF_->Write();
00573 
00574 //     std::vector<TGraphErrors*> graphs ((MuScleFitUtils::fitMass(hMassVSPhi_)));
00575 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphs.begin(); graph != graphs.end(); graph++){
00576 //       (*graph)->Write();
00577 //     }
00578 //     std::vector<TGraphErrors*> graphsB ((MuScleFitUtils::fitMass(hMassVSPhiB_)));
00579 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsB.begin(); graph != graphsB.end(); graph++){
00580 //       (*graph)->Write();
00581 //     }
00582 //     std::vector<TGraphErrors*> graphsWm2 ((MuScleFitUtils::fitMass(hMassVSPhiWm2_)));
00583 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsWm2.begin(); graph != graphsWm2.end(); graph++){
00584 //       (*graph)->Write();
00585 //     }
00586 //     std::vector<TGraphErrors*> graphsWm1 ((MuScleFitUtils::fitMass(hMassVSPhiWm1_)));
00587 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsWm1.begin(); graph != graphsWm1.end(); graph++){
00588 //       (*graph)->Write();
00589 //     }
00590 //     std::vector<TGraphErrors*> graphsW0 ((MuScleFitUtils::fitMass(hMassVSPhiW0_)));
00591 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsW0.begin(); graph != graphsW0.end(); graph++){
00592 //       (*graph)->Write();
00593 //     }
00594 //     std::vector<TGraphErrors*> graphsWp1 ((MuScleFitUtils::fitMass(hMassVSPhiWp1_)));
00595 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsWp1.begin(); graph != graphsWp1.end(); graph++){
00596 //       (*graph)->Write();
00597 //     }
00598 //     std::vector<TGraphErrors*> graphsWp2 ((MuScleFitUtils::fitMass(hMassVSPhiWp2_)));
00599 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsWp2.begin(); graph != graphsWp2.end(); graph++){
00600 //       (*graph)->Write();
00601 //     }
00602 //     std::vector<TGraphErrors*> graphsF ((MuScleFitUtils::fitMass(hMassVSPhiF_)));
00603 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphsF.begin(); graph != graphsF.end(); graph++){
00604 //       (*graph)->Write();
00605 //     }
00606   }
00607 
00608   virtual void Clear() {
00609     hPtVSPhi_->Clear();
00610     hMassVSPhi_->Clear();
00611     hPtVSPhi_prof_->Clear();
00612     hMassVSPhi_prof_->Clear();
00613 
00614     hMassVSPhiB_->Clear();
00615     hMassVSPhiWm2_->Clear(); 
00616     hMassVSPhiWm1_->Clear();
00617     hMassVSPhiW0_->Clear();
00618     hMassVSPhiWp1_->Clear();
00619     hMassVSPhiWp2_->Clear();
00620     hMassVSPhiF_->Clear();
00621   }
00622   
00623  public:
00624   TH2F *hPtVSPhi_;
00625   TH2F *hMassVSPhi_;
00626   TProfile *hMassVSPhi_prof_;
00627   TProfile *hPtVSPhi_prof_;
00628 
00629   TH2F *hMassVSPhiB_;
00630   TH2F *hMassVSPhiWm2_;
00631   TH2F *hMassVSPhiWm1_;
00632   TH2F *hMassVSPhiW0_;
00633   TH2F *hMassVSPhiWp1_;
00634   TH2F *hMassVSPhiWp2_;
00635   TH2F *hMassVSPhiF_;
00636 };
00637 
00638 //---------------------------------------------------------------------------------------
00639 // A set of histograms of particle VS pt
00640 class HPartVSPt : public Histograms
00641 {
00642  public:
00643   HPartVSPt(const TString & name){
00644     name_ = name;
00645     hMassVSPt_ = new TH2F( name+"_MassVSPt", "mass vs transverse momentum", 
00646                            12, -6, 6, 40, 70, 110 );
00647     // TD profile histograms
00648     hMassVSPt_prof_ = new TProfile( name+"_MassVSPt_prof", "mass vs transverse momentum", 
00649                                     12, -3, 3, 86, 116 );
00650   }
00651 
00652   ~HPartVSPt(){
00653     delete hMassVSPt_;
00654     delete hMassVSPt_prof_;
00655   }
00656 
00657   virtual void Fill(const reco::Particle::LorentzVector & p4, const double & weight = 1.) {
00658     Fill(CLHEP::HepLorentzVector(p4.x(),p4.y(),p4.z(),p4.t()), weight);
00659   }
00660 
00661   virtual void Fill(const CLHEP::HepLorentzVector & momentum, const double & weight = 1.) {
00662     hMassVSPt_->Fill(momentum.eta(),momentum.m(), weight);
00663     hMassVSPt_prof_->Fill(momentum.eta(),momentum.m(), weight);    
00664   }
00665     
00666   virtual void Write() {
00667     hMassVSPt_->Write();
00668     hMassVSPt_prof_->Write();
00669    
00670 //     std::vector<TGraphErrors*> graphs( (MuScleFitUtils::fitMass(hMassVSPt_)) );
00671 //     for(std::vector<TGraphErrors*>::const_iterator graph = graphs.begin(); graph != graphs.end(); graph++){
00672 //       (*graph)->Write();
00673 //     }
00674   }
00675   
00676   virtual void Clear() {
00677     hMassVSPt_->Clear();
00678     hMassVSPt_prof_->Clear();
00679   }
00680 
00681  public:
00682   TH2F *hMassVSPt_;
00683   TProfile *hMassVSPt_prof_;
00684 };
00685 
00686 // ---------------------------------------------------
00687 // A set of histograms of Z mass versus muon variables
00688 class HMassVSPart : public Histograms
00689 {
00690  public:
00691   HMassVSPart( const TString & name, const double & minMass = 0., const double & maxMass = 150., const double maxPt = 100. ) {
00692     name_ = name;
00693 
00694     // Kinematical variables
00695     // ---------------------
00696     hMassVSPt_       = new TH2F( name+"_MassVSPt", "resonance mass vs muon transverse momentum", 200, 0., maxPt, 6000, minMass, maxMass );
00697     hMassVSEta_      = new TH2F( name+"_MassVSEta", "resonance mass vs muon pseudorapidity", 60, -6., 6., 6000, minMass, maxMass );
00698     hMassVSPhiPlus_  = new TH2F( name+"_MassVSPhiPlus", "resonance mass vs muon+ phi angle", 64, -3.2, 3.2, 6000, minMass, maxMass );
00699     hMassVSPhiMinus_ = new TH2F( name+"_MassVSPhiMinus", "resonance mass vs muon- phi angle", 64, -3.2, 3.2, 6000, minMass, maxMass );
00700     //hMassVSPt_prof       = new TProfile (name+"_MassVSPt_prof", "resonance mass vs muon transverse momentum", 100, 0., 200., minMass, maxMass);
00701     //hMassVSEta_prof      = new TProfile (name+"_MassVSEta_prof", "resonance mass vs muon pseudorapidity", 30, -6., 6., minMass, maxMass);
00702     //hMassVSPhiPlus_prof  = new TProfile (name+"_MassVSPhiPlus_prof", "resonance mass vs muon+ phi angle", 32, -3.2, 3.2, minMass, maxMass);
00703     //hMassVSPhiMinus_prof = new TProfile (name+"_MassVSPhiMinus_prof", "resonance mass vs muon- phi angle", 32, -3.2, 3.2, minMass, maxMass);
00704    }
00705 
00706   HMassVSPart(const TString & name, TFile* file){
00707     name_=name;
00708     hMassVSPt_       = (TH2F *) file->Get(name+"_MassVSPt");
00709     hMassVSEta_      = (TH2F *) file->Get(name+"_MassVSEta");
00710     hMassVSPhiPlus_  = (TH2F *) file->Get(name+"_MassVSPhiPlus");
00711     hMassVSPhiMinus_ = (TH2F *) file->Get(name+"_MassVSPhiMinus");
00712     //hMassVSPt_prof       = (TProfile *) file->Get(name+"_MassVSPt_prof");
00713     //hMassVSEta_prof      = (TProfile *) file->Get(name+"_MassVSEta_prof");
00714     //hMassVSPhiPlus_prof  = (TProfile *) file->Get(name+"_MassVSPhiPlus_prof");
00715     //hMassVSPhiMinus_prof = (TProfile *) file->Get(name+"_MassVSPhiMinus_prof");
00716   }
00717 
00718   ~HMassVSPart(){
00719     delete hMassVSPt_;
00720     delete hMassVSEta_;
00721     delete hMassVSPhiPlus_;
00722     delete hMassVSPhiMinus_;
00723   }
00724 
00725   virtual void Fill(const reco::Particle::LorentzVector & p41, const reco::Particle::LorentzVector & p42, const int charge, const double & weight = 1.) {
00726     Fill(CLHEP::HepLorentzVector(p41.x(),p41.y(),p41.z(),p41.t()),
00727          CLHEP::HepLorentzVector(p42.x(),p42.y(),p42.z(),p42.t()), charge, weight);
00728   }
00729   
00730   virtual void Fill(const CLHEP::HepLorentzVector & momentum1, const CLHEP::HepLorentzVector & momentum2, const int charge, const double & weight = 1.) { 
00731      hMassVSPt_->Fill(momentum1.perp(),momentum2.m(), weight); 
00732      //hMassVSPt_prof_->Fill(momentum1.perp(),momentum2.m()); 
00733      hMassVSEta_->Fill(momentum1.eta(),momentum2.m(), weight); 
00734      //hMassVSEta_prof_->Fill(momentum1.eta(),momentum2.m()); 
00735      if(charge>0){
00736        hMassVSPhiPlus_->Fill(momentum1.phi(),momentum2.m(), weight);
00737        //hMassVSPhiPlus_prof_->Fill(momentum1.phi(),momentum2.m());
00738      }
00739      else if(charge<0){
00740        hMassVSPhiMinus_->Fill(momentum1.phi(),momentum2.m(), weight);
00741        //hMassVSPhiMinus_prof_->Fill(momentum1.phi(),momentum2.m());
00742      }
00743      else {
00744        LogDebug("Histograms") << "HMassVSPart: wrong charge value = " << charge << std::endl;
00745        abort();
00746      }
00747    }
00748 
00749   virtual void Write() {
00750     hMassVSPt_->Write();
00751     hMassVSEta_->Write();
00752     hMassVSPhiPlus_->Write();
00753     hMassVSPhiMinus_->Write();
00754     //hMassVSPt_prof_->Write();
00755     //hMassVSEta_prof_->Write();    
00756     //hMassVSPhiPlus_prof_->Write();
00757     //hMassVSPhiMinus_prof_->Write();
00758   }
00759 
00760   virtual void Clear() {
00761     hMassVSPt_->Clear();
00762     hMassVSEta_->Clear();    
00763     hMassVSPhiPlus_->Clear();
00764     hMassVSPhiMinus_->Clear();
00765     //hMassVSPt_prof_->Clear();
00766     //hMassVSEta_prof_->Clear();    
00767     //hMassVSPhiPlus_prof_->Clear();
00768     //hMassVSPhiMinus_prof_->Clear();
00769   }
00770 
00771  protected:
00772   TH2F* hMassVSPt_;
00773   TH2F* hMassVSEta_;
00774   TH2F* hMassVSPhiPlus_; 
00775   TH2F* hMassVSPhiMinus_; 
00776   //TProfile* hMassVSPt_prof_;
00777   //TProfile* hMassVSEta_prof_;
00778   //TProfile* hMassVSPhiPlus_prof_;
00779   //TProfile* hMassVSPhiMinus_prof_;
00780 };
00781 
00782 
00783 // ---------------------------------------------------
00784 // A set of histograms of Z mass versus muon variables
00785 class HMassVSPartProfile : public Histograms
00786 {
00787  public:
00788   HMassVSPartProfile( const TString & name, const double & minMass = 0., const double & maxMass = 150., const double maxPt = 100. ) {
00789     name_ = name;
00790 
00791     // Kinematical variables
00792     // ---------------------
00793     hMassVSPt_       = new TProfile2D( name+"_MassVSPt", "resonance mass vs muon transverse momentum", 200, 0., maxPt, 6000, minMass, maxMass, 0., 100. );
00794     hMassVSEta_      = new TProfile2D( name+"_MassVSEta", "resonance mass vs muon pseudorapidity", 60, -6., 6., 6000, minMass, maxMass, 0., 100. );
00795     hMassVSPhiPlus_  = new TProfile2D( name+"_MassVSPhiPlus", "resonance mass vs muon+ phi angle", 64, -3.2, 3.2, 6000, minMass, maxMass, 0., 100. );
00796     hMassVSPhiMinus_ = new TProfile2D( name+"_MassVSPhiMinus", "resonance mass vs muon- phi angle", 64, -3.2, 3.2, 6000, minMass, maxMass, 0., 100. );
00797    }
00798 
00799   HMassVSPartProfile(const TString & name, TFile* file){
00800     name_=name;
00801     hMassVSPt_       = (TProfile2D *) file->Get(name+"_MassVSPt");
00802     hMassVSEta_      = (TProfile2D *) file->Get(name+"_MassVSEta");
00803     hMassVSPhiPlus_  = (TProfile2D *) file->Get(name+"_MassVSPhiPlus");
00804     hMassVSPhiMinus_ = (TProfile2D *) file->Get(name+"_MassVSPhiMinus");
00805   }
00806 
00807   ~HMassVSPartProfile(){
00808     delete hMassVSPt_;
00809     delete hMassVSEta_;
00810     delete hMassVSPhiPlus_;
00811     delete hMassVSPhiMinus_;
00812   }
00813 
00814   virtual void Fill(const reco::Particle::LorentzVector & p41, const reco::Particle::LorentzVector & p42, const int charge, const double & weight = 1.) {
00815     Fill(CLHEP::HepLorentzVector(p41.x(),p41.y(),p41.z(),p41.t()),
00816          CLHEP::HepLorentzVector(p42.x(),p42.y(),p42.z(),p42.t()), charge, weight);
00817   }
00818   
00819   virtual void Fill(const CLHEP::HepLorentzVector & momentum1, const CLHEP::HepLorentzVector & momentum2, const int charge, const double & weight = 1.) { 
00820     hMassVSPt_->Fill(momentum1.perp(),momentum2.m(), weight); 
00821     hMassVSEta_->Fill(momentum1.eta(),momentum2.m(), weight); 
00822     if(charge>0){
00823       hMassVSPhiPlus_->Fill(momentum1.phi(), momentum2.m(), weight);
00824     }
00825     else if(charge<0){
00826       hMassVSPhiMinus_->Fill(momentum1.phi(), momentum2.m(), weight);
00827     }
00828     else {
00829       LogDebug("Histograms") << "HMassVSPartProfile: wrong charge value = " << charge << std::endl;
00830       abort();
00831     }
00832   }
00833 
00834   virtual void Write() {
00835     hMassVSPt_->Write();
00836     hMassVSEta_->Write();
00837     hMassVSPhiPlus_->Write();
00838     hMassVSPhiMinus_->Write();
00839   }
00840 
00841   virtual void Clear() {
00842     hMassVSPt_->Clear();
00843     hMassVSEta_->Clear();    
00844     hMassVSPhiPlus_->Clear();
00845     hMassVSPhiMinus_->Clear();
00846   }
00847 
00848  protected:
00849   TProfile2D* hMassVSPt_;
00850   TProfile2D* hMassVSEta_;
00851   TProfile2D* hMassVSPhiPlus_; 
00852   TProfile2D* hMassVSPhiMinus_; 
00853 };
00854 
00855 //---------------------------------------------------------------------------------------
00857 class HResolutionVSPart : public Histograms
00858 {
00859  public:
00860   HResolutionVSPart(TFile * outputFile, const TString & name, const double maxPt = 100,
00861                     const double & yMinEta = 0., const double & yMaxEta = 2.,
00862                     const double & yMinPt = 0., const double & yMaxPt = 2.,
00863                     const bool doProfiles = false) : Histograms(outputFile, name), doProfiles_(doProfiles)
00864   {
00865     // Kinematical variables
00866 
00867     // hReso           = new TH1F (name+"_Reso", "resolution", 4000, -1, 1);
00868     // hResoVSPtEta    = new TH2F (name+"_ResoVSPtEta", "resolution VS pt and #eta", 200, 0, 200, 60, -3, 3);
00869     // hResoVSPt       = new TH2F (name+"_ResoVSPt", "resolution VS pt", 200, 0, 200, 8000, -1, 1);
00870     // //hResoVSPt_prof  = new TProfile (name+"_ResoVSPt_prof", "resolution VS pt", 100, 0, 200, -1, 1);
00871     // hResoVSEta      = new TH2F (name+"_ResoVSEta", "resolution VS eta", 60, -3, 3, 8000, yMinEta, yMaxEta);
00872     // hResoVSTheta    = new TH2F (name+"_ResoVSTheta", "resolution VS theta", 30, 0, TMath::Pi(), 8000, -1, 1);
00873     // //hResoVSEta_prof = new TProfile (name+"_ResoVSEta_prof", "resolution VS eta", 10, -2.5, 2.5, -1, 1);
00874     // hResoVSPhiPlus  = new TH2F (name+"_ResoVSPhiPlus", "resolution VS phi mu+", 14, -3.2, 3.2, 8000, -1, 1);
00875     // hResoVSPhiMinus = new TH2F (name+"_ResoVSPhiMinus", "resolution VS phi mu-", 14, -3.2, 3.2, 8000, -1, 1);
00876     // //hResoVSPhi_prof = new TProfile (name+"_ResoVSPhi_prof", "resolution VS phi", 14, -3.2, 3.2, -1, 1);
00877     // hAbsReso        = new TH1F (name+"_AbsReso", "resolution", 100, 0, 1);
00878     // hAbsResoVSPt    = new TH2F (name+"_AbsResoVSPt", "Abs resolution VS pt", 200, 0, 500, 100, 0, 1);
00879     // hAbsResoVSEta   = new TH2F (name+"_AbsResoVSEta", "Abs resolution VS eta", 60, -3, 3, 100, 0, 1);
00880     // hAbsResoVSPhi   = new TH2F (name+"_AbsResoVSPhi", "Abs resolution VS phi", 14, -3.2, 3.2, 100, 0, 1);
00881 
00882     hReso_           = new TH1F( name+"_Reso", "resolution", 200, -1, 1 );
00883     hResoVSPtEta_    = new TH2F( name+"_ResoVSPtEta", "resolution VS pt and #eta", 200, 0, maxPt, 60, -3, 3 );
00884     hResoVSPt_       = new TH2F( name+"_ResoVSPt", "resolution VS pt", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00885     hResoVSPt_Bar_   = new TH2F( name+"_ResoVSPt_Bar", "resolution VS pt Barrel", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00886     hResoVSPt_Endc_17_  = new TH2F( name+"_ResoVSPt_Endc_1.7", "resolution VS pt Endcap (1.4<eta<1.7)", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00887     hResoVSPt_Endc_20_  = new TH2F( name+"_ResoVSPt_Endc_2.0", "resolution VS pt Endcap (1.7<eta<2.0)", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00888     hResoVSPt_Endc_24_  = new TH2F( name+"_ResoVSPt_Endc_2.4", "resolution VS pt Endcap (2.0<eta<2.4)", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00889     hResoVSPt_Ovlap_ = new TH2F( name+"_ResoVSPt_Ovlap", "resolution VS pt overlap", 200, 0, maxPt, 200, yMinPt, yMaxPt );
00890     hResoVSEta_      = new TH2F( name+"_ResoVSEta", "resolution VS eta", 200, -3, 3, 200, yMinEta, yMaxEta );
00891     hResoVSTheta_    = new TH2F( name+"_ResoVSTheta", "resolution VS theta", 30, 0, TMath::Pi(), 200, yMinEta, yMaxEta );
00892     hResoVSPhiPlus_  = new TH2F( name+"_ResoVSPhiPlus", "resolution VS phi mu+", 14, -3.2, 3.2, 200, -1, 1 );
00893     hResoVSPhiMinus_ = new TH2F( name+"_ResoVSPhiMinus", "resolution VS phi mu-", 14, -3.2, 3.2, 200, -1, 1 );
00894     hAbsReso_        = new TH1F( name+"_AbsReso", "resolution", 100, 0, 1 );
00895     hAbsResoVSPt_    = new TH2F( name+"_AbsResoVSPt", "Abs resolution VS pt", 200, 0, maxPt, 100, 0, 1 );
00896     hAbsResoVSEta_   = new TH2F( name+"_AbsResoVSEta", "Abs resolution VS eta", 60, -3, 3, 100, 0, 1 );
00897     hAbsResoVSPhi_   = new TH2F( name+"_AbsResoVSPhi", "Abs resolution VS phi", 14, -3.2, 3.2, 100, 0, 1 );
00898     if( doProfiles_ ) {
00899       hResoVSPt_prof_    = new TProfile(name+"_ResoVSPt_prof", "resolution VS pt", 100, 0, maxPt, yMinPt, yMaxPt );
00900       hResoVSPt_Bar_prof_    = new TProfile(name+"_ResoVSPt_Bar_prof", "resolution VS pt Barrel", 100, 0, maxPt, yMinPt, yMaxPt );
00901       hResoVSPt_Endc_17_prof_   = new TProfile(name+"_ResoVSPt_Endc_1.7_prof", "resolution VS pt Endcap (1.4<eta<1.7)", 100, 0, maxPt, yMinPt, yMaxPt );
00902       hResoVSPt_Endc_20_prof_   = new TProfile(name+"_ResoVSPt_Endc_2.0_prof", "resolution VS pt Endcap (1.7<eta<2.0)", 100, 0, maxPt, yMinPt, yMaxPt );
00903       hResoVSPt_Endc_24_prof_   = new TProfile(name+"_ResoVSPt_Endc_2.4_prof", "resolution VS pt Endcap (2.0<eta<2.4)", 100, 0, maxPt, yMinPt, yMaxPt );
00904       hResoVSPt_Ovlap_prof_  = new TProfile(name+"_ResoVSPt_Ovlap_prof", "resolution VS pt Overlap", 100, 0, maxPt, yMinPt, yMaxPt );
00905       hResoVSEta_prof_       = new TProfile(name+"_ResoVSEta_prof", "resolution VS eta", 100, -3.0, 3.0, yMinEta, yMaxEta );
00906       hResoVSPhi_prof_       = new TProfile(name+"_ResoVSPhi_prof", "resolution VS phi", 14, -3.2, 3.2, -1, 1 );
00907     }
00908   }
00909   
00910   HResolutionVSPart(const TString & name, TFile* file) {
00911     name_=name;
00912     hReso_           = (TH1F *) file->Get(name+"_Reso");
00913     hResoVSPtEta_    = (TH2F *) file->Get(name+"_ResoVSPtEta");
00914     hResoVSPt_       = (TH2F *) file->Get(name+"_ResoVSPt");
00915     hResoVSPt_Bar_   = (TH2F *) file->Get(name+"_ResoVSPt");
00916     hResoVSPt_Endc_17_  = (TH2F *) file->Get(name+"_ResoVSPt");
00917     hResoVSPt_Endc_20_  = (TH2F *) file->Get(name+"_ResoVSPt");
00918     hResoVSPt_Endc_24_  = (TH2F *) file->Get(name+"_ResoVSPt");
00919     hResoVSPt_Ovlap_ = (TH2F *) file->Get(name+"_ResoVSPt");
00920     hResoVSEta_      = (TH2F *) file->Get(name+"_ResoVSEta");
00921     hResoVSTheta_    = (TH2F *) file->Get(name+"_ResoVSTheta");
00922     hResoVSPhiPlus_  = (TH2F *) file->Get(name+"_ResoVSPhiPlus");
00923     hResoVSPhiMinus_ = (TH2F *) file->Get(name+"_ResoVSPhiMinus");
00924     hAbsReso_        = (TH1F *) file->Get(name+"_AbsReso");
00925     hAbsResoVSPt_    = (TH2F *) file->Get(name+"_AbsResoVSPt");
00926     hAbsResoVSEta_   = (TH2F *) file->Get(name+"_AbsResoVSEta");
00927     hAbsResoVSPhi_   = (TH2F *) file->Get(name+"_AbsResoVSPhi");
00928     if( doProfiles_ ) {
00929       hResoVSPt_prof_  = (TProfile *) file->Get(name+"_ResoVSPt_prof");
00930       hResoVSPt_Bar_prof_ = (TProfile *) file->Get(name+"_ResoVSPt_prof"); 
00931       hResoVSPt_Endc_17_prof_ = (TProfile *) file->Get(name+"_ResoVSPt_1.7_prof"); 
00932       hResoVSPt_Endc_20_prof_ = (TProfile *) file->Get(name+"_ResoVSPt_2.0_prof"); 
00933       hResoVSPt_Endc_24_prof_ = (TProfile *) file->Get(name+"_ResoVSPt_2.4_prof"); 
00934       hResoVSPt_Ovlap_prof_= (TProfile *) file->Get(name+"_ResoVSPt_prof"); 
00935       hResoVSEta_prof_ = (TProfile *) file->Get(name+"_ResoVSEta_prof");
00936       hResoVSPhi_prof_ = (TProfile *) file->Get(name+"_ResoVSPhi_prof");
00937     }
00938   }
00939 
00940   ~HResolutionVSPart() {
00941     delete hReso_;
00942     delete hResoVSPtEta_;
00943     delete hResoVSPt_;
00944     delete hResoVSPt_Bar_;
00945     delete hResoVSPt_Endc_17_;
00946     delete hResoVSPt_Endc_20_;
00947     delete hResoVSPt_Endc_24_;
00948     delete hResoVSPt_Ovlap_;
00949     delete hResoVSEta_;
00950     delete hResoVSTheta_;
00951     delete hResoVSPhiMinus_;
00952     delete hResoVSPhiPlus_;
00953     delete hAbsReso_;
00954     delete hAbsResoVSPt_;
00955     delete hAbsResoVSEta_;
00956     delete hAbsResoVSPhi_;
00957     if( doProfiles_ ) {
00958       delete hResoVSPt_prof_;
00959       delete hResoVSPt_Bar_prof_;  
00960       delete hResoVSPt_Endc_17_prof_; 
00961       delete hResoVSPt_Endc_20_prof_; 
00962       delete hResoVSPt_Endc_24_prof_; 
00963       delete hResoVSPt_Ovlap_prof_;
00964       delete hResoVSEta_prof_;
00965       delete hResoVSPhi_prof_;
00966     }
00967   }
00968 
00969   virtual void Fill(const reco::Particle::LorentzVector & p4, const double & resValue, const int charge) { 
00970     double pt = p4.Pt();
00971     double eta = p4.Eta();
00972     hReso_->Fill(resValue);
00973     hResoVSPtEta_->Fill(pt, eta,resValue); 
00974     hResoVSPt_->Fill(pt,resValue); 
00975     if(fabs(eta)<=0.9)
00976       hResoVSPt_Bar_->Fill(pt,resValue);
00977     else if(fabs(eta)>0.9 && fabs(eta)<=1.4)
00978       hResoVSPt_Ovlap_->Fill(pt,resValue);
00979     else if(fabs(eta)>1.4 && fabs(eta)<=1.7)
00980       hResoVSPt_Endc_17_->Fill(pt,resValue);
00981     else if(fabs(eta)>1.7 && fabs(eta)<=2.0)
00982       hResoVSPt_Endc_20_->Fill(pt,resValue);
00983     else
00984       hResoVSPt_Endc_24_->Fill(pt,resValue);
00985      
00986     hResoVSEta_->Fill(eta,resValue);
00987     hResoVSTheta_->Fill(p4.Theta(),resValue);
00988     if(charge>0)
00989       hResoVSPhiPlus_->Fill(p4.Phi(),resValue); 
00990     else if(charge<0)
00991       hResoVSPhiMinus_->Fill(p4.Phi(),resValue); 
00992     hAbsReso_->Fill(fabs(resValue)); 
00993     hAbsResoVSPt_->Fill(pt,fabs(resValue)); 
00994     hAbsResoVSEta_->Fill(eta,fabs(resValue)); 
00995     hAbsResoVSPhi_->Fill(p4.Phi(),fabs(resValue));     
00996     if( doProfiles_ ) {
00997       hResoVSPt_prof_->Fill(p4.Pt(),resValue); 
00998       if(fabs(eta)<=0.9)
00999         hResoVSPt_Bar_prof_->Fill(p4.Pt(),resValue); 
01000       else if(fabs(eta)>0.9 && fabs(eta)<=1.4)
01001         hResoVSPt_Ovlap_prof_->Fill(pt,resValue);
01002       else if(fabs(eta)>1.4 && fabs(eta)<=1.7)
01003         hResoVSPt_Endc_17_prof_->Fill(pt,resValue);
01004       else if(fabs(eta)>1.7 && fabs(eta)<=2.0)
01005         hResoVSPt_Endc_20_prof_->Fill(pt,resValue);
01006       else
01007         hResoVSPt_Endc_24_prof_->Fill(pt,resValue);
01008       
01009       hResoVSEta_prof_->Fill(p4.Eta(),resValue); 
01010       hResoVSPhi_prof_->Fill(p4.Phi(),resValue); 
01011     }
01012   }
01013 
01014   virtual void Write() {
01015     if(histoDir_ != 0) histoDir_->cd();
01016 
01017     hReso_->Write();
01018     hResoVSPtEta_->Write();
01019     hResoVSPt_->Write();
01020     hResoVSPt_Bar_->Write();
01021     hResoVSPt_Endc_17_->Write();
01022     hResoVSPt_Endc_20_->Write();
01023     hResoVSPt_Endc_24_->Write();
01024     hResoVSPt_Ovlap_->Write();
01025     hResoVSEta_->Write();
01026     hResoVSTheta_->Write();
01027     hResoVSPhiMinus_->Write();
01028     hResoVSPhiPlus_->Write();
01029     hAbsReso_->Write();
01030     hAbsResoVSPt_->Write();
01031     hAbsResoVSEta_->Write();
01032     hAbsResoVSPhi_->Write();
01033     if( doProfiles_ ) {
01034       hResoVSPt_prof_->Write();
01035       hResoVSPt_Bar_prof_->Write();
01036       hResoVSPt_Endc_17_prof_->Write();
01037       hResoVSPt_Endc_20_prof_->Write();
01038       hResoVSPt_Endc_24_prof_->Write();
01039       hResoVSPt_Ovlap_prof_->Write();
01040       hResoVSEta_prof_->Write();
01041       hResoVSPhi_prof_->Write();
01042     }
01043   }
01044   
01045   virtual void Clear() {
01046     hReso_->Clear();
01047     hResoVSPtEta_->Clear();
01048     hResoVSPt_->Clear();
01049     hResoVSPt_Bar_->Clear();
01050     hResoVSPt_Endc_17_->Clear();
01051     hResoVSPt_Endc_20_->Clear();
01052     hResoVSPt_Endc_24_->Clear();
01053     hResoVSPt_Ovlap_->Clear();
01054     hResoVSEta_->Clear();
01055     hResoVSTheta_->Clear();
01056     hResoVSPhiPlus_->Clear();
01057     hResoVSPhiMinus_->Clear();
01058     hAbsReso_->Clear();
01059     hAbsResoVSPt_->Clear();
01060     hAbsResoVSEta_->Clear();
01061     hAbsResoVSPhi_->Clear();
01062     if( doProfiles_ ) {
01063       hResoVSPt_prof_->Clear();
01064       hResoVSPt_Bar_prof_->Clear();
01065       hResoVSPt_Endc_17_prof_->Clear();
01066       hResoVSPt_Endc_20_prof_->Clear();
01067       hResoVSPt_Endc_24_prof_->Clear();
01068       hResoVSPt_Ovlap_prof_->Clear();
01069       hResoVSEta_prof_->Clear();
01070       hResoVSPhi_prof_->Clear();
01071     }
01072   }
01073 
01074  public:
01075   TH1F* hReso_;
01076   TH2F* hResoVSPtEta_;
01077   TH2F* hResoVSPt_;
01078   TH2F* hResoVSPt_Bar_;
01079   TH2F* hResoVSPt_Endc_17_;
01080   TH2F* hResoVSPt_Endc_20_;
01081   TH2F* hResoVSPt_Endc_24_;
01082   TH2F* hResoVSPt_Ovlap_;
01083   TProfile* hResoVSPt_prof_;
01084   TProfile* hResoVSPt_Bar_prof_;
01085   TProfile* hResoVSPt_Endc_17_prof_;
01086   TProfile* hResoVSPt_Endc_20_prof_;
01087   TProfile* hResoVSPt_Endc_24_prof_;
01088   TProfile* hResoVSPt_Ovlap_prof_;
01089   TH2F* hResoVSEta_;
01090   TH2F* hResoVSTheta_;
01091   TProfile* hResoVSEta_prof_;
01092   TH2F* hResoVSPhiMinus_;
01093   TH2F* hResoVSPhiPlus_;
01094   TProfile* hResoVSPhi_prof_;
01095   TH1F* hAbsReso_;
01096   TH2F* hAbsResoVSPt_;
01097   TH2F* hAbsResoVSEta_;
01098   TH2F* hAbsResoVSPhi_;
01099   bool doProfiles_;
01100 };
01101 
01102 // -------------------------------------------------------------
01103 // A set of histograms of likelihood value versus muon variables
01104 // -------------------------------------------------------------
01105 class HLikelihoodVSPart : public Histograms
01106 {
01107  public:
01108   HLikelihoodVSPart(const TString & name){
01109     name_ = name;
01110 
01111     // Kinematical variables
01112     // ---------------------
01113     hLikeVSPt_       = new TH2F (name+"_LikelihoodVSPt", "likelihood vs muon transverse momentum", 100, 0., 100., 100, -100., 100.);
01114     hLikeVSEta_      = new TH2F (name+"_LikelihoodVSEta", "likelihood vs muon pseudorapidity", 100, -4.,4., 100, -100., 100.);
01115     hLikeVSPhi_      = new TH2F (name+"_LikelihoodVSPhi", "likelihood vs muon phi angle", 100, -3.2, 3.2, 100, -100., 100.);
01116     hLikeVSPt_prof_  = new TProfile (name+"_LikelihoodVSPt_prof", "likelihood vs muon transverse momentum", 40, 0., 100., -1000., 1000. );
01117     hLikeVSEta_prof_ = new TProfile (name+"_LikelihoodVSEta_prof", "likelihood vs muon pseudorapidity", 40, -4.,4., -1000., 1000. );
01118     hLikeVSPhi_prof_ = new TProfile (name+"_LikelihoodVSPhi_prof", "likelihood vs muon phi angle", 40, -3.2, 3.2, -1000., 1000.);
01119    }
01120   
01121   HLikelihoodVSPart(const TString & name, TFile* file){
01122     name_ = name;
01123     hLikeVSPt_       = (TH2F *) file->Get(name+"_LikelihoodVSPt");
01124     hLikeVSEta_      = (TH2F *) file->Get(name+"_LikelihoodVSEta");
01125     hLikeVSPhi_      = (TH2F *) file->Get(name+"_LikelihoodVSPhi");
01126     hLikeVSPt_prof_  = (TProfile *) file->Get(name+"_LikelihoodVSPt_prof");
01127     hLikeVSEta_prof_ = (TProfile *) file->Get(name+"_LikelihoodVSEta_prof");
01128     hLikeVSPhi_prof_ = (TProfile *) file->Get(name+"_LikelihoodVSPhi_prof");
01129   }
01130 
01131   ~HLikelihoodVSPart(){
01132     delete hLikeVSPt_;
01133     delete hLikeVSEta_;
01134     delete hLikeVSPhi_;
01135     delete hLikeVSPt_prof_;
01136     delete hLikeVSEta_prof_;
01137     delete hLikeVSPhi_prof_;
01138   } 
01139 
01140   virtual void Fill(const reco::Particle::LorentzVector & p4, const double & likeValue) {
01141     Fill(CLHEP::HepLorentzVector(p4.x(),p4.y(),p4.z(),p4.t()), likeValue);
01142   }
01143   
01144    virtual void Fill(CLHEP::HepLorentzVector momentum, double likeValue) { 
01145      hLikeVSPt_->Fill(momentum.perp(),likeValue); 
01146      hLikeVSEta_->Fill(momentum.eta(),likeValue); 
01147      hLikeVSPhi_->Fill(momentum.phi(),likeValue); 
01148      hLikeVSPt_prof_->Fill(momentum.perp(),likeValue); 
01149      hLikeVSEta_prof_->Fill(momentum.eta(),likeValue); 
01150      hLikeVSPhi_prof_->Fill(momentum.phi(),likeValue); 
01151    } 
01152   
01153   virtual void Write() {
01154     hLikeVSPt_->Write();
01155     hLikeVSEta_->Write();    
01156     hLikeVSPhi_->Write();
01157     hLikeVSPt_prof_->Write();
01158     hLikeVSEta_prof_->Write();    
01159     hLikeVSPhi_prof_->Write();
01160   }
01161   
01162   virtual void Clear() {
01163     hLikeVSPt_->Reset("ICE");
01164     hLikeVSEta_->Reset("ICE");
01165     hLikeVSPhi_->Reset("ICE");
01166     hLikeVSPt_prof_->Reset("ICE");
01167     hLikeVSEta_prof_->Reset("ICE");    
01168     hLikeVSPhi_prof_->Reset("ICE");
01169   }
01170   
01171  public:
01172   TH2F* hLikeVSPt_;
01173   TH2F* hLikeVSEta_;
01174   TH2F* hLikeVSPhi_;
01175   TProfile* hLikeVSPt_prof_;
01176   TProfile* hLikeVSEta_prof_;
01177   TProfile* hLikeVSPhi_prof_;
01178 };
01179 
01189 class HFunctionResolution : public Histograms
01190 {
01191  public:
01192   HFunctionResolution(TFile * outputFile, const TString & name, const double & ptMax = 100, const int totBinsY = 200) : Histograms(outputFile, name) {
01193     name_ = name;
01194     totBinsX_ = 200;
01195     totBinsY_ = totBinsY;
01196     xMin_ = 0.;
01197     yMin_ = -3.0;
01198     double xMax = ptMax;
01199     double yMax = 3.0;
01200     deltaX_ = xMax - xMin_;
01201     deltaY_ = yMax - yMin_;
01202     hReso_        = new TH1F( name+"_Reso", "resolution", 1000, 0, 1 );
01203     hResoVSPtEta_ = new TH2F( name+"_ResoVSPtEta", "resolution vs pt and #eta", totBinsX_, xMin_, xMax, totBinsY_, yMin_, yMax );
01204     // Create and initialize the resolution arrays
01205     resoVsPtEta_  = new double*[totBinsX_];
01206     resoCount_    = new int*[totBinsX_];
01207     for( int i=0; i<totBinsX_; ++i ) {
01208       resoVsPtEta_[i] = new double[totBinsY_];
01209       resoCount_[i]   = new int[totBinsY_];
01210       for( int j=0; j<totBinsY_; ++j ) {
01211         resoVsPtEta_[i][j] = 0;
01212         resoCount_[i][j] = 0;
01213       }
01214     }
01215     hResoVSPt_prof_       = new TProfile( name+"_ResoVSPt_prof", "resolution VS pt", totBinsX_, xMin_, xMax, yMin_, yMax);
01216     hResoVSPt_Bar_prof_   = new TProfile( name+"_ResoVSPt_Bar_prof", "resolution VS pt Barrel", totBinsX_, xMin_, xMax, yMin_, yMax);
01217     hResoVSPt_Endc_17_prof_  = new TProfile( name+"_ResoVSPt_Endc_1.7_prof", "resolution VS pt Endcap (1.4<eta<1.7)", totBinsX_, xMin_, xMax, yMin_, yMax);
01218     hResoVSPt_Endc_20_prof_  = new TProfile( name+"_ResoVSPt_Endc_2.0_prof", "resolution VS pt Endcap (1.7<eta<2.0)", totBinsX_, xMin_, xMax, yMin_, yMax);
01219     hResoVSPt_Endc_24_prof_  = new TProfile( name+"_ResoVSPt_Endc_2.4_prof", "resolution VS pt Endcap (2.0<eta<2.4)", totBinsX_, xMin_, xMax, yMin_, yMax);
01220     hResoVSPt_Ovlap_prof_ = new TProfile( name+"_ResoVSPt_Ovlap_prof", "resolution VS pt Overlap", totBinsX_, xMin_, xMax, yMin_, yMax);
01221     hResoVSEta_prof_      = new TProfile( name+"_ResoVSEta_prof", "resolution VS eta", totBinsY_, yMin_, yMax, 0, 1);
01222     //hResoVSTheta_prof_    = new TProfile( name+"_ResoVSTheta_prof", "resolution VS theta", 30, 0, TMath::Pi(), 0, 1);
01223     hResoVSPhiPlus_prof_  = new TProfile( name+"_ResoVSPhiPlus_prof", "resolution VS phi mu+", 14, -3.2, 3.2, 0, 1);
01224     hResoVSPhiMinus_prof_ = new TProfile( name+"_ResoVSPhiMinus_prof", "resolution VS phi mu-", 14, -3.2, 3.2, 0, 1);
01225     hResoVSPhi_prof_      = new TProfile( name+"_ResoVSPhi_prof", "resolution VS phi", 14, -3.2, 3.2, -1, 1);
01226   }
01227   ~HFunctionResolution() {
01228     delete hReso_;
01229     delete hResoVSPtEta_;
01230     // Free the resolution arrays
01231     for( int i=0; i<totBinsX_; ++i ) {
01232       delete[] resoVsPtEta_[i];
01233       delete[] resoCount_[i];
01234     }
01235     delete[] resoVsPtEta_;
01236     delete[] resoCount_;
01237     // Free the profile histograms
01238     delete hResoVSPt_prof_;
01239     delete hResoVSPt_Bar_prof_;
01240     delete hResoVSPt_Endc_17_prof_;
01241     delete hResoVSPt_Endc_20_prof_;
01242     delete hResoVSPt_Endc_24_prof_;
01243     delete hResoVSPt_Ovlap_prof_;
01244     delete hResoVSEta_prof_;
01245     //delete hResoVSTheta_prof_;
01246     delete hResoVSPhiPlus_prof_;
01247     delete hResoVSPhiMinus_prof_;
01248     delete hResoVSPhi_prof_;
01249   }
01250   virtual void Fill(const reco::Particle::LorentzVector & p4, const double & resValue, const int charge) {
01251     if( resValue != resValue ) return;
01252     hReso_->Fill(resValue);
01253 
01254     // Fill the arrays with the resolution value and count
01255     int xIndex = getXindex(p4.Pt());
01256     int yIndex = getYindex(p4.Eta());
01257     if ( 0 <= xIndex && xIndex < totBinsX_ && 0 <= yIndex && yIndex < totBinsY_ ) {
01258       resoVsPtEta_[xIndex][yIndex] += resValue;
01259       // ATTENTION: we count only for positive muons because we are considering di-muon resonances
01260       // and we use this counter to compute the mean in the end. The resoVsPtEta value is filled with each muon,
01261       // but they must be considered independently (analogous to a factor 2) so in the end we would have
01262       // to divide by N/2, that is why we only increase the counter for half the muons.
01263       // if( charge > 0 )
01264       // No more. Changing it here influences also other uses of this class. The macro FunctionTerms.cc
01265       // multiplies the terms by the 2 factor.
01266 
01267       resoCount_[xIndex][yIndex] += 1;
01268 
01269       // hResoVSPtEta->Fill(p4.Pt(), p4.Eta(), resValue);
01270       hResoVSPt_prof_->Fill(p4.Pt(),resValue);
01271       if(fabs(p4.Eta())<=0.9)
01272         hResoVSPt_Bar_prof_->Fill(p4.Pt(),resValue);
01273       else if(fabs(p4.Eta())>0.9 && fabs(p4.Eta())<=1.4 )
01274         hResoVSPt_Ovlap_prof_->Fill(p4.Pt(),resValue);
01275       else if(fabs(p4.Eta())>1.4 && fabs(p4.Eta())<=1.7 )
01276         hResoVSPt_Endc_17_prof_->Fill(p4.Pt(),resValue);
01277       else if(fabs(p4.Eta())>1.7 && fabs(p4.Eta())<=2.0 )
01278         hResoVSPt_Endc_20_prof_->Fill(p4.Pt(),resValue);
01279       else
01280         hResoVSPt_Endc_24_prof_->Fill(p4.Pt(),resValue);
01281       hResoVSEta_prof_->Fill(p4.Eta(),resValue);
01282       //hResoVSTheta_prof_->Fill(p4.Theta(),resValue);
01283       if(charge>0)
01284         hResoVSPhiPlus_prof_->Fill(p4.Phi(),resValue);
01285       else if(charge<0)
01286         hResoVSPhiMinus_prof_->Fill(p4.Phi(),resValue);
01287       hResoVSPhi_prof_->Fill(p4.Phi(),resValue);
01288     }
01289   }
01290 
01291   virtual void Write() {
01292     if(histoDir_ != 0) histoDir_->cd();
01293 
01294     hReso_->Write();
01295 
01296     for( int i=0; i<totBinsX_; ++i ) {
01297       for( int j=0; j<totBinsY_; ++j ) {
01298         int N = resoCount_[i][j];
01299         // Fill with the mean value
01300         if( N != 0 ) hResoVSPtEta_->SetBinContent( i+1, j+1, resoVsPtEta_[i][j]/N );
01301         else hResoVSPtEta_->SetBinContent( i+1, j+1, 0 );
01302       }
01303     }
01304     hResoVSPtEta_->Write();
01305 
01306     hResoVSPt_prof_->Write();
01307     hResoVSPt_Bar_prof_->Write();
01308     hResoVSPt_Endc_17_prof_->Write();
01309     hResoVSPt_Endc_20_prof_->Write();
01310     hResoVSPt_Endc_24_prof_->Write();
01311     hResoVSPt_Ovlap_prof_->Write();
01312     hResoVSEta_prof_->Write();
01313     //hResoVSTheta_prof_->Write();
01314     hResoVSPhiMinus_prof_->Write();
01315     hResoVSPhiPlus_prof_->Write();
01316     hResoVSPhi_prof_->Write();
01317 
01318     TCanvas canvas(TString(hResoVSPtEta_->GetName())+"_canvas", TString(hResoVSPtEta_->GetTitle())+" canvas", 1000, 800);
01319     canvas.Divide(2);
01320     canvas.cd(1);
01321     hResoVSPtEta_->Draw("lego");
01322     canvas.cd(2);
01323     hResoVSPtEta_->Draw("surf5");
01324     canvas.Write();
01325     hResoVSPtEta_->Write();
01326 
01327     outputFile_->cd();
01328   }
01329   
01330   virtual void Clear() {
01331     hReso_->Clear();
01332     hResoVSPtEta_->Clear();
01333     hResoVSPt_prof_->Clear();
01334     hResoVSPt_Bar_prof_->Clear();
01335     hResoVSPt_Endc_17_prof_->Clear();
01336     hResoVSPt_Endc_20_prof_->Clear();
01337     hResoVSPt_Endc_24_prof_->Clear();
01338     hResoVSPt_Ovlap_prof_->Clear();
01339     hResoVSEta_prof_->Clear();
01340     //hResoVSTheta_prof_->Clear();
01341     hResoVSPhiPlus_prof_->Clear();
01342     hResoVSPhiMinus_prof_->Clear();
01343     hResoVSPhi_prof_->Clear();
01344   }
01345 
01346  protected:
01347   int getXindex(const double & x) const {
01348     return int((x-xMin_)/deltaX_*totBinsX_);
01349   }
01350   int getYindex(const double & y) const {
01351     return int((y-yMin_)/deltaY_*totBinsY_);
01352   }
01353   TH1F* hReso_;
01354   TH2F* hResoVSPtEta_;
01355   double ** resoVsPtEta_;
01356   int ** resoCount_;
01357   TProfile* hResoVSPt_prof_;
01358   TProfile* hResoVSPt_Bar_prof_;
01359   TProfile* hResoVSPt_Endc_17_prof_;
01360   TProfile* hResoVSPt_Endc_20_prof_;
01361   TProfile* hResoVSPt_Endc_24_prof_;
01362   TProfile* hResoVSPt_Ovlap_prof_;
01363   TProfile* hResoVSEta_prof_;
01364   //TProfile* hResoVSTheta_prof_;
01365   TProfile* hResoVSPhiMinus_prof_;
01366   TProfile* hResoVSPhiPlus_prof_;
01367   TProfile* hResoVSPhi_prof_;
01368   int totBinsX_, totBinsY_;
01369   double xMin_, yMin_;
01370   double deltaX_, deltaY_;
01371 };
01372 
01373 class HFunctionResolutionVarianceCheck : public HFunctionResolution
01374 {
01375 public:
01376   HFunctionResolutionVarianceCheck(TFile * outputFile, const TString & name, const double ptMax = 200) :
01377     HFunctionResolution(outputFile, name, ptMax)
01378   {
01379     histoVarianceCheck_ = new TH1D**[totBinsX_];
01380     for( int i=0; i<totBinsX_; ++i ) {
01381       histoVarianceCheck_[i] = new TH1D*[totBinsY_];
01382       for( int j=0; j<totBinsY_; ++j ) {
01383         std::stringstream namei;
01384         std::stringstream namej;
01385         namei << i;
01386         namej << j;
01387         histoVarianceCheck_[i][j] = new TH1D(name+"_"+namei.str()+"_"+namej.str(), name, 100, 0., 1.);
01388       }
01389     }
01390   }
01391   ~HFunctionResolutionVarianceCheck() {
01392     for( int i=0; i<totBinsX_; ++i ) {
01393       for( int j=0; j<totBinsY_; ++j ) {
01394         delete histoVarianceCheck_[i][j];
01395       }
01396       delete[] histoVarianceCheck_;
01397     }
01398     delete[] histoVarianceCheck_;
01399   }
01400   virtual void Fill(const reco::Particle::LorentzVector & p4, const double & resValue, const int charge) {
01401     if( resValue != resValue ) return;
01402     // Need to convert the (x,y) values to the array indeces
01403     int xIndex = getXindex(p4.Pt());
01404     int yIndex = getYindex(p4.Eta());
01405     // Only fill values if they are in the selected range
01406     if ( 0 <= xIndex && xIndex < totBinsX_ && 0 <= yIndex && yIndex < totBinsY_ ) {
01407       histoVarianceCheck_[xIndex][yIndex]->Fill(resValue);
01408     }
01409     // Call also the fill of the base class
01410     HFunctionResolution::Fill( p4, resValue, charge );
01411   }
01412   void Write() {
01413     if(histoDir_ != 0) histoDir_->cd();
01414     for( int xBin=0; xBin<totBinsX_; ++xBin ) {
01415       for( int yBin=0; yBin<totBinsY_; ++yBin ) {
01416         histoVarianceCheck_[xBin][yBin]->Write();
01417       }
01418     }
01419     HFunctionResolution::Write();
01420   }
01421 protected:
01422   TH1D *** histoVarianceCheck_;
01423 };
01424 
01433 class HResolution : public TH1F {
01434 public:
01435   HResolution( const TString & name, const TString & title,
01436                const int totBins, const double & xMin, const double & xMax,
01437                const double & yMin, const double & yMax, TDirectory * dir = 0) :
01438     dir_(dir),
01439     dir2D_(0),
01440     diffDir_(0)
01441   {
01442     if( dir_ != 0 ) {
01443       dir2D_ = (TDirectory*) dir_->Get("2D");
01444       if(dir2D_ == 0) dir2D_ = dir_->mkdir("2D");
01445       diffDir_ = (TDirectory*) dir_->Get("deltaXoverX");
01446       if(diffDir_ == 0) diffDir_ = dir->mkdir("deltaXoverX");
01447     }
01448     diffHisto_ = new TProfile(name+"_prof", title+" profile", totBins, xMin, xMax, yMin, yMax);
01449     histo2D_ = new TH2F(name+"2D", title, totBins, xMin, xMax, 4000, yMin, yMax);
01450     resoHisto_ = new TH1F(name, title, totBins, xMin, xMax);
01451   }
01452   ~HResolution() {
01453     delete diffHisto_;
01454     delete histo2D_;
01455     delete resoHisto_;
01456   }
01457   virtual Int_t Fill( Double_t x, Double_t y ) {
01458     diffHisto_->Fill(x, y);
01459     histo2D_->Fill(x, y);
01460     return 0;
01461   }
01462   virtual Int_t Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) {
01463     // Loop on all the bins and take the rms.
01464     // The TProfile bin error is by default the standard error on the mean, that is
01465     // rms/sqrt(N). If it is created with the "S" option (as we did NOT do), it would
01466     // already be the rms. Thus we take the error and multiply it by the sqrt of the
01467     // bin entries to get the rms.
01468     // bin 0 is the underflow, bin totBins+1 is the overflow.
01469     unsigned int totBins = diffHisto_->GetNbinsX();
01470     // std::cout << "totBins = " << totBins << std::endl;
01471     for( unsigned int iBin=1; iBin<=totBins; ++iBin ) {
01472       // std::cout << "iBin = " << iBin << ", " << diffHisto_->GetBinError(iBin)*sqrt(diffHisto_->GetBinEntries(iBin)) << std::endl;
01473       resoHisto_->SetBinContent( iBin, diffHisto_->GetBinError(iBin)*sqrt(diffHisto_->GetBinEntries(iBin)) );
01474     }
01475     if( dir_ != 0 ) dir_->cd();
01476     resoHisto_->Write();
01477     if( diffDir_ != 0 ) diffDir_->cd();
01478     diffHisto_->Write();
01479     if( dir2D_ != 0 ) dir2D_->cd();
01480     histo2D_->Write();
01481 
01482     return 0;
01483   }
01484  protected:
01485   TDirectory * dir_;
01486   TDirectory * dir2D_;
01487   TDirectory * diffDir_;
01488   TProfile * diffHisto_;
01489   TH2F * histo2D_;
01490   TH1F * resoHisto_;
01491 };
01492 
01500 class Covariance
01501 {
01502  public:
01503   Covariance() :
01504     productXY_(0),
01505     sumX_(0),
01506     sumY_(0),
01507     N_(0)
01508   {}
01509   void fill(const double & x, const double & y) {
01510     productXY_ += x*y;
01511     sumX_ += x;
01512     sumY_ += y;
01513     ++N_;
01514   }
01515   double covariance() {
01516     if( N_ != 0 ) {
01517       double meanX = sumX_/N_;
01518       double meanY = sumY_/N_;
01519       // std::cout << "meanX*meanY = "<<meanX<<"*"<<meanY<< " = " << meanX*meanY << std::endl;
01520       return (productXY_/N_ - meanX*meanY);
01521     }
01522     return 0.;
01523   }
01524   double getN() {return N_;}
01525  protected:
01526   double productXY_;
01527   double sumX_;
01528   double sumY_;
01529   int N_;
01530 };
01531 
01536 class HCovarianceVSxy : public Histograms
01537 {
01538  public:
01539   HCovarianceVSxy( const TString & name, const TString & title,
01540                    const int totBinsX, const double & xMin, const double & xMax,
01541                    const int totBinsY, const double & yMin, const double & yMax,
01542                    TDirectory * dir = 0, bool varianceCheck = false ) :
01543     totBinsX_(totBinsX), totBinsY_(totBinsY),
01544     xMin_(xMin), deltaX_(xMax-xMin), yMin_(yMin), deltaY_(yMax-yMin),
01545     readMode_(false),
01546     varianceCheck_(varianceCheck)
01547   {
01548     name_ = name;
01549     histoDir_ = dir;
01550     histoCovariance_ = new TH2D(name+"Covariance", title+" covariance", totBinsX, xMin, xMax, totBinsY, yMin, yMax);
01551 
01552     covariances_ = new Covariance*[totBinsX];
01553     for( int i=0; i<totBinsX; ++i ) {
01554       covariances_[i] = new Covariance[totBinsY];
01555     }
01556     if( varianceCheck_ ) {
01557       histoVarianceCheck_ = new TH1D**[totBinsX_];
01558       for( int i=0; i<totBinsX_; ++i ) {
01559         histoVarianceCheck_[i] = new TH1D*[totBinsY_];
01560         for( int j=0; j<totBinsY_; ++j ) {
01561           std::stringstream namei;
01562           std::stringstream namej;
01563           namei << i;
01564           namej << j;
01565           histoVarianceCheck_[i][j] = new TH1D(name+"_"+namei.str()+"_"+namej.str(), name, 10000, -1, 1);
01566         }
01567       }
01568     }
01569   }
01571   HCovarianceVSxy( TFile * inputFile, const TString & name, const TString & dirName ) :
01572     readMode_(true)
01573   {
01574     histoDir_ = (TDirectory*)(inputFile->Get(dirName.Data()));
01575     if( histoDir_ == 0 ) {
01576       std::cout << "Error: directory not found" << std::endl;
01577       exit(0);
01578     }
01579     histoCovariance_ = (TH2D*)(histoDir_->Get(name));
01580     totBinsX_ = histoCovariance_->GetNbinsX();
01581     xMin_ = histoCovariance_->GetXaxis()->GetBinLowEdge(1);
01582     deltaX_ = histoCovariance_->GetXaxis()->GetBinUpEdge(totBinsX_) - xMin_;
01583     totBinsY_ = histoCovariance_->GetNbinsY();
01584     yMin_ = histoCovariance_->GetYaxis()->GetBinLowEdge(1);
01585     deltaY_ = histoCovariance_->GetYaxis()->GetBinUpEdge(totBinsY_) - yMin_;
01586   }
01587 
01588   ~HCovarianceVSxy() {
01589     delete histoCovariance_;
01590     // Free covariances
01591     for(int i=0; i<totBinsX_; ++i) {
01592       delete[] covariances_[i];
01593     }
01594     delete[] covariances_;
01595     // Free variance check histograms
01596     if( varianceCheck_ ) {
01597       for( int i=0; i<totBinsX_; ++i ) {
01598         for( int j=0; j<totBinsY_; ++j ) {
01599           delete histoVarianceCheck_[i][j];
01600         }
01601         delete[] histoVarianceCheck_[i];
01602       }
01603       delete[] histoVarianceCheck_;
01604     }
01605   }
01606 
01611   virtual void Fill( const double & x, const double & y, const double & a, const double & b ) {
01612     // Need to convert the (x,y) values to the array indeces
01613     int xIndex = getXindex(x);
01614     int yIndex = getYindex(y);
01615     // Only fill values if they are in the selected range
01616     if ( 0 <= xIndex && xIndex < totBinsX_ && 0 <= yIndex && yIndex < totBinsY_ ) {
01617       // if( TString(histoCovariance_->GetName()).Contains("CovarianceCotgTheta_Covariance") )
01618       covariances_[xIndex][yIndex].fill(a,b);
01619       // Should be used with the variance, in which case a==b
01620       if( varianceCheck_ ) histoVarianceCheck_[xIndex][yIndex]->Fill(a);
01621     }
01622   }
01623 
01624   double Get( const double & x, const double & y ) const {
01625     // Need to convert the (x,y) values to the array indeces
01626     int xIndex = getXindex(x);
01627     int yIndex = getYindex(y);
01628     // If the values exceed the limits of the histogram, return the border values
01629     if ( xIndex < 0 ) xIndex = 0;
01630     if ( xIndex >= totBinsX_ ) xIndex = totBinsX_-1;
01631     if ( yIndex < 0 ) yIndex = 0;
01632     if ( yIndex >= totBinsY_ ) yIndex = totBinsY_-1;
01633     return histoCovariance_->GetBinContent(xIndex+1, yIndex+1);
01634   }
01635 
01636   void Write() {
01637     if( !readMode_ ) {
01638       std::cout << "writing: " << histoCovariance_->GetName() << std::endl;
01639       for( int xBin=0; xBin<totBinsX_; ++xBin ) {
01640         for( int yBin=0; yBin<totBinsY_; ++yBin ) {
01641           double covariance = covariances_[xBin][yBin].covariance();
01642           // Histogram bins start from 1
01643           // std::cout << "covariance["<<xBin<<"]["<<yBin<<"] with N = "<<covariances_[xBin][yBin].getN()<<" is: " << covariance << std::endl;
01644           histoCovariance_->SetBinContent(xBin+1, yBin+1, covariance);
01645         }
01646       }
01647       if( histoDir_ != 0 ) histoDir_->cd();
01648       TCanvas canvas(TString(histoCovariance_->GetName())+"_canvas", TString(histoCovariance_->GetTitle())+" canvas", 1000, 800);
01649       canvas.Divide(2);
01650       canvas.cd(1);
01651       histoCovariance_->Draw("lego");
01652       canvas.cd(2);
01653       histoCovariance_->Draw("surf5");
01654       canvas.Write();
01655       histoCovariance_->Write();
01656 
01657       TDirectory * binsDir = 0;
01658       if( varianceCheck_ ) {
01659         if ( histoDir_ != 0 ) {
01660           histoDir_->cd();
01661           if( binsDir == 0 ) binsDir = histoDir_->mkdir(name_+"Bins");
01662           binsDir->cd();
01663         }
01664         for( int xBin=0; xBin<totBinsX_; ++xBin ) {
01665           for( int yBin=0; yBin<totBinsY_; ++yBin ) {
01666             histoVarianceCheck_[xBin][yBin]->Write();
01667           }
01668         }
01669       }
01670     }
01671   }
01672   void Clear() {
01673     histoCovariance_->Clear();
01674     if( varianceCheck_ ) {
01675       for( int i=0; i<totBinsX_; ++i ) {
01676         for( int j=0; j<totBinsY_; ++j ) {
01677           histoVarianceCheck_[i][j]->Clear();
01678         }
01679       }
01680     }
01681   }
01682  protected:
01683   int getXindex(const double & x) const {
01684     return int((x-xMin_)/deltaX_*totBinsX_);
01685   }
01686   int getYindex(const double & y) const {
01687     return int((y-yMin_)/deltaY_*totBinsY_);
01688   }
01689   TH2D * histoCovariance_;
01690   Covariance ** covariances_;
01691   int totBinsX_, totBinsY_, totBinsZ_;
01692   double xMin_, deltaX_, yMin_, deltaY_;
01693   bool readMode_;
01694   bool varianceCheck_;
01695   TH1D *** histoVarianceCheck_;
01696 };
01697 
01702 class HCovarianceVSParts : public Histograms
01703 {
01704  public:
01705   HCovarianceVSParts(TFile * outputFile, const TString & name, const double & ptMax ) : Histograms( outputFile, name ) {
01706     int totBinsX = 40;
01707     int totBinsY = 40;
01708     double etaMin = -3.;
01709     double etaMax = 3.;
01710     double ptMin = 0.;
01711 
01712     readMode_ = false;
01713 
01714     // Variances
01715     mapHisto_[name+"Pt"]                    = new HCovarianceVSxy(name+"Pt_", "Pt", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_, true);
01716     mapHisto_[name+"CotgTheta"]             = new HCovarianceVSxy(name+"CotgTheta_", "CotgTheta", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_, true);
01717     mapHisto_[name+"Phi"]                   = new HCovarianceVSxy(name+"Phi_", "Phi", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_, true);
01718     // Covariances
01719     mapHisto_[name+"Pt-CotgTheta"]          = new HCovarianceVSxy(name+"Pt_CotgTheta_", "Pt-CotgTheta", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01720     mapHisto_[name+"Pt-Phi"]                = new HCovarianceVSxy(name+"Pt_Phi_", "Pt-Phi", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01721     mapHisto_[name+"CotgTheta-Phi"]         = new HCovarianceVSxy(name+"CotgTheta_Phi_", "CotgTheta-Phi", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01722     mapHisto_[name+"Pt1-Pt2"]               = new HCovarianceVSxy(name+"Pt1_Pt2_", "Pt1-Pt2", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01723     mapHisto_[name+"CotgTheta1-CotgTheta2"] = new HCovarianceVSxy(name+"CotgTheta1_CotgTheta2_", "CotgTheta1-CotgTheta2", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01724     mapHisto_[name+"Phi1-Phi2"]             = new HCovarianceVSxy(name+"Phi1_Phi2_", "Phi1-Phi2", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01725     mapHisto_[name+"Pt12-CotgTheta21"]      = new HCovarianceVSxy(name+"Pt12_CotgTheta21_", "Pt12-CotgTheta21", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01726     mapHisto_[name+"Pt12-Phi21"]            = new HCovarianceVSxy(name+"Pt12_Phi21_", "Pt12-Phi21", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01727     mapHisto_[name+"CotgTheta12-Phi21"]     = new HCovarianceVSxy(name+"CotgTheta12_Phi21_", "CotgTheta12-Phi21", totBinsX, ptMin, ptMax, totBinsY, etaMin, etaMax, histoDir_);
01728   }
01729 
01731   HCovarianceVSParts( const TString & inputFileName, const TString & name )
01732   {
01733     name_ = name;
01734     TFile * inputFile = new TFile(inputFileName, "READ");
01735     readMode_ = true;
01736 
01737     // Variances
01738     mapHisto_[name_+"Pt"]                    = new HCovarianceVSxy(inputFile, name_+"Pt_"+name_, name_);
01739     mapHisto_[name_+"CotgTheta"]             = new HCovarianceVSxy(inputFile, name_+"CotgTheta_"+name_, name_);
01740     mapHisto_[name_+"Phi"]                   = new HCovarianceVSxy(inputFile, name_+"Phi_"+name_, name_);
01741     // Covariances
01742     mapHisto_[name_+"Pt-CotgTheta"]          = new HCovarianceVSxy(inputFile, name_+"Pt_CotgTheta_"+name_, name_);
01743     mapHisto_[name_+"Pt-Phi"]                = new HCovarianceVSxy(inputFile, name_+"Pt_Phi_"+name_, name_);
01744     mapHisto_[name_+"CotgTheta-Phi"]         = new HCovarianceVSxy(inputFile, name_+"CotgTheta_Phi_"+name_, name_);
01745     mapHisto_[name_+"Pt1-Pt2"]               = new HCovarianceVSxy(inputFile, name_+"Pt1_Pt2_"+name_, name_);
01746     mapHisto_[name_+"CotgTheta1-CotgTheta2"] = new HCovarianceVSxy(inputFile, name_+"CotgTheta1_CotgTheta2_"+name_, name_);
01747     mapHisto_[name_+"Phi1-Phi2"]             = new HCovarianceVSxy(inputFile, name_+"Phi1_Phi2_"+name_, name_);
01748     mapHisto_[name_+"Pt12-CotgTheta21"]      = new HCovarianceVSxy(inputFile, name_+"Pt12_CotgTheta21_"+name_, name_);
01749     mapHisto_[name_+"Pt12-Phi21"]            = new HCovarianceVSxy(inputFile, name_+"Pt12_Phi21_"+name_, name_);
01750     mapHisto_[name_+"CotgTheta12-Phi21"]     = new HCovarianceVSxy(inputFile, name_+"CotgTheta12_Phi21_"+name_, name_);
01751   }
01752 
01753   ~HCovarianceVSParts() {
01754     for (std::map<TString, HCovarianceVSxy*>::const_iterator histo=mapHisto_.begin(); 
01755          histo!=mapHisto_.end(); histo++) {
01756       delete (*histo).second;
01757     }
01758   }
01759 
01760   virtual double Get( const reco::Particle::LorentzVector & recoP1, const TString & covarianceName ) {
01761     return mapHisto_[name_+covarianceName]->Get(recoP1.pt(), recoP1.eta());
01762   }
01763 
01764   virtual void Fill( const reco::Particle::LorentzVector & recoP1,
01765                      const reco::Particle::LorentzVector & genP1,
01766                      const reco::Particle::LorentzVector & recoP2,
01767                      const reco::Particle::LorentzVector & genP2 ) {
01768 
01769     double pt1 = recoP1.pt();
01770     double eta1 = recoP1.eta();
01771     double pt2 = recoP2.pt();
01772     double eta2 = recoP2.eta();
01773 
01774     double diffPt1 = (pt1 - genP1.pt())/genP1.pt();
01775     double diffPt2 = (pt2 - genP2.pt())/genP2.pt();
01776 
01777     double genTheta1 = genP1.theta();
01778     double genTheta2 = genP2.theta();
01779     double recoTheta1 = recoP1.theta();
01780     double recoTheta2 = recoP2.theta();
01781 
01782     double genCotgTheta1 = TMath::Cos(genTheta1)/(TMath::Sin(genTheta1));
01783     double genCotgTheta2 = TMath::Cos(genTheta2)/(TMath::Sin(genTheta2));
01784     double recoCotgTheta1 = TMath::Cos(recoTheta1)/(TMath::Sin(recoTheta1));
01785     double recoCotgTheta2 = TMath::Cos(recoTheta2)/(TMath::Sin(recoTheta2));
01786 
01787     // double diffCotgTheta1 = (recoCotgTheta1 - genCotgTheta1)/genCotgTheta1;
01788     // double diffCotgTheta2 = (recoCotgTheta2 - genCotgTheta2)/genCotgTheta2;
01789     double diffCotgTheta1 = recoCotgTheta1 - genCotgTheta1;
01790     double diffCotgTheta2 = recoCotgTheta2 - genCotgTheta2;
01791 
01792     // double diffPhi1 = (recoP1.phi() - genP1.phi())/genP1.phi();
01793     // double diffPhi2 = (recoP2.phi() - genP2.phi())/genP2.phi();
01794     double diffPhi1 = MuScleFitUtils::deltaPhiNoFabs(recoP1.phi(), genP1.phi());
01795     double diffPhi2 = MuScleFitUtils::deltaPhiNoFabs(recoP2.phi(), genP2.phi());
01796 
01797     // Fill the variances
01798     mapHisto_[name_+"Pt"]->Fill(pt1, eta1, diffPt1, diffPt1);
01799     mapHisto_[name_+"Pt"]->Fill(pt2, eta2, diffPt2, diffPt2);
01800     mapHisto_[name_+"CotgTheta"]->Fill(pt1, eta1, diffCotgTheta1, diffCotgTheta1);
01801     mapHisto_[name_+"CotgTheta"]->Fill(pt2, eta2, diffCotgTheta2, diffCotgTheta2);
01802     mapHisto_[name_+"Phi"]->Fill(pt1, eta1, diffPhi1, diffPhi1);
01803     mapHisto_[name_+"Phi"]->Fill(pt2, eta2, diffPhi2, diffPhi2);
01804 
01805     // Fill these histograms with both muons
01806     mapHisto_[name_+"Pt-CotgTheta"]->Fill(pt1, eta1, diffPt1, diffCotgTheta1 );
01807     mapHisto_[name_+"Pt-CotgTheta"]->Fill(pt2, eta2, diffPt2, diffCotgTheta2 );
01808     mapHisto_[name_+"Pt-Phi"]->Fill(pt1, eta1, diffPt1, diffPhi1);
01809     mapHisto_[name_+"Pt-Phi"]->Fill(pt2, eta2, diffPt2, diffPhi2);
01810     mapHisto_[name_+"CotgTheta-Phi"]->Fill(pt1, eta1, diffCotgTheta1, diffPhi1);
01811     mapHisto_[name_+"CotgTheta-Phi"]->Fill(pt2, eta2, diffCotgTheta2, diffPhi2);
01812 
01813     // We fill two (pt, eta) bins for each pair of values. The bin of the
01814     // first and of the second muon. This should take account for the
01815     // assumed symmetry between the exchange of the first with the second muon.
01816     mapHisto_[name_+"Pt1-Pt2"]->Fill(pt1, eta1, diffPt1, diffPt2);
01817     mapHisto_[name_+"Pt1-Pt2"]->Fill(pt2, eta2, diffPt1, diffPt2);
01818     mapHisto_[name_+"CotgTheta1-CotgTheta2"]->Fill(pt1, eta1, diffCotgTheta1, diffCotgTheta2);
01819     mapHisto_[name_+"CotgTheta1-CotgTheta2"]->Fill(pt2, eta2, diffCotgTheta1, diffCotgTheta2);
01820     mapHisto_[name_+"Phi1-Phi2"]->Fill(pt1, eta1, diffPhi1, diffPhi2);
01821     mapHisto_[name_+"Phi1-Phi2"]->Fill(pt2, eta2, diffPhi1, diffPhi2);
01822 
01823     // Fill the following histograms again for each muon (pt, eta) bin. Same
01824     // reason as in the previous case. If the symmetry is true, it does not
01825     // make any difference the order by which we fill the pt and cotgTheta combinations.
01826     mapHisto_[name_+"Pt12-CotgTheta21"]->Fill(pt1, eta1, diffPt1, diffCotgTheta2);
01827     mapHisto_[name_+"Pt12-CotgTheta21"]->Fill(pt2, eta2, diffPt2, diffCotgTheta1);
01828     mapHisto_[name_+"Pt12-Phi21"]->Fill(pt1, eta1, diffPt1, diffPhi2);
01829     mapHisto_[name_+"Pt12-Phi21"]->Fill(pt2, eta2, diffPt2, diffPhi1);
01830     mapHisto_[name_+"CotgTheta12-Phi21"]->Fill(pt1, eta1, diffCotgTheta1, diffPhi2);
01831     mapHisto_[name_+"CotgTheta12-Phi21"]->Fill(pt2, eta2, diffCotgTheta2, diffPhi1);
01832   }
01833   virtual void Write() {
01834     if( !readMode_ ) {
01835       histoDir_->cd();
01836       for (std::map<TString, HCovarianceVSxy*>::const_iterator histo=mapHisto_.begin(); 
01837            histo!=mapHisto_.end(); histo++) {
01838         (*histo).second->Write();
01839       }
01840     }
01841   }
01842   virtual void Clear() {
01843     for (std::map<TString, HCovarianceVSxy*>::const_iterator histo=mapHisto_.begin(); 
01844          histo!=mapHisto_.end(); histo++) {
01845       (*histo).second->Clear();
01846     }
01847   }
01848  protected:
01849   std::map<TString, HCovarianceVSxy*> mapHisto_;
01850   bool readMode_;
01851 };
01852 
01862 class HMassResolutionVSPart : public Histograms
01863 {
01864  public:
01865   HMassResolutionVSPart(TFile * outputFile, const TString & name) : Histograms( outputFile, name ) {
01866     // Kinematical variables
01867     nameSuffix_[0] = "Plus";
01868     nameSuffix_[1] = "Minus";
01869     TString titleSuffix[] = {" for mu+", " for mu-"};
01870 
01871     mapHisto_[name]                  = new TH1F (name, "#Delta M/M", 4000, -1, 1);
01872     mapHisto_[name+"VSPairPt"]       = new HResolution (name+"VSPairPt", "resolution VS pt of the pair", 100, 0, 200, -1, 1, histoDir_);
01873     mapHisto_[name+"VSPairDeltaEta"] = new HResolution (name+"VSPairDeltaEta", "resolution VS #Delta#eta of the pair", 100, -0.1, 6.2, -1, 1, histoDir_);
01874     mapHisto_[name+"VSPairDeltaPhi"] = new HResolution (name+"VSPairDeltaPhi", "resolution VS #Delta#phi of the pair", 100, -0.1, 3.2, -1, 1, histoDir_);
01875 
01876     for( int i=0; i<2; ++i ) {
01877       mapHisto_[name+"VSPt"+nameSuffix_[i]]  = new HResolution (name+"VSPt"+nameSuffix_[i], "resolution VS pt"+titleSuffix[i], 100, 0, 200, -1, 1, histoDir_);
01878       mapHisto_[name+"VSEta"+nameSuffix_[i]] = new HResolution (name+"VSEta"+nameSuffix_[i], "resolution VS #eta"+titleSuffix[i], 100, -3, 3, -1, 1, histoDir_);
01879       mapHisto_[name+"VSPhi"+nameSuffix_[i]] = new HResolution (name+"VSPhi"+nameSuffix_[i], "resolution VS #phi"+titleSuffix[i], 100, -3.2, 3.2, -1, 1, histoDir_);
01880     }
01881 
01882     // single particles histograms
01883     muMinus.reset( new HDelta("muMinus") );
01884     muPlus.reset( new HDelta("muPlus") );
01885   }
01886 
01887   ~HMassResolutionVSPart(){
01888     for (std::map<TString, TH1*>::const_iterator histo=mapHisto_.begin(); 
01889          histo!=mapHisto_.end(); histo++) {
01890       delete (*histo).second;
01891     }
01892   }
01893 
01894   virtual void Fill( const reco::Particle::LorentzVector & recoP1, const int charge1,
01895                      const reco::Particle::LorentzVector & genP1,
01896                      const reco::Particle::LorentzVector & recoP2, const int charge2,
01897                      const reco::Particle::LorentzVector & genP2,
01898                      const double & recoMass, const double & genMass ) {
01899     muMinus->Fill(recoP1, genP1);
01900     muPlus->Fill(recoP2, genP2);
01901 
01902     Fill( recoP1, charge1, recoP2, charge2, recoMass, genMass );
01903   }
01904 
01905   virtual void Fill( const reco::Particle::LorentzVector & recoP1, const int charge1,
01906                      // const reco::Particle::LorentzVector & genP1,
01907                      const reco::Particle::LorentzVector & recoP2, const int charge2,
01908                      // const reco::Particle::LorentzVector & genP2,
01909                      const double & recoMass, const double & genMass ) {
01910 
01911     if ( charge1 == charge2 ) std::cout << "Error: must get two opposite charge particles" << std::endl;
01912 
01913     double massRes = (recoMass - genMass)/genMass;
01914 
01915     reco::Particle::LorentzVector recoPair( recoP1 + recoP2 );
01916     double pairPt = recoPair.Pt();
01917 
01918     double recoPt[2]  = {recoP1.Pt(),  recoP2.Pt()};
01919     double recoEta[2] = {recoP1.Eta(), recoP2.Eta()};
01920     double recoPhi[2] = {recoP1.Phi(), recoP2.Phi()};
01921 
01922     // std::cout << "pairPt = " << pairPt << ", massRes = ("<<recoMass<<" - "<<genMass<<")/"<<genMass<<" = " << massRes
01923     //      << ", recoPt[0] = " << recoPt[0] << ", recoPt[1] = " << recoPt[1] << std::endl;
01924 
01925     // Index of the histogram. If the muons have charge1 = -1 and charge2 = 1, they already have the
01926     // correct histogram indeces. Otherwise, swap the indeces.
01927     // In any case the negative muon has index = 0  and the positive muon has index = 1.
01928     int id[2] = {0,1};
01929     if ( charge1 > 0 ) {
01930       id[0] = 1;
01931       id[1] = 0;
01932     }
01933 
01934     double pairDeltaEta = fabs(recoEta[0] - recoEta[1]);
01935     double pairDeltaPhi = MuScleFitUtils::deltaPhi(recoPhi[0], recoPhi[1]);
01936 
01937     mapHisto_[name_]->Fill(massRes);
01938     mapHisto_[name_+"VSPairPt"]->Fill(pairPt, massRes);
01939     mapHisto_[name_+"VSPairDeltaEta"]->Fill(pairDeltaEta, massRes);
01940     mapHisto_[name_+"VSPairDeltaPhi"]->Fill(pairDeltaPhi, massRes);
01941 
01942     // Resolution vs single muon quantities
01943     // ------------------------------------
01944     int index = 0;
01945     for( int i=0; i<2; ++i ) {
01946       index = id[i];
01947       mapHisto_[name_+"VSPt"+nameSuffix_[i]]->Fill(recoPt[i], massRes);
01948       mapHisto_[name_+"VSEta"+nameSuffix_[i]]->Fill(recoEta[i], massRes);
01949       mapHisto_[name_+"VSPhi"+nameSuffix_[i]]->Fill(recoPhi[i], massRes);
01950     }
01951   } 
01952 
01953   virtual void Write() {
01954     histoDir_->cd();
01955     for (std::map<TString, TH1*>::const_iterator histo=mapHisto_.begin(); 
01956          histo!=mapHisto_.end(); histo++) {
01957       (*histo).second->Write();
01958     }
01959     // Create the new dir and cd into it
01960     (histoDir_->mkdir("singleMuonsVSgen"))->cd();
01961     muMinus->Write();
01962     muPlus->Write();
01963   }
01964   
01965   virtual void Clear() {
01966     for (std::map<TString, TH1*>::const_iterator histo=mapHisto_.begin(); 
01967          histo!=mapHisto_.end(); histo++) {
01968       (*histo).second->Clear();
01969     }
01970     muMinus->Clear();
01971     muPlus->Clear();
01972   }
01973 
01974 //   HMassResolutionVSPart(const TString & name, TFile* file){
01975 //     string nameSuffix[] = {"Plus", "Minus"};
01976 //     name_ = name;
01977 //     hReso                    = (TH1F *)     file->Get(name+"_Reso");
01978 //     hResoVSPairPt            = (TH2F *)     file->Get(name+"_ResoVSPairPt");
01979 //     hResoVSPairDeltaEta      = (TH2F *)     file->Get(name+"_ResoVSPairDeltaEta");
01980 //     hResoVSPairDeltaPhi      = (TH2F *)     file->Get(name+"_ResoVSPairDeltaPhi");
01981 //     for( int i=0; i<2; ++i ) {
01982 //       hResoVSPt[i]           = (TH2F *)     file->Get(name+"_ResoVSPt"+nameSuffix[i]);
01983 //       hResoVSEta[i]          = (TH2F *)     file->Get(name+"_ResoVSEta"+nameSuffix[i]);
01984 //       hResoVSPhi[i]          = (TH2F *)     file->Get(name+"_ResoVSPhi"+nameSuffix[i]);
01985 //     }
01986 //   }
01987 
01988  protected:
01989   std::map<TString, TH1*> mapHisto_;
01990   TString nameSuffix_[2];
01991   std::auto_ptr<HDelta> muMinus;
01992   std::auto_ptr<HDelta> muPlus;
01993 };
01994 
01995 #endif