TauMaker.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------
00002 //
00003 // file:     TauMaker.cxx
00004 //
00005 // Creates Tau candidates from Atlfast Tracks. 
00006 //
00007 //-----------------------------------------------------------------------
00008 #include <fstream>
00009 #include <cmath>
00010 
00011 #include <GaudiKernel/MsgStream.h>
00012 
00013 #include "CLHEP/Vector/LorentzVector.h"
00014 #include "CLHEP/Random/JamesRandom.h"
00015 #include "CLHEP/Random/RandGauss.h"
00016 #include "CLHEP/Random/RandFlat.h"
00017 #include "CLHEP/Units/SystemOfUnits.h"
00018 #include "CLHEP/Random/RandomEngine.h"
00019 
00020 #include "HepMC/GenVertex.h"
00021 
00022 #include "AtlfastEvent/Phi.h"
00023 #include "AtlfastEvent/Track.h"
00024 #include "AtlfastEvent/CollectionDefs.h"
00025 
00026 #include "AtlfastAlgs/TauMaker.h"
00027 #include "AtlfastAlgs/GlobalEventData.h"
00028 
00029 #include "PathResolver/PathResolver.h"
00030 
00031 // -------------------------------------
00032 
00033 namespace Atlfast
00034 {
00035   //-------------------------------------------------------------------------
00036   // Constructor
00037   //-------------------------------------------------------------------------
00038   TauMaker::TauMaker( const std::string& name, ISvcLocator* pSvcLocator ) 
00039     : Algorithm( name, pSvcLocator ),
00040       m_tesIO(0)
00041   {
00042     
00043     //Default private parameters   
00044     m_TrackEffFile       = "atlfastDatafiles/trackEffInputFile.txt";
00045     m_TrackCollection    = "/Event/AtlfastTracks";
00046     m_outputLocation     = "/Event/AtlfastTaus";
00047     m_recoEtaCut         = 2.5; 
00048     m_pTLeadTrackCut     = 9000.0;
00049     m_pTOtherTrackCut    = 1000.0;
00050     m_maxNumTracks       = 3;
00051     m_detRCoreTrackCut   = 0.2;
00052     m_detRCoreCaloCut    = 0.2;
00053     m_detRRecoSeparation = 0.4; //Min separation of seed track from other reco tau
00054     m_detRTrueTauCut     = 0.2;
00055     m_recoETCut          = 10000.0;
00056     
00057     m_resEflowEne        = 0.3; //Energy Smearing: Need to optimise - guess 30% for now
00058     m_resNeuhEne         = 0.3; //Neutron ECal response - guess 30% for now...
00059     m_resTrack           = 0.5; //Keep for now, may remove later
00060     m_eleVetoEff         = 0.92; //Numbers adapted from TP Week June 2007
00061     m_muoVetoEff         = 0.96; //Numbers adapted from TP Week June 2007
00062     
00063     
00064     //Declare joboption properties here...
00065     declareProperty( "TrackCollection",    m_TrackCollection    );
00066     declareProperty( "OutputLocation",     m_outputLocation     );
00067     declareProperty( "RecoEtaCut",         m_recoEtaCut         );
00068     declareProperty( "pTLeadTrackCut",     m_pTLeadTrackCut     );
00069     declareProperty( "pTOtherTrackCut",    m_pTOtherTrackCut    );
00070     declareProperty( "maxNumTracks",       m_maxNumTracks       );
00071     declareProperty( "detRCoreTrackCut",   m_detRCoreTrackCut   );
00072     declareProperty( "detRCoreCaloCut",    m_detRCoreCaloCut    );
00073     declareProperty( "detRRecoSeparation", m_detRRecoSeparation );
00074     declareProperty( "detRTrueTauCut",     m_detRTrueTauCut     );
00075     declareProperty( "resEflowEne",        m_resEflowEne        );
00076     declareProperty( "recoETCut",          m_recoETCut          );
00077     declareProperty( "resNeuhEne",         m_resNeuhEne         );
00078     declareProperty( "resTrack",           m_resTrack           ); //Possibly obsolete
00079     declareProperty( "eleVetoEff",         m_eleVetoEff         );
00080     declareProperty( "muoVetoEff",         m_muoVetoEff         );
00081     declareProperty( "TrackEffFile",       m_TrackEffFile       );
00082   }
00083   
00084   TauMaker::~TauMaker() {
00085     
00086     if (m_tesIO) {
00087       delete m_tesIO;
00088     }
00089   }
00090   
00091   //----------------------------------------------------------------
00092   // Tool initialization
00093   //----------------------------------------------------------------
00094   StatusCode TauMaker::initialize()
00095   {
00096     MsgStream p_log( messageService(), name() ) ;
00097 
00098     p_log << MSG::VERBOSE << "RecoEtaCut         = ";
00099     p_log << m_recoEtaCut << endreq;
00100     
00101     
00102     GlobalEventData* ged = GlobalEventData::Instance();
00103     int randSeed = ged->randSeed() ;
00104     m_tesIO      = new TesIO(ged->mcLocation(), ged->justHardScatter());
00105     
00106     // Random Number Generators
00107     // Concerns about using the same random number 
00108     // engine for both m_randGauss and m_randFlat.
00109     // pass engine by reference rather than by pointer
00110     // to avoid deletion issues. (if passed by pointer
00111     // the engine is deleted when m_randGauss is deleted,
00112     // but then you can't delete m_randFlat without seg fault)
00113     // OR MAYBE USE GLOBAL RANDOM NUMBER ENGINE?
00114     
00115     m_randEngine   = new HepJamesRandom( randSeed );
00116     m_randGauss    = new RandGauss( *m_randEngine );
00117     m_randFlat     = new RandFlat( *m_randEngine );
00118     
00119     
00120     p_log << MSG::DEBUG << "m_TrackEffFile before PathResolver: " 
00121           << m_TrackEffFile <<endreq;
00122     m_TrackEffFile = PathResolver::find_file (m_TrackEffFile, "DATAPATH");
00123     p_log << MSG::DEBUG << "m_TrackEffFile after PathResolver: " 
00124           << m_TrackEffFile <<endreq;
00125     
00126     // Read in track reconstruction efficiency parametrisation
00127     std::ifstream trackEffFile;
00128     trackEffFile.open(m_TrackEffFile.c_str());
00129     
00130     if(trackEffFile){    
00131       p_log << MSG::INFO 
00132             << "Track Efficiency File " 
00133             << m_TrackEffFile
00134             << " open."
00135             << endreq;    
00136       double pTpoint  = 0.;
00137       double hadTrackEff = 0.;
00138       double muoTrackEff = 0.;
00139       double eleTrackEff = 0.;
00140       int ncolumn;        
00141       trackEffFile>>ncolumn;
00142       // Read corr factor bins from file
00143       for(int i=0; i<ncolumn; i++){
00144         trackEffFile>>pTpoint>>hadTrackEff>>muoTrackEff>>eleTrackEff;
00145         m_trackPTPoint.push_back(pTpoint);
00146         m_trackHadEff.push_back(hadTrackEff);
00147         m_trackMuoEff.push_back(muoTrackEff);
00148         m_trackEleEff.push_back(eleTrackEff);
00149       }
00150     }else{
00151       p_log << MSG::ERROR 
00152             << "Track Efficiency File file not found" 
00153             <<endreq;
00154       return StatusCode::FAILURE ;
00155     }
00156     trackEffFile.close();
00157     
00158     if ( m_trackPTPoint.size() != m_trackHadEff.size() ){
00159       p_log << MSG::FATAL;
00160       p_log << "Inconsistent Size of Track Efficiency Vectors";
00161       p_log << endreq;
00162     }
00163     
00164     return StatusCode::SUCCESS;
00165   }
00166   
00167   //---------------------------------------------------------------
00168   // Tool execution
00169   //---------------------------------------------------------------
00170   StatusCode TauMaker::execute()
00171   {
00172 
00173     MsgStream p_log( messageService(), name() ) ;
00174     
00175     // Container for new Tau objects
00176     TauContainer *container = new TauContainer;
00177 
00178     //---------------------------------------------------------
00179     // retrieve container with MC particles
00180     //---------------------------------------------------------
00181     std::vector<const HepMC::GenParticle*> p_particles;
00182     
00183     TesIoStat stat = m_tesIO->getMC( p_particles);
00184     
00185     if( !stat )
00186       {
00187         p_log << MSG::ERROR << "Unable to getMC";
00188         p_log << endreq;
00189         return StatusCode::RECOVERABLE;
00190         
00191       }
00192     
00193     //----------------------------------------------------------
00194     // retrieve pointer with Atlfast track collection
00195     //----------------------------------------------------------
00196     
00197     // get Atlfast track collection
00198     const TrackCollection* atlColl = 0;
00199     
00200     if(!m_tesIO->getDH(atlColl, m_TrackCollection)){
00201       p_log << MSG::DEBUG
00202             << "Could not retrieve at [" << m_TrackCollection << "] !!"
00203             << endreq ;
00204       return StatusCode::RECOVERABLE ;
00205     }
00206     
00207     if ( p_log.level() <= MSG::WARNING ) {
00208       p_log << MSG::DEBUG 
00209             << "Number of Atlfast tracks: [" 
00210             << atlColl->size() << "] ..."
00211             << endreq;
00212     }
00213     
00214     const TrackCollection::const_iterator itrEnd = atlColl->end();
00215     
00216     //-------------------------------------------------------------
00217     // Randomly tag tracks as having "good reconstruction"
00218     // pT dependent parametrisation of efficiency
00219     
00220     std::vector<unsigned int> TrackQualityVec;    
00221     // 1) First loop over tracks
00222     for ( TrackCollection::const_iterator itr_tag = atlColl->begin();
00223           itr_tag != itrEnd;
00224           ++itr_tag ) {
00225       
00226       const Track * atlTrackTag = *itr_tag;
00227       unsigned int qualitytag = 0;
00228       // 2) Draw random number    
00229       float rtag = randFlat()->fire();
00230       // 3) Get efficiency for good recon according to pT
00231       if( rtag < GetTrackEfficiency(atlTrackTag) ) { qualitytag = 1; }
00232       // 4) fill vector of tags identifying well reconstructed tracks
00233       TrackQualityVec.push_back( qualitytag );
00234     }
00235 
00236     // Check that the size of the TrackQualityVec vector matches
00237     // the size of the track collection.
00238     if( TrackQualityVec.size() != atlColl->size() ){
00239       p_log << MSG::WARNING << "TrackQualityVec Vector Not of Correct Size" <<endreq;     
00240     }
00241 
00242     //---------------------------------------------------------
00243     // Loop over Tracks in track collection
00244     //---------------------------------------------------------
00245 
00246     int seedTrackCounter = 0;
00247         
00248     for ( TrackCollection::const_iterator itr = atlColl->begin();
00249           itr != itrEnd;
00250           ++itr ) {
00251       int tr_IsTrueTau      = 0;
00252 
00253       double resphi         = 0; 
00254 
00255       // ET and position of tau candidate
00256       double tr_ET          = 0;
00257       double tr_Eta         = 0;
00258       double tr_Phi         = 0;
00259 
00260       // Eta Phi position of seed track
00261       double tr_SeedPhi     = 0;
00262       double tr_SeedEta     = 0;
00263 
00264       // Component From Tracks
00265       int tr_NTrackGood      = 0;
00266       int tr_NTrackPoor      = 0;
00267       int tr_SumQTrackGood   = 0;
00268       int tr_SumQTrackPoor   = 0;
00269 
00270       double tr_PTTrack      = 0;
00271       double tr_EtaTrack     = 0;
00272       double tr_PhiTrack     = 0;
00273           
00274       double tr_PTTrackMax   = 0;
00275       double tr_EtaTrackMax  = 0;
00276       double tr_PhiTrackMax  = 0;
00277             
00278       // Neutral Component of Energy
00279       int tr_NPi0           = 0;
00280       double tr_ETPi0       = 0;
00281       double tr_EtaPi0      = 0;
00282       double tr_PhiPi0      = 0;
00283 
00284       // True Leptonic Tracks...
00285       int tr_NMuoTrack = 0;
00286       int tr_NEleTrack = 0;
00287       // Lepton veto flags
00288       int tr_muoVetoFlag = 0;
00289       int tr_eleVetoFlag = 0;
00290 
00291       const Track * atlTrack = *itr;
00292 
00293       p_log << MSG::VERBOSE << "Search Seed Track "<<seedTrackCounter<<"\tquality = "
00294             <<TrackQualityVec.at(seedTrackCounter)<<"\tpdgid = "<<atlTrack->pdg_id()<<"\t"<<endreq;
00295 
00296       int seedTrackQuality = TrackQualityVec.at(seedTrackCounter);
00297       seedTrackCounter++;
00298 
00299       //-------------------------------------------
00300       // Select Primary Track from Track Collection
00301       //-------------------------------------------
00302 
00303       //-----------------------------------------------
00304       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00305       // Temporary fix for Track bug in release 13.0.10
00306       // Ignore tracks with |PID|=24
00307       //-----------------------------------------------
00308       if( abs(atlTrack->pdg_id() )== 24 ) {
00309         continue; }
00310 
00311       //---------------------------------------------------------
00312       // remove tracks not tagged as having "good reconstruction"
00313       //---------------------------------------------------------
00314       if( seedTrackQuality == 0 ) {
00315         continue; }
00316             
00317       //-------------------------------------------
00318       // remove candidates with track momenta below the threshold
00319       //-------------------------------------------
00320       if(  atlTrack->pT() < m_pTLeadTrackCut  ) {
00321         continue; }
00322 
00323       //-------------------------------------------
00324       // remove candidates with pseudorapidity outside range
00325       //-------------------------------------------
00326       if(  std::fabs( atlTrack->eta() ) > m_recoEtaCut  ) {
00327         continue; }
00328 
00329       p_log << MSG::DEBUG << "---> Seed Track ( pT= "<<atlTrack->pT()/GeV
00330             <<" GeV, eta= "<<atlTrack->eta()
00331             <<", phi= "<<atlTrack->phi()
00332             <<", PID= "<<atlTrack->pdg_id()<<" )."<<endreq;
00333 
00334       //-------------------------------------------
00335       // look to see if it overlaps with candidaes
00336       // already in TauContainer
00337       //-------------------------------------------
00338       int separated = 1;
00339 
00340       TauContainer::const_iterator p_iterF = container->begin();
00341       for( ; p_iterF != container->end(); p_iterF++ )
00342         {
00343           //dR separation of seed track from other reconstructed taus
00344           Phi    p_detPhi( atlTrack->phi() - (*p_iterF)->phi() );
00345           double p_detEta = fabs( atlTrack->eta() - (*p_iterF)->eta() );
00346           double p_detCone = sqrt((p_detPhi * p_detPhi) + (p_detEta * p_detEta) );
00347 
00348           if( p_detCone <  m_detRRecoSeparation )separated = 0;
00349         }
00350           
00351       if( separated == 0 ) continue;
00352 
00353 
00354       //-------------------------------------------
00355       // Selected track accepted as a leading seed
00356       //-------------------------------------------
00357           
00358       tr_NTrackGood++;
00359       tr_SumQTrackGood = atlTrack->trajectory().signOfCharge(); 
00360       if( abs(atlTrack->pdg_id()) == 11 ) { tr_NEleTrack++; }
00361       if( abs(atlTrack->pdg_id()) == 13 ) { tr_NMuoTrack++; }
00362 
00363       tr_PTTrack       = atlTrack->pT();
00364       tr_EtaTrack      = atlTrack->eta() * atlTrack->pT();
00365           
00366       tr_ET  = atlTrack->eT();
00367       tr_Eta = atlTrack->eta() * atlTrack->pT();
00368 
00369       tr_SeedEta = atlTrack->eta();
00370       tr_SeedPhi = atlTrack->phi();
00371           
00372       tr_PTTrackMax  = atlTrack->pT();
00373       tr_EtaTrackMax = atlTrack->eta();
00374       tr_PhiTrackMax = atlTrack->phi();
00375           
00376       //-------------------------------------------
00377       // Start iterating over other tracks
00378       //-------------------------------------------
00379       int assocTrackCounter = 0;
00380 
00381       for ( TrackCollection::const_iterator itr2 = atlColl->begin();
00382             itr2 != itrEnd;
00383             ++itr2 ) {
00384 
00385         const Track * atlTrack2 = *itr2;
00386             
00387         //---------------------------------------------------------
00388         // does track have "good reconstruction"?
00389         //---------------------------------------------------------
00390         p_log << MSG::VERBOSE << "Associated Track "<<assocTrackCounter<<"\t \"quality\"="
00391               <<TrackQualityVec.at(assocTrackCounter)<<endreq;
00392 
00393         int assocTrackQuality = TrackQualityVec.at(assocTrackCounter);
00394         assocTrackCounter++;
00395 
00396         //-----------------------------------------------
00397         // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00398         // Temporary fix for Track bug in release 13.0.10
00399         // Ignore tracks with |PID|=24
00400         //-----------------------------------------------
00401         if( abs(atlTrack2->pdg_id() )== 24 ) {
00402           continue; }
00403 
00404         //---------------------------------------------------------
00405         // Check not double counting tracks
00406         //---------------------------------------------------------
00407         if( atlTrack2 == atlTrack ) {
00408           continue; }
00409 
00410         //---------------------------------------------------------
00411         // remove candidates with pseudorapidity outside range
00412         //---------------------------------------------------------
00413         if(  std::fabs( atlTrack2->eta() ) > m_recoEtaCut  ) {
00414           continue; }
00415 
00416         //dR separation of track from the seed track
00417         Phi    tr_detPhi( atlTrack->phi() - atlTrack2->phi() );
00418         double tr_detEta = fabs( atlTrack->eta() - atlTrack2->eta() );
00419         double tr_detCone = sqrt( (tr_detPhi * tr_detPhi) + (tr_detEta * tr_detEta) );
00420 
00421         p_log << MSG::VERBOSE << "Search Associated Track pT = "<<atlTrack2->pT()
00422               <<"\t dR = "<<tr_detCone<<endreq;
00423 
00424         if ( tr_detCone < m_detRCoreTrackCut ) {
00425 
00426           // Track Passes pT cut...
00427           if (atlTrack2->pT() > m_pTOtherTrackCut ){
00428 
00429             // Good Core Tracks:                
00430             if ( assocTrackQuality == 1 ){
00431               p_log << MSG::DEBUG << "-----> \"Good\" Track in Core Cone pT = "
00432                     <<atlTrack2->pT()/GeV << "\t detCone = "<<tr_detCone
00433                     <<"\tPID= "<< atlTrack2->pdg_id()<<endreq;
00434 
00435               tr_NTrackGood++;
00436               tr_SumQTrackGood += atlTrack2->trajectory().signOfCharge();
00437             }
00438             // Other Core tracks:
00439             if ( assocTrackQuality == 0 ){
00440               p_log << MSG::DEBUG << "-----> \"Poor\" Track in Core Cone pT = " 
00441                     << atlTrack2->pT()/GeV <<"  \tdetCone = "<<tr_detCone
00442                     <<" \tPID= "<< atlTrack2->pdg_id()<<endreq;
00443                   
00444               tr_NTrackPoor++;
00445               tr_SumQTrackPoor += atlTrack2->trajectory().signOfCharge();
00446             }
00447 
00448             tr_ET  += atlTrack2->eT();
00449             tr_Eta += atlTrack2->eta()* atlTrack2->pT();
00450             // resphi = difference in phi between othertrack and seed track 
00451             
00452             resphi  = Phi(atlTrack2->phi() - tr_SeedPhi);
00453             tr_Phi += Phi(resphi * atlTrack2->pT());
00454 
00455             if( abs(atlTrack2->pdg_id()) == 11 ) { tr_NEleTrack++; }
00456             if( abs(atlTrack2->pdg_id()) == 13 ) { tr_NMuoTrack++; }
00457 
00458             tr_PTTrack  += atlTrack2->pT();
00459             tr_EtaTrack += atlTrack2->eta()* atlTrack2->pT();
00460             resphi  = Phi(atlTrack2->phi() - tr_SeedPhi);
00461             tr_PhiTrack += resphi * atlTrack2->pT();            
00462 
00463             if( tr_PTTrackMax < atlTrack2->pT() )
00464               {
00465                 tr_PTTrackMax  = atlTrack2->pT();
00466                 tr_EtaTrackMax = atlTrack2->eta();
00467                 tr_PhiTrackMax = atlTrack2->phi();
00468               }
00469           }
00470               
00471               
00472           // Low pT tracks in core region
00473           else if(atlTrack2->pT() <= m_pTOtherTrackCut){
00474             p_log << MSG::DEBUG << "-----> \"Low pT\" Track in Core Cone pT = " << atlTrack2->pT()/GeV 
00475                   <<" \tdetCone = "<<tr_detCone
00476                   <<" \tPID= "<< atlTrack2->pdg_id()<<endreq;
00477           }
00478         }
00479       } // end of itr2 loop
00480 
00481       p_log << MSG::DEBUG << "-----> NTrackGood = " <<tr_NTrackGood 
00482             << "\tPTTrack = " <<tr_PTTrack/GeV << endreq; 
00483       p_log << MSG::DEBUG << "-----> NTrackPoor = " <<tr_NTrackPoor << endreq;
00484       p_log << MSG::DEBUG << "-----> Of which NMuoTrack = "<<tr_NMuoTrack 
00485             << "; and NEleTrack = " <<tr_NEleTrack << endreq; 
00486               
00487       //--------------------------------------------------------------
00488 
00489       // m_maxNumTracks set to 3 by default. Can be changed in joboptions
00490       // to handle candidates with higher track multiplicities
00491 
00492       //if Ntracks is greater than maximum number of tracks cut, reject and continue
00493       if( tr_NTrackGood > m_maxNumTracks ) continue;
00494           
00495       p_log << MSG::DEBUG << "Good Tracks SumQ = " <<tr_SumQTrackGood 
00496             << "; Poor Tracks SumQ = " <<tr_SumQTrackPoor << endreq;
00497 
00498       // Sum Charge of tracks
00499       int tr_SumQ = tr_SumQTrackGood;
00500       if( tr_NTrackGood == 2 && tr_NTrackPoor==1 ) tr_SumQ = tr_SumQTrackGood + tr_SumQTrackPoor;
00501 
00502       int tr_NProng          = 0;
00503       //Decide whether its a 1-prong, 2-prong, 3-prong etc...
00504       if( tr_NTrackGood==1 )                     tr_NProng=1;
00505       if( tr_NTrackGood==2 && tr_NTrackPoor==0 ) tr_NProng=2;
00506       if( tr_NTrackGood==2 && tr_NTrackPoor==1 ) tr_NProng=3;
00507       if( tr_NTrackGood==2 && tr_NTrackPoor>=2 ) continue;
00508       if( tr_NTrackGood==3 )                     tr_NProng=3;
00509       //and for higher n track candidates...
00510       if( tr_NTrackGood >3 && tr_NTrackGood<=m_maxNumTracks) tr_NProng=tr_NTrackGood;
00511 
00512       // Reject Candidates with bad charge sum
00513       if( tr_NProng == 3 && abs(tr_SumQ) != 1 ) 
00514         {
00515           p_log << MSG::DEBUG << "Candidate Rejected NProng =" << tr_NProng
00516                 << "  SumQ = " << tr_SumQ << endreq;
00517           continue;           
00518         }
00519 
00520       //--------------------------------------------------------------
00521       // Having found associated tracks, now look for neutral content
00522       // loop over truth container and find nearby pions
00523       //--------------------------------------------------------------
00524 
00525       std::vector<const HepMC::GenParticle*>::iterator p_MC_Iter;
00526           
00527       for( p_MC_Iter = p_particles.begin(); p_MC_Iter != p_particles.end();
00528            p_MC_Iter++ ) {
00529         if( (*p_MC_Iter)->barcode() >= 99999. ) {
00530           continue; }
00531             
00532         //-------------------------------------------------------
00533         // Check that particle is inside eta cut??
00534         //-------------------------------------------------------
00535         if(  std::fabs(  (*p_MC_Iter)->momentum().pseudoRapidity()) > m_recoEtaCut  )
00536           continue;
00537             
00538         //-------------------------------------------------------
00539         // Find separation of neutral pion from seed track
00540         //-------------------------------------------------------
00541         double p_detPhi = Phi( atlTrack->phi() - (*p_MC_Iter)->momentum().phi() );
00542         double p_detEta = fabs( atlTrack->eta() - (*p_MC_Iter)->momentum().pseudoRapidity() );
00543         double p_detCone = sqrt((p_detPhi * p_detPhi) + (p_detEta * p_detEta) );            
00544 
00545         //-------------------------------------------------------
00546         // neutral pions content
00547         //-------------------------------------------------------
00548         if( std::abs( (*p_MC_Iter)->pdg_id() ) == 111 ){
00549 
00550           p_log << MSG::VERBOSE << "Pi0 pT= " << (*p_MC_Iter)->momentum().perp()/GeV 
00551                 << "\teta = " << (*p_MC_Iter)->momentum().eta() 
00552                 <<"\tphi= "<<(*p_MC_Iter)->momentum().phi()<<"\tdR= "<<p_detCone<< endreq;
00553               
00554           if(  p_detCone <  m_detRCoreCaloCut ) {
00555 
00556             p_log << MSG::DEBUG << "---> Core Pi0 pT= " << (*p_MC_Iter)->momentum().perp()/GeV 
00557                   << "\teta = " << (*p_MC_Iter)->momentum().eta() <<"\tphi= "
00558                   <<(*p_MC_Iter)->momentum().phi()<< endreq;
00559 
00560             tr_ET  += (*p_MC_Iter)->momentum().perp();
00561             tr_Eta += (*p_MC_Iter)->momentum().pseudoRapidity() * (*p_MC_Iter)->momentum().perp();
00562             resphi  = Phi( (*p_MC_Iter)->momentum().phi() - tr_SeedPhi );
00563             tr_Phi += resphi * (*p_MC_Iter)->momentum().perp();
00564 
00565             tr_NPi0++;
00566 
00567             tr_ETPi0  += (*p_MC_Iter)->momentum().perp();
00568             tr_EtaPi0 += (*p_MC_Iter)->momentum().pseudoRapidity() * (*p_MC_Iter)->momentum().perp();
00569             resphi  = Phi( (*p_MC_Iter)->momentum().phi() - tr_SeedPhi );
00570             tr_PhiPi0 += resphi * (*p_MC_Iter)->momentum().perp();
00571                 
00572           }
00573         } else if( std:: abs((*p_MC_Iter)->pdg_id()) == 2112 ){
00574           // Energy from neutrons in core cone...
00575           if(  p_detCone <  m_detRCoreCaloCut ) {
00576             // Add fraction m_resNeuhEne of neutron corresponding to EMCal deposit
00577             tr_ET  +=  m_resNeuhEne * (*p_MC_Iter)->momentum().perp();
00578             tr_Eta += (*p_MC_Iter)->momentum().pseudoRapidity() * m_resNeuhEne * (*p_MC_Iter)->momentum().perp();
00579             resphi  = Phi( (*p_MC_Iter)->momentum().phi() - tr_SeedPhi );
00580             tr_Phi += resphi * m_resNeuhEne * (*p_MC_Iter)->momentum().perp();
00581           }
00582         }
00583       }
00584 
00585       p_log << MSG::DEBUG << "-----> NPi0 = " << tr_NPi0 
00586             << "\tETPi0 = " <<tr_ETPi0/GeV << endreq; 
00587 
00588 
00589       // Check whether candidate has muon or electron tracks...
00590       // If so, randomly decide whether to flag as muon or 
00591       // electron veto.
00592       if( tr_NEleTrack > 0 ){
00593         float rele_veto = randFlat()->fire();
00594         if( rele_veto < m_eleVetoEff ) { 
00595           tr_eleVetoFlag=1;
00596           p_log << MSG::DEBUG << "Flagged by Electron Veto"<< endreq;
00597         }
00598       }
00599       if( tr_NMuoTrack > 0 ){
00600         float rmuo_veto = randFlat()->fire();
00601         if( rmuo_veto < m_muoVetoEff ) { 
00602           tr_muoVetoFlag=1;
00603           p_log << MSG::DEBUG << "Flagged by Muon Veto"<< endreq;
00604         }
00605       }
00606 
00607       p_log << MSG::DEBUG << tr_NProng << "P Candidate Made."<< endreq;
00608       p_log << MSG::VERBOSE << "Sum Core Track pT = "<< tr_PTTrack << endreq;
00609       p_log << MSG::VERBOSE << "Sum Core Neutral pion ET = "<< tr_ETPi0 << endreq;
00610       p_log << MSG::VERBOSE << "Sum Core ET (including other neutrals) = "<< tr_ET/GeV << endreq;
00611           
00612       // Define Bary-Centred eta-phi position...
00613       tr_Eta = tr_Eta / tr_ET;
00614       // Get correct -pi<phi<pi value for weighted phi position
00615       tr_Phi = tr_Phi/tr_ET + tr_SeedPhi;
00616           
00617       p_log << MSG::DEBUG << "Candidate eta = "<< tr_Eta <<", phi = "<< tr_Phi << endreq;
00618           
00619 
00620       //---------------------------------------------------------
00621       // Check if IsTrueTau
00622       //---------------------------------------------------------
00623       std::vector<const HepMC::GenParticle*>::iterator p_partIter;
00624       for( p_partIter = p_particles.begin(); p_partIter != p_particles.end();
00625            p_partIter++ )
00626         {
00627           //Find Taus in truth record
00628           if( std::abs( (*p_partIter)->pdg_id() ) == 15 )
00629             {
00630             // Find Tau children
00631               HepMC::GenVertex*  endVertex = (*p_partIter)->end_vertex();
00632               if(!endVertex) continue;
00633 
00634               HepLorentzVector tauHlv = (*p_partIter)->momentum(); // tau momentum
00635               HepLorentzVector neuHlv; // neutrino momentum
00636               HepLorentzVector visHlv; // visible momentum
00637               
00638               HepMC::GenVertex::particle_iterator firstChild = 
00639                 endVertex->particles_begin(HepMC::children);          
00640               HepMC::GenVertex::particle_iterator endChild = 
00641                 endVertex->particles_end(HepMC::children);            
00642               HepMC::GenVertex::particle_iterator thisChild = firstChild; 
00643               
00644               // Find Decaying tau in MC event information
00645               bool TauDecayVertexInMC = true;         
00646               for(; thisChild!=endChild; ++thisChild){
00647                 //p_log << MSG::VERBOSE << "     Child pdgid = " << (*thisChild)->pdg_id() <<endreq; 
00648                 if(    abs((*thisChild)->pdg_id()) == 11
00649                     || abs((*thisChild)->pdg_id()) == 13
00650                     || abs((*thisChild)->pdg_id()) == 15 )
00651                   {
00652                     //If child is a tau then haven't found a hadronic tau decay vertex
00653                     TauDecayVertexInMC = false;
00654                     break;
00655                   }
00656                 // Find Pt of Taus tau-neutrino
00657                 if(  abs((*thisChild)->pdg_id()) == 12 || 
00658                      abs((*thisChild)->pdg_id()) == 14 || 
00659                      abs((*thisChild)->pdg_id()) == 16 )
00660                   {
00661                     neuHlv += (*thisChild)->momentum();
00662                   }
00663               }
00664               if(TauDecayVertexInMC==false)
00665                 {
00666                   p_log << MSG::VERBOSE << "Not a Hadronic Tau decay. Ignore Vertex. Move to next Vertex."<<endreq;
00667                   continue;
00668                 }
00669               
00670               visHlv = tauHlv - neuHlv;
00671 
00672               // Check whether matches tau candidate with dR cut
00673               // dR separation of tau candidate from a true tau
00674               // should I search for hadronic taus only here??
00675               Phi    truth_detPhi = tr_Phi - visHlv.phi();
00676               double truth_detEta = fabs( tr_Eta - visHlv.pseudoRapidity() );
00677               double truth_detCone = sqrt((truth_detPhi * truth_detPhi) + (truth_detEta * truth_detEta) );
00678                   
00679               if ( truth_detCone < m_detRTrueTauCut ){
00680                 p_log << MSG::DEBUG << "Matches tau with visible decay to eta = "
00681                       << visHlv.pseudoRapidity()
00682                       <<", phi = "<< visHlv.phi() 
00683                       << " (dR = "<< truth_detCone << ")" << endreq;
00684                 tr_IsTrueTau=1;
00685                 break;
00686               }
00687             }
00688         }
00689 
00690       //-------------------------------------------------
00691       // Smear Energy from gaussian distribution
00692       //-------------------------------------------------         
00693       float aa, sigma;
00694       while(1) {
00695         aa = randGauss()->fire();
00696 
00697         sigma = aa* m_resEflowEne/sqrt( tr_ET * cosh( tr_Eta ) / GeV );
00698         if( 1.0 +sigma > .0) break;
00699       }
00700 
00701       p_log << MSG::DEBUG << "After Smearing, ET = "<< tr_ET * (1.0 + sigma) << endreq;
00702 
00703       if ( m_recoETCut > tr_ET * (1.0 + sigma) )
00704         {
00705           p_log << MSG::DEBUG << "Tau candidate rejected. (Smeared ET below m_recoETCut = "<<m_recoETCut<<")"<< endreq;
00706           continue;
00707         }
00708       p_log << MSG::DEBUG << "Recording Tau Candidate in Collection"<< endreq;
00709       //-------------------------------------------------
00710       // Record new object in collection
00711       //-------------------------------------------------
00712       Tau *tr_object = new Tau();
00713           
00714       if( tr_PTTrack != 0 )
00715         {
00716           tr_EtaTrack /= tr_PTTrack;
00717           tr_PhiTrack = Phi(tr_PhiTrack/tr_PTTrack + tr_SeedPhi );
00718         }
00719           
00720       if( tr_ETPi0 != 0 )
00721         {
00722           tr_EtaPi0 /= tr_ETPi0;
00723           tr_PhiPi0 = Phi( tr_PhiPi0/tr_ETPi0 + tr_SeedPhi );
00724         }
00725           
00726       // calculate mass of tau candidate
00727       float pxTrack =  tr_PTTrack * cos( tr_PhiTrack);
00728       float pxPi0  =  tr_ETPi0  * cos( tr_PhiPi0);
00729           
00730       float pyTrack =  tr_PTTrack * sin( tr_PhiTrack);
00731       float pyPi0  =  tr_ETPi0  * sin( tr_PhiPi0);
00732           
00733       float pzTrack =  tr_PTTrack * sinh( tr_EtaTrack);
00734       float pzPi0  =  tr_ETPi0  * sinh( tr_EtaPi0);
00735           
00736       float eeTrack =  tr_PTTrack * cosh( tr_EtaTrack);
00737       float eePi0  =  tr_ETPi0  * cosh( tr_EtaPi0);
00738           
00739       float mass = ( eePi0 + eeTrack )* ( eePi0 + eeTrack )
00740         - ( pxTrack + pxPi0 )*( pxTrack + pxPi0 )
00741         - ( pyTrack + pyPi0 )*( pyTrack + pyPi0 )
00742         - ( pzTrack + pzPi0 )*( pzTrack + pzPi0 );
00743           
00744       if( mass > 0 ) { mass = sqrt (mass); }
00745       if( mass < 0 ) { mass = 0.; }
00746           
00747       tr_object->setE( tr_ET * cosh(  tr_Eta )* (1.0 + sigma) );
00748       tr_object->setM( mass * (1.0 + sigma)  );
00749       tr_object->setEta( tr_Eta );
00750       tr_object->setPhi( tr_Phi );
00751       tr_object->setNTrack( tr_NProng );         
00752       tr_object->setSumQTrack( tr_SumQ );         
00753       tr_object->setIsTrueTau( tr_IsTrueTau );
00754 
00755       tr_object->setEleVeto(tr_eleVetoFlag);
00756       tr_object->setMuoVeto(tr_muoVetoFlag);
00757 
00758       container->push_back( tr_object );
00759       
00760     } // end of itr loop 
00761     
00762     // Clear Track vectors before next event...
00763     TrackQualityVec.clear();
00764     
00765     // Store the taus (if any) in StoreGate
00766     stat = m_tesIO->store( container, m_outputLocation );
00767     std::string mess = stat ? "Store to TES success" : "Store to TES failure";    
00768     p_log << MSG::DEBUG << mess << endreq;
00769     
00770     //---------------------------------------------------------
00771         
00772     return StatusCode::SUCCESS;
00773   }
00774 
00775   StatusCode TauMaker::finalize()
00776   {
00777 
00778     MsgStream p_log( messageService(), name() ) ;
00779     p_log << MSG::DEBUG << "TauMaker Finalize "<< endreq;
00780         
00781     //   Note from CLHEP/Random/RandFlat instructions:
00782     //   "If the engine is passed by pointer then the corresponding engine
00783     //   object will be deleted by the RandFlat destructor.If the engine is
00784     //   passed by reference then the corresponding engine object will not be
00785     //   deleted by the RandFlat destructor." 
00786     //   So don't delete the random engine after m_randflat.
00787 
00788     //still crashing - maybe engine is being deleted when randGauss is deleted,
00789     // then randFlat is trying to delete the same engine again... can fix by using
00790     // two different HepRandomEngines. Seems a bit wasteful. 
00791 
00792     //Pass engine to distribution classes by reference rather than pointer. This way the
00793     //Engine is not deleted when the distribution is deleted
00794 
00795     if (m_randGauss)    delete m_randGauss;
00796     if (m_randFlat)     delete m_randFlat;
00797     if (m_randEngine)   delete m_randEngine;
00798 
00799 
00800     return StatusCode::SUCCESS;
00801   }
00802 
00803   
00804   
00805   double TauMaker::GetTrackEfficiency( const Track * atlTrack ) {
00806     // Get efficiency for a given track to pass "good quality"
00807     // reconstruction cuts. Interpolate as function of pT
00808     
00809     double trackEff = 0.0;
00810 
00811     double trackPT = atlTrack->pT();
00812     double trackID = abs( atlTrack->pdg_id() );
00813 
00814     //Check trackPT is greater than lowest interpolation point
00815     if( trackPT > m_trackPTPoint.at(0) 
00816         &&  trackPT < m_trackPTPoint.at( m_trackPTPoint.size()-1 ) ) {
00817       
00818       for( unsigned int i=1; i<m_trackPTPoint.size(); i++ ){
00819         if( m_trackPTPoint.at(i) > trackPT ) {
00820 
00821           double lowPoint;
00822           double highPoint;
00823 
00824           if(trackID==11){
00825             lowPoint= m_trackEleEff.at(i-1);
00826             highPoint=m_trackEleEff.at(i);        
00827           }else if(trackID==13){
00828             lowPoint= m_trackMuoEff.at(i-1);
00829             highPoint=m_trackMuoEff.at(i);        
00830           }else{
00831             lowPoint=m_trackHadEff.at(i-1);
00832             highPoint=m_trackHadEff.at(i);        
00833           }
00834           double m = ( lowPoint - highPoint ) / (m_trackPTPoint.at(i-1) - m_trackPTPoint.at(i));
00835           trackEff = m*trackPT + ( highPoint - m* m_trackPTPoint.at(i) );
00836           break;
00837         }
00838       }
00839     } else if ( trackPT > m_trackPTPoint.at( m_trackPTPoint.size()-1 ) ) {
00840       if(trackID==11){
00841         trackEff = m_trackEleEff.at( m_trackPTPoint.size()-1 );   
00842       }else if(trackID==13){
00843         trackEff = m_trackMuoEff.at( m_trackPTPoint.size()-1 );   
00844       }else{
00845         trackEff = m_trackHadEff.at( m_trackPTPoint.size()-1 );   
00846       }
00847     }
00848     
00849     return trackEff;
00850   }
00851   
00852 }

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