00001
00002
00003
00004
00005
00006
00007
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 #include <numeric>
00034
00035
00036 #include "GaudiKernel/DataSvc.h"
00037 #include "StoreGate/DataHandle.h"
00038 #include "GaudiKernel/ISvcLocator.h"
00039 #include "GaudiKernel/MsgStream.h"
00040
00041
00042
00043
00044 #include "GeneratorObjects/McEventCollection.h"
00045 #include "HepMC/GenEvent.h"
00046 #include "HepMC/GenVertex.h"
00047
00048
00049 namespace Atlfast{
00050
00051
00052 class SmearCell{
00053 public:
00054 SmearCell(ISmearer* is):
00055 m_smearer(is), m_doSmear((is== 0)? false:true) {}
00056 HepLorentzVector operator()(const HepLorentzVector& sumSoFar,
00057 const ICell* c){
00058
00059 HepLorentzVector sum(0., 0., 0., 0.);
00060
00061 if(m_doSmear){
00062 sum = sumSoFar+(m_smearer->smear( c->momentum() ) );
00063 }else{
00064 sum = sumSoFar+(c->momentum());
00065 }
00066
00067 return sum;
00068 }
00069 private:
00070 ISmearer* m_smearer;
00071 bool m_doSmear;
00072 };
00073
00074
00075
00076
00077
00078
00079 using std::abs;
00080 using std::sort;
00081
00082 JetMaker::JetMaker
00083 ( const std::string& name, ISvcLocator* pSvcLocator )
00084 : Algorithm( name, pSvcLocator ){
00085
00086
00087 m_minPT = 10;
00088 m_maxEta = 5;
00089 m_doSmearing = true;
00090 m_rconeb = 0.400;
00091 m_rconef = 0.400;
00092
00093 m_bPtMin = 5.0;
00094 m_bMaxDeltaR = 0.2;
00095
00096 m_cPtMin = 5.0;
00097 m_cMaxDeltaR = 0.2;
00098
00099 m_tauPtMin = 10.0;
00100 m_tauMaxDeltaR = 0.3;
00101
00102 m_etaTagMax = 2.5;
00103
00104 m_tauJetPtRatio = 0.9;
00105
00106
00107
00108 m_inputLocation = "/Event/AtlfastClusters";
00109 m_outputLocation = "/Event/AtlfastJets";
00110 m_muonLocation = "/Event/AtlfastNonIsolatedMuons";
00111 m_unusedCellLocation = "/Event/AtlfastUnusedCells";
00112 m_missingMomentumLocation = "/Event/AtlfastMissingMomentum";
00113 m_mcTruthLocation = "/Event/McEventCollection";
00114
00115
00116
00117 declareProperty( "MinimumPT", m_minPT ) ;
00118 declareProperty( "MaximumEta", m_maxEta ) ;
00119 declareProperty( "DoSmearing", m_doSmearing );
00120 declareProperty( "RconeB", m_rconeb );
00121 declareProperty( "RconeF", m_rconef );
00122 declareProperty( "bPtMin", m_bPtMin );
00123 declareProperty( "bMaxDeltaR", m_bMaxDeltaR );
00124 declareProperty( "cPtMin", m_cPtMin );
00125 declareProperty( "cMaxDeltaR", m_cMaxDeltaR );
00126 declareProperty( "tauPtMin", m_tauPtMin );
00127 declareProperty( "tauMaxDeltaR", m_tauMaxDeltaR );
00128 declareProperty( "etaTagMax", m_etaTagMax );
00129 declareProperty( "tauJetPtRatio", m_tauJetPtRatio);
00130
00131 declareProperty( "InputLocation", m_inputLocation ) ;
00132 declareProperty( "OutputLocation", m_outputLocation ) ;
00133 declareProperty( "UnusedCellLocation", m_unusedCellLocation ) ;
00134 declareProperty( "MuonLocation", m_muonLocation );
00135 declareProperty( "MissingMomentumLocation", m_missingMomentumLocation );
00136 declareProperty( "McTruthLocation", m_mcTruthLocation );
00137 }
00138
00139 JetMaker::~JetMaker() {
00140
00141 MsgStream log( messageService(), name() ) ;
00142 log << MSG::INFO << "Destructor Called" << endreq;
00143
00144 if (m_smearer) {
00145 log << MSG::INFO << "Deleting jet Smearer" << endreq;
00146 delete m_smearer;
00147 }
00148 if (m_cellSmearer) {
00149 log << MSG::INFO << "Deleting Cell Smearer" << endreq;
00150 delete m_cellSmearer;
00151 }
00152 if (m_tesIO) {
00153 delete m_tesIO;
00154 }
00155 }
00156
00157
00158
00159
00160
00161 StatusCode JetMaker::initialize(){
00162 MsgStream log( messageService(), name() ) ;
00163
00164 log << MSG::DEBUG << "instantiating a JetSmearer" << endreq;
00165
00166
00167 m_tesIO = new TesIO();
00168
00169
00170 GlobalEventData* ged = GlobalEventData::Instance();
00171 int lumi = ged->lumi();
00172 int randSeed = ged->randSeed() ;
00173 m_barrelForwardEta = ged->barrelForwardEta();
00174
00175 if(m_doSmearing){
00176 m_smearer = new JetSmearer(randSeed,
00177 lumi,
00178 m_rconeb,
00179 m_rconef,
00180 m_barrelForwardEta);
00181 m_cellSmearer = new JetSmearer(randSeed,
00182 lumi,
00183 0.,
00184 0.,
00185 m_barrelForwardEta);
00186 } else {
00187 m_smearer = NULL;
00188 m_cellSmearer = NULL;
00189 }
00190
00191 HeaderPrinter hp("Atlfast JetMaker:", log);
00192
00193 hp.add("TES Locations: ");
00194 hp.add(" Muons from ", m_muonLocation);
00195 hp.add(" Clusters from ", m_inputLocation);
00196 hp.add(" GeneratorParticles from ", m_mcTruthLocation);
00197 hp.add(" Jets to ", m_outputLocation);
00198 hp.add(" unused cell,cluster sum to ", m_missingMomentumLocation);
00199 hp.add("Smearing on ", m_doSmearing);
00200 hp.add("Cluster min Pt ", m_minPT);
00201 hp.add("Cluster max Eta ", m_maxEta);
00202 hp.add("Luminosity ", lumi);
00203 hp.add("Initial random seed ", randSeed);
00204 hp.add("End cap Cone size ", m_rconef);
00205 hp.add("Barrel Cone size ", m_rconeb);
00206 hp.add("Eta of start of end cap ", m_barrelForwardEta);
00207 hp.add("Parameters for tags ", " ");
00208 hp.add(" Max eta ", m_etaTagMax);
00209 hp.add(" b-quark min pt ", m_bPtMin);
00210 hp.add(" b-quark max DeltaR ", m_bMaxDeltaR);
00211 hp.add(" c-quark min pt ", m_cPtMin);
00212 hp.add(" c-quark max DeltaR ", m_cMaxDeltaR);
00213 hp.add(" tau lep min pt ", m_tauPtMin);
00214 hp.add(" tau lep max DeltaR ", m_tauMaxDeltaR);
00215 hp.add(" tau/Jet Pt Ratio ", m_tauJetPtRatio);
00216 hp.print();
00217
00218
00219
00220 return StatusCode::SUCCESS ;
00221 }
00222
00223
00224
00225
00226
00227 StatusCode JetMaker::finalize(){
00228
00229 MsgStream log( messageService(), name() ) ;
00230 log << MSG::INFO << "finalizing" << endreq;
00231 return StatusCode::SUCCESS ;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 StatusCode JetMaker::execute( ){
00253
00254 MsgStream log( messageService(), name() ) ;
00255
00256 std::string mess;
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 localClusterCollection my_Clusters ;
00268 MuonCollection my_Muons ;
00269
00270
00271
00272 if( ! m_tesIO->copy<ClusterCollection> ( my_Clusters, m_inputLocation ) ) {
00273 log << MSG::INFO << "No Clusters in TES " << endreq;
00274 } else {
00275 log << MSG::DEBUG << my_Clusters.size()<<" Clusters from TES " << endreq;
00276 }
00277
00278
00279 if( ! m_tesIO->copy<ReconstructedParticleCollection>
00280 ( my_Muons, m_muonLocation ) ) {
00281 log << MSG::DEBUG << "No muons in TES " << endreq;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291 JetCollection* myJets = new JetCollection ;
00292
00293
00294
00295
00296
00297 Jet* candidate ;
00298 localClusterIterator src ;
00299 HepLorentzVector missingMomentum(0.,0.,0.,0.);
00300 const int BQUARK(ParticleCodes::BQUARK);
00301 const int CQUARK(ParticleCodes::CQUARK);
00302
00303 const HepMC_helper::SelectJetTag bSelector(BQUARK, m_bPtMin, m_etaTagMax);
00304 const HepMC_helper::SelectJetTag cSelector(CQUARK, m_cPtMin, m_etaTagMax);
00305 const HepMC_helper::SelectTauTag tauSelector(m_tauPtMin, m_etaTagMax);
00306
00307 MCparticleCollection mcParticles_b ;
00308 MCparticleCollection mcParticles_c ;
00309 MCparticleCollection mcParticles_tau ;
00310
00311 m_tesIO->getMC( mcParticles_b, &bSelector ) ;
00312 m_tesIO->getMC( mcParticles_c, &cSelector ) ;
00313 m_tesIO->getMC( mcParticles_tau, &tauSelector ) ;
00314
00315 for( src = my_Clusters.begin() ; src != my_Clusters.end() ; ++src )
00316 {
00317 IAssociationManager* iAssocMan = *src;
00318 ReconstructedParticle rp;
00319 if (iAssocMan->associations(rp).size() == 0)
00320 {
00321
00322 candidate = this->create( *src );
00323
00324
00325
00326 HepLorentzVector temp4Vec = candidate->momentum();
00327
00328
00329 this->addMuons(candidate, my_Muons);
00330
00331
00332
00333
00334 if( this->isAcceptable( candidate ) ) {
00335
00336
00337 this->tag(candidate,mcParticles_b,mcParticles_c,mcParticles_tau);
00338
00339 log << MSG::DEBUG << "Pushing back a Jet" << endreq;
00340 myJets->push_back( candidate ) ;
00341 log<<MSG::DEBUG<<"jet "<<*candidate<<endreq;
00342 }else {
00343 log << MSG::DEBUG << "Jet fails cuts" << endreq;
00344
00345 missingMomentum += temp4Vec;
00346 delete candidate ;
00347 }
00348 }
00349 }
00350
00351 log<<MSG::DEBUG<<"Missing momentum: clusters "<<missingMomentum<<endreq;
00352 missingMomentum += addUnusedCells(log);
00353 log<<MSG::DEBUG<<"Missing momentum: cells+clstrs "
00354 <<missingMomentum<<endreq;
00355
00356
00357
00358 TesIoStat stat;
00359 log<<MSG::DEBUG<<"Storing "<< myJets->size() <<" Jets"<<endreq;
00360 stat = m_tesIO->store( myJets, m_outputLocation ) ;
00361 if(!stat){
00362 log<<MSG::ERROR<<"Could not store jets"<<endreq;
00363 return stat;
00364 }
00365
00366
00367 MissingMomentum* mm = new MissingMomentum(missingMomentum);
00368 stat = m_tesIO->store(mm,m_missingMomentumLocation ) ;
00369 std::string message = stat? "Stored missing mom":"Failed to missing mom";
00370 log<<MSG::DEBUG<<message<<endreq;
00371
00372
00373 return StatusCode::SUCCESS;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 Jet* JetMaker::create ( Cluster* src )
00390 {
00391 Jet* jet;
00392 MsgStream log( messageService(), name() ) ;
00393 HepLorentzVector vec = src->momentum();
00394
00395 if (m_doSmearing)
00396 {
00397
00398 vec = m_smearer->smear(vec);
00399 }
00400
00401 jet = new Jet(vec, *src);
00402 log << MSG::DEBUG << "Unsmeared Cluster: " << *src << endreq;
00403 log << MSG::DEBUG << "Smeared Jet : " << jet << endreq ;
00404
00405
00406 return jet;
00407
00408
00409 }
00410
00411
00412
00413
00414
00415
00416 void JetMaker::addMuons(Jet* jet, MuonCollection& muons )
00417 {
00418
00419 if (muons.size() == 0) return;
00420
00421 MsgStream log( messageService(), name() ) ;
00422
00423 MuonIterator first = muons.begin() ;
00424 MuonIterator last = muons.end() ;
00425
00426
00427 sort( first, last, SortAttribute::DeltaR(jet) );
00428
00429
00430
00431
00432 float muonJetRdist = m_kinehelp.deltaR( jet, *first ) ;
00433
00434 log << MSG::DEBUG << "distance in R of muon to Jet " << muonJetRdist << endreq;
00435
00436 if (
00437 (
00438 abs((*first)->eta()) <= m_barrelForwardEta &&
00439 muonJetRdist < m_rconeb
00440 )
00441 ||
00442 (
00443 abs((*first)->eta()) > m_barrelForwardEta &&
00444 muonJetRdist < m_rconef
00445 )
00446 )
00447 {
00448
00449 log << MSG::DEBUG
00450 << "Adding muon to jet with momentum "
00451 << (*first)->momentum()
00452 << endreq;
00453
00454 log << MSG::DEBUG << "Old mom: " << *jet << endreq;
00455
00456 jet->setMomentum(jet->momentum() + (*first)->momentum());
00457
00458 log << MSG::DEBUG << "New mom: " << *jet << endreq ;
00459
00460
00461 IAssociationManager* ia = jet;
00462 ia->associate(*first);
00463
00464
00465 muons.erase(first);
00466
00467
00468 }
00469 else
00470 {
00471 log << MSG::DEBUG << "Muon not in R cone" << endreq;
00472 }
00473
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 bool JetMaker::isAcceptable ( Jet* candidate)
00485 {
00486
00487 MsgStream log( messageService(), name() ) ;
00488
00489
00490
00491 if( candidate->pT() < m_minPT ) {
00492 log << MSG::DEBUG << "Candidate failed pt cut: pt " << candidate->pT()
00493 << " min was " << m_minPT << endreq;
00494 return false ;
00495 }
00496
00497 if( abs(candidate->eta()) > m_maxEta ) {
00498 log << MSG::DEBUG << "Candidate failed max eta cut: eta "
00499 << candidate->eta()
00500 << " max was " << m_maxEta << endreq;
00501 return false ;
00502 }
00503
00504 return true ;
00505 }
00506
00507
00508
00509
00510
00511
00512 void JetMaker::tag(Jet* jet,
00513 MCparticleCollection& mcParticles_b,
00514 MCparticleCollection& mcParticles_c,
00515 MCparticleCollection& mcParticles_tau)const {
00516
00517
00518
00519 PartitionCondition::BelowThresholdDeltaR bTagSelector(jet, m_bMaxDeltaR);
00520 int btag = getJetTags(mcParticles_b,bTagSelector);
00521 if(btag != 0 )
00522 {
00523 jet->setBTag();
00524 return;
00525 }
00526
00527
00528 PartitionCondition::BelowThresholdDeltaR cTagSelector(jet, m_cMaxDeltaR);
00529 int ctag = getJetTags( mcParticles_c, cTagSelector);
00530 if(ctag != 0 )
00531 {
00532 jet->setCTag();
00533 return;
00534 }
00535
00536
00537
00538 PartitionCondition::BelowThresholdDeltaR tauTagSelector(jet, m_tauMaxDeltaR);
00539 int tauTag=getTauTags( mcParticles_tau, tauTagSelector, jet->pT());
00540 if(tauTag !=0 ) jet->setTauTag(tauTag);
00541 return;
00542 }
00543
00544
00545
00546 int JetMaker::getJetTags(MCparticleCollection& mcParticles,
00547 const PartitionCondition::BelowThresholdDeltaR& tagSelector)const{
00548
00549 MsgStream log( messageService(), name() ) ;
00550
00551 MCparticleCollectionCIter src ;
00552 for( src = mcParticles.begin(); src != mcParticles.end(); ++src ){
00553 if(tagSelector(SimpleKinematic(*src))) return (*src)->pdg_id();
00554 }
00555 return 0;
00556 }
00557
00558
00559
00560 int JetMaker::getTauTags(
00561 MCparticleCollection& mcParticles,
00562 const PartitionCondition::BelowThresholdDeltaR&
00563 tagSelector,
00564 const double jetPt)const{
00565
00566 MsgStream log( messageService(), name() ) ;
00567 MCparticleCollectionCIter src ;
00568 for( src = mcParticles.begin() ; src != mcParticles.end() ; ++src )
00569 {
00570 double tauPt = (*src)->momentum().perp();
00571 double neuPt=0.;
00572
00573 HepMC::GenVertex* endVertex = (*src)->end_vertex();
00574 if(!endVertex) return 0;
00575
00576 HepMC::GenVertex::particle_iterator firstChild =
00577 endVertex->particles_begin(HepMC::children);
00578
00579 HepMC::GenVertex::particle_iterator endChild =
00580 endVertex->particles_end(HepMC::children);
00581
00582 HepMC::GenVertex::particle_iterator thisChild = firstChild;
00583
00584
00585 for(; thisChild!=endChild; ++thisChild){
00586 if( abs((*thisChild)->pdg_id()) == 16){
00587 neuPt = (*thisChild)->momentum().perp();
00588 }
00589 }
00590
00591 if(tagSelector(SimpleKinematic(*src)) &&
00592 ((tauPt-neuPt)/jetPt) >= m_tauJetPtRatio) return (*src)->pdg_id();
00593
00594 }
00595 return 0;
00596 }
00597
00598 HepLorentzVector JetMaker::addUnusedCells(MsgStream& log) const{
00599
00600 HepLorentzVector temp(0., 0., 0., 0.);
00601
00602
00603 DataHandle<ITwoCptCellCollection> unusedCells;
00604 if( ! m_tesIO->getDH( unusedCells, m_unusedCellLocation) ){
00605 log << MSG::INFO << "No unused cells in TES " << endreq;
00606 return temp;
00607 }
00608 log << MSG::DEBUG << "No unused cells in TES " << endreq;
00609
00610 return std::accumulate(unusedCells->begin(),
00611 unusedCells->end(),
00612 temp,
00613 SmearCell(m_cellSmearer)
00614 );
00615
00616 }
00617
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645