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

JetMaker.cxx

Go to the documentation of this file.
00001 // ================================================
00002 // JetMaker class Implementation
00003 // ================================================
00004 //
00005 // THIS TEXT TO BE REPLACED BY ATLAS STANDARD FORMAT
00006 //
00007 // Namespace Atlfast::
00008 //
00009 #include "AtlfastAlgs/JetMaker.h"
00010 #include "AtlfastAlgs/ISmearer.h"
00011 #include "AtlfastAlgs/JetSmearer.h"
00012 #include "AtlfastAlgs/MissingMomentum.h"
00013 #include "AtlfastAlgs/GlobalEventData.h"
00014 
00015 #include "AtlfastEvent/Jet.h"
00016 #include "AtlfastEvent/ICell.h"
00017 #include "AtlfastEvent/CollectionDefs.h"
00018 #include "AtlfastEvent/ReconstructedParticle.h"
00019 #include "AtlfastEvent/ParticleCodes.h"
00020 #include "AtlfastEvent/MsgStreamDefs.h"
00021 #include "AtlfastEvent/Cluster.h"
00022 #include "AtlfastEvent/MCparticleCollection.h"
00023 
00024 #include "AtlfastUtils/TesIO.h"
00025 #include "AtlfastUtils/HeaderPrinter.h"
00026 #include "AtlfastUtils/HepMC_helper/SelectJetTag.h"
00027 #include "AtlfastUtils/HepMC_helper/SelectTauTag.h"
00028 #include "AtlfastUtils/FunctionObjects.h"
00029 #include "AtlfastEvent/SimpleKinematic.h"
00030 
00031 #include <cmath> 
00032 #include <algorithm>
00033 
00034 // Gaudi includes
00035 #include "GaudiKernel/DataSvc.h"
00036 #include "StoreGate/DataHandle.h"
00037 #include "GaudiKernel/ISvcLocator.h"
00038 #include "GaudiKernel/MsgStream.h"
00039 
00040 
00041 
00042 // CLHEP,HepMC
00043 #include "GeneratorObjects/McEventCollection.h"
00044 #include "HepMC/GenEvent.h"
00045 #include "HepMC/GenVertex.h"
00046 
00047 
00048 //--------------------------------
00049 // Constructors and destructors
00050 //--------------------------------
00051 
00052 namespace Atlfast{
00053   using std::abs;
00054   using std::sort;
00055   
00056   JetMaker::JetMaker 
00057   ( const std::string& name, ISvcLocator* pSvcLocator ) 
00058     : Algorithm( name, pSvcLocator ){
00059     
00060     // Setting the parameter defaults.
00061     m_minPT            = 10;         // Min jet trans momentum
00062     m_maxEta           = 5;          //Max jet eta 
00063     m_doSmearing       = true;       //smearing is done
00064     m_rconeb           = 0.400;
00065     m_rconef           = 0.400;
00066     
00067     m_bPtMin           = 5.0;        //min pt for bquark to tag jet
00068     m_bMaxDeltaR       = 0.2;        //max dR for bquark to tag jet
00069     
00070     m_cPtMin           = 5.0;        //min pt for cquark to tag jet
00071     m_cMaxDeltaR       = 0.2;
00072     
00073     m_tauPtMin         = 10.0;
00074     m_tauMaxDeltaR     = 0.3;
00075     
00076     m_etaTagMax        = 2.5;
00077 
00078     m_tauJetPtRatio    = 0.9;
00079     
00080     
00081     // Default paths for entities in the TES
00082     m_inputLocation             = "/Event/AtlfastClusters";
00083     m_outputLocation            = "/Event/AtlfastJets";
00084     m_muonLocation              = "/Event/AtlfastNonIsolatedMuons";
00085     m_unusedCellLocation        = "/Event/AtlfastUnusedCells";
00086     m_missingMomentumLocation   = "/Event/AtlfastMissingMomentum";
00087     m_mcTruthLocation           = "/Event/McEventCollection";
00088     
00089     // This is how you declare the paramemters to Gaudi so that
00090     // they can be over-written via the job options file
00091     declareProperty( "MinimumPT",       m_minPT ) ;
00092     declareProperty( "MaximumEta",      m_maxEta ) ;
00093     declareProperty( "DoSmearing",      m_doSmearing ); 
00094     declareProperty( "RconeB",          m_rconeb );
00095     declareProperty( "RconeF",          m_rconef );
00096     declareProperty( "bPtMin",          m_bPtMin );
00097     declareProperty( "bMaxDeltaR",      m_bMaxDeltaR );
00098     declareProperty( "cPtMin",          m_cPtMin );
00099     declareProperty( "cMaxDeltaR",      m_cMaxDeltaR );
00100     declareProperty( "tauPtMin",        m_tauPtMin );
00101     declareProperty( "tauMaxDeltaR",    m_tauMaxDeltaR );
00102     declareProperty( "etaTagMax",       m_etaTagMax );
00103     declareProperty( "tauJetPtRatio",   m_tauJetPtRatio);
00104     
00105     declareProperty( "InputLocation",           m_inputLocation ) ;
00106     declareProperty( "OutputLocation",          m_outputLocation ) ;
00107     declareProperty( "UnusedCellLocation",      m_unusedCellLocation ) ;
00108     declareProperty( "MuonLocation",            m_muonLocation );
00109     declareProperty( "MissingMomentumLocation", m_missingMomentumLocation );
00110     declareProperty( "McTruthLocation",         m_mcTruthLocation );
00111   }
00112   
00113   JetMaker::~JetMaker() {
00114     
00115     MsgStream log( messageService(), name() ) ;
00116     log << MSG::INFO << "Destructor Called" << endreq;
00117     
00118     if (m_smearer) {
00119       log << MSG::INFO << "Deleting jet Smearer" << endreq;
00120       delete m_smearer;
00121     }
00122     if (m_cellSmearer) {
00123       log << MSG::INFO << "Deleting Cell Smearer" << endreq;
00124       delete m_cellSmearer;
00125     }
00126     if (m_tesIO) {
00127       delete m_tesIO;
00128     }
00129   } 
00130   
00131   //---------------------------------
00132   // initialise() 
00133   //---------------------------------
00134   
00135   StatusCode JetMaker::initialize(){
00136     MsgStream log( messageService(), name() ) ;
00137     
00138     log << MSG::DEBUG << "instantiating a JetSmearer" << endreq;
00139     
00140     //    m_tesIO = new TesIO(eventDataService());  
00141     m_tesIO = new TesIO();  
00142     
00143     //get the Global Event Data using singleton pattern
00144     GlobalEventData* ged = GlobalEventData::Instance();
00145     int lumi                  = ged->lumi();
00146     int randSeed              = ged->randSeed() ;
00147     m_barrelForwardEta = ged->barrelForwardEta();
00148     
00149     if(m_doSmearing){
00150       m_smearer                 = new JetSmearer(randSeed, 
00151                                                  lumi,
00152                                                  m_rconeb, 
00153                                                  m_rconef, 
00154                                                  m_barrelForwardEta);    
00155       m_cellSmearer             = new JetSmearer(randSeed, 
00156                                                  lumi,
00157                                                  0., 
00158                                                  0., 
00159                                                  m_barrelForwardEta);    
00160     } else {
00161       m_smearer = NULL;
00162       m_cellSmearer = NULL;
00163     }
00164 
00165     HeaderPrinter hp("Atlfast JetMaker:", log);
00166     
00167     hp.add("TES Locations:              ");
00168     hp.add(" Muons from                 ", m_muonLocation); 
00169     hp.add(" Clusters from              ", m_inputLocation); 
00170     hp.add(" GeneratorParticles from    ", m_mcTruthLocation);
00171     hp.add(" Jets to                    ", m_outputLocation);
00172     hp.add(" unused cell,cluster sum to ", m_missingMomentumLocation);
00173     hp.add("Smearing on                 ", m_doSmearing);
00174     hp.add("Cluster min Pt              ", m_minPT);
00175     hp.add("Cluster max Eta             ", m_maxEta);           
00176     hp.add("Luminosity                  ", lumi);
00177     hp.add("Initial random seed         ", randSeed);      
00178     hp.add("End cap Cone size           ", m_rconef);
00179     hp.add("Barrel  Cone size           ", m_rconeb);
00180     hp.add("Eta of start of end cap     ", m_barrelForwardEta);
00181     hp.add("Parameters for tags         ", "       ");
00182     hp.add(" Max eta                    ", m_etaTagMax);
00183     hp.add(" b-quark min pt             ", m_bPtMin);
00184     hp.add(" b-quark max DeltaR         ", m_bMaxDeltaR);
00185     hp.add(" c-quark min pt             ", m_cPtMin);
00186     hp.add(" c-quark max DeltaR         ", m_cMaxDeltaR);
00187     hp.add(" tau lep min pt             ", m_tauPtMin);
00188     hp.add(" tau lep max DeltaR         ", m_tauMaxDeltaR);
00189     hp.add(" tau/Jet Pt Ratio           ", m_tauJetPtRatio);
00190     hp.print();
00191     
00192 
00193 
00194     return StatusCode::SUCCESS ;
00195   }
00196   
00197   //---------------------------------
00198   // finalise() 
00199   //---------------------------------
00200   
00201   StatusCode JetMaker::finalize(){
00202 
00203     MsgStream log( messageService(), name() ) ;
00204     log << MSG::INFO << "finalizing" << endreq;    
00205     return StatusCode::SUCCESS ;
00206   }
00207   
00208   
00209   //----------------------------------------------
00210   // execute() method called once per event
00211   //----------------------------------------------
00212   //
00213   //  This algorithm creates smeared Jets passing cuts. 
00214   //  It scans the list of Clusters from the Monte Carlo truth. 
00215   //  If a Cluster of the right flavour is found it creates 
00216   //  a candidate Jet object by smearing the four vector
00217   //  of the Cluster and adding non-isolated muons. 
00218   // 
00219   //  It then applies kinematic criteria on the properties of the Jet
00220   //  Those which pass the cuts are kept.
00221   //  Finally all successful Jets are added to the event store.
00222   //
00223   //  
00224   //
00225   
00226   StatusCode JetMaker::execute( ){
00227     
00228     MsgStream log( messageService(), name() ) ;    
00229 
00230     std::string mess;
00231     // make a message logging stream
00232     
00233 
00234       
00235 
00236     //.............................
00237     // Make some locals stores which be used to keep pointers to
00238     // all of the entities from the event store which are needed by
00239     // this algorithm. These are all local and are typedefed in this class
00240     
00241     localClusterCollection      my_Clusters ;
00242     MuonCollection         my_Muons ;
00243     //................................
00244     
00245     //    if( ! m_tesIO->copy( my_Clusters, m_inputLocation ) ) {
00246     if( ! m_tesIO->copy<ClusterCollection> ( my_Clusters, m_inputLocation ) ) {
00247       log << MSG::INFO << "No Clusters in TES " << endreq;
00248     } else {
00249       log << MSG::DEBUG << my_Clusters.size()<<" Clusters from TES " << endreq;
00250     }
00251     // get non-isolated muons for jet construction
00252     
00253     if( ! m_tesIO->copy<ReconstructedParticleCollection>
00254         ( my_Muons, m_muonLocation ) ) {
00255       log << MSG::DEBUG << "No muons in TES " << endreq;
00256     }  
00257 
00258     // ......................
00259     // Make a container object which will store pointers to all isolated 
00260     // Jetss which are successfully created.  Since it is going to go 
00261     // into the event store, it has to be a special Gaudi type of container. 
00262     // This is typedefined in the entity include file
00263     // As it is going into the TES it needs to be created on the heap with new.
00264     
00265     JetCollection* myJets = new JetCollection ;
00266     
00267         //.........................................................
00268     // From each Cluster create a reconstructed Jet. 
00269     // If all requirements are satisfied add to the collection
00270     
00271     Jet* candidate ;
00272     localClusterIterator src ;
00273     HepLorentzVector missingMomentum(0.,0.,0.,0.);
00274     const int BQUARK(ParticleCodes::BQUARK);
00275     const int CQUARK(ParticleCodes::CQUARK);
00276     //Construct an object to select b, c and tau quarks with kine conditions
00277     const HepMC_helper::SelectJetTag bSelector(BQUARK, m_bPtMin, m_etaTagMax);
00278     const HepMC_helper::SelectJetTag cSelector(CQUARK, m_cPtMin, m_etaTagMax);
00279     const HepMC_helper::SelectTauTag tauSelector(m_tauPtMin, m_etaTagMax);
00280 
00281     MCparticleCollection  mcParticles_b ;
00282     MCparticleCollection  mcParticles_c ;
00283     MCparticleCollection  mcParticles_tau ;
00284     //get quarks used in tagging from TES using tesio
00285     m_tesIO->getMC( mcParticles_b, &bSelector ) ;
00286     m_tesIO->getMC( mcParticles_c, &cSelector ) ;
00287     m_tesIO->getMC( mcParticles_tau, &tauSelector ) ;
00288  
00289     for( src = my_Clusters.begin() ; src != my_Clusters.end() ; ++src ) 
00290       { 
00291         IAssociationManager* iAssocMan = *src;
00292         ReconstructedParticle rp;
00293         if (iAssocMan->associations(rp).size() == 0)
00294           {
00295             // Make a new jet
00296             candidate = this->create( *src );
00297 
00298             //Make a temp HepLorentzVector from candidates 4-mom
00299             //before muon is added in
00300             HepLorentzVector temp4Vec = candidate->momentum();
00301 
00302             // add isolated muons
00303             this->addMuons(candidate, my_Muons);
00304 
00305             
00306             // add to missing momentum vector if not used in a jet.
00307             // remember, these are smeared momenta if smearing is enabled
00308             if( this->isAcceptable( candidate ) ) {    
00309 
00310             // if the jet is acceptable flavor tag the jet
00311               this->tag(candidate,mcParticles_b,mcParticles_c,mcParticles_tau);
00312 
00313               log << MSG::DEBUG << "Pushing back a Jet" << endreq;
00314               myJets->push_back( candidate ) ; 
00315               log<<MSG::DEBUG<<"jet "<<*candidate<<endreq;
00316             }else {
00317               log << MSG::DEBUG << "Jet fails cuts" << endreq;
00318               //add in temp4Vec to avoid muon double counting
00319               missingMomentum += temp4Vec;
00320               delete candidate ;
00321             }
00322           }
00323       }
00324     
00325     log<<MSG::DEBUG<<"Missing momentum: clusters "<<missingMomentum<<endreq;
00326     missingMomentum += addUnusedCells(log);
00327     log<<MSG::DEBUG<<"Missing momentum: cells+clstrs "
00328        <<missingMomentum<<endreq;
00329     //......................................
00330     // Register any Jets which have been successfilly created in the 
00331     // transient event store. 
00332     TesIoStat stat;
00333     log<<MSG::DEBUG<<"Storing "<< myJets->size() <<" Jets"<<endreq;
00334     stat = m_tesIO->store( myJets, m_outputLocation ) ;
00335     if(!stat){
00336       log<<MSG::ERROR<<"Could not store jets"<<endreq;
00337       return stat;
00338     }
00339 
00340 
00341     MissingMomentum* mm = new MissingMomentum(missingMomentum);
00342     stat = m_tesIO->store(mm,m_missingMomentumLocation ) ;
00343     std::string message = stat? "Stored missing mom":"Failed to missing mom";
00344     log<<MSG::DEBUG<<message<<endreq;
00345   
00346 
00347     return StatusCode::SUCCESS;
00348   }
00349   
00350   
00351   
00352   //----------------------------------
00353   // create()
00354   //----------------------------------
00355   
00356   // Takes a single Cluster and creates a Jet
00357   // according to the desired criteria
00358   //
00359   // Note that we must NEW these jets so they can go to the TES
00360   // and if we decide that we do not want them, we must DELETE them
00361   // Once they are put to the TES, they are no longer our responsibility to delete
00362   
00363   Jet* JetMaker::create ( Cluster* src )
00364   {
00365     Jet* jet;
00366     MsgStream log( messageService(), name() ) ;
00367     HepLorentzVector vec = src->momentum();
00368     
00369     if (m_doSmearing) 
00370       {
00371         // Ask our Smearer make a smeared 4-vector
00372         vec = m_smearer->smear(vec);      
00373       }
00374     
00375     jet = new Jet(vec, *src);
00376     log << MSG::DEBUG << "Unsmeared Cluster: " << *src << endreq;
00377     log << MSG::DEBUG << "Smeared Jet      : " << jet << endreq ;
00378     
00379     // return Jet
00380     return jet;
00381     
00382     
00383   }
00384   //-------------------------------------------
00385   // addmuons
00386   //-------------------------------------------
00387   
00388   // adds non-isolated muons to the jets
00389   
00390   void JetMaker::addMuons(Jet* jet, MuonCollection& muons )
00391   {
00392     
00393     if (muons.size() == 0)  return;
00394     
00395     MsgStream log( messageService(), name() ) ;
00396     
00397     MuonIterator first = muons.begin() ;
00398     MuonIterator last  = muons.end() ;
00399     
00400     // Sort by distance from the jet
00401     sort( first, last, SortAttribute::DeltaR(jet) );
00402     
00403     // check that closest muon is within cone  
00404     // if it is, add muon to jet
00405     
00406     float muonJetRdist = m_kinehelp.deltaR( jet, *first ) ;
00407     
00408     log << MSG::DEBUG << "distance in R of muon to Jet " << muonJetRdist << endreq;
00409     
00410     if (
00411         (
00412          abs((*first)->eta()) <= m_barrelForwardEta && 
00413          muonJetRdist < m_rconeb
00414          ) 
00415         ||
00416         (
00417          abs((*first)->eta()) >  m_barrelForwardEta && 
00418          muonJetRdist < m_rconef
00419          )
00420         ) 
00421       {
00422         
00423         log << MSG::DEBUG 
00424             << "Adding muon to jet with momentum "
00425             << (*first)->momentum() 
00426             << endreq;
00427         
00428         log << MSG::DEBUG << "Old mom: " << *jet << endreq;
00429         
00430         jet->setMomentum(jet->momentum() + (*first)->momentum()); 
00431         
00432         log << MSG::DEBUG << "New mom: " << *jet << endreq ;
00433         
00434         // create association
00435         IAssociationManager* ia = jet;
00436         ia->associate(*first);
00437         
00438         // remove muon from list
00439         muons.erase(first);
00440         
00441         
00442       }
00443     else
00444       {        
00445         log << MSG::DEBUG << "Muon not in R cone" << endreq;
00446       }
00447     
00448   }
00449   
00450   
00451   //-------------------------------------------
00452   // isAcceptable
00453   //------------------------------------------
00454   
00455   // Decides whether a candidate is acceptable to this Maker, i.e. whether
00456   // it wants to proceed and add it to its output product collection
00457   
00458   bool JetMaker::isAcceptable ( Jet* candidate)
00459   {
00460     
00461     MsgStream log( messageService(), name() ) ;
00462     
00463     // Apply kinematic criteria to the candidate jet
00464     
00465     if( candidate->pT() < m_minPT ) {        
00466       log << MSG::DEBUG << "Candidate failed pt cut: pt " << candidate->pT() 
00467           << " min was " << m_minPT << endreq;
00468       return false ;
00469     }
00470     
00471     if( abs(candidate->eta()) > m_maxEta ) {
00472       log << MSG::DEBUG << "Candidate failed max eta cut: eta " 
00473           << candidate->eta() 
00474           << " max was " << m_maxEta << endreq;
00475       return false ;
00476     }
00477     
00478     return true ;
00479   }
00480   
00481   //-------------------------------------------
00482   // tag
00483   //------------------------------------------
00484   //
00485   
00486   void JetMaker::tag(Jet* jet, 
00487                      MCparticleCollection& mcParticles_b, 
00488                      MCparticleCollection& mcParticles_c, 
00489                      MCparticleCollection& mcParticles_tau)const {
00490  
00491     //See if jet can be b-tagged
00492     //Construct an object to select IKinematics within DeltaR of the current jet
00493     PartitionCondition::BelowThresholdDeltaR bTagSelector(jet, m_bMaxDeltaR); 
00494     int btag = getJetTags(mcParticles_b,bTagSelector);
00495     if(btag != 0 )
00496       {
00497         jet->setBTag();
00498         return;
00499       }
00500     //else see if jet can be c-tagged
00501     //Construct an object to select IKinematics within DeltaR of the current jet
00502     PartitionCondition::BelowThresholdDeltaR cTagSelector(jet, m_cMaxDeltaR); 
00503     int ctag = getJetTags( mcParticles_c, cTagSelector);
00504     if(ctag != 0 )
00505       { 
00506         jet->setCTag();
00507         return;
00508       }
00509 
00510     //finally see if jet can be tau-tagged
00511     //Construct an object to select IKinematics within DeltaR of the current jet
00512     PartitionCondition::BelowThresholdDeltaR tauTagSelector(jet, m_tauMaxDeltaR); 
00513     int tauTag=getTauTags( mcParticles_tau, tauTagSelector, jet->pT());
00514     if(tauTag !=0 ) jet->setTauTag(tauTag);
00515     return; 
00516   }
00517   //-------------------------------------------
00518   // getJetTags
00519   //------------------------------------------
00520   int JetMaker::getJetTags(MCparticleCollection&  mcParticles, 
00521                            const PartitionCondition::BelowThresholdDeltaR& tagSelector)const{
00522     
00523     MsgStream log( messageService(), name() ) ;
00524 
00525     MCparticleCollectionCIter src ;
00526         for( src = mcParticles.begin(); src != mcParticles.end(); ++src ){
00527           if(tagSelector(SimpleKinematic(*src))) return (*src)->pdg_id();
00528         }
00529         return 0;
00530   }
00531   //-------------------------------------------
00532   // getTauTags
00533   //------------------------------------------
00534   int JetMaker::getTauTags(
00535                            MCparticleCollection&  mcParticles,
00536                            const PartitionCondition::BelowThresholdDeltaR& 
00537                            tagSelector,
00538                            const double jetPt)const{
00539     
00540     MsgStream log( messageService(), name() ) ;
00541     MCparticleCollectionCIter src ;
00542     for( src = mcParticles.begin() ; src != mcParticles.end() ; ++src )
00543       {
00544         double tauPt = (*src)->momentum().perp();
00545         double neuPt=0.;
00546         // Find Tau children
00547         HepMC::GenVertex*  endVertex = (*src)->end_vertex();
00548         if(!endVertex) return 0;
00549 
00550         HepMC::GenVertex::particle_iterator firstChild = 
00551           endVertex->particles_begin(HepMC::children);
00552         
00553         HepMC::GenVertex::particle_iterator endChild = 
00554           endVertex->particles_end(HepMC::children);
00555         
00556         HepMC::GenVertex::particle_iterator thisChild = firstChild; 
00557         
00558         // Find Pt of Taus tau-neutrino
00559         for(; thisChild!=endChild; ++thisChild){
00560           if(  abs((*thisChild)->pdg_id()) == 16){
00561             neuPt = (*thisChild)->momentum().perp();
00562           }
00563         }
00564           
00565           if(tagSelector(SimpleKinematic(*src))      &&
00566              ((tauPt-neuPt)/jetPt) >= m_tauJetPtRatio) return (*src)->pdg_id();
00567         
00568         }
00569       return 0;
00570   }   
00571 
00572   HepLorentzVector JetMaker::addUnusedCells(MsgStream& log) const{
00573     vector<ICell*> unusedCells;
00574     HepLorentzVector temp(0., 0., 0., 0.);
00575 
00576     //    if( ! m_tesIO->copy( unusedCells, m_unusedCellLocation ) ) {
00577     if( ! m_tesIO->copy<CellCollection> ( unusedCells, m_unusedCellLocation) ){
00578       log << MSG::INFO << "No unused cells  in TES " << endreq;
00579       return temp;
00580     }  
00581     
00582     std::vector<ICell*>::const_iterator iter = unusedCells.begin();
00583     const std::vector<ICell*>::const_iterator end  = unusedCells.end();
00584    
00585     if(m_doSmearing){
00586       for(; iter!=end; ++iter){
00587         temp += m_cellSmearer->smear((*iter)->momentum());
00588       }
00589     }else{
00590       for(; iter!=end; ++iter){
00591         temp += (*iter)->momentum();
00592       }
00593     }
00594 
00595     return temp;
00596   }
00597     
00598 } // end namespace bracket
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 

Generated on Tue Jan 28 09:57:13 2003 for AtlfastAlgs by doxygen1.3-rc1