Execute on an entire collection of clusters.
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;
342 for (const SG::ReadHandleKey<CaloCalibrationHitContainer>& key :
344 {
345 SG::ReadHandle<CaloCalibrationHitContainer> cchc (key, ctx);
346 if ( !cchc.isValid() ) {
348
349
350 msg(MSG::ERROR) <<
"SG does not contain calibration hit container "
352 }
353 foundAllContainers = false;
354 }
355 else {
356 v_cchc.push_back(cchc.cptr());
357 }
358 }
359
360 std::vector<const CaloCalibrationHitContainer *> v_dmcchc;
361 for (const SG::ReadHandleKey<CaloCalibrationHitContainer>& key :
363 {
364 SG::ReadHandle<CaloCalibrationHitContainer> cchc (key, ctx);
365 if ( !cchc.isValid() ) {
367
368
369 ATH_MSG_ERROR(
"SG does not contain DM calibration hit container "
371 }
372 foundAllContainers = false;
373 }
374 else {
375 v_dmcchc.push_back(cchc.cptr());
376 }
377 }
378
381 }
382
383 if ( !foundAllContainers ) {
384 return StatusCode::SUCCESS;
385 }
387
388
390
393
396
397
398
399
400 unsigned int nHitsTotal = 0;
401 unsigned int nHitsWithoutParticleUID = 0;
402
404 v_cchc,
405 cellInfo,
407 clusInfoVec,
408 nHitsTotal,
409 nHitsWithoutParticleUID,
411 [this]() {
412 ATH_MSG_ERROR(
"Invalid uniqueID detected - this sample cannot be properly analysed.");
413 });
414
415
416
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
425
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
438
439 std::array<ClusList, 3> clusLists;
442 }};
443 const std::array<bool, 3> doClusterLists{{
450 }};
451
452 for (unsigned int ii = 0; ii < 3; ++ii) {
453 if (doClusterLists[ii]) {
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
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 , double energy) {
490 engCalibOut[ii][iClus] +=
energy;
491 });
492 }
493
494
495
496
497
498
501 pClusList = &clusLists[0];
503 pClusList = &clusLists[1];
505 pClusList = &clusLists[2];
506 }
507
509
511 for (const CaloCalibrationHit* hit : *dmcchc) {
512 Identifier myId = hit->cellID();
514 CaloDmDescrElement* myCDDE(nullptr);
516 if ( myCDDE ) {
518 if (useParticleID) {
520 }
521
527 }
530 }
531
532
533
534
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
543 for (unsigned int i_cls = 0;
545 i_cls++) {
548
550 auto pos = clusInfo.engCalibParticle.find(uniqueID);
551 if (pos != clusInfo.engCalibParticle.end()) {
552 double engClusTruthUniqueIDCalib =
pos->second.engTot;
553
555 double sum_smp_energy = 0.0;
556
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
576
577 hitClusIndex[hitClusVecIndex] = iClus;
578 hitClusEffEnergy[hitClusVecIndex++] = effEner;
579 hitClusNorm += effEner;
580 }
581 }
582 }
583 }
584
585 hitClusIndex.resize(hitClusVecIndex);
586 hitClusEffEnergy.resize(hitClusVecIndex);
587
588
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;
601 }
602 }
603
604 }
605 }
606 }
607 }
608 }
609
610 }
611
612
613 std::vector<double> engCalibFrac;
615
616 std::map<unsigned int, int> truthIDToPdgCodeMap;
617
618
619 for ( const auto *thisTruthParticle : *truthParticleContainerReadHandle ) {
620
621 if (!thisTruthParticle) {
623 continue;
624 }
625
626 truthIDToPdgCodeMap[
HepMC::uniqueID(thisTruthParticle)] = thisTruthParticle->pdgId();
627 }
628
629
630 int iClus = 0;
631 for (clusIter = theClusColl->begin(), iClus = 0;
632 clusIter != clusIterEnd;
633 ++clusIter, ++iClus) {
636
637
639 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB]
640 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE]
641 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
642
645 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerB];
646
648
650 + clusInfo.engCalibIn.engSmp[CaloSampling::TileGap3];
651
654 + clusInfo.engCalibIn.engSmp[CaloSampling::PreSamplerE];
655
657
660
662
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
669
670
672 if (clusInfo.engCalibIn.engTot > 0.0) {
673
674 for (const auto& p : clusInfo.engCalibParticle) {
675 int pdg_id = 0;
676 if (
auto it = truthIDToPdgCodeMap.find(
p.first); it != truthIDToPdgCodeMap.end()) {
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) {
684 } else if (pdg_id == 111 || pdg_id == 22 || std::abs(pdg_id) == 11) {
686 } else {
688 }
689 }
690 for (
size_t i = 0;
i < engCalibFrac.size();
i++) {
691 engCalibFrac[
i] = engCalibFrac[
i] / clusInfo.engCalibIn.engTot;
692 }
693 }
694 }
695
698
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
705 switch (vMomentsIter->second) {
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;
757 break;
760 break;
763 break;
764 default:
765
766 break;
767 }
768
769 theCluster->
insertMoment(vMomentsIter->second, myMoments[iMoment]);
770 }
771 }
772 }
773
774 return StatusCode::SUCCESS;
775}
#define ATH_MSG_WARNING(x)
std::array< double, CaloDmDescrArea::DMA_MAX > engCalibDeadInArea
std::vector< MyClusInfo > ClusInfo_t
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_DMCalibrationHitContainerNames
Gaudi::Property< bool > m_useParticleID
moment_name_set m_validMoments
Gaudi::Property< std::vector< std::string > > m_momentsNames
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_CalibrationHitContainerNames
const CaloCell_ID * m_calo_id
bool m_doDeadEnergySharing
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
std::atomic< bool > m_foundAllContainers
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
Gaudi::Property< int > m_MatchDmType
const CaloDmDescrManager * m_caloDmDescrManager
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::vector< short > m_CaloSampleNeighbours
std::vector< float > m_CaloSampleEtaMin
std::vector< float > m_CaloSampleEtaMax
DataModel_detail::iterator< DataVector > iterator
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)
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.
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space