Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

DefaultReconstructedParticleMaker.cxx

Go to the documentation of this file.
00001 // ================================================
00002 // DefaultReconstructedParticleMaker class Implementation
00003 // ================================================
00004 //
00005 // THIS TEXT TO BE REPLACED BY ATLAS STANDARD FORMAT
00006 //
00007 // Namespace Atlfast
00008 //
00009 
00010 #include "AtlfastAlgs/DefaultReconstructedParticleMaker.h"
00011 #include "AtlfastAlgs/DefaultSmearer.h"
00012 #include "AtlfastAlgs/ElectronSmearer.h"
00013 #include "AtlfastAlgs/MuonSmearer.h"
00014 #include "AtlfastAlgs/PhotonSmearer.h"
00015 #include "AtlfastAlgs/GlobalEventData.h" 
00016 
00017 #include "AtlfastEvent/MsgStreamDefs.h"
00018 #include "AtlfastEvent/MCparticleCollection.h"
00019 
00020 #include "AtlfastUtils/HeaderPrinter.h"
00021 #include "AtlfastUtils/HepMC_helper/IMCselector.h"
00022 #include "AtlfastUtils/HepMC_helper/SelectType.h"
00023 #include "AtlfastUtils/HepMC_helper/IsFinalState.h"
00024 #include "AtlfastUtils/HepMC_helper/MCCuts.h"
00025 #include "AtlfastUtils/HepMC_helper/NCutter.h"
00026 #include "AtlfastUtils/FunctionObjects.h"
00027 
00028 #include <cmath> 
00029 
00030 // Generic algorithms
00031 #include <algorithm>
00032 
00033 // Gaudi includes
00034 #include "GaudiKernel/DataSvc.h"
00035 #include "StoreGate/DataHandle.h"
00036 
00037 // CLHEP,HepMC
00038 #include "GeneratorObjects/McEventCollection.h"
00039 
00040 namespace Atlfast {
00041   using std::abs;
00042   using std::vector;
00043   using std::sort;
00044   //--------------------------------
00045   // Constructor 
00046   //--------------------------------
00047   
00048   DefaultReconstructedParticleMaker::DefaultReconstructedParticleMaker 
00049   ( const std::string& name, ISvcLocator* pSvcLocator )
00050     : Algorithm( name, pSvcLocator ){
00051     
00052     // Set the parameter defaults.
00053     m_particleType      = 11;
00054     m_mcPtMin           = 0.0;
00055     m_mcEtaMax          = 100.0;
00056     m_PtMin             = 5.0;
00057     m_EtaMax            = 2.5;
00058     m_doSmearing        = true;
00059     m_muSmearKey        = 1;
00060     m_MC_eventLocation  = "/Event/McEventCollection" ;
00061     m_outputLocation    = "/Event/AtlfastReconstructedParticle" ;
00062     
00063     // Declare the paramemters to Gaudi so that
00064     // they can be over-written via the job options file
00065     declareProperty( "ParticleType", m_particleType ) ;
00066     declareProperty( "mcMinimumPt", m_mcPtMin ) ;
00067     declareProperty( "mcMaximumEta", m_mcEtaMax ) ;
00068     declareProperty( "MinimumPt", m_PtMin ) ;
00069     declareProperty( "MaximumEta", m_EtaMax ) ;
00070     declareProperty( "DoSmearing",m_doSmearing ); 
00071     declareProperty( "MC_eventLocation", m_MC_eventLocation ) ;
00072     declareProperty( "OutputLocation", m_outputLocation ) ;
00073     declareProperty( "MuonSmearKey",m_muSmearKey ); 
00074     
00075   }
00076   
00077   //--------------------
00078   // Destructor
00079   //--------------------
00080   
00081   DefaultReconstructedParticleMaker::~DefaultReconstructedParticleMaker() {
00082     MsgStream log( messageService(), name() ) ;
00083     log << MSG::INFO << "Destructor Called" << endreq;
00084     
00085     if (m_smearer) {
00086       log << MSG::INFO << "Deleting smearer" << endreq;
00087       delete m_smearer;
00088     }
00089     if (m_tesIO) {
00090       log << MSG::INFO << "Deleting smearer" << endreq;
00091       delete m_tesIO;
00092     }
00093     if (m_ncutter) {
00094       log << MSG::INFO << "Deleting smearer" << endreq;
00095       delete m_ncutter;
00096     }
00097   }
00098   
00099   
00100   //---------------------------------
00101   // initialise() 
00102   //---------------------------------
00103   
00104   StatusCode DefaultReconstructedParticleMaker::initialize()
00105   {
00106     MsgStream log( messageService(), name() ) ;
00107     
00108     // This method is called by Athena once only, after all 
00109     // properties have been set.
00110     
00111     // Set up NCutter to select the required HepMC::GenParticles
00112     typedef HepMC_helper::IMCselector Selector;
00113 
00114     Selector* typeSelector = new HepMC_helper::SelectType( m_particleType);
00115     Selector* kineSelector = new HepMC_helper::MCCuts(m_mcPtMin, m_mcEtaMax);
00116     Selector* fstaSelector = new HepMC_helper::IsFinalState();
00117 
00118     vector<HepMC_helper::IMCselector*> selectors;
00119     selectors.push_back(fstaSelector);
00120     selectors.push_back(typeSelector);
00121     selectors.push_back(kineSelector);
00122     
00123     m_ncutter = new  HepMC_helper::NCutter(selectors);
00124     
00125     delete typeSelector;
00126     delete fstaSelector;
00127     delete kineSelector;
00128     //=======================================================
00129     
00130     
00131     //    m_tesIO = new TesIO(eventDataService());
00132     m_tesIO = new TesIO();
00133     //=====================
00134     
00135 
00136     //get the Global Event Data using singleton pattern
00137     GlobalEventData* ged = GlobalEventData::Instance();
00138     int lumi = ged->lumi();
00139     log << MSG::DEBUG << "got lumi " << endreq;
00140     int randSeed = ged->randSeed() ;
00141     if (m_doSmearing) this->getSmearer(lumi, randSeed, log);
00142     else m_smearer = NULL;
00143     
00144     HeaderPrinter hp("Atlfast ReconstructedParticle Maker:", log);
00145     hp.add("Particle Type           ", m_particleType);
00146     hp.add("Luminosity              ", lumi);        
00147     hp.add("Minimum four-vector Pt  ", m_mcPtMin);
00148     hp.add("Maximum four-vector Eta ", m_mcEtaMax);
00149     hp.add("Minimum particle    Pt  ", m_PtMin);
00150     hp.add("Maximum particle    Eta ", m_EtaMax);
00151     hp.add("Do Smearing             ", m_doSmearing);
00152     hp.add("Muon  Smearing Flag     ", m_muSmearKey);
00153     hp.add("Random Number Seed      ", randSeed);
00154     hp.add("MC location             ", m_MC_eventLocation);
00155     hp.add("Output Location         ", m_outputLocation);    
00156     hp.print();
00157     
00158 
00159       
00160     
00161         
00162     // We have to build an appropriate smearer object here.
00163     // The code which follows is to be regarded as a temporary fix to
00164     // get around the fact that Algorithms cannot be specialised by
00165     // constructor arguments.
00166     // When tools become avialable we will probably instead just pass 
00167     // an appropriate tool via job options
00168     return StatusCode::SUCCESS ;
00169   }
00170   
00171   //---------------------------------
00172   // finalise() 
00173   //---------------------------------
00174   
00175   StatusCode DefaultReconstructedParticleMaker::finalize()
00176   {
00177     
00178     MsgStream log( messageService(), name() ) ;
00179     
00180     log << MSG::INFO << "Finalizing" << endreq;  
00181     
00182     return StatusCode::SUCCESS ;
00183   }
00184   
00185   
00186   //----------------------------------------------
00187   // execute() method called once per event
00188   //----------------------------------------------
00189   //
00190   //  This algorithm creates smeared ReconstructedParticles.
00191   // 
00192   //  It takes HepMC::GenParticles from the TES as input. 
00193   //  Only HepMC::GenParticles satisfying the selection requirements
00194   //  are used.
00195   //
00196   //  A candidate ReconstructedParticle object is made by smearing the 
00197   //  four vector of the HepMC::GenParticle. 
00198   // 
00199   //  It then applies kinematic selection criteria to the properties of the 
00200   //  ReconstructedParticle. Only those which pass the cuts are kept.
00201   //
00202   //  Finally, all surviving ReconstructedParticles are added to the event 
00203   //  store.
00204   //
00205   //
00206   
00207   StatusCode DefaultReconstructedParticleMaker::execute( )
00208   {
00209     
00210     MsgStream log( messageService(), name() ) ;
00211     std::string mess;
00212     log << MSG::DEBUG << "Execute() " << endreq;
00213     
00214 
00215     //.............................
00216     // Obtain the truth HepMC::GenParticles which we want to process.
00217     // We fill a local collection with pointers to these Particles.
00218     // The private method which is used applies selection criteria
00219     // to the HepMC::GenParticles before placing them in the collection
00220     
00221     MCparticleCollection  my_MC_particles ;
00222     MCparticleCollectionCIter src ;
00223     
00224     TesIoStat stat = m_tesIO->getMC( my_MC_particles, m_ncutter ) ;
00225     mess = stat? "Retrieved MC from TES ":"Failed MC retrieve from TES";
00226     log << MSG::DEBUG << mess << endreq;
00227     
00228     // ......................
00229     // Make a container object which will store pointers to all  
00230     // ReconstructedParticles which are successfully created.  
00231     // Since it is going into the TES, it has to be a special Athena type 
00232     // of container. This is defined in an include file.
00233     
00234     ReconstructedParticleCollection* myReconstructedParticles 
00235       = new ReconstructedParticleCollection ;
00236     
00237     
00238     //.........................................................
00239     // From each mc truth Particle, create a ReconstructedParticle candidate.
00240     // If it satisfies requirements add to the output collection
00241     
00242     ReconstructedParticle* candidate ;
00243     
00244     for(src = my_MC_particles.begin() ; src != my_MC_particles.end() ; ++src){ 
00245         
00246       
00247       candidate = this->create( log, *src ); 
00248       
00249       if( this->isAcceptable( log, candidate ) ) {
00250         myReconstructedParticles->push_back( candidate ) ;     
00251       }else{
00252         delete candidate ;
00253       }
00254         
00255     }
00256     
00257     
00258     //.....................................
00259     // Sort into ascending order of pT
00260     
00261     if( myReconstructedParticles->size() > 0 ){
00262       sort( myReconstructedParticles->begin(),
00263             myReconstructedParticles->end(),
00264             SortAttribute::DescendingPT()
00265             ) ;
00266     }
00267     
00268     
00269     //......................................
00270     // Deal with resulting ReconstructedParticles (if any)
00271     
00272     stat =m_tesIO->store( myReconstructedParticles, m_outputLocation );
00273     mess = stat? "Store to TES success":"Store to TES failure";    
00274     log << MSG::DEBUG << mess << endreq;
00275 
00276     log << MSG::DEBUG << "Ending<-------- " << endreq;
00277     
00278     StatusCode sc=StatusCode::SUCCESS;  
00279     return sc ;
00280     
00281   }
00282   
00283   
00284   
00285   //----------------------------------
00286   // create()
00287   //----------------------------------
00288   
00289   // Takes a single MC Particle and creates a reconstructed
00290   // ReconstructedParticle according to the desired criteria
00291   //
00292   // Note that we must NEW these particles so they can go to the TES
00293   // and if we decide that we do not want them, we must DELETE them
00294   // Once they are put to the TES, they are no longer our responsibility to 
00295   // delete
00296   
00297   ReconstructedParticle* 
00298   DefaultReconstructedParticleMaker::create (
00299                                              MsgStream& log, 
00300                                              const HepMC::GenParticle* src ){
00301     
00302     ReconstructedParticle* candidate ;
00303     
00304     if (m_doSmearing) {
00305       
00306       // Ask our Smearer make a smeared 4-vector
00307       HepLorentzVector evec = m_smearer->smear( src->momentum() );
00308       
00309       log << MSG::DEBUG 
00310           << "\n\t"
00311           << "Unsmeared four-vector: " 
00312           << src->momentum()
00313           << "\n\t" 
00314           << "Smeared four-vector  : " 
00315           << evec 
00316           << endreq;
00317       
00318       // Note:It would really make sense to apply the kinematic cuts here. 
00319       // rather than in isAcceptable method.
00320       // However we leave this to next design phase as we also need to
00321       // consider where to put Isolation cuts.
00322       
00323       //Make a new ReconstructedParticle with smeared 4-vector
00324       //RMS Fix unsigned pdg_id
00325       candidate =  new ReconstructedParticle
00326         (src->pdg_id() /*m_particleType*/, evec, src ) ;
00327     }else{
00328       // Just use the original unsmeared four-momentum
00329       candidate = new ReconstructedParticle
00330         ( src->pdg_id() /*m_particleType*/, src->momentum(), src );
00331     }
00332     
00333     
00334     log << MSG::DEBUG 
00335         << "Created ReconstructedParticle: \n\t " 
00336         << candidate 
00337         << endreq;
00338     
00339     return candidate ;
00340     
00341   }
00342   
00343   
00344   //-------------------------------------------
00345   // isAcceptable
00346   //------------------------------------------
00347   
00348   // Decides whether a candidate is acceptable to this Maker, i.e. whether
00349   // it wants to proceed and add it to its output product collection
00350   
00351   bool DefaultReconstructedParticleMaker::isAcceptable 
00352   (MsgStream& log, const ReconstructedParticle* candidate ){
00353     
00354     // Apply kinematic criteria to the candidate DefaultReconstructedParticle
00355     
00356     if( candidate->pT() < m_PtMin ) {        
00357       log << MSG::DEBUG 
00358           << "Candidate failed pt cut: pt was " 
00359           << candidate->pT() 
00360           << " cut was " 
00361           << m_PtMin 
00362           << endreq;
00363       return false ;
00364     }
00365     
00366     if( abs(candidate->eta()) > m_EtaMax ) {
00367       log << MSG::DEBUG 
00368           << "Candidate failed max eta cut: eta was " 
00369           << candidate->eta() 
00370           << " cut was " 
00371           << m_EtaMax 
00372           << endreq;
00373       return false ;
00374     }
00375     
00376     log << MSG::DEBUG 
00377         << "Candidate passed selection cuts "
00378         << endreq ;
00379     
00380     return true ;
00381   }
00382   
00383   //-------------------------------------------
00384   // getSmearer
00385   //------------------------------------------
00386   void DefaultReconstructedParticleMaker::getSmearer(int lumi, 
00387                                                      int randSeed, 
00388                                                      MsgStream& log){
00389     
00390     if (m_particleType == 11) 
00391       {
00392         log << MSG::DEBUG << "instantiating an ElectronSmearer" << endreq;
00393         m_smearer = new ElectronSmearer(randSeed, lumi);
00394       } 
00395     else if (m_particleType == 13) 
00396       {
00397         log << MSG::DEBUG << "instantiating a MuonSmearer" << endreq;
00398         m_smearer = new MuonSmearer(randSeed, lumi, m_muSmearKey);
00399       } 
00400     else if (m_particleType == 22) 
00401       {
00402         log << MSG::DEBUG << "instantiating a PhotonSmearer" << endreq;
00403         m_smearer = new PhotonSmearer(randSeed, lumi);
00404       } 
00405     else 
00406       {
00407         log << MSG::ERROR 
00408             << "No specific smearer known for particle type " 
00409             << m_particleType 
00410             << " using a default which is probably not what you need!" 
00411             << endreq;
00412         m_smearer = new DefaultSmearer(randSeed);
00413       }
00414   }
00415 } // end namespace bracket
00416 
00417 

Generated on Tue Mar 18 11:18:23 2003 for AtlfastAlgs by doxygen1.3-rc1