Back to home page

sPhenix code displayed by LXR

 
 

    


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   // use const incase something bad happens
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     // Check for shower validity
0203     if (_strict)
0204     {
0205       assert(shower);
0206     }
0207     else if (!shower)
0208     {
0209       ++_errors;
0210       continue;
0211     }
0212 
0213     // Process or store showers based on edep if needed
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   // loop over all the towers
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   // loop over all the towers
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   // loop over the tower shower entries
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   // loop over the tower shower entries
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   // use primary map pointer
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   // use primary map pointer
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 // overlap calculations
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   // reduce cache misses by using only pointer from PrimaryMap
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   // reduce cache misses by using only pointer from PrimaryMap
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   // loop over all the towered cells
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     // loop over all the g4hits in this cell
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       // fill output set
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   // loop over all g4hits
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     // fill output set
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   // need things off of the DST...
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 }