baseAnalysis.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <sstream>
00003 #include <cmath>
00004 #include <stdio.h>
00005 #include "HepMC/GenEvent.h"
00006 #include "HepMC/IO_GenEvent.h"
00007 #include "HepMC/GenParticle.h"
00008 #include "HepMC/GenVertex.h"
00009 #include "HepMC/IO_AsciiParticles.h"
00010 #include "HepMC/SimpleVector.h"
00011 #include "HepPDT/ParticleData.hh"
00012 #include "CLHEP/Vector/LorentzVector.h"
00013 
00014 #include "fastjet/ClusterSequence.hh"
00015 #include "fastjet/SISConePlugin.hh"
00016 
00017 using namespace std;
00018 
00019 // ROOT headers
00020 #include "TH1.h"
00021 #include "TH2.h"
00022 #include "TFile.h"
00023 #include "TMath.h"
00024 #include "TLorentzVector.h"
00025 
00026 //base analysis header
00027 #include "../include/baseAnalysis.h"
00028 
00029 //**********************
00030 
00031 /**
00032 Constructor
00033 */
00034 baseAnalysis::baseAnalysis()
00035 { 
00036   m_Jetfinder_enabled=false;
00037 }
00038 
00039 /**
00040 Destructor: delete all the Pointer
00041 */
00042 baseAnalysis::~baseAnalysis()
00043 {
00044   for (std::vector<TH1D*>::const_iterator i(m_histVector.begin()); i != m_histVector.end(); ++i) {
00045     delete (*i);
00046   }
00047   m_histVector.resize(0);
00048 
00049   //probably not needed anymore, due to averagedHistograms function
00050   //   while (!m_histVectorVariableBin.empty()){
00051   //     delete m_histVectorVariableBin.back();
00052   //     m_histVectorVariableBin.pop_back();
00053   //   }
00054 }
00055 
00056 /**
00057 InitJetFinder: Initialisation of JetFinder
00058 */
00059 int baseAnalysis::InitJetFinder(double coneRadius, double overlapThreshold, double jet_ptmin, double lepton_ptmin, double DeltaR_lepton_track)
00060 {
00061 
00062     if(m_Jetfinder_enabled){
00063         // If the Pointer already exist, delete them
00064         if(m_jetDef) {
00065             delete m_jetDef;
00066             m_jetDef=0;
00067         }
00068         
00069         if(m_plugin){
00070             delete m_plugin;
00071             m_plugin=0;
00072         }
00073     }
00074     
00075  // initialise fastjet
00076   m_coneRadius = coneRadius;
00077   m_overlapThreshold = overlapThreshold;
00078   m_jet_ptmin = jet_ptmin;
00079   m_lepton_ptmin = lepton_ptmin;
00080   m_DeltaR_lepton_track = DeltaR_lepton_track;
00081 
00082   m_plugin = new fastjet::SISConePlugin(m_coneRadius, m_overlapThreshold);
00083   m_jetDef = new fastjet::JetDefinition(m_plugin);
00084 
00085   if(!m_jetDef) return false;
00086 
00087   m_Jetfinder_enabled=true;
00088   return true;
00089 
00090 }
00091 
00092 /**
00093 FindJetableParticles
00094 */
00095 int baseAnalysis::FindJetableParticles(HepMC::GenEvent* hepmcevt)
00096 {
00097 
00098   //delete m_clust_seq;
00099   //m_clust_seq=0;
00100   if(!m_Jetfinder_enabled || !m_jetDef){
00101     std::cout << "baseAnalysis: FastJet Algorithm not initialized!" << std::endl;
00102     return false;
00103   }
00104   CLHEP::HepLorentzVector lv_leadingJet(0,0,0,0);
00105 
00106   for ( HepMC::GenEvent::particle_const_iterator p =
00107           hepmcevt->particles_begin(); p != hepmcevt->particles_end(); ++p ){
00108 
00109     // use the pdg id to identify the particles
00110     int pid = (*p)->pdg_id();
00111 
00112 
00113     
00114     // first of all we need stable particle
00115     if (!(((*p)->status()%1000) == 1)) continue;
00116     if ((*p)->end_vertex()) continue;
00117     
00118     // cut out the neutral particles (charge is not stored in HepMC)
00119     // just remove the neutrinos and Neutron from the final state
00120     if(IsNeutrino(pid) || IsNeutron(pid)) continue;
00121 
00122     // cut out all isolated leptons
00123     // variables for DeltaR calculation
00124     double deltaPhi = 0;
00125     double deltaEta = 0;
00126     double DeltaR = 9999;
00127 
00128     // cut variables
00129     double DeltaRCut = m_DeltaR_lepton_track;
00130     double LeptonpTCut = m_lepton_ptmin;
00131 
00132     if(IsElectron(pid) || IsMuon(pid)) {
00133       int lepton_barcode = (*p)->barcode();
00134       HepMC::GenParticle *lepton = hepmcevt->barcode_to_particle(lepton_barcode);
00135       
00136       // set pt cut for lepton
00137       if(fabs((*lepton).momentum().perp()) > LeptonpTCut) continue;
00138       
00139       // check if it is an isolated lepton
00140       for ( HepMC::GenEvent::particle_const_iterator q = hepmcevt->particles_begin(); 
00141             q != hepmcevt->particles_end(); ++q ){
00142         if(lepton_barcode==(*q)->barcode()) continue;
00143 
00144         // set DeltaR cut
00145         deltaPhi = (*p)->momentum().phi()-(*q)->momentum().phi();
00146 
00147         if( deltaPhi > TMath::Pi() ||  deltaPhi == TMath::Pi() )
00148           {
00149             deltaPhi = deltaPhi - 2 * TMath::Pi() ;
00150           }
00151         
00152         if( deltaPhi < - TMath::Pi() ||  deltaPhi == - TMath::Pi() )
00153           {
00154             deltaPhi = deltaPhi + 2 * TMath::Pi();
00155           }
00156 
00157         deltaEta = (*p)->momentum().eta()-(*q)->momentum().eta();
00158         double DeltaRnew = sqrt( pow(deltaPhi,2) + pow(deltaEta,2));
00159 
00160         if(DeltaRnew < DeltaR) DeltaR = DeltaRnew;
00161       }
00162       if(DeltaR > DeltaRCut) continue;
00163     }
00164 
00165     // or ... remove all charged particles 
00166     //if(chargedParticle(pid)==NOTCHARGED) continue;
00167     
00168     // They need to have a production Vertex --> we will not select incoming Protons from the Beam
00169     if (!(*p)->production_vertex()) continue;
00170     // And since they are stable they should not have a decay vertex.
00171     if ((*p)->end_vertex()) continue;
00172     
00173 //     // check wether the track directly comes from a Z-Boson
00174 //     if( trackfromPID(23,(*p)) ) continue;
00175     
00176 //     // check wether the track directly comes from a W-Boson
00177 //     if( trackfromPID(24,(*p)) ) continue;
00178 //     if( trackfromPID(-24,(*p)) ) continue;
00179     
00180     //set the eta cut for charged particles 
00181     double eta = (*p)->momentum().eta(); 
00182     if(std::abs(eta) > m_max_eta )  continue;
00183     
00184     //set the pt cut for charged particles 
00185     double pt = (*p)->momentum().perp(); 
00186     if(pt < m_min_pt) continue;
00187     
00188     double px = (*p)->momentum().x();
00189     double py = (*p)->momentum().y();
00190     double pz = (*p)->momentum().z();
00191     double pe = (*p)->momentum().e();
00192     
00193     
00194     // jet finding in stable particles record for charged particles
00195     fastjet::PseudoJet tempVec;
00196     tempVec = fastjet::PseudoJet(px,py,pz,pe);
00197     m_input_particles.push_back(tempVec);
00198   }
00199   return true;
00200 }
00201 
00202 /**
00203 FindJet: run JetFinder
00204 */
00205 int baseAnalysis::FindJet(HepMC::GenEvent* hepmcevt) {
00206 
00207   if(!m_Jetfinder_enabled || !m_jetDef){
00208     std::cout << "baseAnalysis: FastJet Algorithm not initialized!" << std::endl;
00209     return false;
00210   }
00211   
00212   // run the jet finding
00213   if(m_input_particles.empty()) {
00214     int input = FindJetableParticles(hepmcevt); 
00215     if(!input) 
00216       return false;
00217   }
00218   
00219   if(m_input_particles.size()) 
00220     m_clust_seq = new fastjet::ClusterSequence(m_input_particles,*m_jetDef);
00221   else
00222     m_clust_seq = 0;
00223   
00224   if(m_input_particles.empty() || m_clust_seq==0) 
00225     return false;
00226   
00227   // select jets above a threshold, e.g. 0.5 GeV                                                                              
00228   m_inclusive_jets= sorted_by_pt(m_clust_seq->inclusive_jets(m_jet_ptmin));
00229   
00230   return true;
00231 }
00232 
00233 vector<fastjet::PseudoJet> baseAnalysis::GetJet(HepMC::GenEvent* hepmcevt) {
00234 
00235   if(m_inclusive_jets.empty()) {
00236     FindJet(hepmcevt);
00237     //int inputJet = FindJet(hepmcevt);
00238     //if(inputJet==FAILURE) std::cout<<"baseAnalysis::no jets found"<<std::endl;
00239   }
00240   return m_inclusive_jets;
00241   //return SUCCESS;
00242 }
00243 
00244 /**
00245 DeleteJetObject: delete all the jet objects
00246 */
00247 int baseAnalysis::DeleteJetObject(HepMC::GenEvent* hepmcevt) {
00248   //if(!m_input_particles.size()&&!m_inclusive_jets.size()&&!m_clust_seq) return FAILURE;
00249   //if(!(m_input_particles.size()&&m_inclusive_jets.size()&&m_clust_seq)) return FAILURE;
00250 
00251   m_input_particles.clear();
00252   m_inclusive_jets.clear();
00253   delete m_clust_seq;
00254   m_clust_seq=0;
00255 
00256   return true;
00257 }
00258 
00259 /**
00260 FindMissingEt: calculate the missing transversal energy of each event
00261 */
00262 int baseAnalysis::FindMissingEt(HepMC::GenEvent* hepmcevt) {
00263 
00264   int properStatus = 1; //stable particles
00265   
00266   exMissTruth = 0.0;
00267   eyMissTruth = 0.0;
00268   etMissTruth = 0.0;
00269   etsumMissTruth = 0.0;
00270   
00271   // loop over the particles and select pdgid and pt
00272   for ( HepMC::GenEvent::particle_const_iterator p =  hepmcevt->particles_begin(); p != hepmcevt->particles_end(); ++p ){
00273 
00274     int pid = (*p)->pdg_id();
00275 
00276     // skip all not stable particles
00277     if ( (*p)->status()%1000 != properStatus ) continue;
00278     if ((*p)->end_vertex()) continue;
00279 
00280     // fiducial range eta cut on 2.5
00281     if(fabs((*p)->momentum().eta()) > 2.5) continue;
00282     // minimum pt for tracks on 0.5 GeV
00283     if((*p)->momentum().perp() < 0.5) continue;
00284 
00285     double px  = (*p)->momentum().px();
00286     double py  = (*p)->momentum().py();
00287     double pt  = (*p)->momentum().perp();
00288 
00289     if ( IsNeutrino(pid) || abs(pid)==1000039 || abs(pid) ==1000022 || abs(pid) ==39 || abs(pid) ==5100022 ) {
00290       exMissTruth += px;    
00291       eyMissTruth += py;
00292       etsumMissTruth += pt;
00293     }
00294   }
00295   
00296   etMissTruth = sqrt(exMissTruth*exMissTruth + eyMissTruth*eyMissTruth); 
00297   
00298   return true;
00299 }
00300 
00301 /**
00302 ClearMissingEt: setting the variables to calculate missing energy to zero
00303 */
00304 int baseAnalysis::ClearMissingEt(HepMC::GenEvent* hepmcevt) {
00305   exMissTruth = 0.0;
00306   eyMissTruth = 0.0;
00307   etMissTruth = 0.0;
00308   etsumMissTruth = 0.0;
00309 
00310   return true;
00311 }
00312 
00313 /** 
00314 Check if final state particle: returns 0 if it is not a final state particle, 1 otherwise
00315 */
00316 int baseAnalysis::IsFinalStateParticle(HepMC::GenParticle *p) {
00317 
00318   // first of all we need stable particle
00319   if (!((*p).status()%1000 == 1)) return false;
00320   // And since they are stable they should not have a decay vertex. 
00321   if ((*p).end_vertex()) return false;
00322     
00323     // fiducial range eta cut on 2.5
00324     if(fabs((*p).momentum().eta()) > 2.5) return false;
00325     // minimum pt for tracks on 0.5
00326     if((*p).momentum().perp() < 0.5) return false;
00327 
00328     return true;
00329 }
00330 
00331 
00332 /**
00333 ClearEvent: delete and clear some variables from the event
00334 */
00335 int baseAnalysis::ClearEvent(HepMC::GenEvent* hepmcevt) {
00336 
00337   baseAnalysis::DeleteJetObject(hepmcevt);
00338   baseAnalysis::ClearMissingEt(hepmcevt);
00339 
00340   return true;
00341 }
00342 
00343 /**
00344 In the final step all the histogramms are stored in a rootfile.
00345 The name of the rootfile can be set with the function setOutpuFileName(const char* filename). 
00346  */
00347 int baseAnalysis::Finalize() 
00348 {
00349   //write the output in a root file
00350   TFile f(m_outputFileName.c_str(),"RECREATE");
00351   Finalize(&f);
00352   f.Close();
00353   
00354   return true;
00355 }
00356 
00357 /**
00358 In the final step all the histogramms are stored in a rootfile.
00359 The name of the rootfile can be set with the function setOutpuFileName(const char* filename). 
00360  */
00361 int baseAnalysis::Finalize(TFile* output) 
00362 {
00363   TDirectory* dir = output->GetDirectory(m_outputRootDir.c_str());
00364   if (dir) {
00365     dir->cd();
00366   } else {
00367     std::cout << "The directory " << m_outputRootDir << " will be created" << std::endl;
00368     dir = output->mkdir(m_outputRootDir.c_str());
00369     dir->cd();
00370   }
00371 
00372   // loop over the standard vector
00373   for ( vector< TH1D * >::const_iterator iter = m_histVector.begin(); iter!=m_histVector.end(); iter++ ) 
00374     (*iter)->Write(); 
00375   
00376   // probably not needed anymore, due to averagedHistograms function
00377   //   for ( vector< TH1D * >::const_iterator iter = m_histVectorVariableBin.begin(); iter!=m_histVectorVariableBin.end(); iter++ ) 
00378   //     (*iter)->Write(); 
00379   
00380   return true;
00381 }
00382 
00383 /**
00384 return the last entry  of the histogram vector, needed for ATHENA (ATLAS software) implementation
00385 */
00386 //TH1D* baseAnalysis::popHisto(std::vector<TH1D*> m_histVector) {
00387 TH1D* baseAnalysis::popHisto() {
00388 
00389   // return NULL pointer if no histogram
00390   if (m_histVector.empty()) return 0;
00391 
00392   // get last element from vector (don't change vector)
00393   TH1D* temp = m_histVector.back();
00394   std::cout<<"m_histVector.back()"<< temp;
00395   // delete last entry from vector
00396   m_histVector.pop_back();
00397   return temp;
00398 }
00399 
00400 /// helper function: convert integer into string
00401 const std::string intToString(const int i) {
00402   std::ostringstream s;
00403   s << i;
00404   return s.str();
00405 }
00406 
00407 
00408 /**
00409 To get a better handling of the several Histogramms. This class initializes the histograms (name, title, binning, x-axis label) 
00410 and collects them in the std::vector m_histVector. By doing this looping over all the 
00411 histograms becomes much more convenient.
00412 */
00413 TH1D* baseAnalysis::initHist(string name, string title, string xlabel, int nrBins, double xmin, double xmax)
00414 {
00415   TDirectory* dir = gDirectory->GetDirectory(("/"+m_outputRootDir).c_str());
00416   if (dir) {
00417     dir->cd();
00418   } else {
00419     gDirectory->cd("/");
00420     dir = gDirectory->mkdir(m_outputRootDir.c_str());
00421     dir->cd();
00422   }
00423 
00424   // TH1D * histo=new TH1D((m_outputRootDir + "_" + intToString(m_histCounter[m_outputRootDir]) + "_" + name).c_str(),title.c_str(),nrBins,xmin,xmax);
00425   TH1D* histo=new TH1D((m_outputRootDir+"_"+intToString(m_histCounter[m_outputRootDir]) + "_" + name).c_str(),title.c_str(),nrBins,xmin,xmax);
00426   histo->GetXaxis()->SetTitle(xlabel.c_str());
00427   histo->GetYaxis()->SetTitle("Count");
00428   baseAnalysis::m_histVector.push_back(histo);
00429 
00430   ++m_histCounter[m_outputRootDir];
00431 
00432   return histo;
00433 }
00434 
00435 /**
00436 histograms with variable bin size
00437 */
00438 TH1D* baseAnalysis::initHistVariableBin(string name, string title, string xlabel, int nbin, Double_t nbinRange[])
00439 {
00440   TDirectory* dir = gDirectory->GetDirectory(("/"+m_outputRootDir).c_str());
00441   if (dir) {
00442     dir->cd();
00443   } else {
00444     gDirectory->cd("/");
00445     dir = gDirectory->mkdir(m_outputRootDir.c_str());
00446     dir->cd();
00447   }
00448 
00449   TH1D* histoVariableBin=new TH1D(name.c_str(),title.c_str(),nbin,nbinRange);
00450   histoVariableBin->GetXaxis()->SetTitle(xlabel.c_str());
00451   histoVariableBin->GetYaxis()->SetTitle("Count");
00452   baseAnalysis::m_histVector.push_back(histoVariableBin);
00453 
00454   return histoVariableBin;
00455 }
00456 
00457 /**
00458 This function returns true if the particle daughter is the decay product of the particle mother. 
00459 The function scans the mother particle up to a certain level,
00460 which can be specified with maxGenerations (negativ number --> all levels).
00461 */
00462 bool baseAnalysis::checkDaughter(HepMC::GenParticle* mother, HepMC::GenParticle* daughter, int maxGenerations)
00463 {
00464   bool found=false;
00465   int maxLoops=maxGenerations;
00466   int loop=1;
00467   
00468   // initialize the maximal number of mothers (Levels) to be checked
00469   if(maxGenerations<0) maxLoops=1000;
00470   
00471   // initialize current Production Vertex and mother particles
00472   // There should always be only one mother particle for decaying particles
00473   HepMC::GenVertex* current_vertex=daughter->production_vertex();
00474   HepMC::GenVertex::particle_iterator current_mother;
00475   
00476   // iterate through the mother particles and compare with mother
00477   // If found match, than stop the loop, otherwise try until there is no production vertex
00478   // or until you have reached the max number of loops specified
00479   while((current_vertex) && !(found) && (loop<maxLoops))
00480     {
00481       current_mother = current_vertex->particles_begin(HepMC::parents);
00482       
00483       if((*current_mother)==mother) 
00484         found=true;
00485       else
00486         current_vertex=(*current_mother)->production_vertex();
00487       
00488       loop++;
00489     }
00490   return found;
00491 }
00492 
00493 
00494 /** check if the track comes from a specific particle e.g. pid(W-Boson)=23 */
00495 bool baseAnalysis::trackfromPID(int pid, HepMC::GenParticle* track, int maxGenerations) 
00496 {
00497   bool found=false;
00498   int maxLoops=maxGenerations;
00499   int loop=1;
00500   
00501   // initialize the maximal number of mothers (Levels) to be checked
00502   if(maxGenerations<0) maxLoops=1000;
00503   
00504   // initialize current Production Vertex and mother particles
00505   // There should always be only one mother particle for decaying particles
00506   HepMC::GenVertex* current_vertex=track->production_vertex();
00507   HepMC::GenVertex::particle_iterator current_mother;
00508   
00509   // iterate through the mother particles and compare with mother
00510   // If found match, than stop the loop, otherwise try until there is no production vertex
00511   // or until you have reached the max number of loops specified
00512   while((current_vertex) && !(found) && (loop<maxLoops))
00513     {
00514       current_mother = current_vertex->particles_begin(HepMC::parents);
00515       
00516      //if no mother anymore, jump out the loop
00517       if(*current_mother==0)break;     
00518 
00519       if((*current_mother)->pdg_id()==pid) 
00520         found=true;
00521       else
00522         current_vertex=(*current_mother)->production_vertex();
00523       
00524       loop++;
00525     }
00526   return found;
00527 }

Generated on Fri Oct 23 14:14:02 2009 for HepMCAnalysis by  doxygen 1.4.7