File indexing completed on 2025-08-05 08:17:54
0001
0002 #include "CaloRawTowerEval.h"
0003 #include "CaloTruthEval.h"
0004
0005 #include <calobase/RawTower.h>
0006 #include <calobase/RawTowerContainer.h>
0007 #include <calobase/TowerInfo.h>
0008 #include <calobase/TowerInfoContainer.h>
0009
0010 #include <g4detectors/PHG4Cell.h>
0011 #include <g4detectors/PHG4CellContainer.h>
0012
0013 #include <g4main/PHG4HitContainer.h>
0014 #include <g4main/PHG4Shower.h>
0015 #include <g4main/PHG4TruthInfoContainer.h>
0016
0017 #include <phool/getClass.h>
0018
0019 #include <cassert>
0020 #include <cfloat>
0021 #include <cmath>
0022 #include <iostream>
0023 #include <map>
0024 #include <set>
0025 #include <string>
0026
0027 class PHG4Hit;
0028
0029 CaloRawTowerEval::CaloRawTowerEval(PHCompositeNode* topNode, const std::string& caloname)
0030 : _caloname(caloname)
0031 , _trutheval(topNode, caloname)
0032 {
0033 get_node_pointers(topNode);
0034 }
0035
0036 CaloRawTowerEval::~CaloRawTowerEval()
0037 {
0038 if (_verbosity > 0)
0039 {
0040 if ((_errors > 0) || (_verbosity > 1))
0041 {
0042 std::cout << "CaloRawTowerEval::~CaloRawTowerEval() - Error Count: " << _errors << std::endl;
0043 }
0044 }
0045 }
0046
0047 void CaloRawTowerEval::next_event(PHCompositeNode* topNode)
0048 {
0049 _cache_all_truth_primary_showers.clear();
0050 _cache_max_truth_primary_shower_by_energy.clear();
0051 _cache_all_towers_from_primary_shower.clear();
0052 _cache_best_tower_from_primary_shower.clear();
0053 _cache_get_energy_contribution_primary_shower.clear();
0054
0055 _cache_all_truth_primary_particles.clear();
0056 _cache_max_truth_primary_particle_by_energy.clear();
0057 _cache_all_towers_from_primary_particle.clear();
0058 _cache_best_tower_from_primary_particle.clear();
0059 _cache_get_energy_contribution_primary_particle.clear();
0060
0061 _cache_all_truth_hits.clear();
0062
0063 _cache_towerinfo_all_truth_primary_showers.clear();
0064 _cache_towerinfo_max_truth_primary_shower_by_energy.clear();
0065 _cache_towerinfo_all_towers_from_primary_shower.clear();
0066 _cache_towerinfo_best_tower_from_primary_shower.clear();
0067 _cache_towerinfo_get_energy_contribution_primary_shower.clear();
0068
0069 _cache_towerinfo_all_truth_primary_particles.clear();
0070 _cache_towerinfo_max_truth_primary_particle_by_energy.clear();
0071 _cache_towerinfo_all_towers_from_primary_particle.clear();
0072 _cache_towerinfo_best_tower_from_primary_particle.clear();
0073 _cache_towerinfo_get_energy_contribution_primary_particle.clear();
0074
0075 _cache_towerinfo_all_truth_hits.clear();
0076
0077 _trutheval.next_event(topNode);
0078
0079 get_node_pointers(topNode);
0080 }
0081
0082 bool CaloRawTowerEval::has_reduced_node_pointers()
0083 {
0084 if (!get_truth_eval()->has_reduced_node_pointers())
0085 {
0086 return false;
0087 }
0088
0089 if (_strict)
0090 {
0091 assert(_towers || _towerinfos);
0092 }
0093 else if (!_towers && !_towerinfos)
0094 {
0095 return false;
0096 }
0097
0098 if (_strict)
0099 {
0100 assert(_truthinfo);
0101 }
0102 else if (!_truthinfo)
0103 {
0104 return false;
0105 }
0106
0107 return true;
0108 }
0109
0110 std::set<PHG4Shower*> CaloRawTowerEval::all_truth_primary_showers(RawTower* tower)
0111 {
0112 if (!has_reduced_node_pointers())
0113 {
0114 ++_errors;
0115 return std::set<PHG4Shower*>();
0116 }
0117
0118 if (_strict)
0119 {
0120 assert(tower);
0121 }
0122 else if (!tower)
0123 {
0124 ++_errors;
0125 return std::set<PHG4Shower*>();
0126 }
0127
0128 if (_do_cache)
0129 {
0130 std::map<RawTower*, std::set<PHG4Shower*> >::iterator iter =
0131 _cache_all_truth_primary_showers.find(tower);
0132 if (iter != _cache_all_truth_primary_showers.end())
0133 {
0134 return iter->second;
0135 }
0136 }
0137
0138 std::set<PHG4Shower*> showers;
0139
0140 RawTower::ShowerConstRange shower_range = tower->get_g4showers();
0141 for (RawTower::ShowerConstIterator iter = shower_range.first;
0142 iter != shower_range.second;
0143 ++iter)
0144 {
0145 PHG4Shower* shower = _truthinfo->GetShower(iter->first);
0146
0147 if (_strict)
0148 {
0149 assert(shower);
0150 }
0151 else if (!shower)
0152 {
0153 ++_errors;
0154 continue;
0155 }
0156
0157 showers.insert(shower);
0158 }
0159
0160 if (_do_cache)
0161 {
0162 _cache_all_truth_primary_showers.insert(std::make_pair(tower, showers));
0163 }
0164
0165 return showers;
0166 }
0167
0168 std::set<PHG4Shower*> CaloRawTowerEval::all_truth_primary_showers(TowerInfo* tower)
0169 {
0170 if (!has_reduced_node_pointers())
0171 {
0172 ++_errors;
0173 return std::set<PHG4Shower*>();
0174 }
0175
0176 if (_strict)
0177 {
0178 assert(tower);
0179 }
0180 else if (!tower)
0181 {
0182 ++_errors;
0183 return std::set<PHG4Shower*>();
0184 }
0185
0186 if (_do_cache)
0187 {
0188 if (auto iter = _cache_towerinfo_all_truth_primary_showers.find(tower); iter != _cache_towerinfo_all_truth_primary_showers.end())
0189 {
0190 return iter->second;
0191 }
0192 }
0193
0194 std::set<PHG4Shower*> showers;
0195
0196 const TowerInfo::ShowerEdepMap& showerEdepMap = tower->get_showerEdepMap();
0197
0198 for (const auto& [showerID, edep] : showerEdepMap)
0199 {
0200 PHG4Shower* shower = _truthinfo->GetShower(showerID);
0201
0202
0203 if (_strict)
0204 {
0205 assert(shower);
0206 }
0207 else if (!shower)
0208 {
0209 ++_errors;
0210 continue;
0211 }
0212
0213
0214 showers.insert(shower);
0215 }
0216
0217 if (_do_cache)
0218 {
0219 _cache_towerinfo_all_truth_primary_showers.insert(std::make_pair(tower, showers));
0220 }
0221
0222 return showers;
0223 }
0224
0225 PHG4Shower* CaloRawTowerEval::max_truth_primary_shower_by_energy(RawTower* tower)
0226 {
0227 if (!has_reduced_node_pointers())
0228 {
0229 ++_errors;
0230 return nullptr;
0231 }
0232
0233 if (_strict)
0234 {
0235 assert(tower);
0236 }
0237 else if (!tower)
0238 {
0239 ++_errors;
0240 return nullptr;
0241 }
0242
0243 if (_do_cache)
0244 {
0245 std::map<RawTower*, PHG4Shower*>::iterator iter =
0246 _cache_max_truth_primary_shower_by_energy.find(tower);
0247 if (iter != _cache_max_truth_primary_shower_by_energy.end())
0248 {
0249 return iter->second;
0250 }
0251 }
0252
0253 PHG4Shower* max_shower = nullptr;
0254 float max_e = FLT_MAX * -1.0;
0255 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0256
0257 for (auto shower : showers)
0258 {
0259 if (_strict)
0260 {
0261 assert(shower);
0262 }
0263 else if (!shower)
0264 {
0265 ++_errors;
0266 continue;
0267 }
0268
0269 float e = get_energy_contribution(tower, shower);
0270 if (std::isnan(e))
0271 {
0272 continue;
0273 }
0274 if (e > max_e)
0275 {
0276 max_e = e;
0277 max_shower = shower;
0278 }
0279 }
0280
0281 if (_do_cache)
0282 {
0283 _cache_max_truth_primary_shower_by_energy.insert(std::make_pair(tower, max_shower));
0284 }
0285
0286 return max_shower;
0287 }
0288
0289 PHG4Shower* CaloRawTowerEval::max_truth_primary_shower_by_energy(TowerInfo* tower)
0290 {
0291 if (!has_reduced_node_pointers())
0292 {
0293 ++_errors;
0294 return nullptr;
0295 }
0296
0297 if (_strict)
0298 {
0299 assert(tower);
0300 }
0301 else if (!tower)
0302 {
0303 ++_errors;
0304 return nullptr;
0305 }
0306 if (_do_cache)
0307 {
0308 if (auto iter = _cache_towerinfo_max_truth_primary_shower_by_energy.find(tower); iter != _cache_towerinfo_max_truth_primary_shower_by_energy.end())
0309 {
0310 return iter->second;
0311 }
0312 }
0313
0314 PHG4Shower* max_shower = nullptr;
0315 float max_e = FLT_MAX * -1.0;
0316 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0317
0318 for (auto shower : showers)
0319 {
0320 if (_strict)
0321 {
0322 assert(shower);
0323 }
0324 else if (!shower)
0325 {
0326 ++_errors;
0327 continue;
0328 }
0329
0330 float e = get_energy_contribution(tower, shower);
0331 if (std::isnan(e))
0332 {
0333 continue;
0334 }
0335 if (e > max_e)
0336 {
0337 max_e = e;
0338 max_shower = shower;
0339 }
0340 }
0341
0342 if (_do_cache)
0343 {
0344 _cache_towerinfo_max_truth_primary_shower_by_energy.insert(std::make_pair(tower, max_shower));
0345 }
0346
0347 return max_shower;
0348 }
0349
0350 RawTower* CaloRawTowerEval::best_tower_from(PHG4Shower* shower)
0351 {
0352 if (!has_reduced_node_pointers())
0353 {
0354 ++_errors;
0355 return nullptr;
0356 }
0357
0358 if (_strict)
0359 {
0360 assert(shower);
0361 }
0362 else if (!shower)
0363 {
0364 ++_errors;
0365 return nullptr;
0366 }
0367
0368 if (!_trutheval.is_primary(shower))
0369 {
0370 return nullptr;
0371 }
0372
0373 if (_do_cache)
0374 {
0375 std::map<PHG4Shower*, RawTower*>::iterator iter =
0376 _cache_best_tower_from_primary_shower.find(shower);
0377 if (iter != _cache_best_tower_from_primary_shower.end())
0378 {
0379 return iter->second;
0380 }
0381 }
0382
0383 RawTower* best_tower = nullptr;
0384 float best_energy = FLT_MAX * -1.0;
0385 std::set<RawTower*> towers = all_towers_from(shower);
0386 for (auto tower : towers)
0387 {
0388 if (_strict)
0389 {
0390 assert(tower);
0391 }
0392 else if (!tower)
0393 {
0394 ++_errors;
0395 continue;
0396 }
0397
0398 float energy = get_energy_contribution(tower, shower);
0399 if (std::isnan(energy))
0400 {
0401 continue;
0402 }
0403 if (energy > best_energy)
0404 {
0405 best_tower = tower;
0406 best_energy = energy;
0407 }
0408 }
0409
0410 if (_do_cache)
0411 {
0412 _cache_best_tower_from_primary_shower.insert(std::make_pair(shower, best_tower));
0413 }
0414
0415 return best_tower;
0416 }
0417
0418 TowerInfo* CaloRawTowerEval::best_towerinfo_from(PHG4Shower* shower)
0419 {
0420 if (!has_reduced_node_pointers())
0421 {
0422 ++_errors;
0423 return nullptr;
0424 }
0425
0426 if (_strict)
0427 {
0428 assert(shower);
0429 }
0430 else if (!shower)
0431 {
0432 ++_errors;
0433 return nullptr;
0434 }
0435
0436 if (!_trutheval.is_primary(shower))
0437 {
0438 return nullptr;
0439 }
0440
0441 if (_do_cache)
0442 {
0443 if (auto iter = _cache_towerinfo_best_tower_from_primary_shower.find(shower); iter != _cache_towerinfo_best_tower_from_primary_shower.end())
0444 {
0445 return iter->second;
0446 }
0447 }
0448
0449 TowerInfo* best_tower = nullptr;
0450 float best_energy = FLT_MAX * -1.0;
0451 std::set<TowerInfo*> towers = all_towerinfos_from(shower);
0452 for (auto tower : towers)
0453 {
0454 if (_strict)
0455 {
0456 assert(tower);
0457 }
0458 else if (!tower)
0459 {
0460 ++_errors;
0461 continue;
0462 }
0463
0464 float energy = get_energy_contribution(tower, shower);
0465 if (std::isnan(energy))
0466 {
0467 continue;
0468 }
0469 if (energy > best_energy)
0470 {
0471 best_tower = tower;
0472 best_energy = energy;
0473 }
0474 }
0475
0476 if (_do_cache)
0477 {
0478 _cache_towerinfo_best_tower_from_primary_shower.insert(std::make_pair(shower, best_tower));
0479 }
0480
0481 return best_tower;
0482 }
0483
0484 std::set<RawTower*> CaloRawTowerEval::all_towers_from(PHG4Shower* shower)
0485 {
0486 if (!has_reduced_node_pointers())
0487 {
0488 ++_errors;
0489 return std::set<RawTower*>();
0490 }
0491
0492 if (_strict)
0493 {
0494 assert(shower);
0495 }
0496 else if (!shower)
0497 {
0498 ++_errors;
0499 return std::set<RawTower*>();
0500 }
0501
0502 if (!_trutheval.is_primary(shower))
0503 {
0504 return std::set<RawTower*>();
0505 }
0506
0507 if (_do_cache)
0508 {
0509 std::map<PHG4Shower*, std::set<RawTower*> >::iterator iter =
0510 _cache_all_towers_from_primary_shower.find(shower);
0511 if (iter != _cache_all_towers_from_primary_shower.end())
0512 {
0513 return iter->second;
0514 }
0515 }
0516
0517 std::set<RawTower*> towers;
0518
0519
0520 for (RawTowerContainer::Iterator iter = _towers->getTowers().first;
0521 iter != _towers->getTowers().second;
0522 ++iter)
0523 {
0524 RawTower* tower = iter->second;
0525
0526 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0527 for (auto candidate : showers)
0528 {
0529 if (_strict)
0530 {
0531 assert(candidate);
0532 }
0533 else if (!candidate)
0534 {
0535 ++_errors;
0536 continue;
0537 }
0538
0539 if (candidate->get_id() == shower->get_id())
0540 {
0541 towers.insert(tower);
0542 }
0543 }
0544 }
0545
0546 if (_do_cache)
0547 {
0548 _cache_all_towers_from_primary_shower.insert(std::make_pair(shower, towers));
0549 }
0550
0551 return towers;
0552 }
0553
0554 std::set<TowerInfo*> CaloRawTowerEval::all_towerinfos_from(PHG4Shower* shower)
0555 {
0556 if (!has_reduced_node_pointers())
0557 {
0558 ++_errors;
0559 return std::set<TowerInfo*>();
0560 }
0561
0562 if (_strict)
0563 {
0564 assert(shower);
0565 }
0566 else if (!shower)
0567 {
0568 ++_errors;
0569 return std::set<TowerInfo*>();
0570 }
0571
0572 if (!_trutheval.is_primary(shower))
0573 {
0574 return std::set<TowerInfo*>();
0575 }
0576
0577 if (_do_cache)
0578 {
0579 if (auto iter = _cache_towerinfo_all_towers_from_primary_shower.find(shower); iter != _cache_towerinfo_all_towers_from_primary_shower.end())
0580 {
0581 return iter->second;
0582 }
0583 }
0584
0585 std::set<TowerInfo*> towers;
0586
0587
0588 unsigned int ntowers = _towerinfos->size();
0589 for (unsigned int channel = 0; channel < ntowers; channel++)
0590 {
0591 TowerInfo* tower = _towerinfos->get_tower_at_channel(channel);
0592
0593 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0594 for (auto candidate : showers)
0595 {
0596 if (_strict)
0597 {
0598 assert(candidate);
0599 }
0600 else if (!candidate)
0601 {
0602 ++_errors;
0603 continue;
0604 }
0605
0606 if (candidate->get_id() == shower->get_id())
0607 {
0608 towers.insert(tower);
0609 }
0610 }
0611 }
0612
0613 if (_do_cache)
0614 {
0615 _cache_towerinfo_all_towers_from_primary_shower.insert(std::make_pair(shower, towers));
0616 }
0617
0618 return towers;
0619 }
0620
0621 float CaloRawTowerEval::get_energy_contribution(RawTower* tower, PHG4Shower* shower)
0622 {
0623 if (!has_reduced_node_pointers())
0624 {
0625 ++_errors;
0626 return NAN;
0627 }
0628
0629 if (_strict)
0630 {
0631 assert(tower);
0632 assert(shower);
0633 }
0634 else if (!tower || !shower)
0635 {
0636 ++_errors;
0637 return NAN;
0638 }
0639
0640 if (!_trutheval.is_primary(shower))
0641 {
0642 return NAN;
0643 }
0644
0645 if (_do_cache)
0646 {
0647 std::map<std::pair<RawTower*, PHG4Shower*>, float>::iterator iter =
0648 _cache_get_energy_contribution_primary_shower.find(std::make_pair(tower, shower));
0649 if (iter != _cache_get_energy_contribution_primary_shower.end())
0650 {
0651 return iter->second;
0652 }
0653 }
0654
0655
0656 float energy = 0.0;
0657 RawTower::ShowerConstRange range = tower->get_g4showers();
0658 RawTower::ShowerConstIterator iter = tower->find_g4shower(shower->get_id());
0659 if (iter != range.second)
0660 {
0661 energy = iter->second;
0662 }
0663
0664 if (_do_cache)
0665 {
0666 _cache_get_energy_contribution_primary_shower.insert(std::make_pair(std::make_pair(tower, shower), energy));
0667 }
0668
0669 return energy;
0670 }
0671
0672 float CaloRawTowerEval::get_energy_contribution(TowerInfo* tower, PHG4Shower* shower)
0673 {
0674 if (!has_reduced_node_pointers())
0675 {
0676 ++_errors;
0677 return NAN;
0678 }
0679
0680 if (_strict)
0681 {
0682 assert(tower);
0683 assert(shower);
0684 }
0685 else if (!tower || !shower)
0686 {
0687 ++_errors;
0688 return NAN;
0689 }
0690
0691 if (!_trutheval.is_primary(shower))
0692 {
0693 return NAN;
0694 }
0695
0696 if (_do_cache)
0697 {
0698 if (auto iter = _cache_towerinfo_get_energy_contribution_primary_shower.find(std::make_pair(tower, shower)); iter != _cache_towerinfo_get_energy_contribution_primary_shower.end())
0699 {
0700 return iter->second;
0701 }
0702 }
0703
0704
0705 float energy = 0.0;
0706
0707 const TowerInfo::ShowerEdepMap& showerEdepMap = tower->get_showerEdepMap();
0708 auto showerIter = showerEdepMap.find(shower->get_id());
0709 if (showerIter != showerEdepMap.end())
0710 {
0711 energy = showerIter->second;
0712 }
0713
0714 if (_do_cache)
0715 {
0716 _cache_towerinfo_get_energy_contribution_primary_shower.insert(std::make_pair(std::make_pair(tower, shower), energy));
0717 }
0718
0719 return energy;
0720 }
0721
0722 std::set<PHG4Particle*> CaloRawTowerEval::all_truth_primary_particles(RawTower* tower)
0723 {
0724 if (!has_reduced_node_pointers())
0725 {
0726 ++_errors;
0727 return std::set<PHG4Particle*>();
0728 }
0729
0730 if (_strict)
0731 {
0732 assert(tower);
0733 }
0734 else if (!tower)
0735 {
0736 ++_errors;
0737 return std::set<PHG4Particle*>();
0738 }
0739
0740 if (_do_cache)
0741 {
0742 std::map<RawTower*, std::set<PHG4Particle*> >::iterator iter =
0743 _cache_all_truth_primary_particles.find(tower);
0744 if (iter != _cache_all_truth_primary_particles.end())
0745 {
0746 return iter->second;
0747 }
0748 }
0749
0750 std::set<PHG4Particle*> truth_primaries;
0751
0752 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0753
0754 for (auto shower : showers)
0755 {
0756 PHG4Particle* primary = get_truth_eval()->get_primary_particle(shower);
0757
0758 if (_strict)
0759 {
0760 assert(primary);
0761 }
0762 else if (!primary)
0763 {
0764 ++_errors;
0765 continue;
0766 }
0767
0768 truth_primaries.insert(primary);
0769 }
0770
0771 if (_do_cache)
0772 {
0773 _cache_all_truth_primary_particles.insert(std::make_pair(tower, truth_primaries));
0774 }
0775
0776 return truth_primaries;
0777 }
0778
0779 std::set<PHG4Particle*> CaloRawTowerEval::all_truth_primary_particles(TowerInfo* tower)
0780 {
0781 if (!has_reduced_node_pointers())
0782 {
0783 ++_errors;
0784 return std::set<PHG4Particle*>();
0785 }
0786
0787 if (_strict)
0788 {
0789 assert(tower);
0790 }
0791 else if (!tower)
0792 {
0793 ++_errors;
0794 return std::set<PHG4Particle*>();
0795 }
0796
0797 if (_do_cache)
0798 {
0799 if (auto iter = _cache_towerinfo_all_truth_primary_particles.find(tower); iter != _cache_towerinfo_all_truth_primary_particles.end())
0800 {
0801 return iter->second;
0802 }
0803 }
0804
0805 std::set<PHG4Particle*> truth_primaries;
0806
0807 std::set<PHG4Shower*> showers = all_truth_primary_showers(tower);
0808
0809 for (auto shower : showers)
0810 {
0811 PHG4Particle* primary = get_truth_eval()->get_primary_particle(shower);
0812
0813 if (_strict)
0814 {
0815 assert(primary);
0816 }
0817 else if (!primary)
0818 {
0819 ++_errors;
0820 continue;
0821 }
0822
0823 truth_primaries.insert(primary);
0824 }
0825
0826 if (_do_cache)
0827 {
0828 _cache_towerinfo_all_truth_primary_particles.insert(std::make_pair(tower, truth_primaries));
0829 }
0830
0831 return truth_primaries;
0832 }
0833
0834 PHG4Particle* CaloRawTowerEval::max_truth_primary_particle_by_energy(RawTower* tower)
0835 {
0836 if (!has_reduced_node_pointers())
0837 {
0838 ++_errors;
0839 return nullptr;
0840 }
0841
0842 if (_strict)
0843 {
0844 assert(tower);
0845 }
0846 else if (!tower)
0847 {
0848 ++_errors;
0849 return nullptr;
0850 }
0851
0852 if (_do_cache)
0853 {
0854 std::map<RawTower*, PHG4Particle*>::iterator iter =
0855 _cache_max_truth_primary_particle_by_energy.find(tower);
0856 if (iter != _cache_max_truth_primary_particle_by_energy.end())
0857 {
0858 return iter->second;
0859 }
0860 }
0861
0862 PHG4Particle* max_primary = nullptr;
0863 PHG4Shower* max_shower = max_truth_primary_shower_by_energy(tower);
0864
0865 if (max_shower)
0866 {
0867 max_primary = get_truth_eval()->get_primary_particle(max_shower);
0868 }
0869
0870 if (_do_cache)
0871 {
0872 _cache_max_truth_primary_particle_by_energy.insert(std::make_pair(tower, max_primary));
0873 }
0874
0875 return max_primary;
0876 }
0877
0878 PHG4Particle* CaloRawTowerEval::max_truth_primary_particle_by_energy(TowerInfo* tower)
0879 {
0880 if (!has_reduced_node_pointers())
0881 {
0882 ++_errors;
0883 return nullptr;
0884 }
0885
0886 if (_strict)
0887 {
0888 assert(tower);
0889 }
0890 else if (!tower)
0891 {
0892 ++_errors;
0893 return nullptr;
0894 }
0895
0896 if (_do_cache)
0897 {
0898 if (auto iter = _cache_towerinfo_max_truth_primary_particle_by_energy.find(tower); iter != _cache_towerinfo_max_truth_primary_particle_by_energy.end())
0899 {
0900 return iter->second;
0901 }
0902 }
0903
0904 PHG4Particle* max_primary = nullptr;
0905 PHG4Shower* max_shower = max_truth_primary_shower_by_energy(tower);
0906
0907 if (max_shower)
0908 {
0909 max_primary = get_truth_eval()->get_primary_particle(max_shower);
0910 }
0911
0912 if (_do_cache)
0913 {
0914 _cache_towerinfo_max_truth_primary_particle_by_energy.insert(std::make_pair(tower, max_primary));
0915 }
0916
0917 return max_primary;
0918 }
0919
0920 std::set<RawTower*> CaloRawTowerEval::all_towers_from(PHG4Particle* primary)
0921 {
0922 if (!has_reduced_node_pointers())
0923 {
0924 ++_errors;
0925 return std::set<RawTower*>();
0926 }
0927
0928 if (_strict)
0929 {
0930 assert(primary);
0931 }
0932 else if (!primary)
0933 {
0934 ++_errors;
0935 return std::set<RawTower*>();
0936 }
0937
0938 if (!_trutheval.is_primary(primary))
0939 {
0940 return std::set<RawTower*>();
0941 }
0942
0943
0944 primary = get_truth_eval()->get_primary_particle(primary);
0945
0946 if (_strict)
0947 {
0948 assert(primary);
0949 }
0950 else if (!primary)
0951 {
0952 ++_errors;
0953 return std::set<RawTower*>();
0954 }
0955
0956 if (_do_cache)
0957 {
0958 std::map<PHG4Particle*, std::set<RawTower*> >::iterator iter =
0959 _cache_all_towers_from_primary_particle.find(primary);
0960 if (iter != _cache_all_towers_from_primary_particle.end())
0961 {
0962 return iter->second;
0963 }
0964 }
0965
0966 std::set<RawTower*> towers;
0967
0968 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
0969
0970 if (shower)
0971 {
0972 towers = all_towers_from(shower);
0973 }
0974
0975 if (_do_cache)
0976 {
0977 _cache_all_towers_from_primary_particle.insert(std::make_pair(primary, towers));
0978 }
0979
0980 return towers;
0981 }
0982
0983 std::set<TowerInfo*> CaloRawTowerEval::all_towerinfos_from(PHG4Particle* primary)
0984 {
0985 if (!has_reduced_node_pointers())
0986 {
0987 ++_errors;
0988 return std::set<TowerInfo*>();
0989 }
0990
0991 if (_strict)
0992 {
0993 assert(primary);
0994 }
0995 else if (!primary)
0996 {
0997 ++_errors;
0998 return std::set<TowerInfo*>();
0999 }
1000
1001 if (!_trutheval.is_primary(primary))
1002 {
1003 return std::set<TowerInfo*>();
1004 }
1005
1006
1007 primary = get_truth_eval()->get_primary_particle(primary);
1008
1009 if (_strict)
1010 {
1011 assert(primary);
1012 }
1013 else if (!primary)
1014 {
1015 ++_errors;
1016 return std::set<TowerInfo*>();
1017 }
1018
1019 if (_do_cache)
1020 {
1021 if (auto iter = _cache_towerinfo_all_towers_from_primary_particle.find(primary); iter != _cache_towerinfo_all_towers_from_primary_particle.end())
1022 {
1023 return iter->second;
1024 }
1025 }
1026
1027 std::set<TowerInfo*> towers;
1028
1029 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
1030
1031 if (shower)
1032 {
1033 towers = all_towerinfos_from(shower);
1034 }
1035
1036 if (_do_cache)
1037 {
1038 _cache_towerinfo_all_towers_from_primary_particle.insert(std::make_pair(primary, towers));
1039 }
1040
1041 return towers;
1042 }
1043
1044 RawTower* CaloRawTowerEval::best_tower_from(PHG4Particle* primary)
1045 {
1046 if (!has_reduced_node_pointers())
1047 {
1048 ++_errors;
1049 return nullptr;
1050 }
1051
1052 if (_strict)
1053 {
1054 assert(primary);
1055 }
1056 else if (!primary)
1057 {
1058 ++_errors;
1059 return nullptr;
1060 }
1061
1062 if (!_trutheval.is_primary(primary))
1063 {
1064 return nullptr;
1065 }
1066
1067 primary = get_truth_eval()->get_primary_particle(primary);
1068
1069 if (_strict)
1070 {
1071 assert(primary);
1072 }
1073 else if (!primary)
1074 {
1075 ++_errors;
1076 return nullptr;
1077 }
1078
1079 if (_do_cache)
1080 {
1081 std::map<PHG4Particle*, RawTower*>::iterator iter =
1082 _cache_best_tower_from_primary_particle.find(primary);
1083 if (iter != _cache_best_tower_from_primary_particle.end())
1084 {
1085 return iter->second;
1086 }
1087 }
1088
1089 RawTower* best_tower = nullptr;
1090 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
1091 if (shower)
1092 {
1093 best_tower = best_tower_from(shower);
1094 }
1095
1096 if (_do_cache)
1097 {
1098 _cache_best_tower_from_primary_particle.insert(std::make_pair(primary, best_tower));
1099 }
1100
1101 return best_tower;
1102 }
1103
1104 TowerInfo* CaloRawTowerEval::best_towerinfo_from(PHG4Particle* primary)
1105 {
1106 if (!has_reduced_node_pointers())
1107 {
1108 ++_errors;
1109 return nullptr;
1110 }
1111
1112 if (_strict)
1113 {
1114 assert(primary);
1115 }
1116 else if (!primary)
1117 {
1118 ++_errors;
1119 return nullptr;
1120 }
1121
1122 if (!_trutheval.is_primary(primary))
1123 {
1124 return nullptr;
1125 }
1126
1127 primary = get_truth_eval()->get_primary_particle(primary);
1128
1129 if (_strict)
1130 {
1131 assert(primary);
1132 }
1133 else if (!primary)
1134 {
1135 ++_errors;
1136 return nullptr;
1137 }
1138
1139 if (_do_cache)
1140 {
1141 if (auto iter = _cache_towerinfo_best_tower_from_primary_particle.find(primary); iter != _cache_towerinfo_best_tower_from_primary_particle.end())
1142 {
1143 return iter->second;
1144 }
1145 }
1146
1147 TowerInfo* best_tower = nullptr;
1148 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
1149 if (shower)
1150 {
1151 best_tower = best_towerinfo_from(shower);
1152 }
1153
1154 if (_do_cache)
1155 {
1156 _cache_towerinfo_best_tower_from_primary_particle.insert(std::make_pair(primary, best_tower));
1157 }
1158
1159 return best_tower;
1160 }
1161
1162
1163 float CaloRawTowerEval::get_energy_contribution(RawTower* tower, PHG4Particle* primary)
1164 {
1165 if (!has_reduced_node_pointers())
1166 {
1167 ++_errors;
1168 return NAN;
1169 }
1170
1171 if (_strict)
1172 {
1173 assert(tower);
1174 assert(primary);
1175 }
1176 else if (!tower || !primary)
1177 {
1178 ++_errors;
1179 return NAN;
1180 }
1181
1182 if (!_trutheval.is_primary(primary))
1183 {
1184 return NAN;
1185 }
1186
1187
1188 primary = get_truth_eval()->get_primary_particle(primary);
1189
1190 if (_strict)
1191 {
1192 assert(primary);
1193 }
1194 else if (!primary)
1195 {
1196 ++_errors;
1197 return NAN;
1198 }
1199
1200 if (_do_cache)
1201 {
1202 std::map<std::pair<RawTower*, PHG4Particle*>, float>::iterator iter =
1203 _cache_get_energy_contribution_primary_particle.find(std::make_pair(tower, primary));
1204 if (iter != _cache_get_energy_contribution_primary_particle.end())
1205 {
1206 return iter->second;
1207 }
1208 }
1209
1210 float energy = 0.0;
1211
1212 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
1213
1214 if (shower)
1215 {
1216 energy = get_energy_contribution(tower, shower);
1217 }
1218
1219 if (_do_cache)
1220 {
1221 _cache_get_energy_contribution_primary_particle.insert(std::make_pair(std::make_pair(tower, primary), energy));
1222 }
1223
1224 return energy;
1225 }
1226
1227 float CaloRawTowerEval::get_energy_contribution(TowerInfo* tower, PHG4Particle* primary)
1228 {
1229 if (!has_reduced_node_pointers())
1230 {
1231 ++_errors;
1232 return NAN;
1233 }
1234
1235 if (_strict)
1236 {
1237 assert(tower);
1238 assert(primary);
1239 }
1240 else if (!tower || !primary)
1241 {
1242 ++_errors;
1243 return NAN;
1244 }
1245
1246 if (!_trutheval.is_primary(primary))
1247 {
1248 return NAN;
1249 }
1250
1251
1252 primary = get_truth_eval()->get_primary_particle(primary);
1253
1254 if (_strict)
1255 {
1256 assert(primary);
1257 }
1258 else if (!primary)
1259 {
1260 ++_errors;
1261 return NAN;
1262 }
1263
1264 if (_do_cache)
1265 {
1266 if (auto iter = _cache_towerinfo_get_energy_contribution_primary_particle.find(std::make_pair(tower, primary)); iter != _cache_towerinfo_get_energy_contribution_primary_particle.end())
1267 {
1268 return iter->second;
1269 }
1270 }
1271
1272 float energy = 0.0;
1273
1274 PHG4Shower* shower = get_truth_eval()->get_primary_shower(primary);
1275
1276 if (shower)
1277 {
1278 energy = get_energy_contribution(tower, shower);
1279 }
1280
1281 if (_do_cache)
1282 {
1283 _cache_towerinfo_get_energy_contribution_primary_particle.insert(std::make_pair(std::make_pair(tower, primary), energy));
1284 }
1285
1286 return energy;
1287 }
1288
1289 bool CaloRawTowerEval::has_full_node_pointers()
1290 {
1291 if (!get_truth_eval()->has_full_node_pointers())
1292 {
1293 return false;
1294 }
1295
1296 if (_strict)
1297 {
1298 assert(_towers || _towerinfos);
1299 }
1300 else if (!_towers && !_towerinfos)
1301 {
1302 return false;
1303 }
1304
1305 if (_strict)
1306 {
1307 assert(_g4cells);
1308 }
1309 else if (!_g4cells)
1310 {
1311 return false;
1312 }
1313
1314 if (_strict)
1315 {
1316 assert(_g4hits);
1317 }
1318 else if (!_g4hits)
1319 {
1320 return false;
1321 }
1322
1323 if (_strict)
1324 {
1325 assert(_truthinfo);
1326 }
1327 else if (!_truthinfo)
1328 {
1329 return false;
1330 }
1331
1332 return true;
1333 }
1334
1335 std::set<PHG4Hit*> CaloRawTowerEval::all_truth_hits(RawTower* tower)
1336 {
1337 if (!has_full_node_pointers())
1338 {
1339 ++_errors;
1340 return std::set<PHG4Hit*>();
1341 }
1342
1343 if (_strict)
1344 {
1345 assert(tower);
1346 }
1347 else if (!tower)
1348 {
1349 ++_errors;
1350 return std::set<PHG4Hit*>();
1351 }
1352
1353 if (_do_cache)
1354 {
1355 std::map<RawTower*, std::set<PHG4Hit*> >::iterator iter =
1356 _cache_all_truth_hits.find(tower);
1357 if (iter != _cache_all_truth_hits.end())
1358 {
1359 return iter->second;
1360 }
1361 }
1362
1363 std::set<PHG4Hit*> truth_hits;
1364
1365 RawTower::CellConstRange cell_range = tower->get_g4cells();
1366 for (RawTower::CellConstIterator cell_iter = cell_range.first;
1367 cell_iter != cell_range.second; ++cell_iter)
1368 {
1369 unsigned int cell_id = cell_iter->first;
1370 PHG4Cell* cell = _g4cells->findCell(cell_id);
1371
1372 if (_strict)
1373 {
1374 assert(cell);
1375 }
1376 else if (!cell)
1377 {
1378 ++_errors;
1379 continue;
1380 }
1381
1382
1383 for (PHG4Cell::EdepConstIterator hit_iter = cell->get_g4hits().first;
1384 hit_iter != cell->get_g4hits().second;
1385 ++hit_iter)
1386 {
1387 PHG4Hit* g4hit = _g4hits->findHit(hit_iter->first);
1388
1389 if (_strict)
1390 {
1391 assert(g4hit);
1392 }
1393 else if (!g4hit)
1394 {
1395 ++_errors;
1396 continue;
1397 }
1398
1399
1400 truth_hits.insert(g4hit);
1401 }
1402 }
1403
1404 if (_do_cache)
1405 {
1406 _cache_all_truth_hits.insert(std::make_pair(tower, truth_hits));
1407 }
1408
1409 return truth_hits;
1410 }
1411
1412 std::set<PHG4Hit*> CaloRawTowerEval::all_truth_hits(TowerInfo* tower)
1413 {
1414 if (!has_full_node_pointers())
1415 {
1416 ++_errors;
1417 return std::set<PHG4Hit*>();
1418 }
1419
1420 if (_strict)
1421 {
1422 assert(tower);
1423 }
1424 else if (!tower)
1425 {
1426 ++_errors;
1427 return std::set<PHG4Hit*>();
1428 }
1429
1430 if (_do_cache)
1431 {
1432 if (auto iter = _cache_towerinfo_all_truth_hits.find(tower); iter != _cache_towerinfo_all_truth_hits.end())
1433 {
1434 return iter->second;
1435 }
1436 }
1437
1438 std::set<PHG4Hit*> truth_hits;
1439 const TowerInfo::EdepMap& edepMap = tower->get_hitEdepMap();
1440
1441 for (const auto& [hitID, edep] : edepMap)
1442 {
1443 PHG4Hit* g4hit = _g4hits->findHit(hitID);
1444
1445 if (_strict)
1446 {
1447 assert(g4hit);
1448 }
1449 else if (!g4hit)
1450 {
1451 ++_errors;
1452 continue;
1453 }
1454
1455 truth_hits.insert(g4hit);
1456 }
1457
1458 if (_do_cache)
1459 {
1460 _cache_towerinfo_all_truth_hits.insert(std::make_pair(tower, truth_hits));
1461 }
1462
1463 return truth_hits;
1464 }
1465
1466 void CaloRawTowerEval::get_node_pointers(PHCompositeNode* topNode)
1467 {
1468
1469 std::string towername = "TOWER_CALIB_" + _caloname;
1470 _towers = findNode::getClass<RawTowerContainer>(topNode, towername.c_str());
1471
1472 std::string towerinfoname = "TOWERINFO_CALIB_" + _caloname;
1473 _towerinfos = findNode::getClass<TowerInfoContainer>(topNode, towerinfoname.c_str());
1474
1475 std::string cellname = "G4CELL_" + _caloname;
1476 _g4cells = findNode::getClass<PHG4CellContainer>(topNode, cellname.c_str());
1477
1478 std::string hitname = "G4HIT_" + _caloname;
1479 _g4hits = findNode::getClass<PHG4HitContainer>(topNode, hitname.c_str());
1480
1481 _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
1482
1483 return;
1484 }