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;
1129 bool gotIso = eg->isolationCaloCorrection(coreV,Iso::etcone, Iso::core57cells, Iso::coreEnergy);
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:569
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.
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
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.
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
retrieve(aClass, aKey=None)
Definition PyKernel.py:110
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.