TrackMaker.cxx

Go to the documentation of this file.
00001 // ================================================
00002 // TrackMaker class Implementation
00003 // ================================================
00004 //
00005 // THIS TEXT TO BE REPLACED BY ATLAS STANDARD FORMAT
00006 //
00007 // Namespace Atlfast::
00008 //
00009 #include "AtlfastAlgs/TrackMaker.h"
00010 #include "AtlfastAlgs/TrackSmearer.h"
00011 #include "AtlfastAlgs/GlobalEventData.h"
00012 
00013 #include "AtlfastEvent/ChargeService.h"
00014 
00015 #include "AtlfastUtils/HepMC_helper/IMCselector.h"
00016 #include "AtlfastUtils/HepMC_helper/IsCharged.h"
00017 #include "AtlfastUtils/HepMC_helper/IsFinalState.h"
00018 #include "AtlfastUtils/HepMC_helper/IsFromHardScatter.h"
00019 #include "AtlfastUtils/HepMC_helper/RejectType.h"
00020 #include "AtlfastUtils/HepMC_helper/NCutter.h"
00021 #include "AtlfastUtils/HepMC_helper/MCCuts.h"
00022 
00023 #include "CLHEP/Matrix/Matrix.h"
00024 #include "CLHEP/Units/SystemOfUnits.h"
00025 
00026 #include <cmath> 
00027 #include <algorithm>
00028 #include <fstream>
00029 
00030 // Gaudi includes
00031 #include "GaudiKernel/DataSvc.h"
00032 
00033 // Generator includes
00034 //#include "GeneratorObjects/McEventCollection.h"
00035 
00036 //--------------------------------
00037 // Constructors and destructors
00038 //--------------------------------
00039 
00040 using std::abs;
00041 
00042 namespace Atlfast 
00043 {
00044 
00045   TrackMaker::TrackMaker ( const std::string& name, ISvcLocator* pSvcLocator ) : 
00046     Algorithm( name, pSvcLocator ), 
00047     m_tesIO(0),
00048     m_ncutter(0),
00049     m_smearer(0),
00050     m_chargeService(0)
00051   {
00052     
00053     // Setting the parameter defaults - these can be changed by user via
00054     // jobOptions
00055     m_mcPtMin           = 0.5*GeV;
00056     m_mcEtaMax          = 2.5;
00057     m_vlMax             = 40.0*cm;
00058     m_vtMax             = 5.05*cm;
00059     m_doSmearing        = true;
00060     m_bField            = 2.0;
00061     m_muonParamFile     = "atlfastDatafiles/Atlfast_MuonResParam_CSC.dat";
00062     m_pionParamFile     = "atlfastDatafiles/Atlfast_PionResParam_DC1_NewUnits.dat";
00063     m_electronParamFile = "atlfastDatafiles/Atlfast_ElectronResParam_CSC.dat";
00064     m_bremParamFile     = "atlfastDatafiles/Atlfast_ElectronBremParam_CSC.dat";
00065     
00066     // Default paths for entities in the TES
00067     m_outputLocation    = "/Event/AtlfastTracks";
00068     
00069     // Declare the paramemters to Athena so that
00070     // they can be over-written via the job options file
00071     declareProperty( "McPtMinimum",           m_mcPtMin ) ;
00072     declareProperty( "McEtaMaximum",          m_mcEtaMax ) ;
00073     declareProperty( "vlMaximum",             m_vlMax ) ;
00074     declareProperty( "vtMaximum",             m_vtMax ) ;
00075     declareProperty( "DoSmearing",            m_doSmearing ); 
00076     declareProperty( "Bfield",                m_bField );
00077     declareProperty( "OutputLocation",        m_outputLocation ) ;
00078     declareProperty( "MuonParamFile",         m_muonParamFile );
00079     declareProperty( "PionParamFile",         m_pionParamFile );
00080     declareProperty( "ElectronParamFile",     m_electronParamFile );
00081     declareProperty( "ElectronBremParamFile", m_bremParamFile );
00082   }
00083   
00084   //----------------------------
00085   // Destructor
00086   //----------------------------
00087   TrackMaker::~TrackMaker() 
00088   {
00089 
00090     if (m_ncutter) delete m_ncutter;
00091     if (m_tesIO) delete m_tesIO;
00092     if (m_smearer) delete m_smearer;
00093     if (m_chargeService) delete m_chargeService;
00094   } 
00095   
00096   
00097   //---------------------------------
00098   // initialise() 
00099   //---------------------------------
00100   
00101   StatusCode TrackMaker::initialize()
00102   {
00103     MsgStream log( messageService(), name() ) ;
00104     
00105     //get the Global Event Data from singleton pattern
00106     GlobalEventData* ged         = GlobalEventData::Instance();
00107     int lumi                     = ged->lumi();
00108     int randSeed                 = ged->randSeed() ;
00109     m_mcLocation                 = ged->mcLocation();  
00110     std::vector<int> invisibles  = ged->invisibles();
00111 
00112     log << MSG::INFO << "Got invisibles " << invisibles << endreq ;
00113 
00114     m_tesIO = new TesIO(m_mcLocation, ged->justHardScatter());
00115     
00116     //=======================================================
00117     // Set up NCutter to select the required HepMC::GenParticles
00118     HepMC_helper::IMCselector* charged;
00119     try
00120     {
00121       charged = new HepMC_helper::IsCharged() ;
00122     }
00123     catch(std::string errMsg)
00124     {
00125       log << MSG::ERROR << "Error making IsCharged " << errMsg<< endreq ;
00126     }
00127     catch(...)
00128     {
00129       log << MSG::ERROR << "Unknown Error making IsCharged " << endreq ;
00130     }
00131     HepMC_helper::IMCselector* cuts            = new HepMC_helper::MCCuts( m_mcPtMin, m_mcEtaMax ) ;
00132     HepMC_helper::IMCselector* finalState      = new HepMC_helper::IsFinalState();
00133     HepMC_helper::IMCselector* fromHardScatter = new HepMC_helper::IsFromHardScatter();
00134     HepMC_helper::IMCselector* invisible       = new HepMC_helper::RejectType(invisibles);
00135 
00136 
00137     vector<HepMC_helper::IMCselector*> selectors;
00138     selectors.push_back(fromHardScatter);
00139     selectors.push_back(finalState);
00140     selectors.push_back(charged);
00141     selectors.push_back(cuts);
00142     selectors.push_back(invisible);
00143     
00144     m_ncutter = new HepMC_helper::NCutter(selectors);
00145     
00146     delete cuts;
00147     delete charged;
00148     delete finalState;
00149     delete fromHardScatter;
00150     delete invisible;
00151 
00152 
00153     try
00154     {
00155       m_chargeService = new ChargeService() ;
00156     }
00157     catch(std::string errMsg)
00158     {
00159       log << MSG::ERROR << "Error making ChargeService " << errMsg<< endreq ;
00160     }
00161     catch(...)
00162     {
00163       log << MSG::ERROR << "Unknown Error making ChargeService " << endreq ;
00164     }
00165     m_smearer = new TrackSmearer( randSeed, log, m_muonParamFile, 
00166                                                  m_pionParamFile,
00167                                                  m_electronParamFile,
00168                                                  m_bremParamFile );
00169     log << MSG::DEBUG << "got lumi " << endreq;
00170 
00171     HeaderPrinter hp("Atlfast Track Maker:", log);
00172     hp.add("Luminosity              ",     lumi);        
00173     hp.add("Minimum four-vector Pt  ",     m_mcPtMin);
00174     hp.add("Maximum four-vector Eta ",     m_mcEtaMax);
00175     hp.add("Maximum Transverse Vertex ",   m_vtMax);
00176     hp.add("Maximum Longitudinal Vertex ", m_vlMax);
00177     hp.add("Do Smearing             ",     m_doSmearing);
00178     hp.add("B Field                 ",     m_bField);
00179     hp.add("Muon Parameters         ",     m_muonParamFile);
00180     hp.add("Pion Parameters         ",     m_pionParamFile);    
00181     hp.add("Electron Parameters     ",     m_electronParamFile);    
00182     hp.add("Electron Brem Parameters",     m_bremParamFile);    
00183     hp.add("Random Number Seed      ",     randSeed);
00184     hp.add("MC location             ",     m_mcLocation);
00185     hp.add("Output Location         ",     m_outputLocation);    
00186     hp.print();
00187     log << MSG::INFO << "Initialised successfully " << endreq;    
00188     return StatusCode::SUCCESS;
00189   }
00190   
00191   //---------------------------------
00192   // finalise() 
00193   //---------------------------------
00194   
00195   StatusCode TrackMaker::finalize()
00196   {
00197     
00198     MsgStream log( messageService(), name() ) ;
00199     
00200     log << MSG::INFO << "Finalised successfully " << endreq ;
00201     
00202     return StatusCode::SUCCESS ;
00203   }
00204   
00205   
00206   //----------------------------------------------
00207   // execute() method called once per event
00208   //----------------------------------------------
00209   //
00210   //  This algorithm creates smeared Tracks passing cuts. 
00211   //  It scans the list of HepMC::GenParticles from the Monte Carlo truth. 
00212   //  It creates a Track object by smearing the Trajectory track parameters
00213   //  corresponding to the HepMC::GenParticle. 
00214   // 
00215   //  It then applies kinematic criteria on the properties of the Track
00216   //  Those which pass the cuts are kept.
00217   //  Finally all successful ReconstructedParticles are added to 
00218   //the event store.
00219   //
00220   
00221   StatusCode TrackMaker::execute()
00222   {
00223 
00224     //................................
00225     // make a message logging stream
00226     
00227     MsgStream log( messageService(), name() ) ;
00228     log << MSG::DEBUG << "Execute() " << endreq;
00229     
00230 
00231     //.........................................................
00232     // We now need to access the HepMC event record(s) in the event store
00233     // and iterate over them to extract HepMC::GenParticles.
00234     // This method will only select the particles which are required
00235     // and add them to a local store (mcParticles)
00236     
00237     MCparticleCollection  mcParticles ;
00238     TesIoStat stat; 
00239     std::string message;
00240     
00241     stat = m_tesIO->getMC( mcParticles, m_ncutter );
00242     message = stat?  "Found MCparticles in TES":"No MC particles found in TES";
00243     log<<MSG::DEBUG << message <<" "<<mcParticles.size()<<endreq;
00244     // ......................
00245     // Make a container object which will store pointers to all isolated 
00246     // Tracks which are successfully created.  Since it is going to go 
00247     // into the event store, it has to be a special Athena container. 
00248     // This is typedefined in an include file
00249     
00250     TrackCollection* tracks = new TrackCollection ;
00251     
00252 
00253     //.........................................................
00254     // From each mc Track create a reconstructed Track. 
00255     // If all requirements are satisfied add to the collection
00256     
00257     Track* candidate ;
00258     MCparticleCollectionCIter src ;
00259     
00260     for( src = mcParticles.begin() ; src != mcParticles.end() ; ++src ) 
00261     { 
00262       log << MSG::DEBUG << *src << endreq;
00263       candidate = this->create( *src ); 
00264       log << MSG::DEBUG << "Created: " << candidate << endreq;
00265       
00266       if( this->isAcceptable(candidate) ) 
00267       {    
00268         log << MSG::DEBUG << "Passed cuts" << endreq;
00269         tracks->push_back(candidate) ; 
00270         log << MSG::DEBUG << "pushed back track" <<endreq;
00271       }
00272       else 
00273       {
00274         log << MSG::DEBUG << "Failed cuts" << endreq;
00275         delete candidate ;
00276       }
00277     }
00278     
00279     //......................................
00280     // Register any Tracks which have been successfilly created in the 
00281     // transient event store. If there are none then we delete the empty list.
00282 
00283     stat = m_tesIO->store(tracks, m_outputLocation);
00284     message = stat  ?  "Stored tracks in TES"  :  "Error storing tracks in TES";
00285     log << MSG::DEBUG << message << " " << tracks->size() << endreq;
00286     
00287     return stat; 
00288 
00289   }
00290   
00291   
00292   
00293   //----------------------------------
00294   // create()
00295   //----------------------------------
00296   
00297   // Takes a single MC Particle and creates a Track
00298   // according to the desired criteria
00299   //
00300   // Note that we must NEW these particles so they can go to the TES
00301   // and if we decide that we do not want them, we must DELETE them
00302   // Once they are put to the TES, they are no longer our responsibility 
00303   // to delete
00304   
00305   Track* TrackMaker::create( const HepMC::GenParticle* src )
00306   {
00307     
00308     // Construct the Trajectory parameters corresponding to the source particle
00309     TrackTrajectory originalTrajectory = this->extractTrajectory( src ) ;
00310 
00311     if ( m_doSmearing ) 
00312     {
00313       // Ask our Smearer make a smeared set of Trajectory parameters
00314       // If this needs to be different for different particles then
00315       // it can be done here. Best  method of dispatching to be decided later
00316 
00317       Track myTrack( originalTrajectory, src );
00318       Track smearedTrack = m_smearer->smear( myTrack );
00319       
00320       // Return a new track
00321       Track* newTrack = new Track( smearedTrack );
00322       return newTrack;
00323     } 
00324     else 
00325     {
00326       // Just return the track with unsmeared four-momentum
00327       return new Track( originalTrajectory, src ) ;
00328     }
00329   }
00330   
00331   
00332   
00333   //-------------------------------------------
00334   // isAcceptable
00335   //------------------------------------------
00336   
00337   // Decides whether a candidate is acceptable to this Maker, i.e. whether
00338   // it wants to proceed and add it to its output product collection
00339   // however there are no post creation conditions applied to tracks
00340   // in this version 
00341   
00342   bool TrackMaker::isAcceptable ( Track* candidate )
00343   {
00344     HepPoint3D vertex = candidate->trajectory().startPoint();
00345     int pdg = abs( candidate->pdg_id() );
00346     if ( abs( vertex.z() ) > m_vlMax ) return false;
00347  
00348     // test track for vl and vt
00349     if ( pdg == 11 || pdg == 13 ) 
00350     {
00351       if ( vertex.perp() > m_vtMax ) return false;
00352     }
00353     return true ;
00354   }
00355   
00356   
00357   // Extract Trajectory parameters from HepMC::GenParticle
00358   TrackTrajectory TrackMaker::extractTrajectory( const HepMC::GenParticle* particle ) 
00359   {
00360     // Look up vertex
00361     Hep3Vector vertex = (particle->production_vertex())->position().getV();
00362     // Get 4-momentum and explicitly convert to 3-momentum
00363     Hep3Vector threeMomentum = particle->momentum().getV() ;
00364     // Obtain charge of particle
00365     double charge=m_chargeService->operator()(particle);
00366     
00367     return TrackTrajectory( threeMomentum, vertex, charge, m_bField ) ;
00368     
00369   }
00370   
00371 } // end namespace bracket

Generated on Mon Sep 24 14:19:12 2007 for AtlfastAlgs by  doxygen 1.5.1