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#include <iterator>
28#include <sstream>
29#include <set>
30
31#include "CaloEvent/CaloCell.h"
37
39
41
42#include <CLHEP/Vector/LorentzVector.h>
43#include <cmath>
44
45
46using CLHEP::HepLorentzVector;
47using CLHEP::MeV;
48using CLHEP::cm;
49
50
51//###############################################################################
52
54 const std::string& name,
55 const IInterface* parent)
56 : AthAlgTool(type, name, parent)
57{
58 declareInterface<CaloClusterCollectionProcessor>(this);
59 for (int im = 0; im < 3; im++) {
60 m_i_phi_eta[im].resize(m_n_eta_out);
61 }
62}
63
64
65//###############################################################################
66
68{
69 ATH_MSG_INFO("Initializing " << name());
70
71 for (const std::string& name : m_momentsNames) {
72 bool isValid(false);
73 for (const moment_name_pair& vname : m_validNames) {
74 if (name == vname.first) {
75 m_validMoments.insert(vname);
76 isValid = true;
77 ATH_MSG_DEBUG("Inserting " << name);
78 break;
79 }
80 }
81 if (!isValid) {
82 msg() << MSG::ERROR << "Moment " << name
83 << " is not a valid Moment name and will be ignored! "
84 << "Valid names are:";
85 for (unsigned int i = 0; i < m_validNames.size(); i++) {
86 msg() << (i == 0 ? " " : ", ") << m_validNames[i].first;
87 }
88 msg() << endmsg;
89 }
90 }
91
92 // to switch on clever DeadMaterial assignment procedure
93 // and check if tight, medium and/or loose versions for out-of-cluster and
94 // simple dead-material assignment are wanted
95 for (const moment_name_pair& vname : m_validNames) {
96 switch (vname.second) {
99 break;
101 m_doOutOfClusterL = true;
102 break;
104 m_doOutOfClusterM = true;
105 break;
107 m_doOutOfClusterT = true;
108 break;
110 m_doCalibFrac = true;
111 break;
113 m_doCalibFrac = true;
114 break;
116 m_doCalibFrac = true;
117 break;
118 default:
119 break;
120 }
121 }
122
124 ATH_MSG_INFO("Usage of ParticleID was switched off (UseParticleID==False), no ENG_CALIB_FRAC_* moments will be available");
125 m_doCalibFrac = false;
126 }
127
128 for (const std::string& name : m_momentsNamesAOD) {
129 for (const moment_name_pair& vname : m_validNames) {
130 if (vname.first == name) {
131 m_momentsAOD.insert(vname.second);
132 break;
133 }
134 }
135 }
138 }
139
140 // dead material identifier description manager
142
143 ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
144 ATH_CHECK(detStore()->retrieve(m_caloDM_ID));
145
151 m_rmaxOut,
153
157 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
158
159 return StatusCode::SUCCESS;
160}
161
162
164 int n_phi_out,
165 int n_eta_out,
166 double out_phi_max,
167 double out_eta_max,
168 const double (&rmaxOut)[3],
169 std::array<std::vector<std::vector<CalibHitIPhiIEtaRange>>, 3>& i_phi_eta)
170{
171 for (int im = 0; im < 3; ++im) {
172 i_phi_eta[im].clear();
173 i_phi_eta[im].resize(n_eta_out);
174 }
175
176 for (int jeta = 0; jeta < n_eta_out; ++jeta) {
177 const double eta0 = (jeta + 0.5) * out_eta_max / n_eta_out;
178 HepLorentzVector middle(1, 0, 0, 1);
179 middle.setREtaPhi(1. / std::cosh(eta0), eta0, 0.0);
180
181 double x_rmaxOut[3];
182 for (int im = 0; im < 3; ++im) {
183 x_rmaxOut[im] = rmaxOut[im] * angle_mollier_factor(eta0);
184 }
185
186 for (int jp = -n_phi_out; jp < n_phi_out; ++jp) {
187 const double phi = (jp + 0.5) * out_phi_max / n_phi_out;
188 int ietaMin[3] = {n_eta_out, n_eta_out, n_eta_out};
189 int ietaMax[3] = {-n_eta_out, -n_eta_out, -n_eta_out};
190
191 for (int je = -n_eta_out; je < n_eta_out; ++je) {
192 const double eta = (je + 0.5) * out_eta_max / n_eta_out;
193 HepLorentzVector cpoint(1, 0, 0, 1);
194 cpoint.setREtaPhi(1. / std::cosh(eta), eta, phi);
195 const double r = middle.angle(cpoint.vect());
196 for (int im = 0; im < 3; ++im) {
197 if (r < x_rmaxOut[im]) {
198 if (je < ietaMin[im]) {
199 ietaMin[im] = je;
200 }
201 if (je > ietaMax[im]) {
202 ietaMax[im] = je;
203 }
204 }
205 }
206 }
207
208 for (int im = 0; im < 3; ++im) {
209 if (ietaMin[im] <= ietaMax[im]) {
210 CalibHitIPhiIEtaRange theRange{};
211 theRange.iPhi = static_cast<char>(jp);
212 theRange.iEtaMin = static_cast<char>(ietaMin[im]);
213 theRange.iEtaMax = static_cast<char>(ietaMax[im]);
214 i_phi_eta[im][jeta].push_back(theRange);
215 }
216 }
217 }
218 }
219}
220
221
223 const xAOD::CaloClusterContainer& theClusColl,
224 CellInfoSet_t& cellInfo)
225{
226 cellInfo.clear();
227
228 int iClus = 0;
229 for (const xAOD::CaloCluster* theCluster : theClusColl) {
230 xAOD::CaloCluster::const_cell_iterator cellIter = theCluster->cell_begin();
231 xAOD::CaloCluster::const_cell_iterator cellIterEnd = theCluster->cell_end();
232
233 for (; cellIter != cellIterEnd; ++cellIter) {
234 const CaloCell* pCell = *cellIter;
235 const Identifier myId = pCell->ID();
236
237 MyCellInfo info(iClus, cellIter.weight());
238 CellInfoSet_t::iterator bookmark = cellInfo.lower_bound(myId);
239 if (bookmark == cellInfo.end() || bookmark->first != myId) {
240 if (bookmark != cellInfo.begin()) {
241 --bookmark;
242 }
243 cellInfo.emplace_hint(bookmark, myId, std::move(info));
244 }
245 else {
246 bookmark->second.Add(info);
247 }
248 }
249
250 ++iClus;
251 }
252}
253
254
255//###############################################################################
256
258 const xAOD::CaloClusterContainer& theClusColl,
259 const ClusInfo_t& clusInfoVec,
260 int n_phi_out,
261 int n_eta_out,
262 double out_phi_max,
263 double out_eta_max,
264 const std::array<std::vector<std::vector<CalibHitIPhiIEtaRange>>, 3>& i_phi_eta,
265 const std::array<bool, 3>& doOutOfCluster,
266 const std::array<ClusList*, 3>& clusLists)
267{
268 for (unsigned int ii = 0; ii < 3; ++ii) {
269 ClusList* pClusList = clusLists[ii];
270 if (!doOutOfCluster[ii] || pClusList == nullptr) {
271 continue;
272 }
273
274 int iClus = -1;
275 for (const xAOD::CaloCluster* theCluster : theClusColl) {
276 ++iClus;
277 const MyClusInfo& clusInfo = clusInfoVec[iClus];
278
279 if (clusInfo.engCalibIn.engTot <= 0.) {
280 continue;
281 }
282
283 int iEtaSign = 1;
284 if (theCluster->eta() < 0.) {
285 iEtaSign = -1;
286 }
287
288 const int jeta = static_cast<int>(std::floor(n_eta_out * (theCluster->eta() / out_eta_max)));
289 int jphi = static_cast<int>(std::floor(n_phi_out * (theCluster->phi() / out_phi_max)));
290
291 if (jeta < -n_eta_out || jeta >= n_eta_out) {
292 continue;
293 }
294
295 if (jphi < -n_phi_out) {
296 jphi += 2 * n_phi_out;
297 }
298 if (jphi >= n_phi_out) {
299 jphi -= 2 * n_phi_out;
300 }
301
302 unsigned int iEtaBin = static_cast<unsigned int>(jeta);
303 if (jeta < 0) {
304 iEtaBin = std::abs(jeta) - 1;
305 }
306
307 const std::vector<CalibHitIPhiIEtaRange>& bins = i_phi_eta[ii][iEtaBin];
308 for (const CalibHitIPhiIEtaRange& range : bins) {
309 int jp = range.iPhi + jphi;
310 if (jp < -n_phi_out) {
311 jp += 2 * n_phi_out;
312 }
313 if (jp >= n_phi_out) {
314 jp -= 2 * n_phi_out;
315 }
316
317 const int jEtaMin = (iEtaSign < 0) ? -range.iEtaMax - 1 : range.iEtaMin;
318 const int jEtaMax = (iEtaSign < 0) ? -range.iEtaMin - 1 : range.iEtaMax;
319
320 for (int je = jEtaMin; je <= jEtaMax; ++je) {
321 (*pClusList)[(jp + n_phi_out) * (2 * n_eta_out + 1) + je + n_eta_out].push_back(iClus);
322 }
323 }
324 }
325 }
326}
327
328
329//###############################################################################
330
331StatusCode
333 xAOD::CaloClusterContainer *theClusColl) const
334{
335
336 ATH_MSG_DEBUG("Starting CaloCalibClusterMomentsMaker2::execute");
338 const CaloDetDescrManager* calo_dd_man = *caloMgrHandle;
339
340 bool foundAllContainers (true);
341 std::vector<const CaloCalibrationHitContainer *> v_cchc;
344 {
346 if ( !cchc.isValid() ) {
348 // print ERROR message only if there was at least one event with
349 // all containers
350 msg(MSG::ERROR) << "SG does not contain calibration hit container "
351 << key.key() << endmsg;
352 }
353 foundAllContainers = false;
354 }
355 else {
356 v_cchc.push_back(cchc.cptr());
357 }
358 }
359
360 std::vector<const CaloCalibrationHitContainer *> v_dmcchc;
363 {
365 if ( !cchc.isValid() ) {
367 // print ERROR message only if there was at least one event with
368 // all containers
369 ATH_MSG_ERROR("SG does not contain DM calibration hit container "
370 << key.key());
371 }
372 foundAllContainers = false;
373 }
374 else {
375 v_dmcchc.push_back(cchc.cptr());
376 }
377 }
378
379 if ( !m_foundAllContainers && foundAllContainers ) {
381 }
382
383 if ( !foundAllContainers ) {
384 return StatusCode::SUCCESS;
385 }
386 ATH_MSG_DEBUG("SG has all containers ");
387
388 // will contain detailed info about cluster calibration energies
389 ClusInfo_t clusInfoVec(theClusColl->size());
390
391 CellInfoSet_t cellInfo;
392 buildCellInfoMap(*theClusColl, cellInfo);
393
394 xAOD::CaloClusterContainer::iterator clusIter = theClusColl->begin();
395 xAOD::CaloClusterContainer::iterator clusIterEnd = theClusColl->end();
396
397 /* ********************************************
398 calculate total calib energy inside clusters
399 ******************************************** */
400 unsigned int nHitsTotal = 0;
401 unsigned int nHitsWithoutParticleUID = 0;
402
404 v_cchc,
405 cellInfo,
406 *m_calo_id,
407 clusInfoVec,
408 nHitsTotal,
409 nHitsWithoutParticleUID,
411 [this]() {
412 ATH_MSG_ERROR("Invalid uniqueID detected - this sample cannot be properly analysed.");
413 });
414
415 // if all calibration hits have ParticleUID (i.e. GenParticle::id()) == 0
416 // when simulation was done without ParticleUID
417 bool doCalibFrac = m_doCalibFrac;
418 bool useParticleID = m_useParticleID;
419 if (m_useParticleID && (nHitsTotal == nHitsWithoutParticleUID)) {
420 ATH_MSG_INFO("Calibration hits do not have ParticleUID, ids of particle-caused hits are always 0. Continuing without ParticleID machinery.");
421 useParticleID = false;
422 }
423
424 // reading particle information for later calculation of calibration energy fraction caused
425 // by particles of different types
427
428 if (doCalibFrac && !truthParticleContainerReadHandle.isValid()) {
429 ATH_MSG_WARNING("Invalid read handle to TruthParticleContainer with key: "
431 doCalibFrac = false;
432 }
433
434 std::array<std::vector<double>, 3> engCalibOut;
435
436 /* ****************************************************************
437 lists of clusters populating given area [eta*phi][iClus list]
438 **************************************************************** */
439 std::array<ClusList, 3> clusLists;
440 const std::array<bool, 3> doOutOfCluster{{
442 }};
443 const std::array<bool, 3> doClusterLists{{
450 }};
451
452 for (unsigned int ii = 0; ii < 3; ++ii) {
453 if (doClusterLists[ii]) {
454 clusLists[ii].resize((2 * m_n_phi_out + 1) * (2 * m_n_eta_out + 1));
455 engCalibOut[ii].resize(theClusColl->size(), 0.0);
456 }
457 }
458
459 std::array<ClusList*, 3> clusListPtrs{{&clusLists[0], &clusLists[1], &clusLists[2]}};
461 *theClusColl,
462 clusInfoVec,
468 doClusterLists,
469 clusListPtrs);
470
471 /* ****************************************************************
472 calculate out-of-cluster energy of clusters
473 **************************************************************** */
475 std::array<const ClusList*, 3> constClusListPtrs{{
476 &clusLists[0], &clusLists[1], &clusLists[2]
477 }};
479 v_cchc,
480 cellInfo,
481 *calo_dd_man,
482 clusInfoVec,
487 doOutOfCluster,
488 constClusListPtrs,
489 [&engCalibOut](unsigned int ii, int iClus, int /*uniqueID*/, double energy) {
490 engCalibOut[ii][iClus] += energy;
491 });
492 }
493
494 // ------------------------------------------------------------------------
495 // calculate dead-material energy of clusters (way2)
496 // + energy is shared among clusters within certain area
497 // + distance to clusters and energy in specific samplings are used as sharing criteria
498 // + calculations are done separately for different dead material areas
499 ClusList* pClusList = nullptr;
500 if ( m_MatchDmType == kMatchDmLoose ) {
501 pClusList = &clusLists[0];
502 } else if ( m_MatchDmType == kMatchDmMedium ) {
503 pClusList = &clusLists[1];
504 } else if ( m_MatchDmType == kMatchDmTight ) {
505 pClusList = &clusLists[2];
506 }
507
508 if (m_doDeadEnergySharing && pClusList) {
509
510 for (const CaloCalibrationHitContainer* dmcchc : v_dmcchc) {
511 for (const CaloCalibrationHit* hit : *dmcchc) {
512 Identifier myId = hit->cellID();
513 if (m_calo_id->is_lar_dm(myId) || m_calo_id->is_tile_dm(myId)) {
514 CaloDmDescrElement* myCDDE(nullptr);
515 myCDDE = m_caloDmDescrManager->get_element(myId);
516 if ( myCDDE ) {
517 int uniqueID(HepMC::UNDEFINED_ID);
518 if (useParticleID) {
519 uniqueID = HepMC::uniqueID(hit);
520 }
521
522 int jeO = (int)floor(m_n_eta_out * (myCDDE->eta() / m_out_eta_max));
523 if ( jeO >= -m_n_eta_out && jeO < m_n_eta_out ) {
524 int jpO = (int)floor(m_n_phi_out * (myCDDE->phi() / m_out_phi_max));
525 if ( jpO < -m_n_phi_out ) {
526 jpO += 2 * m_n_phi_out;
527 }
528 if ( jpO >= m_n_phi_out ) {
529 jpO -= 2 * m_n_phi_out;
530 }
531
532 /* ****************************************
533 share energy of DM hit among different clusters
534 ***************************************** */
535 int nDmArea = m_caloDmDescrManager->get_dm_area(myId);
536 const CaloDmRegion *dmRegion = m_caloDmDescrManager->get_dm_region(myId);
537 int hitClusVecIndex = 0;
538 std::vector<int> hitClusIndex(theClusColl->size());
539 std::vector<double> hitClusEffEnergy(theClusColl->size());
540 double hitClusNorm = 0.0;
541
542 // loop over clusters which match given DM hit
543 for (unsigned int i_cls = 0;
544 i_cls < (*pClusList)[(jpO + m_n_phi_out) * (2 * m_n_eta_out + 1) + jeO + m_n_eta_out].size();
545 i_cls++) {
546 int iClus = (*pClusList)[(jpO + m_n_phi_out) * (2 * m_n_eta_out + 1) + jeO + m_n_eta_out][i_cls];
547 xAOD::CaloCluster * theCluster = theClusColl->at(iClus);
548
549 MyClusInfo& clusInfo = clusInfoVec[iClus];
550 auto pos = clusInfo.engCalibParticle.find(uniqueID);
551 if (pos != clusInfo.engCalibParticle.end()) {
552 double engClusTruthUniqueIDCalib = pos->second.engTot;
553
554 if (engClusTruthUniqueIDCalib > m_energyMinCalib && theCluster->e() > m_energyMin) {
555 double sum_smp_energy = 0.0;
556 // loop over calo sampling numbers registered for given DM area
557 for (unsigned int i_smp = 0; i_smp < dmRegion->m_CaloSampleNeighbours.size(); i_smp++) {
560 if ( (dmRegion->m_CaloSampleEtaMin[i_smp] - 0.5) <= theCluster->eta() &&
561 theCluster->eta() <= (dmRegion->m_CaloSampleEtaMax[i_smp] + 0.5) ) {
562 sum_smp_energy += pos->second.engSmp[nsmp];
563 }
564 }
565 if (sum_smp_energy > 0.0) {
566 double phi_diff = myCDDE->phi() - theCluster->phi();
567 if (phi_diff <= -M_PI) {
568 phi_diff += 2. * M_PI;
569 } else if (phi_diff > M_PI) {
570 phi_diff -= 2. * M_PI;
571 }
572 double eta_diff = (myCDDE->eta() - theCluster->eta());
573 float distance = sqrt(eta_diff * eta_diff + phi_diff * phi_diff);
574
575 double effEner = pow(sum_smp_energy, m_apars_alpha) * exp(-distance / m_apars_r0);
576
577 hitClusIndex[hitClusVecIndex] = iClus;
578 hitClusEffEnergy[hitClusVecIndex++] = effEner;
579 hitClusNorm += effEner;
580 }
581 } // good energetic cluster
582 } // we found a uniqueID
583 } // loop over clusters in the list
584
585 hitClusIndex.resize(hitClusVecIndex);
586 hitClusEffEnergy.resize(hitClusVecIndex);
587
588 // now we have to calculate weight for assignment hit energy to cluster
589 if (hitClusNorm > 0.0) {
590 const double inv_hitClusNorm = 1. / hitClusNorm;
591 for (unsigned int i_cls = 0; i_cls < hitClusIndex.size(); i_cls++) {
592 int iClus = hitClusIndex[i_cls];
593 double dm_weight = hitClusEffEnergy[i_cls] * inv_hitClusNorm;
594 if (dm_weight > 1.0 || dm_weight < 0.0) {
595 std::cout << "CaloCalibClusterMomentsMaker2::execute() ->Error! Strange weight "
596 << dm_weight << std::endl;
597 std::cout << hitClusEffEnergy[i_cls] << " " << hitClusNorm << std::endl;
598 }
599 clusInfoVec[iClus].engCalibDeadInArea[nDmArea] += hit->energyTotal() * dm_weight;
600 clusInfoVec[iClus].engCalibDeadInArea[CaloDmDescrArea::DMA_ALL] += hit->energyTotal() * dm_weight;
601 }
602 } // hit clus norm
603
604 } // loop over united ieta*iphi
605 } // myCDDE
606 } // tile and lar
607 } // loop over DM calibration hits
608 } // loop over containers
609
610 } // doDeadEnergySharing
611
612 // fraction of calibration energies caused by different particles
613 std::vector<double> engCalibFrac;
614 engCalibFrac.resize(kCalibFracMax, 0.0);
615
616 std::map<unsigned int, int> truthIDToPdgCodeMap;
617
618 // loop on truth particle container is slow, so put needed information in a map for faster key lookup in later loops
619 for ( const auto *thisTruthParticle : *truthParticleContainerReadHandle ) {
620
621 if (!thisTruthParticle) {
622 ATH_MSG_WARNING("Got invalid pointer to TruthParticle");
623 continue;
624 }
625
626 truthIDToPdgCodeMap[HepMC::uniqueID(thisTruthParticle)] = thisTruthParticle->pdgId();
627 } // truth particle loop
628
629 // assign moments
630 int iClus = 0;
631 for (clusIter = theClusColl->begin(), iClus = 0;
632 clusIter != clusIterEnd;
633 ++clusIter, ++iClus) {
634 xAOD::CaloCluster * theCluster = *clusIter;
635 MyClusInfo& clusInfo = clusInfoVec[iClus];
636
637 // total DM energy assigned to cluster
638 double eng_calib_dead_tot = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_ALL]
639 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB]
640 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE]
641 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
642 // DM energy before barrel presampler, inside it, and between presampler and strips
643 double eng_calib_dead_emb0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EMB0]
645 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB];
646 // DM energy between barrel and tile
647 double eng_calib_dead_tile0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EMB3_TILE0];
648 // DM energy before scintillator and inside scintillator
649 double eng_calib_dead_tileg3 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_SCN]
650 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
651 // DM energy before endcap presampler, inside it and between presampler and strips
652 double eng_calib_dead_eme0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EME0]
654 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE];
655 // DM energy between emec and hec
656 double eng_calib_dead_hec0 = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_EME3_HEC0];
657 // DM energy before FCAL and between HEC and FCAL
658 double eng_calib_dead_fcal = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_FCAL0]
660 // DM leakage behind the calorimeter
661 double eng_calib_dead_leakage = clusInfo.engCalibDeadInArea[CaloDmDescrArea::DMA_LEAK];
662 // the rest of DM energy which remains unclassified
663 double eng_calib_dead_unclass = eng_calib_dead_tot - eng_calib_dead_emb0 - eng_calib_dead_tile0
664 - eng_calib_dead_tileg3 - eng_calib_dead_eme0 - eng_calib_dead_hec0 - eng_calib_dead_fcal
665 - eng_calib_dead_leakage;
666
667 if (doCalibFrac) {
668/*****************************************************************************
669Calculation of energy fraction caused by particles of different types
670*****************************************************************************/
671 engCalibFrac.assign(kCalibFracMax, 0.0);
672 if (clusInfo.engCalibIn.engTot > 0.0) {
673 // each MyClusInfo has a map of particle's uniqueID (GenParticle::id()) and particle calibration deposits in given cluster
674 for (const auto& p : clusInfo.engCalibParticle) {
675 int pdg_id = 0;
676 if (auto it = truthIDToPdgCodeMap.find(p.first); it != truthIDToPdgCodeMap.end()) {
677 pdg_id = it->second;
678 } else {
679 ATH_MSG_WARNING("truthIDToPdgCodeMap cannot find an entry with uniqueID " << p.first);
680 continue;
681 }
682 if (std::abs(pdg_id) == 211) {
683 engCalibFrac[kCalibFracHAD] += p.second.engTot;
684 } else if (pdg_id == 111 || pdg_id == 22 || std::abs(pdg_id) == 11) {
685 engCalibFrac[kCalibFracEM] += p.second.engTot;
686 } else {
687 engCalibFrac[kCalibFracREST] += p.second.engTot;
688 }
689 }
690 for (size_t i = 0; i < engCalibFrac.size(); i++) {
691 engCalibFrac[i] = engCalibFrac[i] / clusInfo.engCalibIn.engTot;
692 }
693 }
694 }
695
696 if ( !m_momentsNames.empty() ) {
697 std::vector<double> myMoments(m_validMoments.size(), 0);
698 // assign moments
699 moment_name_set::const_iterator vMomentsIter = m_validMoments.begin();
700 moment_name_set::const_iterator vMomentsIterEnd = m_validMoments.end();
701
702 int iMoment = 0;
703 for (; vMomentsIter != vMomentsIterEnd; ++vMomentsIter, ++iMoment) {
704 // now calculate the actual moments
705 switch (vMomentsIter->second) {
707 ATH_MSG_DEBUG("Inserting ENG_CALIB_TOT");
708 myMoments[iMoment] = clusInfo.engCalibIn.engTot;
709 break;
711 myMoments[iMoment] = engCalibOut[0][iClus];
712 break;
714 myMoments[iMoment] = engCalibOut[1][iClus];
715 break;
717 myMoments[iMoment] = engCalibOut[2][iClus];
718 break;
720 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB];
721 break;
723 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE];
724 break;
726 myMoments[iMoment] = clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
727 break;
729 myMoments[iMoment] = eng_calib_dead_tot;
730 break;
732 myMoments[iMoment] = eng_calib_dead_emb0;
733 break;
735 myMoments[iMoment] = eng_calib_dead_tile0;
736 break;
738 myMoments[iMoment] = eng_calib_dead_tileg3;
739 break;
741 myMoments[iMoment] = eng_calib_dead_eme0;
742 break;
744 myMoments[iMoment] = eng_calib_dead_hec0;
745 break;
747 myMoments[iMoment] = eng_calib_dead_fcal;
748 break;
750 myMoments[iMoment] = eng_calib_dead_leakage;
751 break;
753 myMoments[iMoment] = eng_calib_dead_unclass;
754 break;
756 myMoments[iMoment] = engCalibFrac[kCalibFracEM];
757 break;
759 myMoments[iMoment] = engCalibFrac[kCalibFracHAD];
760 break;
762 myMoments[iMoment] = engCalibFrac[kCalibFracREST];
763 break;
764 default:
765 // nothing to be done for other moments
766 break;
767 }
768
769 theCluster->insertMoment(vMomentsIter->second, myMoments[iMoment]);
770 }
771 }
772 }
773
774 return StatusCode::SUCCESS;
775}
776
777
778/* ****************************************************************************
779
780**************************************************************************** */
782{
783 double eta = fabs(x);
784 double ff;
785 if (eta < 1.6) {
786 ff = atan(5.0 * 1.7 / (200.0 * cosh(eta)));
787 } else if (eta < 3.2) {
788 ff = atan(5.0 * 1.6 / (420. / tanh(eta)));
789 } else {
790 ff = atan(5.0 * 0.95 / (505. / tanh(eta)));
791 }
792 return ff * (1. / atan(5.0 * 1.7 / 200.0));
793}
#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 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:
const ServiceHandle< StoreGateSvc > & detStore() const
MsgStream & msg() const
std::array< double, CaloDmDescrArea::DMA_MAX > engCalibDeadInArea
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.
Gaudi::Property< std::vector< std::string > > m_momentsNames
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
Gaudi::Property< std::vector< std::string > > m_momentsNamesAOD
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
Class to store calorimeter calibration hit.
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()
std::vector< short > m_CaloSampleNeighbours
std::vector< float > m_CaloSampleEtaMin
std::vector< float > m_CaloSampleEtaMax
const T * at(size_type n) const
Access an element, as an rvalue.
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.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
void insertMoment(MomentType type, double value)
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version).
virtual double phi() const
The azimuthal angle ( ) of the particle.
@ 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)
constexpr int UNDEFINED_ID
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.