ATLAS Offline Software
Loading...
Searching...
No Matches
CaloIsolationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// CaloIsolationTool
7//
8// (c) ATLAS software
10
11//<<<<<< INCLUDES >>>>>>
13#include "CaloGeoHelpers/CaloSampling.h"
15
16#ifndef XAOD_ANALYSIS
17#include "CaloEvent/CaloCell.h"
23#include "GaudiKernel/ThreadLocalContext.h"
24#endif // XAOD_ANALYSIS
25
26// #include "IsolationCorrections/IIsolationCorrectionTool.h"
32
36#include "xAODPFlow/FEHelpers.h"
38
39#include <cmath>
40
42#include <TFile.h>
43
44namespace {
45#if defined(SIMULATIONBASE) || defined(XAOD_ANALYSIS)
46size_t cluster_size (const xAOD::CaloCluster* ) { return 0; }
47#else
48size_t cluster_size (const xAOD::CaloCluster* cl) { return cl->size(); }
49#endif
50}
51
52
53namespace xAOD {
54
57 {
58#ifndef XAOD_ANALYSIS
59 declareInterface<ICaloCellIsolationTool>(this);
60 declareInterface<ICaloTopoClusterIsolationTool>(this);
61 declareInterface<INeutralEFlowIsolationTool>(this);
62#endif // XAOD_ANALYSIS
63 }
64
66
68#ifndef XAOD_ANALYSIS
69 if (!m_assoTool.empty())
70 ATH_CHECK(m_assoTool.retrieve());
71
72 if (!m_caloExtTool.empty())
73 ATH_CHECK(m_caloExtTool.retrieve());
74
75 if (!m_clustersInConeTool.empty())
77
78 if (!m_pflowObjectsInConeTool.empty())
80
81 if (!m_caloFillRectangularTool.empty()) {
83 }
84
85 //check calo number specified for EM Calos
86 unsigned int nSubCalo=static_cast<int>(CaloCell_ID::NSUBCALO);
87 if (m_EMCaloNums.size()>nSubCalo || m_HadCaloNums.size()>nSubCalo) {
88 ATH_MSG_ERROR(" More than " << nSubCalo << " calo specified. Required for EM =" << m_EMCaloNums.size()<< ", and for HCAL = " << m_HadCaloNums.size() << ". Must be wrong. Stop.");
89 return StatusCode::FAILURE;
90 }
91
92 for (unsigned int index=0; index < m_EMCaloNums.size() ; ++index) {
93 if (m_EMCaloNums[index]<0 || m_EMCaloNums[index]>=(int)nSubCalo ) {
94 ATH_MSG_ERROR("Invalid calo specification:" << m_EMCaloNums[index] << "Stop.");
95 return StatusCode::FAILURE;
96 } else
97 ATH_MSG_DEBUG("Select calorimeter " << m_EMCaloNums[index]);
98 }
99
100 for (unsigned int index=0; index < m_HadCaloNums.size() ; ++index) {
101 if (m_HadCaloNums[index]<0 || m_HadCaloNums[index]>=(int)nSubCalo) {
102 ATH_MSG_ERROR("Invalid calo specification:" << m_HadCaloNums[index] << "Stop.");
103 return StatusCode::FAILURE;
104 } else
105 ATH_MSG_DEBUG("Select calorimeter " << m_HadCaloNums[index]);
106 }
107
109 ATH_CHECK(m_caloMgrKey.initialize());
110#endif // XAOD_ANALYSIS
111
112 if (!m_IsoLeakCorrectionTool.empty())
114
115 // initialize the read handles (for now do all of them in all cases)
116
121
122 if (m_useEtaDepPU) {
124 if (filename.empty()){
125 ATH_MSG_ERROR ( "Could NOT resolve file name " << m_puZetaCorrectionFileName );
126 return StatusCode::FAILURE ;
127 }
128 ATH_MSG_INFO("Path found for pileup correction = "<< filename);
129 std::unique_ptr<TFile> f(TFile::Open(filename.c_str(), "READ"));
130 m_puZetaCorrection[xAOD::Iso::topoetcone20] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone20"));
131 m_puZetaCorrection[xAOD::Iso::topoetcone30] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone30"));
132 m_puZetaCorrection[xAOD::Iso::topoetcone40] = std::unique_ptr<TGraph>((TGraph*)f->Get("topoetcone40"));
133 f->Close();
134
135 if (m_isMC) {
137 if (filename.empty()){
138 ATH_MSG_ERROR ( "Could NOT resolve file name " << m_puZetaMCCorrectionFileName );
139 return StatusCode::FAILURE ;
140 }
141 ATH_MSG_INFO("Path found for mc additional correction of pileup correction = "<< filename);
142 std::unique_ptr<TFile> g(TFile::Open(filename.c_str(), "READ"));
143 m_puZetaMCCorrection[xAOD::Iso::topoetcone20] = std::unique_ptr<TGraph>((TGraph*)g->Get("topoetcone20"));
144 m_puZetaMCCorrection[xAOD::Iso::topoetcone30] = std::unique_ptr<TGraph>((TGraph*)g->Get("topoetcone30"));
145 m_puZetaMCCorrection[xAOD::Iso::topoetcone40] = std::unique_ptr<TGraph>((TGraph*)g->Get("topoetcone40"));
146 g->Close();
147 }
148 }
149
150 // Exit function
151 return StatusCode::SUCCESS;
152 }
153
154
156 return StatusCode::SUCCESS;
157 }
158
159
160 // IParticle interface for cell-based isolation (etcone)
162 const std::vector<Iso::IsolationType>& cones,
163 const CaloCorrection& corrlist,
164 const CaloCellContainer* container) const {
165#ifdef XAOD_ANALYSIS
166 (void) result;
167 (void) particle;
168 (void) cones;
169 (void) corrlist;
170 (void) container;
171 return false;
172#else // XAOD_ANALYSIS
173 derefMap_t derefMap;
175 const IParticle* ip = getReferenceParticle(particle);
176 if( !ip ){
177 ATH_MSG_WARNING("Failed to obtain reference particle");
178 return false;
179 }
180 derefMap[ip] = &particle;
181
182 double coneCoreSize = m_coneCoreSizeEg;
183 if (particle.type() == Type::Muon)
184 coneCoreSize = m_coneCoreSizeMu;
185
186 // muon etcone isolation
187 const Muon* muon = dynamic_cast<const Muon*>(&particle);
188 if(muon) return caloCellIsolation(result,*muon,cones,corrlist,coneCoreSize,derefMap);
189
190 // egamma etcone isolation
191 const Egamma* egam = dynamic_cast<const Egamma*>(ip);
192 if( egam ) return caloCellIsolation(result,*egam,cones,corrlist,container);
193
194 ATH_MSG_WARNING("CaloCellIsolation only supported for Muons and Egamma");
195
196 return true;
197#endif // not XAOD_ANALYSIS
198 }
199
200 // IParticle interface for cluster-based isolation (topoetcone)
202 const std::vector<Iso::IsolationType>& cones,
203 const CaloCorrection& corrlist,
204 const CaloClusterContainer* container ) const {
205
206 if ( cones.empty() ) {
207 ATH_MSG_DEBUG("No isolation required");
208 return false;
209 }
210
211 double coneCoreSize = m_coneCoreSizeEg;
212 if (particle.type() == Type::Muon)
213 coneCoreSize = m_coneCoreSizeMu;
214
215 derefMap_t derefMap;
217 const IParticle* ip = getReferenceParticle(particle);
218 if( !ip ){
219 ATH_MSG_WARNING("Failed to obtain reference particle");
220 return false;
221 }
222 derefMap[ip] = &particle;
223
224 // muon topoetcone isolation
225 const TrackParticle* trkp = dynamic_cast<const TrackParticle*>(ip);
226 if( trkp ) return caloTopoClusterIsolation(result,*trkp,cones,corrlist,container,coneCoreSize,derefMap);
227
228 // egamma topoetcone isolation
229 const Egamma* egam = dynamic_cast<const Egamma*>(ip);
230 if( egam ) return caloTopoClusterIsolation(result,*egam,cones,corrlist,container, coneCoreSize);
231
232 ATH_MSG_WARNING("CaloTopoClusterIsolation only supported for TrackParticles and Egamma");
233
234 return true;
235 }
236
237
238 // interface for pflow based isolation
240 const std::vector<Iso::IsolationType>& cones,
241 const CaloCorrection& corrlist) const{
242
243 //
244 double coneCoreSize = m_coneCoreSizeEg;
245 if (particle.type() == Type::Muon)
246 coneCoreSize = m_coneCoreSizeMu;
247
248 derefMap_t derefMap;
250 const IParticle* ip = getReferenceParticle(particle);
251 if( !ip ){
252 ATH_MSG_WARNING("Failed to obtain reference particle");
253 return false;
254 }
255 derefMap[ip] = &particle;
256
257 // muon pflowetcone isolation
258 const TrackParticle* trkp = dynamic_cast<const TrackParticle*>(ip);
259 if ( trkp ) return neutralEflowIsolation(result,*trkp,cones,corrlist,coneCoreSize,derefMap);
260
261 // egamma pflowetcone isolation
262 const Egamma* egam = dynamic_cast<const Egamma*>(ip);
263 if ( egam ) return neutralEflowIsolation(result,*egam,cones,corrlist,coneCoreSize);
264
265 ATH_MSG_WARNING("FlowElementIsolation only supported for Egamma and TrackParticle");
266
267 return true;
268 }
269
270
271 // casted interface for Muon cell-based isolation (etcone)
273#ifndef XAOD_ANALYSIS
274 const Muon& muon,
275#endif
276 const std::vector<Iso::IsolationType>& isoTypes, const CaloCorrection& corrlist
277#ifndef XAOD_ANALYSIS
278 , double coneCoreSize
279 , const derefMap_t& derefMap
280#endif
281 ) const {
282 if( isoTypes.empty() ) {
283 ATH_MSG_WARNING("Empty list passed, failing calculation");
284 return false;
285 }
286
287 unsigned int typesize = isoTypes.size();
288 initresult(result, corrlist, typesize);
289
290 // get cones
291 Iso::IsolationFlavour theFlavour = Iso::isolationFlavour(isoTypes.front());
292
293 if (theFlavour == Iso::etcone)
294#ifndef XAOD_ANALYSIS
295 return etConeIsolation(result, muon, isoTypes, coneCoreSize, derefMap);
296#else
297 return true;
298#endif
299
300 ATH_MSG_WARNING("Unsupported isolation flavour passed, cannot calculate isolation " <<
301 static_cast<int>(theFlavour));
302
303 return false;
304 }
305
306 // casted interface for EGamma cell-based isolation (etcone)
308 const std::vector<Iso::IsolationType>& isoTypes,
309 const CaloCorrection& corrlist
310#ifndef XAOD_ANALYSIS
312#endif
313 ) const {
314 if( isoTypes.empty() ) {
315 ATH_MSG_WARNING("Empty list passed, failing calculation");
316 return false;
317 }
318
319 unsigned int typesize = isoTypes.size();
320 initresult(result, corrlist, typesize);
321
322 std::vector<float> coneSizes;
323 coneSizes.resize(isoTypes.size());
324 for (unsigned int is = 0; is < isoTypes.size(); is++)
325 coneSizes[is] = Iso::coneSize(isoTypes[is]);
326
327 // get cones
328 Iso::IsolationFlavour theFlavour = Iso::isolationFlavour(isoTypes.front());
329
330 if (theFlavour == Iso::etcone){
331#ifndef XAOD_ANALYSIS
332 etConeIsolation(result, eg, isoTypes, container);
333#else
334 return true;
335#endif
336 }else{
337 ATH_MSG_WARNING("Unsupported isolation flavour passed, cannot calculate isolation " << static_cast<int>(theFlavour));
338 return false;
339 }
340
341 // Apply corrections
342 // core energy subtraction
343 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::core57cells))) {
344 if (!correctIsolationEnergy_Eeg57(result,isoTypes,&eg))
345 ATH_MSG_WARNING("Could not compute core cell energy for egamma in etcone");
346 }
347
348 // leakage correction
349 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::ptCorrection))) {
350 if (!PtCorrection(result, eg, isoTypes))
351 ATH_MSG_WARNING("Could not apply pt correction to etcone isolation");
352 }
353
354 return true;
355 }
356
357 // casted interface for EGamma cluster-based isolation (topoetcone)
359 const Egamma& eg,
360 const std::vector<Iso::IsolationType>& isoTypes,
361 const CaloCorrection& corrlist,
363 double coneCoreSize) const
364 {
365
366 if( isoTypes.empty() ) {
367 ATH_MSG_WARNING("Empty list passed, failing calculation");
368 return false;
369 }
370
371 unsigned int typesize = isoTypes.size();
372 initresult(result, corrlist, typesize);
373
374 std::vector<float> coneSizes;
375 coneSizes.reserve(isoTypes.size());
376
377 for( auto isoType : isoTypes ){
378 coneSizes.push_back(Iso::coneSize(isoType));
379 }
380
381 float phi = eg.caloCluster()->phi();
382 float eta = eg.caloCluster()->eta();
383
384 const CaloCluster* fwdClus = eg.author(xAOD::EgammaParameters::AuthorFwdElectron) ? eg.caloCluster() : nullptr;
385
386 if (!topoConeIsolation(result, eta, phi, coneSizes, true, container, fwdClus, &eg, coneCoreSize)) {
387 ATH_MSG_WARNING("topoConeIsolation failed for egamma");
388 return false;
389 }
390
391 // 5x7 : no meaning for fwd electron
392 if (fwdClus == nullptr && (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::core57cells)))) {
393 // Apply core energy subtraction
394 if (!correctIsolationEnergy_Eeg57(result,isoTypes,&eg))
395 ATH_MSG_WARNING("Could not compute core cell energy for egamma in topoetcone");
396 }
397
398 // leakage : at least for the time being, no meaning for fwd electron
399 if ((!m_saveOnlyRequestedCorrections && fwdClus == nullptr) || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::ptCorrection))) {
400 // do pt correction
401 if (!PtCorrection(result, eg, isoTypes))
402 ATH_MSG_WARNING("Could not apply pt correction to topoetcone isolation");
403 }
404 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))) {
405 // do pile-up correction
406 if (!EDCorrection(result,isoTypes,eta,"topo",fwdClus))
407 ATH_MSG_WARNING("Could not apply ED correction to topo isolation");
408 }
409
410 return true;
411
412 }
413
414 // casted interface for EGamma pflow-based isolation
416 const Egamma& eg,
417 const std::vector<Iso::IsolationType>& isoTypes,
418 const CaloCorrection& corrlist,
419 double coneCoreSize) const
420 {
421
422 if( isoTypes.empty() ) {
423 ATH_MSG_WARNING("Empty list passed, failing calculation");
424 return false;
425 }
426 if(!m_useEMScale){
427 ATH_MSG_WARNING("Only EM scale is supported by neutralEflowIsolation");
428 return false;
429 }
430
431 unsigned int typesize = isoTypes.size();
432 initresult(result, corrlist, typesize);
433
434 std::vector<float> coneSizes;
435 coneSizes.reserve(isoTypes.size());
436
437 for( auto isoType : isoTypes ){
438 coneSizes.push_back(Iso::coneSize(isoType));
439 }
440
441 // neutral pflow are pv-corrected
442 // ==> use electron eta/phi (not associated SC eta/phi)
443 // ==> for photons, there is a mismatch...
444 float phi = eg.phi();
445 float eta = eg.eta();
446
447 ATH_MSG_DEBUG("eg pt eta phi " << eg.pt() << " " << eta << " " << phi
448 << " cluster eta, phi = " << eg.caloCluster()->eta() << " " << eg.caloCluster()->phi());
449
450 if (!pflowConeIsolation(result, eta, phi, coneSizes, true, nullptr, coneCoreSize, &eg)) {
451 ATH_MSG_WARNING("pflowConeIsolation failed");
452 return false;
453 }
454
455 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::core57cells))) {
456 // Apply core energy subtraction
457 if (!correctIsolationEnergy_Eeg57(result,isoTypes,&eg))
458 ATH_MSG_WARNING("Could not compute core cell energy for egamma in neflowisol");
459 }
460
461 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::ptCorrection))) {
462 // do pt correction
463 if (!PtCorrection(result, eg, isoTypes))
464 ATH_MSG_WARNING("Could not apply pt correction to isolation");
465 }
466
467 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))) {
468 // do pile-up correction
469 std::string type = "PFlow";
470 if (!EDCorrection(result,isoTypes,eta,type,nullptr))
471 ATH_MSG_WARNING("Could not apply ED correction to topo isolation");
472 }
473
474 return true;
475 }
476
477 // casted interface for TP pflow-based isolation
478 bool
481 const TrackParticle& tp,
482 const std::vector<Iso::IsolationType>& isoTypes,
483 const CaloCorrection& corrlist,
484 double coneCoreSize,
485 derefMap_t& derefMap) const
486 {
487
488 if( isoTypes.empty() ) {
489 ATH_MSG_WARNING("Empty list passed, failing calculation");
490 return false;
491 }
492
493 unsigned int typesize = isoTypes.size();
494 initresult(result, corrlist, typesize);
495
496 std::vector<float> coneSizes;
497 coneSizes.reserve(isoTypes.size());
498
499 for( auto isoType : isoTypes ){
500 coneSizes.push_back(Iso::coneSize(isoType));
501 }
502
503 float phi = tp.phi();
504 float eta = tp.eta();
505 if(!GetExtrapEtaPhi(&tp,eta,phi,derefMap)) {
506 ATH_MSG_WARNING("TrackParticle eta = " << tp.eta() << ", phi = " << tp.phi() << " not updated from extraplation!");
507 }
508 ATH_MSG_DEBUG("TrackParticle eta = " << tp.eta() << ", phi = " << tp.phi() << ", extrap eta = " << eta << ", phi = " << phi);
509
510 // The core subtraction with pflow removal is done in the method below
511 if (!pflowConeIsolation(result, eta, phi, coneSizes, false, nullptr, coneCoreSize)) {
512 ATH_MSG_WARNING("pflowConeIsolation failed for muon");
513 return false;
514 }
515
516 // core energy subtraction
517 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))) {
518 if (!correctIsolationEnergy_MuonCore(result, tp, derefMap))
519 ATH_MSG_WARNING("Could not compute muon core energy (cells) from neflowisol");
520 }
521
522 // do pile-up correction
523 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))) {
524 std::string type = "PFlow";
525 if (!EDCorrection(result,isoTypes,eta,type,nullptr))
526 ATH_MSG_WARNING("Could not apply ED correction to eflow isolation for muon");
527 }
528
529 return true;
530 }
531
533 derefMap_t& derefMap) const
534 {
536 static const SG::AuxElement::ConstAccessor< char > Decorated("caloExt_Decorated");
537 static const SG::AuxElement::ConstAccessor< float > Eta("caloExt_eta");
538 static const SG::AuxElement::ConstAccessor< float > Phi("caloExt_phi");
539 if(Decorated.isAvailable(*tp) && Decorated(*tp)){
540 eta = Eta(*tp);
541 phi = Phi(*tp);
542 return true;
543 }
544
546 const Muon* mu = dynamic_cast<const Muon*>(derefMap[tp]);
547 if(mu){
548 const auto *cluster = mu->cluster();
549 if(cluster){
550 float etaT = 0, phiT = 0, dphiT = 0.;
551 int nSample = 0;
552 for(unsigned int i=0; i<CaloSampling::Unknown; i++) // dangerous?
553 {
554 auto s = static_cast<CaloSampling::CaloSample>(i);
555 if(!cluster->hasSampling(s)) continue;
556 ATH_MSG_DEBUG("Sampling: " << i << "eta-phi (" << cluster->etaSample(s) << ", " << cluster->phiSample(s) << ")");
557 etaT += cluster->etaSample(s);
558 if( nSample == 0 ){
559 phiT = cluster->phiSample(s);
560 }
561 else{
562 dphiT += xAOD::P4Helpers::deltaPhi( cluster->phiSample(s), phiT ) ;
563 }
564 nSample++;
565 }
566 if(nSample>0){
567 eta = etaT/nSample;
568 phi = phiT + dphiT/nSample;
569 return true;
570 }else{
571 ATH_MSG_WARNING("Muon calo cluster is empty????");
572 }
573 }else{
574 ATH_MSG_DEBUG("Muon calo cluster not found.");
575 }
576 }
577
578#ifndef XAOD_ANALYSIS
580 ATH_MSG_DEBUG("Geting calo extension caloExtension tool.");
581 // If we have an extension cache then it owns the extension, otherwise we own it
582 // Therefore we have to prepare both an owning and a non-owning pointer
583 std::unique_ptr<Trk::CaloExtension> caloExtensionUPtr;
584 const Trk::CaloExtension* caloExtension = nullptr;
585 if (m_caloExtensionKey.empty())
586 {
587 caloExtensionUPtr =
588 m_caloExtTool->caloExtension(Gaudi::Hive::currentContext(), *tp);
589 caloExtension = caloExtensionUPtr.get();
590 }
591 else
592 {
594 if (!cache.isValid())
595 {
596 ATH_MSG_WARNING("Failed to retrieve calo extension cache " << m_caloExtensionKey);
597 return false;
598 }
599 caloExtension = m_caloExtTool->caloExtension(*tp, *cache);
600 }
601 if(!caloExtension){
602 ATH_MSG_WARNING("Can not get caloExtension.");
603 return false;
604 };
605
606 const std::vector<Trk::CurvilinearParameters>& intersections = caloExtension->caloLayerIntersections();
607 if(!intersections.empty()){
608 Amg::Vector3D avePoint(0,0,0);
609 for (unsigned int i = 0; i < intersections.size(); ++i){
610 const Amg::Vector3D& point = intersections[i].position();
611 ATH_MSG_DEBUG("Intersection: " << i << " ID: " << m_parsIdHelper.caloSample(intersections[i].cIdentifier())
612 << " eta-phi (" << point.eta() << ", " << point.phi() << ")");
613 avePoint += point;
614 }
615 avePoint = (1./intersections.size())*avePoint;
616 eta = avePoint.eta();
617 phi = avePoint.phi();
618 return true;
619 }else{
620 ATH_MSG_WARNING("Muon Calo extension got no intersection!!!");
621 }
622#endif // xAOD
624 ATH_MSG_WARNING("Calo extension can not be obtained!!!");
625 return false;
626 }
627
628 // casted interface for TrackParticle cluster-based isolation (topoetcone)
630 const TrackParticle& tp,
631 const std::vector<Iso::IsolationType>& isoTypes,
632 const CaloCorrection& corrlist,
634 double coneCoreSize,
635 derefMap_t& derefMap) const {
636 if( isoTypes.empty() ) {
637 ATH_MSG_WARNING("Empty list passed, failing calculation");
638 return false;
639 }
640
641 unsigned int typesize = isoTypes.size();
642 initresult(result, corrlist, typesize);
643 std::vector<float> coneSizes;
644 coneSizes.reserve(isoTypes.size());
645
646for( auto isoType : isoTypes ){
647 coneSizes.push_back(Iso::coneSize(isoType));
648 }
649
650 float phi = tp.phi();
651 float eta = tp.eta();
652 if(!GetExtrapEtaPhi(&tp,eta,phi,derefMap)) ATH_MSG_WARNING("TrackParticle eta = " << tp.eta() << ", phi = " << tp.phi() << " not updated from extraplation!");
653 ATH_MSG_DEBUG("TrackParticle eta = " << tp.eta() << ", phi = " << tp.phi() << ", extrap eta = " << eta << ", phi = " << phi);
654
655 // get energy in cones
656 if (!topoConeIsolation(result, eta, phi, coneSizes, false, container, nullptr, nullptr, coneCoreSize)) {
657 ATH_MSG_WARNING("Could not compute topo isolation for muons");
658 return false;
659 }
660
661 // core energy subtraction
662 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))) {
663 if (!correctIsolationEnergy_MuonCore(result, tp, derefMap))
664 ATH_MSG_WARNING("Could not compute muon core energy (cells) from topoetcone");
665 }
666
667 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))) {
668 if (!EDCorrection(result,isoTypes,eta,"topo",nullptr))
669 ATH_MSG_WARNING("Could not apply ED correction to topo isolation");
670 }
671
672 return true;
673 }
674
675#ifndef XAOD_ANALYSIS
676 // etcone implementation for TrackParticle
678 const std::vector<Iso::IsolationType>& isoTypes,
680 double coneCoreSize,
681 const derefMap_t& derefMap) const {
682
683 // for now always use track, should move to extrapolation to calo entrance
684 const Trk::Track* track = tp.track();
685 if( !track ) {
686 ATH_MSG_WARNING("Failed to access track");
687 return false;
688 }
689
690 std::vector<double> conesf;
691 double maxConeSize = -1;
692 for( auto isoType : isoTypes ){
693 if( Iso::isolationFlavour(isoType) != Iso::etcone ) {
694 ATH_MSG_WARNING("Unsupported isolation type passed, cannot calculate isolation " << static_cast<int>(isoType));
695 return false;
696 }
697 double cone = Iso::coneSize(isoType);
698 conesf.push_back(cone);
699 if(cone>maxConeSize) maxConeSize = cone;
700 }
701
703 const double coreConeDR = coneCoreSize;
704 bool doCoreCone = (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)));
705 if(doCoreCone && maxConeSize<coreConeDR) maxConeSize = coreConeDR;
706
708 ATH_MSG_DEBUG("calculating etcone for # " << conesf.size() << " cones");
709 std::unique_ptr<const Rec::ParticleCellAssociation> association=m_assoTool->particleCellAssociation(tp,maxConeSize,container);
710 if( !association) {
711 ATH_MSG_DEBUG("failed to obtain the ParticleCellAssociation");
712 return false;
713 }
714
715 Trk::CaloCellSelectorLayerdR selector(maxConeSize);
716 selector.preSelectAction(association->caloExtension());
717 ATH_MSG_DEBUG("looping over cells " << association->data().size());
718 for(unsigned int i=0; i<conesf.size(); i++){
719 double totE = 0.;
720 selector.setConeSize(conesf[i]);
721 for (const auto *aCell : association->data()){
722 if( !selector.select(*aCell) ) continue;
723 if (m_ExcludeTG3 && CaloCell_ID::TileGap3 == aCell->caloDDE()->getSampling()) continue;
724 totE += aCell->et();
725 }
726 result.etcones[i] = totE;
727 ATH_MSG_DEBUG("etcone raw: coneSize = " << conesf[i] << "; etcone = " << result.etcones[i]);
728 }
729 ATH_MSG_DEBUG("done looping over cells ");
730
732 if(doCoreCone){
733 ATH_MSG_DEBUG("starting etcone, coreCone");
734 double totE = 0.;
735 selector.setConeSize(coreConeDR);
736 for (const auto *aCell : association->data()){
737 if( !selector.select(*aCell) ) continue;
738 if (m_ExcludeTG3 && CaloCell_ID::TileGap3 == aCell->caloDDE()->getSampling()) continue;
739 totE += aCell->et();
740 }
741 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
742 corecorr[Iso::coreEnergy] = totE;
743 corecorr[Iso::coreArea] = coreConeDR*coreConeDR*M_PI;
744 result.coreCorrections[Iso::coreCone] = corecorr;
745 ATH_MSG_DEBUG("done etcone, coreCone");
746
748 if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))){
749 double ecore = totE;
750 ATH_MSG_DEBUG("Applying coreCone correction for trackParticle etcone isolation.");
751 for( unsigned int i=0;i<result.etcones.size();++i ) {
752 result.etcones[i] -= ecore;
753 ATH_MSG_DEBUG("i: " << i << " cone [before] " << result.etcones[i]+ecore << " cone [after] " << result.etcones[i]);
754 }
755 }
756 }
757
758 // calculate etcore
760 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))){
762 }
763
764 return true;
765 }
766#endif
767
768#ifndef XAOD_ANALYSIS
769 // etcone implementation for Muon
771 const std::vector<Iso::IsolationType>& isoTypes,
772 double coneCoreSize,
773 const derefMap_t& derefMap) const {
774
775 std::vector<double> conesf;
776 double maxConeSize = -1;
777 for( auto isoType : isoTypes ){
778 if( Iso::isolationFlavour(isoType) != Iso::etcone ) {
779 ATH_MSG_WARNING("Unsupported isolation type passed, cannot calculate isolation " << static_cast<int>(isoType));
780 return false;
781 }
782 double cone = Iso::coneSize(isoType);
783 conesf.push_back(cone);
784 if(cone>maxConeSize) maxConeSize = cone;
785 }
787 const double coreConeDR = coneCoreSize;
788 bool doCoreCone = (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)));
789 if(doCoreCone && maxConeSize<coreConeDR) maxConeSize = coreConeDR;
790
791 if(!muon.clusterLink().isValid()){
792 ATH_MSG_DEBUG("no valid cluster link");
793 //no cluster, set everything to 0
794 for(unsigned int i=0; i<conesf.size(); i++) result.etcones[i] = 0;
795 if(doCoreCone){
796 ATH_MSG_DEBUG("starting etcone, coreCone");
797 double totE = 0.;
798 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
799 corecorr[Iso::coreEnergy] = totE;
800 corecorr[Iso::coreArea] = coreConeDR*coreConeDR*M_PI;
801 result.coreCorrections[Iso::coreCone] = corecorr;
802 ATH_MSG_DEBUG("done etcone, coreCone");
804 if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))){
805 double ecore = totE;
806 ATH_MSG_DEBUG("Applying coreCone correction for trackParticle etcone isolation.");
807 for( unsigned int i=0;i<result.etcones.size();++i ) {
808 result.etcones[i] -= ecore;
809 ATH_MSG_DEBUG("i: " << i << " cone [before] " << result.etcones[i]+ecore << " cone [after] " << result.etcones[i]);
810 }
811 }
812 }
813 }
814 else{
815 const xAOD::CaloCluster* muonCluster=*muon.clusterLink();
817 ATH_MSG_DEBUG("calculating etcone for # " << conesf.size() << " cones");
818 Trk::CaloCellSelectorLayerdR selector(maxConeSize);
819 selector.preSelectAction(*muonCluster);
820 ATH_MSG_DEBUG("looping over cells " << muonCluster->size());
821 for(unsigned int i=0; i<conesf.size(); i++){
822 double totE = 0.;
823 selector.setConeSize(conesf[i]);
824 xAOD::CaloCluster::const_cell_iterator cell_itr=muonCluster->begin();
825 for(; cell_itr!=muonCluster->end(); ++cell_itr){
826 if( !selector.select(**cell_itr) ) continue;
827 if (m_ExcludeTG3 && CaloCell_ID::TileGap3 == (*cell_itr)->caloDDE()->getSampling()) continue;
828 totE += (*cell_itr)->et();
829 }
830 result.etcones[i] = totE;
831 ATH_MSG_DEBUG("etcone raw: coneSize = " << conesf[i] << "; etcone = " << result.etcones[i]);
832 }
833 ATH_MSG_DEBUG("done looping over cells ");
835 if(doCoreCone){
836 ATH_MSG_DEBUG("starting etcone, coreCone");
837 double totE = 0.;
838 selector.setConeSize(coreConeDR);
839 xAOD::CaloCluster::const_cell_iterator cell_itr=muonCluster->begin();
840 for(; cell_itr!=muonCluster->end(); ++cell_itr){
841 if( !selector.select(**cell_itr) ) continue;
842 if (m_ExcludeTG3 && CaloCell_ID::TileGap3 == (*cell_itr)->caloDDE()->getSampling()) continue;
843 totE += (*cell_itr)->et();
844 }
845 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
846 corecorr[Iso::coreEnergy] = totE;
847 corecorr[Iso::coreArea] = coreConeDR*coreConeDR*M_PI;
848 result.coreCorrections[Iso::coreCone] = corecorr;
849 ATH_MSG_DEBUG("done etcone, coreCone");
850
852 if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))){
853 double ecore = totE;
854 ATH_MSG_DEBUG("Applying coreCone correction for trackParticle etcone isolation.");
855 for( unsigned int i=0;i<result.etcones.size();++i ) {
856 result.etcones[i] -= ecore;
857 ATH_MSG_DEBUG("i: " << i << " cone [before] " << result.etcones[i]+ecore << " cone [after] " << result.etcones[i]);
858 }
859 }
860 }
861 }
862 // calculate etcore
864 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))){
865 const TrackParticle* tp = nullptr;
866 if(muon.primaryTrackParticleLink().isValid() && muon.author()!=2) tp = *muon.primaryTrackParticleLink();
867 if( !tp) tp = *muon.inDetTrackParticleLink();
869 }
870
871 return true;
872 }
873#endif
874
875#ifndef XAOD_ANALYSIS
876 // etcone implementation for Egamma
878 const std::vector<Iso::IsolationType>& isoTypes,
879 const CaloCellContainer* container ) const {
880 if( isoTypes.empty() ) {
881 ATH_MSG_WARNING("Empty list passed, failing calculation");
882 return false;
883 }
884
886 const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
887
888 std::vector<float> coneSizes; coneSizes.resize(3);
889 std::vector<float> coneSizesSquared; coneSizesSquared.resize(3);
890 for (unsigned int i = 0; i < isoTypes.size(); i++) {
891 float dR = Iso::coneSize(isoTypes.at(i));
892 coneSizes[i] = dR;
893 coneSizesSquared[i] = dR*dR;
894 }
895
896 float phi = eg.caloCluster()->phi();
897 float eta = eg.caloCluster()->eta();
898
899 // Define a new Calo Cell list corresponding to EM Calo
900 std::vector<CaloCell_ID::SUBCALO> Vec_EMCaloEnums;
901 for (unsigned int n=0; n < m_EMCaloNums.size(); ++n) {
902 Vec_EMCaloEnums.push_back(static_cast<CaloCell_ID::SUBCALO>( m_EMCaloNums[n] ));
903 }
904 CaloCellList EMccl(caloDDMgr,container, Vec_EMCaloEnums);
905
906 std::vector<CaloCell_ID::SUBCALO> Vec_HadCaloEnums;
907 for (unsigned int n=0; n < m_HadCaloNums.size(); ++n) {
908 Vec_HadCaloEnums.push_back(static_cast<CaloCell_ID::SUBCALO>( m_HadCaloNums[n] ));
909 }
910 CaloCellList HADccl(caloDDMgr,container, Vec_HadCaloEnums);
911
912 // Let's determine some values based on the input specs
913 // Search for largest radius
914 double Rmax = 0.0;
915 for (unsigned int n=0; n< coneSizes.size(); n++)
916 if (coneSizes[n] > Rmax) Rmax = coneSizes[n];
917
918 // get the cells for the first one; by convention, it must be bigger than all the other cones.
919 EMccl.select(eta,phi,Rmax);
920
921 for (const auto *it: EMccl) {
922 double etacel=it->eta();
923 double phicel=it->phi();
924
925 double deleta = eta-etacel;
926 float delphi = Phi_mpi_pi(phi-phicel);
927 double drcel2 = (deleta*deleta) + (delphi*delphi);
928
929 for (unsigned int i = 0; i < coneSizes.size(); i++) {
930 if (drcel2 < coneSizesSquared[i])
931 result.etcones[i] += it->et();
932 }
933 }//end loop over cell-list
934
935
936 // get the cells for the first one; by convention, it must be bigger than all the other cones.
937 HADccl.select(eta, phi, Rmax);
938
939 for (const auto *it: HADccl) {
940 // Optionally remove TileGap cells
941 if (m_ExcludeTG3 && CaloCell_ID::TileGap3 == it->caloDDE()->getSampling()) {
942 ATH_MSG_DEBUG("Excluding cell with Et = " << it->et());
943 continue;
944 }
945
946 // if no TileGap cells excluded, log energy of all cells
947 double etacel = it->eta();
948 double phicel = it->phi();
949
950 double deleta = eta-etacel;
951 float delphi = Phi_mpi_pi(phi-phicel);
952 double drcel2 = (deleta*deleta) + (delphi*delphi);
953
954 for (unsigned int i = 0; i < coneSizes.size(); i++) {
955 if (drcel2 < coneSizesSquared[i])
956 result.etcones[i] += it->et();
957 }
958 }//end loop over cell-list
959
960 return true;
961 }
962#endif
963
965 std::vector<float>& coneSizes,
966 bool coreEMonly,
968 const CaloCluster* fwdClus,
969 const Egamma* egObj,
970 double coneCoreSize) const
971 {
972
973 // offline topocluster container is large: preselect only those in max cone size
974 auto max_cone_iter=std::max_element(coneSizes.begin(), coneSizes.end());
975 float max_cone= (*max_cone_iter);
976 std::vector<const CaloCluster*> clusts;
977 if(!container){
978#ifndef XAOD_ANALYSIS
980 m_clustersInConeTool->particlesInCone(eta,phi,max_cone,clusts);
981 }else{
982 ATH_MSG_WARNING("No CaloClustersInConeTool available");
983 }
984#else
985 if(!particlesInCone(eta,phi,max_cone,clusts))
986 ATH_MSG_WARNING("No CaloClustersInConeTool available");
987#endif
988 }else{ // trigger container is small enough
989 auto clItr = container->begin();
990 auto clItrE = container->end();
991 for(; clItr != clItrE; ++clItr){
992 clusts.push_back (*clItr);
993 }
994 }
995
996 // Calculate isolation for topo cluster
997 if (!topoClustCones (result,eta,phi, coneSizes, clusts)) {
998 ATH_MSG_WARNING("Could not compute topo isolation");
999 return false;
1000 }
1001
1002 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))) {
1003 // Subtract core (easier to do that here than outside like other core corrections)
1004 if (!correctIsolationEnergy_TopoCore(result, eta, phi, -1, -1, coneCoreSize*coneCoreSize, clusts, coreEMonly, fwdClus, egObj))
1005 ATH_MSG_WARNING("Could not compute topo core");
1006 }
1007
1008 return true;
1009 }
1010
1011 bool
1013 float eta,
1014 float phi,
1015 std::vector<float>& coneSizes,
1016 bool coreEMonly,
1018 double coneCoreSize,
1019 const Egamma *egObj) const
1020 {
1021
1022 // container is large: preselect only those in max cone size
1023 auto max_cone_iter=std::max_element(coneSizes.begin(), coneSizes.end());
1024 float max_cone = (*max_cone_iter);
1025 std::vector<const FlowElement*> clusts;
1026 if (!container) {
1027#ifndef XAOD_ANALYSIS
1029 m_pflowObjectsInConeTool->particlesInCone(eta,phi,max_cone,clusts);
1030 } else {
1031 ATH_MSG_WARNING("No FlowElementsInConeTool available");
1032 }
1033#else
1034 if(!particlesInCone(eta,phi,max_cone,clusts)) ATH_MSG_WARNING("Failed to get particles in cone.");
1035#endif
1036 } else { // trigger container is small enough
1037 auto clItr = container->begin();
1038 auto clItrE = container->end();
1039 for(; clItr != clItrE; ++clItr){
1040 clusts.push_back (*clItr);
1041 }
1042 }
1043
1044 // Calculate isolation for pflow objects
1045 if (!pflowObjCones (result,eta,phi,coneSizes,clusts)) {
1046 ATH_MSG_WARNING("Could not compute pflow isolation");
1047 return false;
1048 }
1049
1050 if (!m_saveOnlyRequestedCorrections || result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))) {
1051 // Core subtraction
1052 // be careful, require a certain tag of eflowRec, below which eSample are not always filled
1053 if (!correctIsolationEnergy_pflowCore(result, eta, phi, -1, -1, coneCoreSize*coneCoreSize, clusts, coreEMonly, egObj))
1054 ATH_MSG_WARNING("Could not compure pflow core");
1055 }
1056
1057 return true;
1058 }
1059
1064 std::vector<float>& coneSizes,
1065 const std::vector<const CaloCluster*>& clusts) const
1066 {
1067
1068 ATH_MSG_DEBUG("In CaloIsolationTool::topoClustCones");
1069
1070 for (const CaloCluster* cl : clusts) {
1071 float et = (m_useEMScale ? cl->p4(CaloCluster::State::UNCALIBRATED).Et() : cl->pt() );
1072 if(et <= 0 || fabs(cl->eta()) > 7.0) continue;
1073
1074 float st = 1./cosh(cl->p4(CaloCluster::State::UNCALIBRATED).Eta());
1075 float tilegap3_et = cl->eSample(CaloSampling::TileGap3)*st;
1076 et -= tilegap3_et;
1077
1078 float dPhi = Phi_mpi_pi(cl->phi()-phi);
1079 float dEta = cl->eta()-eta;
1080 float dr=sqrt(dPhi*dPhi+ dEta*dEta);
1081
1082 for (unsigned int i = 0; i < coneSizes.size(); i++) {
1083 if (dr < coneSizes[i]) {
1084 ATH_MSG_DEBUG("Adding topo " << cl << " dR = " << dr << " et of a topo clust et = " << et
1085 << " (calibrated " << cl->pt() << ", tilegap et = " << tilegap3_et << ")");
1086 result.etcones[i] += et;
1087 }
1088 }
1089 }
1090
1091 return true;
1092 }
1093
1098 std::vector<float>& coneSizes,
1099 const std::vector<const FlowElement*>& clusts) const
1100 {
1101
1102 ATH_MSG_DEBUG("In pflowObjCones obj eta = " << eta << " phi = " << phi);
1103
1104 for (const FlowElement* cl : clusts) {
1105 float et = cl->pt();
1106 if (et <= 0 || fabs(cl->eta()) > 7.0) continue;
1107
1108 float dPhi = Phi_mpi_pi(cl->phi()-phi);
1109 float dEta = cl->eta()-eta;
1110 float dR = sqrt(dPhi*dPhi+ dEta*dEta);
1111
1112 for (unsigned int i = 0; i < coneSizes.size(); i++) {
1113 if (dR < coneSizes[i]) {
1114 result.etcones[i] += et;
1115 }
1116 }
1117 }
1118
1119 return true;
1120 }
1121
1122
1124 const std::vector<Iso::IsolationType>& isoTypes,
1125 const Egamma* eg) const
1126 {
1127
1128 float coreV = 0;
1130 if (gotIso)
1131 ATH_MSG_DEBUG("core57cells available = " << coreV);
1132 else
1133 ATH_MSG_DEBUG("core57cells not available");
1134 if ((gotIso && fabs(coreV) < 1e-3) || !gotIso) {
1135#ifndef XAOD_ANALYSIS
1136 const CaloCluster *cleg = eg->caloCluster();
1137 // now correct the isolation energy for the core cluster energy
1138 float eraw57=0., eta=0.;
1139
1140 if(cleg && cleg->getCellLinks()){
1141 double seedEta = cleg->eta0(), seedPhi = cleg->phi0();
1142 std::unique_ptr<CaloCluster> egcCloneFor57 = CaloClusterStoreHelper::makeCluster(cleg->getCellLinks()->getCellContainer(),
1143 seedEta,seedPhi,
1144 cleg->clusterSize());
1145
1146 if (!m_caloFillRectangularTool->execute (Gaudi::Hive::currentContext(),
1147 egcCloneFor57.get()).isSuccess())
1148 {
1149 return false;
1150 }
1151 if(egcCloneFor57->size()==0){
1152 ATH_MSG_WARNING("Size of Created Cluster is 0 aka no cells");
1153 return false;
1154 }
1155
1156 eraw57 = egcCloneFor57->e();
1157 eta = cleg->eta(); //FillRectangularCluster doesn't recalculated the overall cluster eta (only per-sampling)
1158 coreV = eraw57/cosh(eta);
1159 ATH_MSG_DEBUG("Number of cells in 5x7 " << egcCloneFor57->size()
1160 << " seed eta,phi " << cleg->eta0() << " " << cleg->phi0()
1161 << " eraw = " << eraw57 << " etraw = " << coreV
1162 );
1163 }
1164#else
1165 return false;
1166#endif // XAOD_ANALYSIS
1167 }
1168
1169 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1170 corecorr[Iso::coreEnergy] = coreV;
1171 corecorr[Iso::coreArea] = 5*0.025*7*TMath::Pi()/128;
1172 result.coreCorrections[Iso::core57cells] = corecorr;
1173 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::core57cells))) {
1174 for (unsigned int i = 0; i < isoTypes.size(); i++){
1175 result.etcones[i] -= coreV;
1176 }
1177 }
1178
1179 return true;
1180 }
1181
1182
1184 float dEtaMax_core, float dPhiMax_core, float dR2Max_core,
1185 const std::vector<const CaloCluster*>& clusts, bool onlyEM,
1186 const CaloCluster* fwdClus,
1187 const Egamma* egObj) const
1188 {
1189 ATH_MSG_DEBUG("In CaloIsolationTool::correctIsolationEnergy_TopoCore");
1190 ATH_MSG_DEBUG("particle: eta " << eta << " phi " << phi);
1191
1192
1193 // I do not remember why I put areacore = 0 for fwdClus !!
1194 float areacore = -999.;
1195 if (fwdClus == nullptr) {
1196 if (dEtaMax_core>0 && dPhiMax_core>0) areacore = 4*dEtaMax_core*dPhiMax_core;
1197 else if (dR2Max_core>0) areacore = M_PI*dR2Max_core;
1198 } else
1199 areacore = 0;
1200
1201 double topoCore(0.);
1202 if (fwdClus) {
1203 topoCore = fwdClus->p4(CaloCluster::State::UNCALIBRATED).Et();
1204 ATH_MSG_DEBUG("Including " << topoCore << " in the core transverse energy of the fwd electron");
1205 } else {
1206 for (const CaloCluster* cl : clusts) {
1207 ATH_MSG_DEBUG("cl: eta " << cl->eta() << " phi " << cl->phi()
1208 << " E " << cl->p4(CaloCluster::State::UNCALIBRATED).E()
1209 << " pt " << cl->p4(CaloCluster::State::UNCALIBRATED).Et()
1210 << " cal E " << cl->e());
1212 float dPhi = Phi_mpi_pi(cl->phi()-phi);
1213 if(dEtaMax_core>0 && fabs(dPhi) > dPhiMax_core) continue;
1214 float dEta = cl->eta()-eta;
1215 if(dPhiMax_core>0 && fabs(dEta) > dEtaMax_core) continue;
1216 if(dR2Max_core>0 && dPhi*dPhi+dEta*dEta > dR2Max_core) continue;
1217 ATH_MSG_DEBUG("dist: dPhi " << dPhi << " dEta " << dEta << " dR2 " << dPhi*dPhi+dEta*dEta);
1218
1220 float et = (m_useEMScale ? cl->p4(CaloCluster::State::UNCALIBRATED).Et() : cl->pt() );
1221 if(et <= 0 || fabs(cl->eta()) > 7.0) continue;
1222
1224 double ettg3 = cl->eSample(CaloSampling::TileGap3)/cosh(cl->p4(CaloCluster::State::UNCALIBRATED).Eta());
1225 et -= ettg3;
1226 if (fabs(ettg3) > 1)
1227 ATH_MSG_DEBUG("After TG3 removal, pt = " << et);
1228
1230 double emfrac = 1.;
1231 if(onlyEM){
1232 double eEM = cl->energyBE(0)+cl->energyBE(1)+cl->energyBE(2)+cl->energyBE(3);
1233 emfrac = std::min(1., eEM / cl->p4(CaloCluster::State::UNCALIBRATED).E());
1234 }
1235 et *= emfrac;
1236
1238 topoCore += et;
1239 ATH_MSG_DEBUG("adding in core et: " << et << " (em frac = " << emfrac << " dR = " << sqrt(dPhi*dPhi+dEta*dEta) << ") total " << topoCore);
1240 }
1241 }
1242
1243 double topoCoreSC(0.);
1244 double test = 0;
1245 double topoCoreSCem = 0;
1247 const std::vector<const CaloCluster*> assocClus = EgammaHelpers::getAssociatedTopoClusters(egObj->caloCluster());
1248 for (unsigned int ic = 0; ic < assocClus.size(); ic++) {
1249 const CaloCluster* cl = assocClus.at(ic);
1250 test += cl->pt();
1251 topoCoreSC += cl->p4(CaloCluster::State::UNCALIBRATED).Et();
1252 ATH_MSG_DEBUG("Adding topo " << ic << " ptr = " << cl << " contrib, pt = " << cl->pt()
1253 << " uncal pt = " << cl->p4(CaloCluster::State::UNCALIBRATED).Et()
1254 << " eta,phi = " << cl->eta() << " " << cl->phi()
1255 << " uncal eta,phi = " << cl->p4(CaloCluster::State::UNCALIBRATED).Eta()
1256 << " " << cl->p4(CaloCluster::State::UNCALIBRATED).Phi()
1257 << " nCells = " << cluster_size(cl)
1258 );
1259
1261 double ettg3 = cl->eSample(CaloSampling::TileGap3)/cosh(cl->p4(CaloCluster::State::UNCALIBRATED).Eta());
1262 topoCoreSCem -= ettg3;
1263
1265 double emfrac = 1.;
1266 if(onlyEM){
1267 double eEM = cl->energyBE(0)+cl->energyBE(1)+cl->energyBE(2)+cl->energyBE(3);
1268 emfrac = std::min(1., eEM / cl->p4(CaloCluster::State::UNCALIBRATED).E());
1269 }
1270 topoCoreSCem += emfrac*cl->p4(CaloCluster::State::UNCALIBRATED).Et();
1271
1272 //auto itc = assocClus.at(ic)->begin();
1273 //for (; itc != assocClus.at(ic)->end(); itc++)
1274 // std::cout << "A cell " << (*itc) << " eta = " << (*itc)->eta() << std::endl;
1275 }
1276 ATH_MSG_DEBUG("Including " << topoCore << " only em, no tg3 " << topoCoreSCem << " calibrated " << test << " in the core transverse energy of the super cluster egamma object made of "
1277 << assocClus.size() << " clusters with corresponding pT = " << egObj->pt()
1278 << " cluster pT = " << egObj->caloCluster()->pt() << " cluster un cal pT = "
1280 << " nCells = " << cluster_size(egObj->caloCluster())
1281 );
1282 //auto itc = egObj->caloCluster()->begin();
1283 //for (; itc != egObj->caloCluster()->end(); itc++)
1284 //std::cout << "A cell in the SC " << (*itc) << " eta = " << (*itc)->eta() << std::endl;
1285
1286 std::map<Iso::IsolationCorrectionParameter,float> corecorrSC;
1287 corecorrSC[Iso::coreEnergy] = topoCoreSCem;
1288 corecorrSC[Iso::coreArea] = areacore;
1289 result.coreCorrections[Iso::coreConeSC] = corecorrSC;
1290
1291 }
1292
1293 ATH_MSG_DEBUG("core energy, std = " << topoCore << " topo-assoc (full) = " << topoCoreSC << " topo-assoc (only em, no tg3) = " << topoCoreSCem);
1294
1295 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1296 corecorr[Iso::coreEnergy] = topoCore;
1297 corecorr[Iso::coreArea] = areacore;
1298 result.coreCorrections[Iso::coreCone] = corecorr;
1299
1300 float toSub = 0;
1301 bool doSub = false;
1302 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) ||
1303 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC))) {
1304 doSub = true;
1305 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) &&
1306 !result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC)))
1307 toSub = topoCore;
1308 else if (!result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) &&
1309 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC)))
1310 toSub = topoCoreSCem;
1311 else {
1312 ATH_MSG_WARNING("Cannot do two core subtraction ! Using coreCone");
1313 toSub = topoCore;
1314 }
1315 }
1316
1317 if (doSub) {
1318 for (unsigned int i = 0; i < result.etcones.size(); i++){
1319 result.etcones[i] -= toSub;
1320 ATH_MSG_DEBUG("TopoCore correction i=" << i << " cone [before] " << result.etcones[i]+toSub << " cone [after] " << result.etcones[i]);
1321 }
1322 }
1323
1324 return true;
1325 }
1326
1328 float eta, float phi,
1329 float detaMax, float dphiMax,
1330 float dR2Max,
1331 const std::vector<const FlowElement*>& clusts,
1332 bool onlyEM, const Egamma* egObj) const
1333 {
1334
1335 float pflowCore(0.);
1336 for (const FlowElement* cl : clusts) {
1337 ATH_MSG_DEBUG("pflo: eta " << cl->eta() << " phi " << cl->phi() << " pt " << cl->pt() << " charge " << cl->charge());
1338 float dphi = Phi_mpi_pi(cl->phi()-phi);
1339 if (detaMax > 0 && fabs(dphi) > dphiMax) continue;
1340 float deta = cl->eta()-eta;
1341 if (dphiMax > 0 && fabs(deta) > detaMax) continue;
1342 if (dR2Max > 0 && dphi*dphi+deta*deta > dR2Max) continue;
1343
1345 float et = cl->pt();
1346 if (et <= 0 || fabs(cl->eta()) > 7.0) continue;
1347
1348 double emfrac = 1.;
1349 if (onlyEM) {
1350 const xAOD::CaloCluster *ocl = dynamic_cast<const xAOD::CaloCluster*>(cl->otherObject(0));
1351 if(ocl) {
1352 double eEM = ocl->energyBE(0)+ocl->energyBE(1)+ocl->energyBE(2)+ocl->energyBE(3);
1353 emfrac = std::min(1.,eEM / cl->e());
1354 }
1355 }
1356 et *= emfrac;
1357
1359 pflowCore += et;
1360 ATH_MSG_DEBUG("pflow to be added to core: et = " << et << " (em frac = " << emfrac << "), total = " << pflowCore);
1361 }
1362
1363 if (egObj) {
1364 float pflowCoreSC(0.);
1365 // These are the original FE, before origin correction, before CSSK... But the index should still match
1366 // for the corresponding FE in the post-processed container
1367 std::vector<const xAOD::FlowElement*> fes = EgammaHelpers::getAssociatedFlowElements(egObj);
1368 ATH_MSG_DEBUG("Number of associated neutral FE = " << fes.size());
1369 for (const FlowElement *fe : fes) {
1370 if (fe == nullptr) {
1371 ATH_MSG_DEBUG("null pointer to associated neutral");
1372 continue;
1373 }
1374 ATH_MSG_DEBUG("asso pflo: eta " << fe->eta() << " phi " << fe->phi() << " pt " << fe->pt() << " charge " << fe->charge() << " index = " << fe->index());
1375 const FlowElement *afe(nullptr);
1376 for (const FlowElement *cl : clusts) {
1377 if (fe->index() == cl->index()) {
1378 afe = cl;
1379 break;
1380 }
1381 }
1382 if (afe == nullptr)
1383 continue;
1384 ATH_MSG_DEBUG("asso pflo after vertex correction : eta " << afe->eta() << " phi " << afe->phi() << " pt " << afe->pt());
1386 float et = afe->pt();
1387 if (et <= 0 || fabs(afe->eta()) > 7.0) continue;
1388
1389 double emfrac = 1.;
1390 if (m_ExcludeTG3 || onlyEM) {
1391 std::vector<float> allEne = FEHelpers::getEnergiesPerSampling(*afe);
1392
1393 if (m_ExcludeTG3)
1394 et -= allEne.at(17)/cosh(afe->eta());
1395
1396 if (onlyEM) {
1397 double eEM = 0;
1398 for (int i = 0; i <= 7; i++) eEM += allEne.at(i);
1399 double eAll = fe->e();
1400 if (m_ExcludeTG3)
1401 eAll -= allEne.at(17);
1402 emfrac = std::min(1.,eEM / eAll);
1403 }
1404 et *= emfrac;
1405 }
1407 pflowCoreSC += et;
1408 ATH_MSG_DEBUG("asso pflow to be added to core " << fe << " et = " << et << " (em frac = " << emfrac << "), total = " << pflowCoreSC);
1409 }
1410 std::map<Iso::IsolationCorrectionParameter,float> corecorrSC;
1411 corecorrSC[Iso::coreEnergy] = pflowCoreSC;
1412 corecorrSC[Iso::coreArea] = 0;
1413 result.coreCorrections[Iso::coreConeSC] = corecorrSC;
1414 }
1415
1417 float areacore = -999.;
1418 if (detaMax > 0 && dphiMax > 0) areacore = 4*detaMax*dphiMax;
1419 else if (dR2Max > 0) areacore = M_PI*dR2Max;
1420
1421 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1422 corecorr[Iso::coreEnergy] = pflowCore;
1423 corecorr[Iso::coreArea] = areacore;
1424 result.coreCorrections[Iso::coreCone] = corecorr;
1425
1426 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))) {
1427 for (unsigned int i = 0; i < result.etcones.size(); i++) {
1428 ATH_MSG_DEBUG("pflow, cone type " << i << ", in cone " << result.etcones[i] << ", subtracted " << result.etcones[i]-pflowCore);
1429 result.etcones[i] -= pflowCore;
1430 }
1431 }
1432
1433 return true;
1434 }
1435
1436
1437 // etcone implementation for TrackParticle
1439 TrackParticle& tp,
1440 const derefMap_t& derefMap) const {
1441
1442 ATH_MSG_DEBUG("in CaloIsolationTool::correctIsolationEnergy_MuonCore ");
1443
1444 // initialize varialbes
1445 double ecore = 0.;
1446 auto muI = derefMap.find(&tp);
1447 static const SG::ConstAccessor<float> ET_CoreAcc ("ET_Core");
1448 if(muI!=derefMap.end()){
1449 ecore = ET_CoreAcc.withDefault (*muI->second, 0);
1450 }else{
1451 ATH_MSG_WARNING("ET_Core of muon not found! coreMuon isolation correction will not be applied!!!");
1452 return false;
1453 }
1454
1455 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1456 corecorr[Iso::coreEnergy] = ecore;
1457 corecorr[Iso::coreArea] = 0;
1458 result.coreCorrections[Iso::coreMuon] = corecorr;
1459
1460 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))) {
1461 for( unsigned int i=0;i<result.etcones.size();++i ) {
1462 result.etcones[i] -= ecore;
1463 ATH_MSG_DEBUG("MuonCore i=" << i << " cone [before] " << result.etcones[i]+ecore << " cone [after] " << result.etcones[i]);
1464 }
1465 }
1466
1467 return true;
1468 }
1469
1471 const Egamma& eg,
1472 const std::vector<Iso::IsolationType>& isoTypes) const
1473 {
1474// #ifndef XAOD_ANALYSIS
1475 if(m_IsoLeakCorrectionTool.empty()) return false;
1476// #endif // XAOD_ANALYSIS
1477
1478 std::vector<float> corrvec;
1479 corrvec.resize(isoTypes.size(),0.);
1480 for (unsigned int i = 0; i < isoTypes.size(); i++) {
1481
1482// #ifndef XAOD_ANALYSIS
1483 corrvec[i] = m_IsoLeakCorrectionTool->GetPtCorrection(eg, isoTypes[i]);
1484// #else
1485// corrvec[i] = eg.isolationCaloCorrection (isoTypes[i], Iso::ptCorrection);
1486// #endif // XAOD_ANALYSIS
1487 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::ptCorrection))) {
1488 result.etcones[i] -= corrvec[i];
1489 ATH_MSG_DEBUG("eta = " << eg.eta() << ", phi = " << eg.phi() << ", pt = " << eg.pt() << ", isoType = " << Iso::toCString(isoTypes[i])
1490 << ", ptcorr = " << corrvec[i] << ", isol pt corrected = " << result.etcones[i] );
1491 }
1492 }
1493 result.noncoreCorrections[Iso::ptCorrection] = corrvec;
1495 // get the correction from xAOD file
1496
1497 return true;
1498 }
1499
1501 const std::vector<Iso::IsolationType>& isoTypes,
1502 float eta, // In principle, could be (eta,phi)
1503 const std::string& type,
1504 const CaloCluster* fwdClus) const
1505
1506 {
1507 std::vector<float> corrvec;
1508 corrvec.resize(isoTypes.size(),0.);
1509
1510 // assume two densities for the time being
1511 const SG::ReadHandleKey<EventShape>* esKey = (fabs(eta) < 1.5 || m_useEtaDepPU) ? &m_tpEDCentral : &m_tpEDForward;
1512 if (type == "PFlow") {
1513 esKey = (fabs(eta) < 1.5) ? &m_efEDCentral : &m_efEDForward;
1514 } else if (fwdClus != nullptr) {
1515 ATH_MSG_DEBUG("No pileup correction for forward electron isolation yet");
1516 result.noncoreCorrections[Iso::pileupCorrection] = corrvec;
1517 return true;
1518 }
1519
1520 SG::ReadHandle<EventShape> edShape(*esKey);
1521 // check is only used for serial running; remove when MT scheduler used
1522 if(!edShape.isValid()) {
1523 ATH_MSG_FATAL("Failed to retrieve "<< esKey->key());
1524 return false;
1525 }
1526
1527 double rho = 0;
1528 bool gotDensity = edShape->getDensity(EventShape::Density,rho);
1529 if (!gotDensity) {
1530 ATH_MSG_WARNING("Cannot retrieve density " << esKey->key() << " for isolation correction. No ED correction");
1531 return false;
1532 }
1533
1534 // Get the core size
1535 float areacore = 0;
1536 std::map<xAOD::Iso::IsolationCorrectionParameter,float> ecore;
1537 if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))){
1538 ecore = result.coreCorrections.find(Iso::coreMuon)->second;
1539 }else if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::core57cells))){
1540 ecore = result.coreCorrections.find(Iso::core57cells)->second;
1541 }else if(result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))){
1542 ecore = result.coreCorrections.find(Iso::coreCone)->second;
1543 }
1544
1545 auto iter = ecore.find(xAOD::Iso::coreArea);
1546 if (iter != ecore.end())
1547 areacore = ecore.find(xAOD::Iso::coreArea)->second;
1548
1549 for (unsigned int i = 0; i < isoTypes.size(); i++) {
1550 float dR = Iso::coneSize(isoTypes.at(i));
1551 float toSub = rho*(dR*dR*M_PI - areacore);
1552 // The improved PU correction is only for central EGamma objects, and topoetcone
1553 if (m_useEtaDepPU && fwdClus == nullptr && Iso::isolationFlavour(isoTypes.at(i)) == Iso::topoetcone) {
1554 double areaCorr = 0;
1555 auto puZeta = m_puZetaCorrection.find(isoTypes.at(i));
1556 if (puZeta != m_puZetaCorrection.end()) {
1557 areaCorr = puZeta->second->Eval(std::abs(eta)); // CW might have done it vs etaBE(2). This eta here is caloCluster eta...
1558 } else {
1559 ATH_MSG_WARNING("Requested refined eta dependent pileup correction but no zeta correction provided " << Iso::toCString(isoTypes.at(i)));
1560 }
1561 if (m_isMC) {
1562 auto puZetaMC = m_puZetaMCCorrection.find(isoTypes.at(i));
1563 if (puZetaMC != m_puZetaMCCorrection.end()) {
1564 areaCorr -= puZetaMC->second->Eval(std::abs(eta));
1565 } else {
1566 ATH_MSG_WARNING("Requested refined eta dependent pileup correction for mc but no zeta correction provided " << Iso::toCString(isoTypes.at(i)));
1567 }
1568 }
1569 toSub *= areaCorr;
1570 }
1571 corrvec[i] = toSub;
1572 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))){
1573 result.etcones[i] -= toSub;
1574 }
1575 ATH_MSG_DEBUG("ED correction ("<< type << ")for size " << dR << " = " << toSub << " (areacore=" << areacore << ")");
1576 }
1577
1578 result.noncoreCorrections[Iso::pileupCorrection] = corrvec;
1579 return true;
1580 }
1581
1583 const CaloCorrection& corrlist,
1584 unsigned int typesize) {
1585
1586 result.corrlist = corrlist;
1587 result.coreCorrections.clear();
1588 result.noncoreCorrections.clear();
1589 result.etcones.resize(typesize,0.);
1590
1591 }
1592
1594 const TrackParticle* tp = dynamic_cast<const TrackParticle*>(&particle);
1595 if( tp ) return tp;
1596 const Muon* muon = dynamic_cast<const Muon*>(&particle);
1597 if( muon ) {
1598 ATH_MSG_DEBUG("muon with author "<<muon->author()<<" and pT "<<muon->pt());
1599 const TrackParticle* tp = nullptr;
1600 //note: if STACO, the track particle has no Trk::Track associated, so use the ID track
1601 if(muon->primaryTrackParticleLink().isValid() && muon->author()!=2) tp = *muon->primaryTrackParticleLink();
1602 if( !tp) tp = *muon->inDetTrackParticleLink();
1603 if( !tp ) {
1604 ATH_MSG_WARNING(" No TrackParticle found for muon " );
1605 return nullptr;
1606 }
1607 return tp;
1608 }
1609 return &particle;
1610 }
1611
1612
1613#ifdef XAOD_ANALYSIS // particlesInCone tool will not be avaible. Write our own...
1614 bool CaloIsolationTool::particlesInCone( float eta, float phi, float dr, std::vector<const CaloCluster*>& output ) const {
1616 const CaloClusterContainer* caloClusters = 0;
1617 std::string m_caloClusterLocation = "CaloCalTopoClusters";
1618 if(evtStore()->retrieve(caloClusters, m_caloClusterLocation).isFailure()) {
1619 ATH_MSG_FATAL( "Unable to retrieve " << m_caloClusterLocation );
1620 return false;
1621 }
1622
1623 const float m_minPt = 1e-3;
1625 float dr2 = dr*dr;
1626 for(auto trk: *caloClusters){
1627 if(trk->pt()<m_minPt) continue;
1628
1629 float dEta = eta-trk->eta();
1630 float dPhi = Phi_mpi_pi(phi-trk->phi());
1631 if(dr2<(dEta*dEta+dPhi*dPhi)) continue;
1632 output.push_back(trk);
1633 }
1634
1635 return true;
1636 }
1637 bool CaloIsolationTool::particlesInCone( float eta, float phi, float dr, std::vector<const FlowElement*>& output ) const{
1639 const FlowElementContainer* Clusters = 0;
1640 std::string m_ClusterLocation = "JetETMissNeutralParticleFlowObjects";
1641 if(evtStore()->retrieve(Clusters,m_ClusterLocation).isFailure()) {
1642 ATH_MSG_FATAL( "Unable to retrieve " << m_ClusterLocation);
1643 return false;
1644 }
1645
1646 const float m_minPt = 1e-3;
1648 float dr2 = dr*dr;
1649 for(auto trk: *Clusters){
1650 if(trk->pt()<m_minPt) continue;
1651 float dEta = eta-trk->eta();
1652 float dPhi = Phi_mpi_pi(phi-trk->phi());
1653 if(dr2<(dEta*dEta+dPhi*dPhi))continue;
1654 output.push_back(trk);
1655 }
1656
1657 return true;
1658 }
1659#endif // XAOD_ANALYSIS
1660} // end of namespace
1661
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
Helper class to provide constant type-safe access to aux data.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
@ Phi
Definition RPCdef.h:8
@ Eta
Definition RPCdef.h:8
ServiceHandle< StoreGateSvc > & evtStore()
Container class for CaloCell.
void select(double eta, double phi, double deta, double dphi)
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
static std::unique_ptr< xAOD::CaloCluster > makeCluster(const CaloCellContainer *cellCont)
Creates a valid CaloCluster with a private Aux-Store and CellLink container.
This class provides the client interface for accessing the detector description information common to...
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:570
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
const_reference_type withDefault(const ELT &e, const T &deflt) const
Fetch the variable for one element, as a const reference, with a default.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const std::string & key() const
Return the StoreGate ID for the referenced object.
Tracking class to hold the extrapolation through calorimeter Layers Both the caloEntryLayerIntersecti...
const std::vector< CurvilinearParameters > & caloLayerIntersections() const
access to the intersections with the calorimeter layers.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
ClusterSize clusterSize() const
Get cluster size.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
const_iterator end() const
virtual double pt() const
The transverse momentum ( ) of the particle (negative for negative-energy clusters)
const_iterator begin() const
virtual double eta() const
The pseudorapidity ( ) of the particle.
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version)
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
virtual double phi() const
The azimuthal angle ( ) of the particle.
flt_t eta0() const
Returns raw of cluster seed.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
flt_t phi0() const
Returns raw of cluster seed.
virtual bool caloCellIsolation(CaloIsolation &result, const IParticle &particle, const std::vector< Iso::IsolationType > &cones, const CaloCorrection &corrections, const CaloCellContainer *container=0) const override
ICaloCellIsolationTool interface for cell isolation: The tool expects the cones to be order in decrea...
bool PtCorrection(CaloIsolation &result, const Egamma &eg, const std::vector< Iso::IsolationType > &isoTypes) const
bool GetExtrapEtaPhi(const TrackParticle *tp, float &eta, float &phi, derefMap_t &derefMap) const
Gaudi::Property< std::vector< int > > m_HadCaloNums
vector of calo-id to treat
bool pflowObjCones(CaloIsolation &result, float eta, float phi, std::vector< float > &m_coneSizes, const std::vector< const FlowElement * > &clusts) const
Calculate isolation cones in pflow objects around eg.
bool correctIsolationEnergy_MuonCore(CaloIsolation &result, const TrackParticle &tp, const derefMap_t &derefMap) const
bool etConeIsolation(CaloIsolation &result, const TrackParticle &tp, const std::vector< Iso::IsolationType > &isoTypes, const CaloCellContainer *container, double coneCoreSize, const derefMap_t &derefMap) const
Gaudi::Property< bool > m_InitializeReadHandles
Property: Initialize read Handles.
bool pflowConeIsolation(CaloIsolation &result, float eta, float phi, std::vector< float > &m_coneSizes, bool coreEMonly, const FlowElementContainer *container, double coneCoreSize, const Egamma *egObj=nullptr) const
bool correctIsolationEnergy_Eeg57(CaloIsolation &result, const std::vector< Iso::IsolationType > &isoTypes, const Egamma *eg) const
SG::ReadHandleKey< EventShape > m_efEDForward
Property: Name of the forward neutral energy flow energy-density container.
ToolHandle< Trk::IParticleCaloExtensionTool > m_caloExtTool
ToolHandle< IFlowElementsInConeTool > m_pflowObjectsInConeTool
ToolHandle< CaloClusterProcessor > m_caloFillRectangularTool
Property: calo cluster filling tool.
Trk::TrackParametersIdHelper m_parsIdHelper
SG::ReadHandleKey< EventShape > m_efEDCentral
Property: Name of the central neutral energy flow energy-density container.
std::map< Iso::IsolationType, std::unique_ptr< TGraph > > m_puZetaCorrection
map of the zeta corrections (one / cone size)
Gaudi::Property< bool > m_useEtaDepPU
Property: use pileup dependent correction.
Gaudi::Property< double > m_coneCoreSizeEg
Property: The size of the coneCore core energy calculation.
bool correctIsolationEnergy_pflowCore(CaloIsolation &result, float eta, float phi, float detaMax, float dphiMax, float dR2Max, const std::vector< const FlowElement * > &clusts, bool onlyEM=false, const Egamma *egObj=nullptr) const
Correct the pflow isolation using sum of pflow objects in core region.
virtual StatusCode finalize() override
SG::ReadHandleKey< CaloExtensionCollection > m_caloExtensionKey
The input calorimeter extensions.
float Phi_mpi_pi(float x) const
static void initresult(CaloIsolation &result, const CaloCorrection &corrlist, unsigned int typesize)
virtual bool caloTopoClusterIsolation(CaloIsolation &result, const IParticle &tp, const std::vector< Iso::IsolationType > &cones, const CaloCorrection &corrections, const CaloClusterContainer *container=0) const override
ICaloTopoClusterIsolationTool interface:
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
std::map< const IParticle *, const IParticle * > derefMap_t
map to the orignal particle
ToolHandle< Rec::IParticleCaloCellAssociationTool > m_assoTool
CaloIsolationTool(const std::string &name)
Gaudi::Property< std::string > m_puZetaCorrectionFileName
name of the root file for the eta dependant pileup correction
Gaudi::Property< bool > m_ExcludeTG3
Property: exclude tile scintillator.
SG::ReadHandleKey< EventShape > m_tpEDForward
Property: Name of the forward topocluster energy-density container.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
CaloDetDescrManager from ConditionStore.
Gaudi::Property< bool > m_useEMScale
Property: Use TopoClusters at the EM scale.
SG::ReadHandleKey< EventShape > m_tpEDCentral
Property: Name of the central topocluster energy-density container.
Gaudi::Property< std::string > m_puZetaMCCorrectionFileName
const IParticle * getReferenceParticle(const IParticle &particle) const
get reference particle
ToolHandle< ICaloClustersInConeTool > m_clustersInConeTool
Gaudi::Property< bool > m_saveOnlyRequestedCorrections
Property: save only requested corrections (trigger usage mainly)
Gaudi::Property< double > m_coneCoreSizeMu
bool correctIsolationEnergy_TopoCore(CaloIsolation &result, float eta, float phi, float dEtaMax_core, float dPhiMax_core, float dR2Max_core, const std::vector< const CaloCluster * > &clusts, bool onlyEM, const CaloCluster *fwdClus, const Egamma *egObj) const
Correct the topo cluster isolation using sum of topo cluster in core region.
Gaudi::Property< bool > m_isMC
Property: need to know if this is MC (from rec.doTruth) for eta dep pileup corr.
Gaudi::Property< std::vector< int > > m_EMCaloNums
vector of calo-id to treat
bool topoClustCones(CaloIsolation &result, float eta, float phi, std::vector< float > &m_coneSizes, const std::vector< const CaloCluster * > &clusts) const
Calculate isolation cones in topo clusters around eg.
bool EDCorrection(CaloIsolation &result, const std::vector< Iso::IsolationType > &isoTypes, float eta, const std::string &type, const CaloCluster *fwdClus) const
virtual bool neutralEflowIsolation(CaloIsolation &result, const IParticle &tp, const std::vector< Iso::IsolationType > &cones, const CaloCorrection &corrections) const override
INeutralEFlowIsolationTool interface:
std::map< Iso::IsolationType, std::unique_ptr< TGraph > > m_puZetaMCCorrection
ToolHandle< CP::IIsolationCorrectionTool > m_IsoLeakCorrectionTool
Tool for pt-corrected isolation calculation (new)
bool topoConeIsolation(CaloIsolation &result, float eta, float phi, std::vector< float > &coneSizes, bool coreEMonly, const CaloClusterContainer *container, const CaloCluster *fwdClus, const Egamma *egObj, double coneCoreSize) const
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition Egamma_v1.cxx:66
bool isolationCaloCorrection(float &value, const Iso::IsolationFlavour flavour, const Iso::IsolationCaloCorrection corr, const Iso::IsolationCorrectionParameter param) const
Accessor for flavour and type depended Isolation Calo correction.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition Egamma_v1.cxx:71
uint16_t author(uint16_t bitmask=EgammaParameters::AuthorALL) const
Get author.
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
Definition Egamma_v1.cxx:76
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
virtual double pt() const override
virtual double phi() const override
The azimuthal angle ( ) of the particle.
virtual double eta() const override
The pseudorapidity ( ) of the particle.
Class providing the definition of the 4-vector interface.
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Eigen::Matrix< double, 3, 1 > Vector3D
std::vector< float > getEnergiesPerSampling(const xAOD::FlowElement &fe)
Definition FEHelpers.cxx:78
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
bool dPhi(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
bool dEta(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition index.py:1
output
Definition merge.py:16
std::vector< const xAOD::CaloCluster * > getAssociatedTopoClusters(const xAOD::CaloCluster *cluster)
Return a vector of all the topo clusters associated with the egamma cluster.
std::vector< const xAOD::FlowElement * > getAssociatedFlowElements(const xAOD::Egamma *eg, bool neutral=true, bool charged=false)
Return a vector of the flow elements associated with the egamma cluster (only neutral for default)
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition EgammaDefs.h:30
IsolationFlavour isolationFlavour(IsolationType type)
convert Isolation Type into Isolation Flavour
@ topoetcone20
Topo-cluster ET-sum.
IsolationFlavour
Enumeration for different ways of calculating isolation in xAOD files.
@ topoetcone
Topo-cluster ET-sum.
@ etcone
Calorimeter isolation.
static const char * toCString(IsolationConeSize conesize)
@ coreArea
area used to calculate this correction
float coneSize(IsolationConeSize type)
convert Isolation Size into cone size
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
FlowElementContainer_v1 FlowElementContainer
Definition of the current "pfo container version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
TrackParticle_v1 TrackParticle
Reference the current persistent version:
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.