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

Generated on Mon Jan 4 15:22:34 2010 for HepMCAnalysis by  doxygen 1.4.7