Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

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

Generated on Thu Jul 23 14:57:36 2009 for HepMCAnalysis by  doxygen 1.3.9.1