ATLAS Offline Software
Loading...
Searching...
No Matches
CaloCalibClusterMomentsMaker2.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5//-----------------------------------------------------------------------
6// File and Version Information:
7// $Id: CaloCalibClusterMomentsMaker2.cxx,v 1.16 2009-05-18 16:16:49 pospelov Exp $
8//
9// Description: see CaloCalibClusterMomentsMaker2.h
10//
11// Environment:
12// Software developed for the ATLAS Detector at CERN LHC
13//
14// Author List:
15// Sven Menke
16//
17//-----------------------------------------------------------------------
18
19//-----------------------
20// This Class's Header --
21//-----------------------
23
24//---------------
25// C++ Headers --
26//---------------
27
28
29#include "CaloEvent/CaloCell.h"
35
37
39
40#include <CLHEP/Vector/LorentzVector.h>
41
42#include <iterator>
43#include <sstream>
44#include <string_view>
45#include <utility>
46
47
48using CLHEP::HepLorentzVector;
49using CLHEP::MeV;
50using CLHEP::cm;
51
52namespace {
53
54constexpr std::array<std::pair<std::string_view, xAOD::CaloCluster::MomentType>, 19>
55 s_validMomentNames{{
56 {"ENG_CALIB_TOT", xAOD::CaloCluster::ENG_CALIB_TOT},
57 {"ENG_CALIB_OUT_L", xAOD::CaloCluster::ENG_CALIB_OUT_L},
58 {"ENG_CALIB_OUT_M", xAOD::CaloCluster::ENG_CALIB_OUT_M},
59 {"ENG_CALIB_OUT_T", xAOD::CaloCluster::ENG_CALIB_OUT_T},
60 {"ENG_CALIB_EMB0", xAOD::CaloCluster::ENG_CALIB_EMB0},
61 {"ENG_CALIB_EME0", xAOD::CaloCluster::ENG_CALIB_EME0},
62 {"ENG_CALIB_TILEG3", xAOD::CaloCluster::ENG_CALIB_TILEG3},
63 {"ENG_CALIB_DEAD_TOT", xAOD::CaloCluster::ENG_CALIB_DEAD_TOT},
64 {"ENG_CALIB_DEAD_EMB0", xAOD::CaloCluster::ENG_CALIB_DEAD_EMB0},
65 {"ENG_CALIB_DEAD_TILE0", xAOD::CaloCluster::ENG_CALIB_DEAD_TILE0},
66 {"ENG_CALIB_DEAD_TILEG3", xAOD::CaloCluster::ENG_CALIB_DEAD_TILEG3},
67 {"ENG_CALIB_DEAD_EME0", xAOD::CaloCluster::ENG_CALIB_DEAD_EME0},
68 {"ENG_CALIB_DEAD_HEC0", xAOD::CaloCluster::ENG_CALIB_DEAD_HEC0},
69 {"ENG_CALIB_DEAD_FCAL", xAOD::CaloCluster::ENG_CALIB_DEAD_FCAL},
70 {"ENG_CALIB_DEAD_LEAKAGE", xAOD::CaloCluster::ENG_CALIB_DEAD_LEAKAGE},
71 {"ENG_CALIB_DEAD_UNCLASS", xAOD::CaloCluster::ENG_CALIB_DEAD_UNCLASS},
72 {"ENG_CALIB_FRAC_EM", xAOD::CaloCluster::ENG_CALIB_FRAC_EM},
73 {"ENG_CALIB_FRAC_HAD", xAOD::CaloCluster::ENG_CALIB_FRAC_HAD},
74 {"ENG_CALIB_FRAC_REST", xAOD::CaloCluster::ENG_CALIB_FRAC_REST}
75 }};
76
77constexpr std::array<std::string_view, 19> s_aodMomentNames{{
78 "ENG_CALIB_TOT",
79 "ENG_CALIB_OUT_L",
80 "ENG_CALIB_OUT_M",
81 "ENG_CALIB_OUT_T",
82 "ENG_CALIB_EMB0",
83 "ENG_CALIB_EME0",
84 "ENG_CALIB_TILEG3",
85 "ENG_CALIB_DEAD_TOT",
86 "ENG_CALIB_DEAD_EMB0",
87 "ENG_CALIB_DEAD_TILE0",
88 "ENG_CALIB_DEAD_TILEG3",
89 "ENG_CALIB_DEAD_EME0",
90 "ENG_CALIB_DEAD_HEC0",
91 "ENG_CALIB_DEAD_FCAL",
92 "ENG_CALIB_DEAD_LEAKAGE",
93 "ENG_CALIB_DEAD_UNCLASS",
94 "ENG_CALIB_FRAC_EM",
95 "ENG_CALIB_FRAC_HAD",
96 "ENG_CALIB_FRAC_REST"
97}};
98
99} // namespace
100
101
102//###############################################################################
103
105 const std::string& name,
106 const IInterface* parent)
107 : AthAlgTool(type, name, parent),
108 m_calo_id(nullptr),
109 m_caloDM_ID(nullptr),
110 m_caloDmDescrManager(nullptr),
111 m_useParticleID(true),
112 m_energyMin(200*MeV),
114 m_apars_alpha(0.5),
115 m_apars_r0(0.2),
117{
118 declareInterface<CaloClusterCollectionProcessor>(this);
119 // Name(s) of Moments to calculate
120 declareProperty("MomentsNames", m_momentsNames);
121 m_validNames.reserve(s_validMomentNames.size());
122 for (const auto& [thisName, moment] : s_validMomentNames) {
123 m_validNames.emplace_back(thisName, moment);
124 }
125
126 // Name(s) of Moments which can be stored on the AOD - all others go to ESD
127 m_momentsNamesAOD.reserve(s_aodMomentNames.size());
128 for (const std::string_view thisName : s_aodMomentNames) {
129 m_momentsNamesAOD.emplace_back(thisName);
130 }
131
132 declareProperty("AODMomentsNames", m_momentsNamesAOD);
133 declareProperty("CalibrationHitContainerNames", m_CalibrationHitContainerNames);
134 declareProperty("DMCalibrationHitContainerNames", m_DMCalibrationHitContainerNames);
135 m_n_phi_out = 127; // not more than 127 since we store indices (-127,...-1,0,...,126) and have 8 bits only
136 m_n_eta_out = 127;
138 m_out_eta_max = 6;
139
140 m_rmaxOut[0] = 1.0;
141 m_rmaxOut[1] = 0.5;
142 m_rmaxOut[2] = 0.3;
143
144 for (int im = 0; im < 3; im++) {
145 m_i_phi_eta[im].resize(m_n_eta_out);
146 }
147 m_doDeadEnergySharing = false;
148 m_foundAllContainers = false;
149 m_doOutOfClusterL = false;
150 m_doOutOfClusterM = false;
151 m_doOutOfClusterT = false;
152 m_doDeadL = false;
153 m_doDeadM = false;
154 m_doDeadT = false;
155 m_doCalibFrac = false;
156
157 declareProperty("MatchDmType", m_MatchDmType);
158 declareProperty("UseParticleID", m_useParticleID);
159}
160
161
162//###############################################################################
163
165{
166 ATH_MSG_INFO("Initializing " << name());
167
168 for (const std::string& name : m_momentsNames) {
169 bool isValid(false);
170 for (const moment_name_pair& vname : m_validNames) {
171 if (name == vname.first) {
172 m_validMoments.insert(vname);
173 isValid = true;
174 ATH_MSG_DEBUG("Inserting " << name);
175 break;
176 }
177 }
178 if (!isValid) {
179 msg() << MSG::ERROR << "Moment " << name
180 << " is not a valid Moment name and will be ignored! "
181 << "Valid names are:";
182 for (unsigned int i = 0; i < m_validNames.size(); i++) {
183 msg() << (i == 0 ? " " : ", ") << m_validNames[i].first;
184 }
185 msg() << endmsg;
186 }
187 }
188
189 // to switch on clever DeadMaterial assignment procedure
190 // and check if tight, medium and/or loose versions for out-of-cluster and
191 // simple dead-material assignment are wanted
192 for (const moment_name_pair& vname : m_validNames) {
193 switch (vname.second) {
196 break;
198 m_doOutOfClusterL = true;
199 break;
201 m_doOutOfClusterM = true;
202 break;
204 m_doOutOfClusterT = true;
205 break;
207 m_doCalibFrac = true;
208 break;
210 m_doCalibFrac = true;
211 break;
213 m_doCalibFrac = true;
214 break;
215 default:
216 break;
217 }
218 }
219
221 ATH_MSG_INFO("Usage of ParticleID was switched off (UseParticleID==False), no ENG_CALIB_FRAC_* moments will be available");
222 m_doCalibFrac = false;
223 }
224
225 for (const std::string& name : m_momentsNamesAOD) {
226 for (const moment_name_pair& vname : m_validNames) {
227 if (vname.first == name) {
228 m_momentsAOD.insert(vname.second);
229 break;
230 }
231 }
232 }
235 }
236
237 // dead material identifier description manager
239
240 ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
241 ATH_CHECK(detStore()->retrieve(m_caloDM_ID));
242
248 m_rmaxOut,
250
254 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
255
256 return StatusCode::SUCCESS;
257}
258
259
261 int n_phi_out,
262 int n_eta_out,
263 double out_phi_max,
264 double out_eta_max,
265 const double (&rmaxOut)[3],
266 std::array<std::vector<std::vector<CalibHitIPhiIEtaRange>>, 3>& i_phi_eta)
267{
268 for (int im = 0; im < 3; ++im) {
269 i_phi_eta[im].clear();
270 i_phi_eta[im].resize(n_eta_out);
271 }
272
273 for (int jeta = 0; jeta < n_eta_out; ++jeta) {
274 const double eta0 = (jeta + 0.5) * out_eta_max / n_eta_out;
275 HepLorentzVector middle(1, 0, 0, 1);
276 middle.setREtaPhi(1. / std::cosh(eta0), eta0, 0.0);
277
278 double x_rmaxOut[3];
279 for (int im = 0; im < 3; ++im) {
280 x_rmaxOut[im] = rmaxOut[im] * angle_mollier_factor(eta0);
281 }
282
283 for (int jp = -n_phi_out; jp < n_phi_out; ++jp) {
284 const double phi = (jp + 0.5) * out_phi_max / n_phi_out;
285 int ietaMin[3] = {n_eta_out, n_eta_out, n_eta_out};
286 int ietaMax[3] = {-n_eta_out, -n_eta_out, -n_eta_out};
287
288 for (int je = -n_eta_out; je < n_eta_out; ++je) {
289 const double eta = (je + 0.5) * out_eta_max / n_eta_out;
290 HepLorentzVector cpoint(1, 0, 0, 1);
291 cpoint.setREtaPhi(1. / std::cosh(eta), eta, phi);
292 const double r = middle.angle(cpoint.vect());
293 for (int im = 0; im < 3; ++im) {
294 if (r < x_rmaxOut[im]) {
295 if (je < ietaMin[im]) {
296 ietaMin[im] = je;
297 }
298 if (je > ietaMax[im]) {
299 ietaMax[im] = je;
300 }
301 }
302 }
303 }
304
305 for (int im = 0; im < 3; ++im) {
306 if (ietaMin[im] <= ietaMax[im]) {
307 CalibHitIPhiIEtaRange theRange{};
308 theRange.iPhi = static_cast<char>(jp);
309 theRange.iEtaMin = static_cast<char>(ietaMin[im]);
310 theRange.iEtaMax = static_cast<char>(ietaMax[im]);
311 i_phi_eta[im][jeta].push_back(theRange);
312 }
313 }
314 }
315 }
316}
317
318
320 const xAOD::CaloClusterContainer& theClusColl,
321 CellInfoSet_t& cellInfo)
322{
323 cellInfo.clear();
324
325 int iClus = 0;
326 for (const xAOD::CaloCluster* theCluster : theClusColl) {
327 xAOD::CaloCluster::const_cell_iterator cellIter = theCluster->cell_begin();
328 xAOD::CaloCluster::const_cell_iterator cellIterEnd = theCluster->cell_end();
329
330 for (; cellIter != cellIterEnd; ++cellIter) {
331 const CaloCell* pCell = *cellIter;
332 const Identifier myId = pCell->ID();
333
334 MyCellInfo info(iClus, cellIter.weight());
335 CellInfoSet_t::iterator bookmark = cellInfo.lower_bound(myId);
336 if (bookmark == cellInfo.end() || bookmark->first != myId) {
337 if (bookmark != cellInfo.begin()) {
338 --bookmark;
339 }
340 cellInfo.emplace_hint(bookmark, myId, std::move(info));
341 }
342 else {
343 bookmark->second.Add(info);
344 }
345 }
346
347 ++iClus;
348 }
349}
350
351
352//###############################################################################
353
355 const xAOD::CaloClusterContainer& theClusColl,
356 const ClusInfo_t& clusInfoVec,
357 int n_phi_out,
358 int n_eta_out,
359 double out_phi_max,
360 double out_eta_max,
361 const std::array<std::vector<std::vector<CalibHitIPhiIEtaRange>>, 3>& i_phi_eta,
362 const std::array<bool, 3>& doOutOfCluster,
363 const std::array<ClusList*, 3>& clusLists)
364{
365 for (unsigned int ii = 0; ii < 3; ++ii) {
366 ClusList* pClusList = clusLists[ii];
367 if (!doOutOfCluster[ii] || pClusList == nullptr) {
368 continue;
369 }
370
371 int iClus = -1;
372 for (const xAOD::CaloCluster* theCluster : theClusColl) {
373 ++iClus;
374 const MyClusInfo& clusInfo = clusInfoVec[iClus];
375
376 if (clusInfo.engCalibIn.engTot <= 0.) {
377 continue;
378 }
379
380 int iEtaSign = 1;
381 if (theCluster->eta() < 0.) {
382 iEtaSign = -1;
383 }
384
385 const int jeta = static_cast<int>(std::floor(n_eta_out * (theCluster->eta() / out_eta_max)));
386 int jphi = static_cast<int>(std::floor(n_phi_out * (theCluster->phi() / out_phi_max)));
387
388 if (jeta < -n_eta_out || jeta >= n_eta_out) {
389 continue;
390 }
391
392 if (jphi < -n_phi_out) {
393 jphi += 2 * n_phi_out;
394 }
395 if (jphi >= n_phi_out) {
396 jphi -= 2 * n_phi_out;
397 }
398
399 unsigned int iEtaBin = static_cast<unsigned int>(jeta);
400 if (jeta < 0) {
401 iEtaBin = std::abs(jeta) - 1;
402 }
403
404 const std::vector<CalibHitIPhiIEtaRange>& bins = i_phi_eta[ii][iEtaBin];
405 for (const CalibHitIPhiIEtaRange& range : bins) {
406 int jp = range.iPhi + jphi;
407 if (jp < -n_phi_out) {
408 jp += 2 * n_phi_out;
409 }
410 if (jp >= n_phi_out) {
411 jp -= 2 * n_phi_out;
412 }
413
414 const int jEtaMin = (iEtaSign < 0) ? -range.iEtaMax - 1 : range.iEtaMin;
415 const int jEtaMax = (iEtaSign < 0) ? -range.iEtaMin - 1 : range.iEtaMax;
416
417 for (int je = jEtaMin; je <= jEtaMax; ++je) {
418 (*pClusList)[(jp + n_phi_out) * (2 * n_eta_out + 1) + je + n_eta_out].push_back(iClus);
419 }
420 }
421 }
422 }
423}
424
425
426//###############################################################################
427
428StatusCode
430 xAOD::CaloClusterContainer *theClusColl) const
431{
432
433 ATH_MSG_DEBUG("Starting CaloCalibClusterMomentsMaker2::execute");
435 const CaloDetDescrManager* calo_dd_man = *caloMgrHandle;
436
437 bool foundAllContainers (true);
438 std::vector<const CaloCalibrationHitContainer *> v_cchc;
441 {
443 if ( !cchc.isValid() ) {
445 // print ERROR message only if there was at least one event with
446 // all containers
447 msg(MSG::ERROR) << "SG does not contain calibration hit container "
448 << key.key() << endmsg;
449 }
450 foundAllContainers = false;
451 }
452 else {
453 v_cchc.push_back(cchc.cptr());
454 }
455 }
456
457 std::vector<const CaloCalibrationHitContainer *> v_dmcchc;
460 {
462 if ( !cchc.isValid() ) {
464 // print ERROR message only if there was at least one event with
465 // all containers
466 ATH_MSG_ERROR("SG does not contain DM calibration hit container "
467 << key.key());
468 }
469 foundAllContainers = false;
470 }
471 else {
472 v_dmcchc.push_back(cchc.cptr());
473 }
474 }
475
476 if ( !m_foundAllContainers && foundAllContainers ) {
478 }
479
480 if ( !foundAllContainers ) {
481 return StatusCode::SUCCESS;
482 }
483 ATH_MSG_DEBUG("SG has all containers ");
484
485 // will contain detailed info about cluster calibration energies
486 ClusInfo_t clusInfoVec(theClusColl->size());
487
488 CellInfoSet_t cellInfo;
489 buildCellInfoMap(*theClusColl, cellInfo);
490
491 xAOD::CaloClusterContainer::iterator clusIter = theClusColl->begin();
492 xAOD::CaloClusterContainer::iterator clusIterEnd = theClusColl->end();
493
494 /* ********************************************
495 calculate total calib energy inside clusters
496 ******************************************** */
497 unsigned int nHitsTotal = 0;
498 unsigned int nHitsWithoutParticleUID = 0;
499
501 v_cchc,
502 cellInfo,
503 *m_calo_id,
504 clusInfoVec,
505 nHitsTotal,
506 nHitsWithoutParticleUID,
508 [this]() {
509 ATH_MSG_ERROR("Invalid uniqueID detected - this sample cannot be properly analysed.");
510 });
511
512 // if all calibration hits have ParticleUID (i.e. GenParticle::id()) == 0
513 // when simulation was done without ParticleUID
514 bool doCalibFrac = m_doCalibFrac;
515 bool useParticleID = m_useParticleID;
516 if (m_useParticleID && (nHitsTotal == nHitsWithoutParticleUID)) {
517 ATH_MSG_INFO("Calibration hits do not have ParticleUID, ids of particle-caused hits are always 0. Continuing without ParticleID machinery.");
518 useParticleID = false;
519 }
520
521 // reading particle information for later calculation of calibration energy fraction caused
522 // by particles of different types
524
525 if (doCalibFrac && !truthParticleContainerReadHandle.isValid()) {
526 ATH_MSG_WARNING("Invalid read handle to TruthParticleContainer with key: "
528 doCalibFrac = false;
529 }
530
531 std::array<std::vector<double>, 3> engCalibOut;
532
533 /* ****************************************************************
534 lists of clusters populating given area [eta*phi][iClus list]
535 **************************************************************** */
536 std::array<ClusList, 3> clusLists;
537 const std::array<bool, 3> doOutOfCluster{{
539 }};
540 const std::array<bool, 3> doClusterLists{{
547 }};
548
549 for (unsigned int ii = 0; ii < 3; ++ii) {
550 if (doClusterLists[ii]) {
551 clusLists[ii].resize((2 * m_n_phi_out + 1) * (2 * m_n_eta_out + 1));
552 engCalibOut[ii].resize(theClusColl->size(), 0.0);
553 }
554 }
555
556 std::array<ClusList*, 3> clusListPtrs{{&clusLists[0], &clusLists[1], &clusLists[2]}};
558 *theClusColl,
559 clusInfoVec,
565 doClusterLists,
566 clusListPtrs);
567
568 /* ****************************************************************
569 calculate out-of-cluster energy of clusters
570 **************************************************************** */
572 std::array<const ClusList*, 3> constClusListPtrs{{
573 &clusLists[0], &clusLists[1], &clusLists[2]
574 }};
576 v_cchc,
577 cellInfo,
578 *calo_dd_man,
579 clusInfoVec,
584 doOutOfCluster,
585 constClusListPtrs,
586 [&engCalibOut](unsigned int ii, int iClus, int /*uniqueID*/, double energy) {
587 engCalibOut[ii][iClus] += energy;
588 });
589 }
590
591 // ------------------------------------------------------------------------
592 // calculate dead-material energy of clusters (way2)
593 // + energy is shared among clusters within certain area
594 // + distance to clusters and energy in specific samplings are used as sharing criteria
595 // + calculations are done separately for different dead material areas
596 ClusList* pClusList = nullptr;
597 if ( m_MatchDmType == kMatchDmLoose ) {
598 pClusList = &clusLists[0];
599 } else if ( m_MatchDmType == kMatchDmMedium ) {
600 pClusList = &clusLists[1];
601 } else if ( m_MatchDmType == kMatchDmTight ) {
602 pClusList = &clusLists[2];
603 }
604
605 if (m_doDeadEnergySharing && pClusList) {
607 v_dmcchc,
608 *theClusColl,
609 clusInfoVec,
610 *pClusList,
611 useParticleID,
612 [&clusInfoVec](int iClus, int /*uniqueID*/, int nDmArea, double energy) {
613 clusInfoVec[iClus].engCalibDeadInArea[nDmArea] += energy;
614 clusInfoVec[iClus].engCalibDeadInArea[CaloDmDescrArea::DMA_ALL] += energy;
615 });
616 } // doDeadEnergySharing
617
618 // fraction of calibration energies caused by different particles
619 std::vector<double> engCalibFrac;
620 engCalibFrac.resize(kCalibFracMax, 0.0);
621
622 std::map<unsigned int, int> truthIDToPdgCodeMap;
623
624 // loop on truth particle container is slow, so put needed information in a map for faster key lookup in later loops
625 for ( const auto *thisTruthParticle : *truthParticleContainerReadHandle ) {
626
627 if (!thisTruthParticle) {
628 ATH_MSG_WARNING("Got invalid pointer to TruthParticle");
629 continue;
630 }
631
632 truthIDToPdgCodeMap[HepMC::uniqueID(thisTruthParticle)] = thisTruthParticle->pdgId();
633 } // truth particle loop
634
635 // assign moments
636 int iClus = 0;
637 for (clusIter = theClusColl->begin(), iClus = 0;
638 clusIter != clusIterEnd;
639 ++clusIter, ++iClus) {
640 xAOD::CaloCluster * theCluster = *clusIter;
641 MyClusInfo& clusInfo = clusInfoVec[iClus];
642
643 // total DM energy assigned to cluster
644 double eng_calib_dead_tot = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_ALL]
645 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB]
646 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE]
647 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
648 // DM energy before barrel presampler, inside it, and between presampler and strips
649 double eng_calib_dead_emb0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EMB0]
651 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB];
652 // DM energy between barrel and tile
653 double eng_calib_dead_tile0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EMB3_TILE0];
654 // DM energy before scintillator and inside scintillator
655 double eng_calib_dead_tileg3 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_SCN]
656 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
657 // DM energy before endcap presampler, inside it and between presampler and strips
658 double eng_calib_dead_eme0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EME0]
660 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE];
661 // DM energy between emec and hec
662 double eng_calib_dead_hec0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EME3_HEC0];
663 // DM energy before FCAL and between HEC and FCAL
664 double eng_calib_dead_fcal = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_FCAL0]
666 // DM leakage behind the calorimeter
667 double eng_calib_dead_leakage = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_LEAK];
668 // the rest of DM energy which remains unclassified
669 double eng_calib_dead_unclass = eng_calib_dead_tot - eng_calib_dead_emb0 - eng_calib_dead_tile0
670 - eng_calib_dead_tileg3 - eng_calib_dead_eme0 - eng_calib_dead_hec0 - eng_calib_dead_fcal
671 - eng_calib_dead_leakage;
672
673 if (doCalibFrac) {
674/*****************************************************************************
675Calculation of energy fraction caused by particles of different types
676*****************************************************************************/
677 engCalibFrac.assign(kCalibFracMax, 0.0);
678 if (clusInfo.engCalibIn.engTot > 0.0) {
679 // each MyClusInfo has a map of particle's uniqueID (GenParticle::id()) and particle calibration deposits in given cluster
680 for (const auto& p : clusInfo.engCalibParticle) {
681 int pdg_id = 0;
682 if (auto it = truthIDToPdgCodeMap.find(p.first); it != truthIDToPdgCodeMap.end()) {
683 pdg_id = it->second;
684 } else {
685 ATH_MSG_WARNING("truthIDToPdgCodeMap cannot find an entry with uniqueID " << p.first);
686 continue;
687 }
688 if (std::abs(pdg_id) == 211) {
689 engCalibFrac[kCalibFracHAD] += p.second.engTot;
690 } else if (pdg_id == 111 || pdg_id == 22 || std::abs(pdg_id) == 11) {
691 engCalibFrac[kCalibFracEM] += p.second.engTot;
692 } else {
693 engCalibFrac[kCalibFracREST] += p.second.engTot;
694 }
695 }
696 for (size_t i = 0; i < engCalibFrac.size(); i++) {
697 engCalibFrac[i] = engCalibFrac[i] / clusInfo.engCalibIn.engTot;
698 }
699 }
700 }
701
702 if ( !m_momentsNames.empty() ) {
703 std::vector<double> myMoments(m_validMoments.size(), 0);
704 // assign moments
705 moment_name_set::const_iterator vMomentsIter = m_validMoments.begin();
706 moment_name_set::const_iterator vMomentsIterEnd = m_validMoments.end();
707
708 int iMoment = 0;
709 for (; vMomentsIter != vMomentsIterEnd; ++vMomentsIter, ++iMoment) {
710 // now calculate the actual moments
711 switch (vMomentsIter->second) {
713 ATH_MSG_DEBUG("Inserting ENG_CALIB_TOT");
714 myMoments[iMoment] = clusInfo.engCalibIn.engTot;
715 break;
717 myMoments[iMoment] = engCalibOut[0][iClus];
718 break;
720 myMoments[iMoment] = engCalibOut[1][iClus];
721 break;
723 myMoments[iMoment] = engCalibOut[2][iClus];
724 break;
726 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB];
727 break;
729 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE];
730 break;
732 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
733 break;
735 myMoments[iMoment] = eng_calib_dead_tot;
736 break;
738 myMoments[iMoment] = eng_calib_dead_emb0;
739 break;
741 myMoments[iMoment] = eng_calib_dead_tile0;
742 break;
744 myMoments[iMoment] = eng_calib_dead_tileg3;
745 break;
747 myMoments[iMoment] = eng_calib_dead_eme0;
748 break;
750 myMoments[iMoment] = eng_calib_dead_hec0;
751 break;
753 myMoments[iMoment] = eng_calib_dead_fcal;
754 break;
756 myMoments[iMoment] = eng_calib_dead_leakage;
757 break;
759 myMoments[iMoment] = eng_calib_dead_unclass;
760 break;
762 myMoments[iMoment] = engCalibFrac[kCalibFracEM];
763 break;
765 myMoments[iMoment] = engCalibFrac[kCalibFracHAD];
766 break;
768 myMoments[iMoment] = engCalibFrac[kCalibFracREST];
769 break;
770 default:
771 // nothing to be done for other moments
772 break;
773 }
774
775 theCluster->insertMoment(vMomentsIter->second, myMoments[iMoment]);
776 }
777 }
778 }
779
780 return StatusCode::SUCCESS;
781}
782
783
784/* ****************************************************************************
785
786**************************************************************************** */
788{
789 double eta = fabs(x);
790 double ff;
791 if (eta < 1.6) {
792 ff = atan(5.0 * 1.7 / (200.0 * cosh(eta)));
793 } else if (eta < 3.2) {
794 ff = atan(5.0 * 1.6 / (420. / tanh(eta)));
795 } else {
796 ff = atan(5.0 * 0.95 / (505. / tanh(eta)));
797 }
798 return ff * (1. / atan(5.0 * 1.7 / 200.0));
799}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescrManager.
static const double MeV
static const std::vector< std::string > bins
Handle class for reading from StoreGate.
#define x
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
MsgStream & msg() const
std::array< double, CaloDmDescrArea::DMA_MAX > engCalibDeadInArea
void accumulateDeadMaterialEnergy(const std::vector< const CaloCalibrationHitContainer * > &v_dmcchc, const xAOD::CaloClusterContainer &theClusColl, const ClusInfo_t &clusInfoVec, const ClusList &clusList, bool useParticleID, AddDeadMaterialEnergy &&addDeadMaterialEnergy) const
Accumulate dead-material calibration-hit energy assigned to clusters.
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_DMCalibrationHitContainerNames
std::set< xAOD::CaloCluster::MomentType > m_momentsAOD
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override
Execute on an entire collection of clusters.
static void initializeOutOfClusterDistanceTables(int n_phi_out, int n_eta_out, double out_phi_max, double out_eta_max, const double(&rmaxOut)[3], std::array< std::vector< std::vector< CalibHitIPhiIEtaRange > >, 3 > &i_phi_eta)
Precompute eta/phi lookup tables for quick out-of-cluster hit association to clusters.
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_CalibrationHitContainerNames
std::map< Identifier, MyCellInfo > CellInfoSet_t
static void accumulateClusterCalibHits(const std::vector< const CaloCalibrationHitContainer * > &v_cchc, const CellInfoSet_t &cellInfo, const CaloCell_ID &calo_id, ClusInfo_t &clusInfoVec, unsigned int &nHitsTotal, unsigned int &nHitsWithoutParticleUID, bool useParticleID, InvalidUniqueIdHandler &&invalidUniqueIdHandler)
Accumulate calibration-hit energy inside clusters.
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleContainerKey
static void buildOutOfClusterClusterLists(const xAOD::CaloClusterContainer &theClusColl, const ClusInfo_t &clusInfoVec, int n_phi_out, int n_eta_out, double out_phi_max, double out_eta_max, const std::array< std::vector< std::vector< CalibHitIPhiIEtaRange > >, 3 > &i_phi_eta, const std::array< bool, 3 > &doOutOfCluster, const std::array< ClusList *, 3 > &clusLists)
Build lookup lists of clusters for out-of-cluster energy sharing.
static void buildCellInfoMap(const xAOD::CaloClusterContainer &theClusColl, CellInfoSet_t &cellInfo)
Build a map of calorimeter cells contributing to clusters.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
CaloCalibClusterMomentsMaker2(const std::string &type, const std::string &name, const IInterface *parent)
std::array< std::vector< std::vector< CalibHitIPhiIEtaRange > >, 3 > m_i_phi_eta
const CaloDmDescrManager * m_caloDmDescrManager
std::vector< std::vector< int > > ClusList
static void accumulateOutOfClusterEnergy(const std::vector< const CaloCalibrationHitContainer * > &v_cchc, const CellInfoSet_t &cellInfo, const CaloDetDescrManager &calo_dd_man, const ClusInfo_t &clusInfoVec, int n_phi_out, int n_eta_out, double out_phi_max, double out_eta_max, const std::array< bool, 3 > &doOutOfCluster, const std::array< const ClusList *, 3 > &clusLists, AddOutOfClusterEnergy &&addOutOfClusterEnergy)
std::pair< std::string, xAOD::CaloCluster::MomentType > moment_name_pair
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
This class provides the client interface for accessing the detector description information common to...
static const CaloDmDescrManager * instance()
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
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_pointer_type cptr()
Dereference the pointer.
void insertMoment(MomentType type, double value)
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version).
@ ENG_CALIB_OUT_M
Attached Calibration Hit energy outside clusters but inside the calorimeter with medium matching (Ang...
@ ENG_CALIB_OUT_L
Attached Calibration Hit energy outside clusters but inside the calorimeter with loose matching (Angl...
@ ENG_CALIB_DEAD_UNCLASS
Attached Calibration Hit energy in dead material in unclassified areas of the detector.
@ ENG_CALIB_DEAD_HEC0
Attached Calibration Hit energy in dead material between EME3 and HEC0.
@ ENG_CALIB_DEAD_TILEG3
Attached Calibration Hit energy in dead material before scintillator.
@ ENG_CALIB_FRAC_REST
Calibration Hit energy inside the cluster caused by other particles.
@ ENG_CALIB_DEAD_EME0
Attached Calibration Hit energy in dead material before EME0, between EME0 and EME1.
@ ENG_CALIB_DEAD_TILE0
Attached Calibration Hit energy in dead material between EMB3 and TILE0.
@ ENG_CALIB_FRAC_EM
Calibration Hit energy inside the cluster caused by e/gamma/pi0.
@ ENG_CALIB_DEAD_FCAL
Attached Calibration Hit energy in dead material before FCAL, between FCAL and HEC.
@ ENG_CALIB_TOT
Calibration Hit energy inside the cluster.
@ ENG_CALIB_OUT_T
Attached Calibration Hit energy outside clusters but inside the calorimeter with tight matching (Angl...
@ ENG_CALIB_DEAD_LEAKAGE
Attached Calibration Hit energy in dead material behind calorimeters.
@ ENG_CALIB_FRAC_HAD
Calibration Hit energy inside the cluster caused by charged pi+ and pi-.
@ ENG_CALIB_EMB0
Calibration Hit energy inside the cluster barrel presampler.
@ ENG_CALIB_EME0
Calibration Hit energy inside the cluster endcap presampler.
@ ENG_CALIB_DEAD_EMB0
Attached Calibration Hit energy in dead material before EMB0, between EMB0 and EMB1.
@ ENG_CALIB_DEAD_TOT
Attached Calibration Hit energy in dead material.
@ ENG_CALIB_TILEG3
Calibration Hit energy inside the cluster scintillator.
int r
Definition globals.cxx:22
int uniqueID(const T &p)
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.