baseAnalysis.cc

Go to the documentation of this file.
00001 // STL
00002 #include <iostream>
00003 #include <sstream>
00004 #include <cmath>
00005 #include <stdio.h>
00006 
00007 #include "HepMC/GenEvent.h"
00008 #include "HepMC/IO_GenEvent.h"
00009 #include "HepMC/GenParticle.h"
00010 #include "HepMC/GenVertex.h"
00011 #include "HepMC/IO_AsciiParticles.h"
00012 #include "HepMC/SimpleVector.h"
00013 #include "HepPDT/ParticleData.hh"
00014 #include "CLHEP/Vector/LorentzVector.h"
00015 #include "fastjet/ClusterSequence.hh"
00016 #include "fastjet/SISConePlugin.hh"
00017 
00018 // ROOT 
00019 #include "TH1.h"
00020 #include "TH2.h"
00021 #include "TFile.h"
00022 #include "TMath.h"
00023 #include "TLorentzVector.h"
00024 
00025 #include "../include/baseAnalysis.h"
00026 
00027 //#define NDEBUG
00028 #include <cassert>
00029 
00030 using namespace std;
00031 
00032 /**
00033 Constructor
00034 */
00035 baseAnalysis::baseAnalysis()
00036 { 
00037   // initialize pointers!
00038   m_plugin = 0;
00039   m_jetDef = 0;
00040   m_clust_seq = 0;
00041 
00042   //for jet finder
00043   m_coneRadius          = 0.;
00044   m_overlapThreshold    = 0.;
00045   m_jet_ptmin           = 0.;
00046   m_lepton_ptmin        = 0.;
00047   m_DeltaR_lepton_track = 0.;
00048   m_Jetfinder_enabled   = false;
00049   
00050   // specify the maximum eta of tracks
00051   m_max_eta = 0.;
00052   m_min_pt  = 0.;
00053 
00054   // for calculation of the missing energy
00055   exMissTruth     = 0.;
00056   eyMissTruth     = 0.;
00057   etMissTruth     = 0.;
00058   etsumMissTruth  = 0.;
00059 
00060   // another pointer to be initialized  
00061 //  m_particleTable = 0;
00062 }
00063 
00064 /**
00065 Destructor: delete all the Pointer
00066 */
00067 baseAnalysis::~baseAnalysis()
00068 {
00069   // clean-up memory assigned to pointers
00070   /*if (m_plugin) {
00071     delete m_plugin;
00072     m_plugin = 0;
00073   }
00074   
00075   if (m_jetDef) {
00076     delete m_jetDef;
00077     m_jetDef = 0;
00078   }
00079   
00080   if ( m_clust_seq ) {
00081     m_clust_seq = 0;
00082     delete m_clust_seq;
00083   }*/
00084   
00085 /*  for (std::vector<TH1D*>::const_iterator i(m_histVector.begin()); i != m_histVector.end(); ++i) {
00086     delete (*i);
00087   }
00088   m_histVector.resize(0);*/
00089 
00090   //probably not needed anymore, due to averagedHistograms function
00091 /*  for (std::vector<TH1D*>::const_iterator i(m_histVectorVariableBin.begin()); i != m_histVectorVariableBin.end(); ++i) {
00092     delete (*i);
00093   }
00094   m_histVectorVariableBin.resize(0);*/
00095 
00096 //   while (!m_histVectorVariableBin.empty()){
00097 //     delete m_histVectorVariableBin.back();
00098 //     m_histVectorVariableBin.pop_back();
00099 //   }
00100 }
00101 
00102 // ---------------------------------------------------------------------- 
00103 int baseAnalysis::Init(double maxeta, double minpt) 
00104 {
00105   // this method is normally implemented in a derived class(es)
00106   cout << "baseAnalysis: WARNING: You have called the dummy function Init()." << endl; 
00107   return 0;
00108 }
00109 
00110 // ---------------------------------------------------------------------- 
00111 int baseAnalysis::Process(HepMC::GenEvent* hepmcevt) 
00112 { 
00113   // this method is normally implemented in a derived class(es)
00114   cout << "baseAnalysis: WARNING: You have called the dummy function Process()." << endl; 
00115   return 0;
00116 } 
00117 
00118 // ---------------------------------------------------------------------- 
00119 vector< TH1D* > baseAnalysis::averagedHistograms() 
00120 {
00121   return m_histVector;
00122 }
00123 
00124 // ---------------------------------------------------------------------- 
00125 vector<TH1D*>& baseAnalysis::Histograms()
00126 {
00127   return m_histVector;
00128 }
00129 
00130 /**
00131 InitJetFinder: Initialisation of JetFinder
00132 */
00133 int baseAnalysis::InitJetFinder(double coneRadius,  double overlapThreshold, double jet_ptmin, double lepton_ptmin, 
00134   double DeltaR_lepton_track, int jetalgorithm)
00135 {
00136 // jetalgorithm = 1 for siscone, =2 for antikt
00137 
00138     if(m_Jetfinder_enabled){
00139         // If the Pointer already exist, delete them
00140         if(m_jetDef) {
00141             delete m_jetDef;
00142             m_jetDef=0;
00143         }
00144         
00145         if(m_plugin){
00146             delete m_plugin;
00147             m_plugin=0;
00148         }
00149     }
00150     
00151  // initialise fastjet
00152   m_coneRadius = coneRadius;
00153   m_overlapThreshold = overlapThreshold;
00154   m_jet_ptmin = jet_ptmin;
00155   m_lepton_ptmin = lepton_ptmin;
00156   m_DeltaR_lepton_track = DeltaR_lepton_track;
00157 
00158   
00159   if(jetalgorithm == 1) {
00160       m_plugin = new fastjet::SISConePlugin(m_coneRadius, m_overlapThreshold);
00161       m_jetDef = new fastjet::JetDefinition(m_plugin);}
00162   else if (jetalgorithm==2) {
00163     m_plugin = 0;
00164     m_jetDef = new fastjet::JetDefinition(fastjet::antikt_algorithm,m_coneRadius);}
00165   else
00166     m_jetDef = 0;
00167 
00168   //   m_plugin = fastjet::antikt_algorithm(m_coneRadius);}
00169 
00170 
00171   if(!m_jetDef) return false;
00172 
00173   m_Jetfinder_enabled=true;
00174   return true;
00175 
00176 }
00177 
00178 
00179 
00180 /**
00181 FindJetableParticles
00182 */
00183 int baseAnalysis::FindJetableParticles(HepMC::GenEvent* hepmcevt)
00184 {
00185   //delete m_clust_seq;
00186   //m_clust_seq=0;
00187   if(!m_Jetfinder_enabled || !m_jetDef){
00188     cerr << "baseAnalysis: FastJet Algorithm not initialized!" << endl;
00189     return false;
00190   }
00191   CLHEP::HepLorentzVector lv_leadingJet(0,0,0,0);
00192 
00193   for ( HepMC::GenEvent::particle_const_iterator p =
00194           hepmcevt->particles_begin(); p != hepmcevt->particles_end(); ++p ){
00195 
00196     // use the pdg id to identify the particles
00197     int pid = (*p)->pdg_id();
00198 
00199 
00200     
00201     // first of all we need stable particle
00202     if (!(((*p)->status()%1000) == 1)) continue;
00203     if ((*p)->end_vertex()) continue;
00204     
00205     // cut out the neutral particles (charge is not stored in HepMC)
00206     // just remove the neutrinos and Neutron from the final state
00207     if(IsNeutrino(pid) || IsNeutron(pid)) continue;
00208 
00209     // cut out all isolated leptons
00210     // variables for DeltaR calculation
00211     double deltaPhi = 0;
00212     double deltaEta = 0;
00213     double DeltaR = 9999;
00214 
00215     // cut variables
00216     double DeltaRCut = m_DeltaR_lepton_track;
00217     double LeptonpTCut = m_lepton_ptmin;
00218 
00219     if(IsElectron(pid) || IsMuon(pid)) {
00220       int lepton_barcode = (*p)->barcode();
00221       HepMC::GenParticle *lepton = hepmcevt->barcode_to_particle(lepton_barcode);
00222       
00223       // set pt cut for lepton
00224       if(fabs((*lepton).momentum().perp()) > LeptonpTCut) continue;
00225       
00226       // check if it is an isolated lepton
00227       for ( HepMC::GenEvent::particle_const_iterator q = hepmcevt->particles_begin(); 
00228             q != hepmcevt->particles_end(); ++q ){
00229         if(lepton_barcode==(*q)->barcode()) continue;
00230 
00231         // set DeltaR cut
00232         deltaPhi = (*p)->momentum().phi()-(*q)->momentum().phi();
00233 
00234         if( deltaPhi > TMath::Pi() ||  deltaPhi == TMath::Pi() )
00235           {
00236             deltaPhi = deltaPhi - 2 * TMath::Pi() ;
00237           }
00238         
00239         if( deltaPhi < - TMath::Pi() ||  deltaPhi == - TMath::Pi() )
00240           {
00241             deltaPhi = deltaPhi + 2 * TMath::Pi();
00242           }
00243 
00244         deltaEta = (*p)->momentum().eta()-(*q)->momentum().eta();
00245         double DeltaRnew = sqrt( pow(deltaPhi,2) + pow(deltaEta,2));
00246 
00247         if(DeltaRnew < DeltaR) DeltaR = DeltaRnew;
00248       }
00249       if(DeltaR > DeltaRCut) continue;
00250     }
00251 
00252     // or ... remove all charged particles 
00253     //if(chargedParticle(pid)==NOTCHARGED) continue;
00254     
00255     // They need to have a production Vertex --> we will not select incoming Protons from the Beam
00256     if (!(*p)->production_vertex()) continue;
00257     // And since they are stable they should not have a decay vertex.
00258     if ((*p)->end_vertex()) continue;
00259     
00260 //     // check wether the track directly comes from a Z-Boson
00261 //     if( trackfromPID(23,(*p)) ) continue;
00262     
00263 //     // check wether the track directly comes from a W-Boson
00264 //     if( trackfromPID(24,(*p)) ) continue;
00265 //     if( trackfromPID(-24,(*p)) ) continue;
00266     
00267     //set the eta cut for charged particles 
00268     double eta = (*p)->momentum().eta(); 
00269     if(std::abs(eta) > m_max_eta )  continue;
00270     
00271     //set the pt cut for charged particles 
00272     double pt = (*p)->momentum().perp(); 
00273     if(pt < m_min_pt) continue;
00274     
00275     double px = (*p)->momentum().x();
00276     double py = (*p)->momentum().y();
00277     double pz = (*p)->momentum().z();
00278     double pe = (*p)->momentum().e();
00279     
00280     
00281     // jet finding in stable particles record for charged particles
00282     fastjet::PseudoJet tempVec;
00283     tempVec = fastjet::PseudoJet(px,py,pz,pe);
00284     m_input_particles.push_back(tempVec);
00285   }
00286   return true;
00287 }
00288 
00289 /**
00290 FindJet: run JetFinder
00291 */
00292 int baseAnalysis::FindJet(HepMC::GenEvent* hepmcevt) 
00293 {
00294   if (!m_Jetfinder_enabled || !m_jetDef) {
00295     cerr << "baseAnalysis: FastJet Algorithm not initialized!" << endl;
00296     return false;
00297   }
00298   
00299   // run the jet finding
00300   if (m_input_particles.empty()) {
00301     if ( !FindJetableParticles(hepmcevt) ) {
00302       return false;
00303     }
00304   }
00305   
00306   if (m_input_particles.size()) { 
00307     m_clust_seq = new fastjet::ClusterSequence(m_input_particles, *m_jetDef);
00308   } else {
00309     m_clust_seq = 0;
00310   }
00311   
00312   if (m_input_particles.empty() || m_clust_seq==0) { 
00313     return false;
00314   }
00315   
00316   // select jets above a threshold, e.g. 0.5 GeV                                                                              
00317   m_inclusive_jets = sorted_by_pt( m_clust_seq->inclusive_jets( m_jet_ptmin ) );
00318   
00319   return true;
00320 }
00321 
00322 // ---------------------------------------------------------------------- 
00323 vector< fastjet::PseudoJet > baseAnalysis::GetJet(HepMC::GenEvent* hepmcevt) 
00324 {
00325   if(m_inclusive_jets.empty()) {
00326     FindJet(hepmcevt);
00327     //int inputJet = FindJet(hepmcevt);
00328     //if(inputJet==FAILURE) std::cout<<"baseAnalysis::no jets found"<<std::endl;
00329   }
00330   return m_inclusive_jets;
00331   //return SUCCESS;
00332 }
00333   
00334 // ---------------------------------------------------------------------- 
00335 void baseAnalysis::SetJet( vector< fastjet::PseudoJet > *inclusive_jets )
00336 {
00337   m_inclusive_jets = *inclusive_jets;
00338 }
00339 
00340 /**
00341 DeleteJetObject: delete all the jet objects
00342 */
00343 int baseAnalysis::DeleteJetObject(HepMC::GenEvent* hepmcevt) {
00344   //if(!m_input_particles.size()&&!m_inclusive_jets.size()&&!m_clust_seq) return FAILURE;
00345   //if(!(m_input_particles.size()&&m_inclusive_jets.size()&&m_clust_seq)) return FAILURE;
00346 
00347   m_input_particles.clear();
00348    m_inclusive_jets.clear();
00349   delete m_clust_seq;
00350   m_clust_seq=0;
00351 
00352   return true;
00353 }
00354 
00355 /**
00356 FindMissingEt: calculate the missing transversal energy of each event
00357 */
00358 int baseAnalysis::FindMissingEt(HepMC::GenEvent* hepmcevt) 
00359 {
00360   int properStatus = 1; //stable particles
00361   
00362   exMissTruth     = 0.0;
00363   eyMissTruth     = 0.0;
00364   etMissTruth     = 0.0;
00365   etsumMissTruth  = 0.0;
00366   
00367   // loop over the particles in GenEvent and select pdgid and pt
00368   for ( HepMC::GenEvent::particle_const_iterator p =  hepmcevt->particles_begin(); p != hepmcevt->particles_end(); ++p ) {
00369     int pid = (*p)->pdg_id();
00370 
00371     // skip all not stable particles
00372     if ( (*p)->status()%1000 != properStatus ) continue;
00373     if ( (*p)->end_vertex() ) continue;
00374 
00375     // fiducial range eta cut on 2.5
00376     if(fabs((*p)->momentum().eta()) > 2.5) continue;
00377     // minimum pt for tracks on 0.5 GeV
00378     if((*p)->momentum().perp() < 0.5) continue;
00379 
00380     double px  = (*p)->momentum().px();
00381     double py  = (*p)->momentum().py();
00382     double pt  = (*p)->momentum().perp();
00383 
00384     if ( IsNeutrino(pid) || abs(pid)==1000039 || abs(pid) ==1000022 || abs(pid) ==39 || abs(pid) ==5100022 ) {
00385       exMissTruth     += px;    
00386       eyMissTruth     += py;
00387       etsumMissTruth  += pt;
00388     }
00389   }
00390   
00391   etMissTruth = sqrt(exMissTruth*exMissTruth + eyMissTruth*eyMissTruth); 
00392   
00393   return true;
00394 }
00395 
00396 /**
00397 ClearMissingEt: setting the variables to calculate missing energy to zero
00398 */
00399 int baseAnalysis::ClearMissingEt(HepMC::GenEvent* hepmcevt) 
00400 {
00401   exMissTruth     = 0.0;
00402   eyMissTruth     = 0.0;
00403   etMissTruth     = 0.0;
00404   etsumMissTruth  = 0.0;
00405 
00406   return true;
00407 }
00408 
00409 /** 
00410 Check if final state particle: returns 0 if it is not a final state particle, 1 otherwise
00411 */
00412 int baseAnalysis::IsFinalStateParticle(HepMC::GenParticle *p) 
00413 {
00414   // first of all we need stable particle
00415   if ( !( (*p).status()%1000 == 1 ) ) return false;
00416 
00417   // And since they are stable they should not have a decay vertex. 
00418   if ( (*p).end_vertex() ) return false;
00419     
00420   // fiducial range eta cut on 2.5
00421   if( fabs((*p).momentum().eta()) > 2.5 ) return false;
00422   
00423   // minimum pt for tracks on 0.5
00424   if( (*p).momentum().perp() < 0.5 ) return false;
00425 
00426   return true;
00427 }
00428 
00429 /**
00430 ClearEvent: 
00431   delete and clear some variables from the event
00432 */
00433 int baseAnalysis::ClearEvent(HepMC::GenEvent* hepmcevt) 
00434 {
00435   baseAnalysis::DeleteJetObject(hepmcevt);
00436   baseAnalysis::ClearMissingEt(hepmcevt);
00437 
00438   return true;
00439 }
00440 
00441 // ---------------------------------------------------------------------- 
00442 int baseAnalysis::setOutputFileName(const string& filename)
00443 { 
00444   m_outputFileName = filename; 
00445   return 0;
00446 }
00447   
00448 // ---------------------------------------------------------------------- 
00449 int baseAnalysis::setOutputRootDir(const string& dirname)
00450 { 
00451   m_outputRootDir = dirname; 
00452   return 0;
00453 }
00454 
00455 // ---------------------------------------------------------------------- 
00456 bool baseAnalysis::IsNeutrino(int pid) 
00457 { 
00458   if( abs(pid)==12 || abs(pid)==14 || abs(pid)==16) return true; 
00459   else return false; 
00460 }
00461 
00462 // ---------------------------------------------------------------------- 
00463 bool baseAnalysis::IsGamma(int pid) 
00464 { 
00465   if( abs(pid)==22 ) return true; 
00466   else return false;
00467 }
00468 
00469 // ---------------------------------------------------------------------- 
00470 bool baseAnalysis::IsNeutron(int pid) 
00471 { 
00472   if( abs(pid)==2112 ) return true; 
00473   else return false; 
00474 }
00475 
00476 // ---------------------------------------------------------------------- 
00477 bool baseAnalysis::IsK0(int pid) 
00478 { 
00479   if( abs(pid)==130 || abs(pid)==310 || abs(pid)==311 ) return true; 
00480   else return false; 
00481 }
00482 
00483 // ---------------------------------------------------------------------- 
00484 bool baseAnalysis::IsPi0(int pid) 
00485 { 
00486   if( abs(pid)==111 || abs(pid)==113 || abs(pid)==221 ) return true; 
00487   else return false; 
00488 }
00489 
00490 // ---------------------------------------------------------------------- 
00491 bool baseAnalysis::IsElectron(int pid) 
00492 { 
00493   if( abs(pid)==11 ) return true; 
00494   else return false; 
00495 }
00496 
00497 // ---------------------------------------------------------------------- 
00498 bool baseAnalysis::IsMuon(int pid) 
00499 { 
00500   if( abs(pid)==13 ) return true; 
00501   else return false; 
00502 }
00503 
00504 // ---------------------------------------------------------------------- 
00505 bool baseAnalysis::IsGluon(int pid) 
00506 { 
00507   if( abs(pid)==21 ) return true; 
00508   else return false; 
00509 }
00510 
00511 // ---------------------------------------------------------------------- 
00512 bool baseAnalysis::chargedParticle(int pid) 
00513 { 
00514   if( IsNeutrino(pid) || IsGamma(pid) || IsNeutron(pid) || IsK0(pid) || IsPi0(pid) || IsGluon(pid) || 
00515     abs(pid)== 94 || abs(pid)==1000039 || abs(pid) ==1000022 || abs(pid) ==39 || abs(pid) ==5100022 ) {
00516       //above neutral particles and some "special" neutral particles
00517     return false;
00518   }  
00519   
00520   return true;
00521 }
00522   
00523 // ---------------------------------------------------------------------- 
00524 int baseAnalysis::setMaxEtaCut(double maxeta)
00525 { 
00526   m_max_eta = maxeta; 
00527   return 0;
00528 }
00529 
00530 // ---------------------------------------------------------------------- 
00531 int baseAnalysis::setMinPtCut(double minpt)
00532 { 
00533   m_min_pt = minpt; 
00534   return 0;
00535 }
00536 
00537 /**
00538 Finalize:
00539 In the final step all the histogramms are stored in a rootfile.
00540 The name of the rootfile can be set with the function setOutputFileName(const string& fileName). 
00541  */
00542 int baseAnalysis::Finalize() 
00543 {
00544   //write the output in a root file
00545   TFile f(m_outputFileName.c_str(), "RECREATE");
00546   Finalize(&f);
00547   f.Close();
00548   
00549   return true;
00550 }
00551 
00552 /**
00553 In the final step all the histogramms are stored in a rootfile.
00554 The name of the rootfile can be set with the function setOutputFileName(const string &fileName). 
00555  */
00556 int baseAnalysis::Finalize(TFile* output) 
00557 {
00558   TDirectory* dir = output->GetDirectory(m_outputRootDir.c_str());
00559   if (dir) {
00560     dir->cd();
00561   } else {
00562     cout << "The directory " << m_outputRootDir << " will be created" << endl;
00563     dir = output->mkdir(m_outputRootDir.c_str());
00564     dir->cd();
00565   }
00566 
00567   // loop over the standard vector
00568   for ( vector< TH1D * >::const_iterator iter = m_histVector.begin(); iter!=m_histVector.end(); iter++ ) 
00569     (*iter)->Write(); 
00570   
00571   // probably not needed anymore, due to averagedHistograms function
00572   //   for ( vector< TH1D * >::const_iterator iter = m_histVectorVariableBin.begin(); iter!=m_histVectorVariableBin.end(); iter++ ) 
00573   //     (*iter)->Write(); 
00574   
00575   return true;
00576 }
00577 
00578 /**
00579 popHisto:
00580 return the last entry  of the histogram vector, needed for ATHENA (ATLAS software) implementation
00581 */
00582 //TH1D* baseAnalysis::popHisto(std::vector<TH1D*> m_histVector) {
00583 TH1D* baseAnalysis::popHisto() 
00584 {
00585   // return NULL pointer if no histogram
00586   if (m_histVector.empty()) return 0;
00587 
00588   // get last element from vector (don't change vector)
00589   TH1D* temp = m_histVector.back();
00590   std::cout<<"m_histVector.back()"<< temp;
00591   // delete last entry from vector
00592   m_histVector.pop_back();
00593   return temp;
00594 }
00595 
00596 /**
00597 InitHist:
00598   To get a better handling of the several Histogramms. This class initializes the histograms (name, title, binning, x-axis label) 
00599   and collects them in the std::vector m_histVector. By doing this looping over all the 
00600   histograms becomes much more convenient.
00601 */
00602 TH1D* baseAnalysis::initHist(const string &name, const string &title, const string &xlabel, 
00603     int nrBins, double xmin, double xmax)
00604 {
00605   TDirectory* dir = gDirectory->GetDirectory(("/"+m_outputRootDir).c_str());
00606   if (dir) {
00607     dir->cd();
00608   } else {
00609     gDirectory->cd("/");
00610     dir = gDirectory->mkdir(m_outputRootDir.c_str());
00611     dir->cd();
00612   }
00613 
00614     // convert integer into string
00615   int histCnt = m_histCounter[ m_outputRootDir ];
00616   ostringstream ssHistCnt;
00617   ssHistCnt << histCnt; 
00618 
00619   TH1D* histo = new TH1D((m_outputRootDir + "_" + ssHistCnt.str() + "_" + name).c_str(), title.c_str(), 
00620     nrBins, xmin, xmax);
00621   //TH1D* histo=new TH1D((m_outputRootDir+"_"+intToString(m_histCounter[m_outputRootDir]) + "_" + name).c_str(),
00622   //title.c_str(),nrBins,xmin,xmax);
00623 
00624   histo->GetXaxis()->SetTitle(xlabel.c_str());
00625   histo->GetYaxis()->SetTitle("Count");
00626   m_histVector.push_back(histo);
00627 
00628   ++m_histCounter[m_outputRootDir];
00629 
00630   return histo;
00631 }
00632 
00633 /**
00634 InitHistVariableBin: 
00635   histograms with variable bin size
00636 */
00637 TH1D* baseAnalysis::initHistVariableBin(const string &name, const string &title, const string &xlabel, 
00638     int nbin, Double_t nbinRange[])
00639 {
00640   TDirectory* dir = gDirectory->GetDirectory( ("/"+m_outputRootDir).c_str() );
00641   if (dir) {
00642     dir->cd();
00643   } else {
00644     gDirectory->cd("/");
00645     dir = gDirectory->mkdir(m_outputRootDir.c_str());
00646     dir->cd();
00647   }
00648 
00649   TH1D* histoVariableBin = new TH1D(name.c_str(), title.c_str(), nbin, nbinRange);
00650   histoVariableBin->GetXaxis()->SetTitle(xlabel.c_str());
00651   histoVariableBin->GetYaxis()->SetTitle("Count");
00652   m_histVector.push_back(histoVariableBin);
00653 
00654   return histoVariableBin;
00655 }
00656 
00657 /**
00658 CheckDaughter:
00659   This function returns true if the particle daughter is the decay product of the particle mother. 
00660   The function scans the mother particle up to a certain level,
00661   which can be specified with maxGenerations (negativ number --> all levels).
00662 */
00663 bool baseAnalysis::checkDaughter(HepMC::GenParticle* mother, HepMC::GenParticle* daughter, int maxGenerations)
00664 {
00665   // initialize the maximal number of mothers (Levels) to be checked
00666   const size_t maxLoops = ((maxGenerations < 0) ? 1000 : maxGenerations);
00667   
00668   // initialize current Production Vertex and mother particles
00669   // There should always be only one mother particle for decaying particles
00670   HepMC::GenVertex* current_vertex = daughter->production_vertex();
00671   HepMC::GenVertex::particle_iterator current_mother;
00672   
00673   bool found = false;
00674   size_t loopCnt = 1;
00675 
00676   // iterate through the mother particles and compare with mother
00677   // If found match, than stop the loop, otherwise try until there is no production vertex
00678   // or until you have reached the max number of loops specified
00679   while ((current_vertex) && !(found) && (loopCnt < maxLoops)) {
00680     current_mother = current_vertex->particles_begin(HepMC::parents);
00681       
00682     if ((*current_mother) == mother) {
00683         found = true;
00684     } else {
00685         current_vertex = (*current_mother)->production_vertex();
00686     }
00687     // check next level  
00688     ++loopCnt;
00689   }
00690   return found;
00691 }
00692 
00693 /** 
00694 TrackFromPID: 
00695   check if the track comes from a specific particle e.g. pid(W-Boson)=23 
00696 */
00697 bool baseAnalysis::trackfromPID(int pid, HepMC::GenParticle* track, int maxGenerations) 
00698 {
00699   // initialize the maximal number of mothers (Levels) to be checked
00700   const size_t maxLoops = ((maxGenerations < 0) ? 1000 : maxGenerations);
00701    
00702   // initialize current Production Vertex and mother particles
00703   // There should always be only one mother particle for decaying particles
00704   HepMC::GenVertex* current_vertex=track->production_vertex();
00705   HepMC::GenVertex::particle_iterator current_mother;
00706   
00707   bool found = false;
00708   size_t loopCnt = 1;
00709 
00710   // iterate through the mother particles and compare with mother
00711   // If found match, than stop the loop, otherwise try until there is no production vertex
00712   // or until you have reached the max number of loops specified
00713   while ((current_vertex) && !(found) && (loopCnt < maxLoops)) {
00714     current_mother = current_vertex->particles_begin(HepMC::parents);
00715       
00716     //if no mother anymore, jump out the loop
00717     if (*current_mother == 0) break;     
00718 
00719     if ((*current_mother)->pdg_id() == pid) {
00720             found = true;
00721     } else {
00722         current_vertex = (*current_mother)->production_vertex();
00723     }
00724     // check next level  
00725     ++loopCnt;
00726   }
00727 
00728   return found;
00729 }
00730 
00731 /**
00732 GetRapidity: 
00733   calculate rapidity of a given particle 
00734 */
00735 double baseAnalysis::getRapidity(const HepMC::GenEvent::particle_const_iterator &p) 
00736 {
00737   double e  = (*p)->momentum().e();
00738   double pz = (*p)->momentum().pz();
00739   double rapidity = 0.5 * log((e + pz) / (e - pz));
00740   return rapidity;
00741 }
00742 

Generated on Tue Mar 1 01:18:31 2011 for HepMCAnalysis by  doxygen 1.4.7