ATLAS Offline Software
Loading...
Searching...
No Matches
CaloIsolationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
311 , const CaloCellContainer* container
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,
362 const CaloClusterContainer* container,
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
480 CaloIsolation& result,
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,
633 const CaloClusterContainer* container,
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,
679 const CaloCellContainer* container,
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] = std::move(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))){
761 correctIsolationEnergy_MuonCore(result, tp, derefMap);
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.cluster()){
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] = std::move(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.cluster();
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] = std::move(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 = muon.trackParticle(muon.author() != xAOD::Muon::Author::STACO ?
866 xAOD::Muon::TrackParticleType::Primary :
867 xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
868 correctIsolationEnergy_MuonCore(result, *tp, derefMap);
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,
967 const CaloClusterContainer* container,
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,
1017 const FlowElementContainer* container,
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] = std::move(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 float areacore = -999.;
1193 if (dEtaMax_core>0 && dPhiMax_core>0) areacore = 4*dEtaMax_core*dPhiMax_core;
1194 else if (dR2Max_core>0) areacore = M_PI*dR2Max_core;
1195 double topoCore(0.);
1196 for (const CaloCluster* cl : clusts) {
1197 ATH_MSG_DEBUG("cl: eta " << cl->eta() << " phi " << cl->phi()
1198 << " E " << cl->p4(CaloCluster::State::UNCALIBRATED).E()
1199 << " pt " << cl->p4(CaloCluster::State::UNCALIBRATED).Et()
1200 << " cal E " << cl->e());
1202 float dPhi = Phi_mpi_pi(cl->phi()-phi);
1203 if(dEtaMax_core>0 && fabs(dPhi) > dPhiMax_core) continue;
1204 float dEta = cl->eta()-eta;
1205 if(dPhiMax_core>0 && fabs(dEta) > dEtaMax_core) continue;
1206 if(dR2Max_core>0 && dPhi*dPhi+dEta*dEta > dR2Max_core) continue;
1207 ATH_MSG_DEBUG("dist: dPhi " << dPhi << " dEta " << dEta << " dR2 " << dPhi*dPhi+dEta*dEta);
1208
1210 float et = (m_useEMScale ? cl->p4(CaloCluster::State::UNCALIBRATED).Et() : cl->pt() );
1211 if(et <= 0 || fabs(cl->eta()) > 7.0) continue;
1212
1214 double ettg3 = cl->eSample(CaloSampling::TileGap3)/cosh(cl->p4(CaloCluster::State::UNCALIBRATED).Eta());
1215 et -= ettg3;
1216 if (fabs(ettg3) > 1)
1217 ATH_MSG_DEBUG("After TG3 removal, pt = " << et);
1218
1220 double emfrac = 1.;
1221 if(onlyEM && !fwdClus){
1222 double eEM = cl->energyBE(0)+cl->energyBE(1)+cl->energyBE(2)+cl->energyBE(3);
1223 emfrac = std::min(1., eEM / cl->p4(CaloCluster::State::UNCALIBRATED).E());
1224 }
1225 et *= emfrac;
1226
1228 topoCore += et;
1229 ATH_MSG_DEBUG("adding in core et: " << et << " (em frac = " << emfrac << " dR = " << sqrt(dPhi*dPhi+dEta*dEta) << ") total " << topoCore);
1230 }
1231
1232 double topoCoreSC(0.);
1233 double test = 0;
1234 double topoCoreSCem = 0;
1236 const std::vector<const CaloCluster*> assocClus = EgammaHelpers::getAssociatedTopoClusters(egObj->caloCluster());
1237 for (unsigned int ic = 0; ic < assocClus.size(); ic++) {
1238 const CaloCluster* cl = assocClus.at(ic);
1239 test += cl->pt();
1240 topoCoreSC += cl->p4(CaloCluster::State::UNCALIBRATED).Et();
1241 ATH_MSG_DEBUG("Adding topo " << ic << " ptr = " << cl << " contrib, pt = " << cl->pt()
1242 << " uncal pt = " << cl->p4(CaloCluster::State::UNCALIBRATED).Et()
1243 << " eta,phi = " << cl->eta() << " " << cl->phi()
1244 << " uncal eta,phi = " << cl->p4(CaloCluster::State::UNCALIBRATED).Eta()
1245 << " " << cl->p4(CaloCluster::State::UNCALIBRATED).Phi()
1246 << " nCells = " << cluster_size(cl)
1247 );
1248
1250 double ettg3 = cl->eSample(CaloSampling::TileGap3)/cosh(cl->p4(CaloCluster::State::UNCALIBRATED).Eta());
1251 topoCoreSCem -= ettg3;
1252
1254 double emfrac = 1.;
1255 if(onlyEM){
1256 double eEM = cl->energyBE(0)+cl->energyBE(1)+cl->energyBE(2)+cl->energyBE(3);
1257 emfrac = std::min(1., eEM / cl->p4(CaloCluster::State::UNCALIBRATED).E());
1258 }
1259 topoCoreSCem += emfrac*cl->p4(CaloCluster::State::UNCALIBRATED).Et();
1260
1261 //auto itc = assocClus.at(ic)->begin();
1262 //for (; itc != assocClus.at(ic)->end(); itc++)
1263 // std::cout << "A cell " << (*itc) << " eta = " << (*itc)->eta() << std::endl;
1264 }
1265 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 "
1266 << assocClus.size() << " clusters with corresponding pT = " << egObj->pt()
1267 << " cluster pT = " << egObj->caloCluster()->pt() << " cluster un cal pT = "
1269 << " nCells = " << cluster_size(egObj->caloCluster())
1270 );
1271 //auto itc = egObj->caloCluster()->begin();
1272 //for (; itc != egObj->caloCluster()->end(); itc++)
1273 //std::cout << "A cell in the SC " << (*itc) << " eta = " << (*itc)->eta() << std::endl;
1274
1275 std::map<Iso::IsolationCorrectionParameter,float> corecorrSC;
1276 corecorrSC[Iso::coreEnergy] = topoCoreSCem;
1277 corecorrSC[Iso::coreArea] = areacore;
1278 result.coreCorrections[Iso::coreConeSC] = std::move(corecorrSC);
1279
1280 }
1281
1282 ATH_MSG_DEBUG("core energy, std = " << topoCore << " topo-assoc (full) = " << topoCoreSC << " topo-assoc (only em, no tg3) = " << topoCoreSCem);
1283
1284 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1285 corecorr[Iso::coreEnergy] = topoCore;
1286 corecorr[Iso::coreArea] = areacore;
1287 result.coreCorrections[Iso::coreCone] = std::move(corecorr);
1288
1289 float toSub = 0;
1290 bool doSub = false;
1291 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) ||
1292 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC))) {
1293 doSub = true;
1294 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) &&
1295 !result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC)))
1296 toSub = topoCore;
1297 else if (!result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone)) &&
1298 result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreConeSC)))
1299 toSub = topoCoreSCem;
1300 else {
1301 ATH_MSG_WARNING("Cannot do two core subtraction ! Using coreCone");
1302 toSub = topoCore;
1303 }
1304 }
1305
1306 if (doSub) {
1307 for (unsigned int i = 0; i < result.etcones.size(); i++){
1308 result.etcones[i] -= toSub;
1309 ATH_MSG_DEBUG("TopoCore correction i=" << i << " cone [before] " << result.etcones[i]+toSub << " cone [after] " << result.etcones[i]);
1310 }
1311 }
1312
1313 return true;
1314 }
1315
1317 float eta, float phi,
1318 float detaMax, float dphiMax,
1319 float dR2Max,
1320 const std::vector<const FlowElement*>& clusts,
1321 bool onlyEM, const Egamma* egObj) const
1322 {
1323
1324 float pflowCore(0.);
1325 for (const FlowElement* cl : clusts) {
1326 ATH_MSG_DEBUG("pflo: eta " << cl->eta() << " phi " << cl->phi() << " pt " << cl->pt() << " charge " << cl->charge());
1327 float dphi = Phi_mpi_pi(cl->phi()-phi);
1328 if (detaMax > 0 && fabs(dphi) > dphiMax) continue;
1329 float deta = cl->eta()-eta;
1330 if (dphiMax > 0 && fabs(deta) > detaMax) continue;
1331 if (dR2Max > 0 && dphi*dphi+deta*deta > dR2Max) continue;
1332
1334 float et = cl->pt();
1335 if (et <= 0 || fabs(cl->eta()) > 7.0) continue;
1336
1337 double emfrac = 1.;
1338 if (onlyEM) {
1339 const xAOD::CaloCluster *ocl = dynamic_cast<const xAOD::CaloCluster*>(cl->otherObject(0));
1340 if(ocl) {
1341 double eEM = ocl->energyBE(0)+ocl->energyBE(1)+ocl->energyBE(2)+ocl->energyBE(3);
1342 emfrac = std::min(1.,eEM / cl->e());
1343 }
1344 }
1345 et *= emfrac;
1346
1348 pflowCore += et;
1349 ATH_MSG_DEBUG("pflow to be added to core: et = " << et << " (em frac = " << emfrac << "), total = " << pflowCore);
1350 }
1351
1352 if (egObj) {
1353 float pflowCoreSC(0.);
1354 // These are the original FE, before origin correction, before CSSK... But the index should still match
1355 // for the corresponding FE in the post-processed container
1356 std::vector<const xAOD::FlowElement*> fes = EgammaHelpers::getAssociatedFlowElements(egObj);
1357 ATH_MSG_DEBUG("Number of associated neutral FE = " << fes.size());
1358 for (const FlowElement *fe : fes) {
1359 if (fe == nullptr) {
1360 ATH_MSG_DEBUG("null pointer to associated neutral");
1361 continue;
1362 }
1363 ATH_MSG_DEBUG("asso pflo: eta " << fe->eta() << " phi " << fe->phi() << " pt " << fe->pt() << " charge " << fe->charge() << " index = " << fe->index());
1364 const FlowElement *afe(nullptr);
1365 for (const FlowElement *cl : clusts) {
1366 if (fe->index() == cl->index()) {
1367 afe = cl;
1368 break;
1369 }
1370 }
1371 if (afe == nullptr)
1372 continue;
1373 ATH_MSG_DEBUG("asso pflo after vertex correction : eta " << afe->eta() << " phi " << afe->phi() << " pt " << afe->pt());
1375 float et = afe->pt();
1376 if (et <= 0 || fabs(afe->eta()) > 7.0) continue;
1377
1378 double emfrac = 1.;
1379 if (m_ExcludeTG3 || onlyEM) {
1380 std::vector<float> allEne = FEHelpers::getEnergiesPerSampling(*afe);
1381
1382 if (m_ExcludeTG3)
1383 et -= allEne.at(17)/cosh(afe->eta());
1384
1385 if (onlyEM) {
1386 double eEM = 0;
1387 for (int i = 0; i <= 7; i++) eEM += allEne.at(i);
1388 double eAll = fe->e();
1389 if (m_ExcludeTG3)
1390 eAll -= allEne.at(17);
1391 emfrac = std::min(1.,eEM / eAll);
1392 }
1393 et *= emfrac;
1394 }
1396 pflowCoreSC += et;
1397 ATH_MSG_DEBUG("asso pflow to be added to core " << fe << " et = " << et << " (em frac = " << emfrac << "), total = " << pflowCoreSC);
1398 }
1399 std::map<Iso::IsolationCorrectionParameter,float> corecorrSC;
1400 corecorrSC[Iso::coreEnergy] = pflowCoreSC;
1401 corecorrSC[Iso::coreArea] = 0;
1402 result.coreCorrections[Iso::coreConeSC] = std::move(corecorrSC);
1403 }
1404
1406 float areacore = -999.;
1407 if (detaMax > 0 && dphiMax > 0) areacore = 4*detaMax*dphiMax;
1408 else if (dR2Max > 0) areacore = M_PI*dR2Max;
1409
1410 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1411 corecorr[Iso::coreEnergy] = pflowCore;
1412 corecorr[Iso::coreArea] = areacore;
1413 result.coreCorrections[Iso::coreCone] = std::move(corecorr);
1414
1415 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreCone))) {
1416 for (unsigned int i = 0; i < result.etcones.size(); i++) {
1417 ATH_MSG_DEBUG("pflow, cone type " << i << ", in cone " << result.etcones[i] << ", subtracted " << result.etcones[i]-pflowCore);
1418 result.etcones[i] -= pflowCore;
1419 }
1420 }
1421
1422 return true;
1423 }
1424
1425
1426 // etcone implementation for TrackParticle
1428 TrackParticle& tp,
1429 const derefMap_t& derefMap) const {
1430
1431 ATH_MSG_DEBUG("in CaloIsolationTool::correctIsolationEnergy_MuonCore ");
1432
1433 // initialize varialbes
1434 double ecore = 0.;
1435 auto muI = derefMap.find(&tp);
1436 static const SG::ConstAccessor<float> ET_CoreAcc ("ET_Core");
1437 if(muI!=derefMap.end()){
1438 ecore = ET_CoreAcc.withDefault (*muI->second, 0);
1439 }else{
1440 ATH_MSG_WARNING("ET_Core of muon not found! coreMuon isolation correction will not be applied!!!");
1441 return false;
1442 }
1443
1444 std::map<Iso::IsolationCorrectionParameter,float> corecorr;
1445 corecorr[Iso::coreEnergy] = ecore;
1446 corecorr[Iso::coreArea] = 0;
1447 result.coreCorrections[Iso::coreMuon] = std::move(corecorr);
1448
1449 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::coreMuon))) {
1450 for( unsigned int i=0;i<result.etcones.size();++i ) {
1451 result.etcones[i] -= ecore;
1452 ATH_MSG_DEBUG("MuonCore i=" << i << " cone [before] " << result.etcones[i]+ecore << " cone [after] " << result.etcones[i]);
1453 }
1454 }
1455
1456 return true;
1457 }
1458
1460 const Egamma& eg,
1461 const std::vector<Iso::IsolationType>& isoTypes) const
1462 {
1463// #ifndef XAOD_ANALYSIS
1464 if(m_IsoLeakCorrectionTool.empty()) return false;
1465// #endif // XAOD_ANALYSIS
1466
1467 std::vector<float> corrvec;
1468 corrvec.resize(isoTypes.size(),0.);
1469 for (unsigned int i = 0; i < isoTypes.size(); i++) {
1470
1471// #ifndef XAOD_ANALYSIS
1472 corrvec[i] = m_IsoLeakCorrectionTool->GetPtCorrection(eg, isoTypes[i]);
1473// #else
1474// corrvec[i] = eg.isolationCaloCorrection (isoTypes[i], Iso::ptCorrection);
1475// #endif // XAOD_ANALYSIS
1476 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::ptCorrection))) {
1477 result.etcones[i] -= corrvec[i];
1478 ATH_MSG_DEBUG("eta = " << eg.eta() << ", phi = " << eg.phi() << ", pt = " << eg.pt() << ", isoType = " << Iso::toCString(isoTypes[i])
1479 << ", ptcorr = " << corrvec[i] << ", isol pt corrected = " << result.etcones[i] );
1480 }
1481 }
1482 result.noncoreCorrections[Iso::ptCorrection] = std::move(corrvec);
1484 // get the correction from xAOD file
1485
1486 return true;
1487 }
1488
1490 const std::vector<Iso::IsolationType>& isoTypes,
1491 float eta, // In principle, could be (eta,phi)
1492 const std::string& type,
1493 const CaloCluster* fwdClus) const
1494
1495 {
1496 std::vector<float> corrvec;
1497 corrvec.resize(isoTypes.size(),0.);
1498
1499 // assume two densities for the time being
1500 const SG::ReadHandleKey<EventShape>* esKey = (fabs(eta) < 1.5 || m_useEtaDepPU) ? &m_tpEDCentral : &m_tpEDForward;
1501 if (type == "PFlow") {
1502 esKey = (fabs(eta) < 1.5) ? &m_efEDCentral : &m_efEDForward;
1503 } else if (fwdClus != nullptr) {
1504 ATH_MSG_DEBUG("No pileup correction for forward electron isolation yet");
1505 result.noncoreCorrections[Iso::pileupCorrection] = std::move(corrvec);
1506 return true;
1507 }
1508
1509 SG::ReadHandle<EventShape> edShape(*esKey);
1510 // check is only used for serial running; remove when MT scheduler used
1511 if(!edShape.isValid()) {
1512 ATH_MSG_FATAL("Failed to retrieve "<< esKey->key());
1513 return false;
1514 }
1515
1516 double rho = 0;
1517 bool gotDensity = edShape->getDensity(EventShape::Density,rho);
1518 if (!gotDensity) {
1519 ATH_MSG_WARNING("Cannot retrieve density " << esKey->key() << " for isolation correction. No ED correction");
1520 return false;
1521 }
1522
1523 // Get the core size
1524 float areacore = 0;
1525 std::map<xAOD::Iso::IsolationCorrectionParameter,float> ecore;
1526 for (const auto param:{Iso::coreMuon, Iso::core57cells,Iso::coreCone}){
1527 if (result.corrlist.calobitset.test(static_cast<unsigned int>(param))){
1528 if (auto it = result.coreCorrections.find(param); it != result.coreCorrections.end()) {
1529 ecore = it->second;
1530 }
1531 break;
1532 }
1533 }
1534
1535 auto iter = ecore.find(xAOD::Iso::coreArea);
1536 if (iter != ecore.end())
1537 areacore = ecore.find(xAOD::Iso::coreArea)->second;
1538
1539 for (unsigned int i = 0; i < isoTypes.size(); i++) {
1540 float dR = Iso::coneSize(isoTypes.at(i));
1541 float toSub = rho*(dR*dR*M_PI - areacore);
1542 // The improved PU correction is only for central EGamma objects, and topoetcone
1543 if (m_useEtaDepPU && fwdClus == nullptr && Iso::isolationFlavour(isoTypes.at(i)) == Iso::topoetcone) {
1544 double areaCorr = 0;
1545 auto puZeta = m_puZetaCorrection.find(isoTypes.at(i));
1546 if (puZeta != m_puZetaCorrection.end()) {
1547 areaCorr = puZeta->second->Eval(std::abs(eta)); // CW might have done it vs etaBE(2). This eta here is caloCluster eta...
1548 } else {
1549 ATH_MSG_WARNING("Requested refined eta dependent pileup correction but no zeta correction provided " << Iso::toCString(isoTypes.at(i)));
1550 }
1551 if (m_isMC) {
1552 auto puZetaMC = m_puZetaMCCorrection.find(isoTypes.at(i));
1553 if (puZetaMC != m_puZetaMCCorrection.end()) {
1554 areaCorr -= puZetaMC->second->Eval(std::abs(eta));
1555 } else {
1556 ATH_MSG_WARNING("Requested refined eta dependent pileup correction for mc but no zeta correction provided " << Iso::toCString(isoTypes.at(i)));
1557 }
1558 }
1559 toSub *= areaCorr;
1560 }
1561 corrvec[i] = toSub;
1562 if (result.corrlist.calobitset.test(static_cast<unsigned int>(Iso::pileupCorrection))){
1563 result.etcones[i] -= toSub;
1564 }
1565 ATH_MSG_DEBUG("ED correction ("<< type << ")for size " << dR << " = " << toSub << " (areacore=" << areacore << ")");
1566 }
1567
1568 result.noncoreCorrections[Iso::pileupCorrection] = std::move(corrvec);
1569 return true;
1570 }
1571
1573 const CaloCorrection& corrlist,
1574 unsigned int typesize) {
1575
1576 result.corrlist = corrlist;
1577 result.coreCorrections.clear();
1578 result.noncoreCorrections.clear();
1579 result.etcones.resize(typesize,0.);
1580
1581 }
1582
1584 const TrackParticle* tp = dynamic_cast<const TrackParticle*>(&particle);
1585 if( tp ) return tp;
1586 const Muon* muon = dynamic_cast<const Muon*>(&particle);
1587 if( muon ) {
1588 ATH_MSG_DEBUG("muon with author "<<muon->author()<<" and pT "<<muon->pt());
1589 const TrackParticle* tp = muon->trackParticle(muon->author() != xAOD::Muon::Author::STACO ?
1590 xAOD::Muon::TrackParticleType::Primary :
1591 xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
1592 if( !tp ) {
1593 ATH_MSG_WARNING(" No TrackParticle found for muon " );
1594 return nullptr;
1595 }
1596 return tp;
1597 }
1598 return &particle;
1599 }
1600
1601
1602#ifdef XAOD_ANALYSIS // particlesInCone tool will not be avaible. Write our own...
1603 bool CaloIsolationTool::particlesInCone( float eta, float phi, float dr, std::vector<const CaloCluster*>& output ) const {
1605 const CaloClusterContainer* caloClusters = 0;
1606 std::string m_caloClusterLocation = "CaloCalTopoClusters";
1607 if(evtStore()->retrieve(caloClusters, m_caloClusterLocation).isFailure()) {
1608 ATH_MSG_FATAL( "Unable to retrieve " << m_caloClusterLocation );
1609 return false;
1610 }
1611
1612 const float m_minPt = 1e-3;
1614 float dr2 = dr*dr;
1615 for(auto trk: *caloClusters){
1616 if(trk->pt()<m_minPt) continue;
1617
1618 float dEta = eta-trk->eta();
1619 float dPhi = Phi_mpi_pi(phi-trk->phi());
1620 if(dr2<(dEta*dEta+dPhi*dPhi)) continue;
1621 output.push_back(trk);
1622 }
1623
1624 return true;
1625 }
1626 bool CaloIsolationTool::particlesInCone( float eta, float phi, float dr, std::vector<const FlowElement*>& output ) const{
1628 const FlowElementContainer* Clusters = 0;
1629 std::string m_ClusterLocation = "JetETMissNeutralParticleFlowObjects";
1630 if(evtStore()->retrieve(Clusters,m_ClusterLocation).isFailure()) {
1631 ATH_MSG_FATAL( "Unable to retrieve " << m_ClusterLocation);
1632 return false;
1633 }
1634
1635 const float m_minPt = 1e-3;
1637 float dr2 = dr*dr;
1638 for(auto trk: *Clusters){
1639 if(trk->pt()<m_minPt) continue;
1640 float dEta = eta-trk->eta();
1641 float dPhi = Phi_mpi_pi(phi-trk->phi());
1642 if(dr2<(dEta*dEta+dPhi*dPhi))continue;
1643 output.push_back(trk);
1644 }
1645
1646 return true;
1647 }
1648#endif // XAOD_ANALYSIS
1649} // end of namespace
1650
#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_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(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...
Helper class to provide constant type-safe access to aux data.
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.