Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:18:00

0001 #include "SvtxHitEval.h"
0002 
0003 #include <trackbase/TrkrClusterContainer.h>
0004 #include <trackbase/TrkrDefs.h>
0005 #include <trackbase/TrkrHitSet.h>
0006 #include <trackbase/TrkrHitSetContainer.h>
0007 #include <trackbase/TrkrHitTruthAssoc.h>
0008 
0009 #include <g4main/PHG4Hit.h>
0010 #include <g4main/PHG4HitContainer.h>
0011 #include <g4main/PHG4HitDefs.h>
0012 #include <g4main/PHG4Particle.h>
0013 #include <g4main/PHG4TruthInfoContainer.h>
0014 
0015 #include <phool/getClass.h>
0016 #include <phool/phool.h>
0017 
0018 #include <cassert>
0019 #include <cfloat>
0020 #include <cmath>
0021 #include <iostream>  // for operator<<, endl, basic_...
0022 #include <map>
0023 #include <set>
0024 
0025 class TrkrHit;
0026 
0027 SvtxHitEval::SvtxHitEval(PHCompositeNode* topNode)
0028   : _trutheval(topNode)
0029 {
0030   get_node_pointers(topNode);
0031 }
0032 
0033 SvtxHitEval::~SvtxHitEval()
0034 {
0035   if (_verbosity > 0)
0036   {
0037     if ((_errors > 0) || (_verbosity > 1))
0038     {
0039       std::cout << "SvtxHitEval::~SvtxHitEval() - Error Count: " << _errors << std::endl;
0040     }
0041   }
0042 }
0043 
0044 void SvtxHitEval::next_event(PHCompositeNode* topNode)
0045 {
0046   _cache_all_truth_hits.clear();
0047   _cache_max_truth_hit_by_energy.clear();
0048   _cache_all_truth_particles.clear();
0049   _cache_max_truth_particle_by_energy.clear();
0050   _cache_all_hits_from_particle.clear();
0051   _cache_all_hits_from_g4hit.clear();
0052   _cache_best_hit_from_g4hit.clear();
0053   _cache_get_energy_contribution_g4particle.clear();
0054   _cache_get_energy_contribution_g4hit.clear();
0055 
0056   _trutheval.next_event(topNode);
0057 
0058   get_node_pointers(topNode);
0059 }
0060 
0061 /*
0062 PHG4Cell* SvtxHitEval::get_cell(SvtxHit* hit)
0063 {
0064   if (!has_node_pointers())
0065   {
0066     ++_errors;
0067     std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0068     return nullptr;
0069   }
0070 
0071   if (_strict)
0072   {
0073     assert(hit);
0074   }
0075   else if (!hit)
0076   {
0077     ++_errors;
0078     std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0079     return nullptr;
0080   }
0081 
0082   // hop from reco hit to g4cell
0083   PHG4Cell* cell = nullptr;
0084   if (_g4cells_svtx) cell = _g4cells_svtx->findCell(hit->get_cellid());
0085   if (!cell && _g4cells_tracker) cell = _g4cells_tracker->findCell(hit->get_cellid());
0086   if (!cell && _g4cells_maps) cell = _g4cells_maps->findCell(hit->get_cellid());
0087 
0088   // only noise hits (cellid left at default value) should not trace
0089   if ((_strict) && (hit->get_cellid() != 0xFFFFFFFF))
0090   {
0091     assert(cell);
0092   }
0093   else if (!cell)
0094   {
0095     ++_errors;
0096     std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0097   }
0098 
0099   return cell;
0100 }
0101 */
0102 
0103 std::set<PHG4Hit*> SvtxHitEval::all_truth_hits(TrkrDefs::hitkey hit_key)
0104 {
0105   if (!has_node_pointers())
0106   {
0107     ++_errors;
0108     if (_verbosity > 0)
0109     {
0110       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0111     }
0112     return std::set<PHG4Hit*>();
0113   }
0114 
0115   if (_strict)
0116   {
0117     assert(hit_key);
0118   }
0119   else if (!hit_key)
0120   {
0121     ++_errors;
0122     if (_verbosity > 0)
0123     {
0124       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0125     }
0126     return std::set<PHG4Hit*>();
0127   }
0128 
0129   if (_do_cache)
0130   {
0131     std::map<TrkrDefs::hitkey, std::set<PHG4Hit*> >::iterator iter =
0132         _cache_all_truth_hits.find(hit_key);
0133     if (iter != _cache_all_truth_hits.end())
0134     {
0135       return iter->second;
0136     }
0137   }
0138 
0139   std::set<PHG4Hit*> truth_hits;
0140 
0141   /*
0142   // hop from reco hit to g4cell
0143   PHG4Cell* cell = nullptr;
0144   if (_g4cells_svtx) cell = _g4cells_svtx->findCell(hit->get_cellid());
0145   if (!cell && _g4cells_tracker) cell = _g4cells_tracker->findCell(hit->get_cellid());
0146   if (!cell && _g4cells_maps) cell = _g4cells_maps->findCell(hit->get_cellid());
0147 
0148   // only noise hits (cellid left at default value) should not trace
0149   if ((_strict) && (hit->get_cellid() != 0xFFFFFFFF))
0150     assert(cell);
0151   else if (!cell)
0152   {
0153     ++_errors;
0154     std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0155     return truth_hits;
0156   }
0157 
0158   //std::cout << "Eval: hitid " << hit->get_id() << " cellid " << cell->get_cellid() << std::endl;
0159   // loop over all the g4hits in this cell
0160   for (PHG4Cell::EdepConstIterator g4iter = cell->get_g4hits().first;
0161        g4iter != cell->get_g4hits().second;
0162        ++g4iter)
0163   {
0164     //std::cout << "    Looking for hit " << g4iter->first << " in layer " << cell->get_layer() << " with edep " << g4iter->second << std::endl;
0165     PHG4Hit* g4hit = nullptr;
0166     if (_g4hits_svtx) g4hit = _g4hits_svtx->findHit(g4iter->first);
0167     if (!g4hit && _g4hits_tracker) g4hit = _g4hits_tracker->findHit(g4iter->first);
0168     if (!g4hit && _g4hits_maps) g4hit = _g4hits_maps->findHit(g4iter->first);
0169     if (!g4hit) std::cout << "    Failed to find  g4hit " << g4iter->first << " with edep " << g4iter->second << std::endl;
0170     if (_strict)
0171       assert(g4hit);
0172     else if (!g4hit)
0173     {
0174       ++_errors;
0175       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0176       continue;
0177     }
0178   */
0179 
0180   // get all of the g4hits for this hit_key
0181   // have to start with all hitsets, unfortunately
0182   TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets();
0183   for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; iter != all_hitsets.second; ++iter)
0184   {
0185     TrkrDefs::hitsetkey hitset_key = iter->first;
0186     unsigned int trkrid = TrkrDefs::getTrkrId(hitset_key);
0187     TrkrHitSet* hitset = iter->second;
0188 
0189     // does this hitset contain our hitkey?
0190     TrkrHit* hit = nullptr;
0191     hit = hitset->getHit(hit_key);
0192     if (hit)
0193     {
0194       // get g4hits for this hit
0195 
0196       std::multimap<TrkrDefs::hitsetkey, std::pair<TrkrDefs::hitkey, PHG4HitDefs::keytype> > temp_map;
0197       _hit_truth_map->getG4Hits(hitset_key, hit_key, temp_map);  // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only
0198       for (auto& htiter : temp_map)
0199       {
0200         // extract the g4 hit key here and add the g4hit to the set
0201         PHG4HitDefs::keytype g4hitkey = htiter.second.second;
0202         // std::cout << "           hitkey " << hitkey <<  " g4hitkey " << g4hitkey << std::endl;
0203         PHG4Hit* g4hit = nullptr;
0204         switch (trkrid)
0205         {
0206         case TrkrDefs::tpcId:
0207           g4hit = _g4hits_tpc->findHit(g4hitkey);
0208           break;
0209         case TrkrDefs::inttId:
0210           g4hit = _g4hits_intt->findHit(g4hitkey);
0211           break;
0212         case TrkrDefs::mvtxId:
0213           g4hit = _g4hits_mvtx->findHit(g4hitkey);
0214           break;
0215         case TrkrDefs::micromegasId:
0216           g4hit = _g4hits_mms->findHit(g4hitkey);
0217           break;
0218         default:
0219           break;
0220         }
0221         // fill output set
0222         if (g4hit)
0223         {
0224           truth_hits.insert(g4hit);
0225         }
0226       }
0227     }
0228   }
0229 
0230   if (_do_cache)
0231   {
0232     _cache_all_truth_hits.insert(std::make_pair(hit_key, truth_hits));
0233   }
0234 
0235   return truth_hits;
0236 }
0237 
0238 std::set<PHG4Hit*> SvtxHitEval::all_truth_hits(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid)
0239 {
0240   if (!has_node_pointers())
0241   {
0242     ++_errors;
0243     if (_verbosity > 0)
0244     {
0245       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0246     }
0247     return std::set<PHG4Hit*>();
0248   }
0249 
0250   if (_strict)
0251   {
0252     assert(hit_key);
0253   }
0254   else if (!hit_key)
0255   {
0256     ++_errors;
0257     if (_verbosity > 0)
0258     {
0259       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0260     }
0261     return std::set<PHG4Hit*>();
0262   }
0263 
0264   if (_do_cache)
0265   {
0266     std::map<TrkrDefs::hitkey, std::set<PHG4Hit*> >::iterator iter =
0267         _cache_all_truth_hits.find(hit_key);
0268     if (iter != _cache_all_truth_hits.end())
0269     {
0270       return iter->second;
0271     }
0272   }
0273 
0274   std::set<PHG4Hit*> truth_hits;
0275   TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(trkrid);
0276 
0277   for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; iter != all_hitsets.second; ++iter)
0278   {
0279     TrkrDefs::hitsetkey hitset_key = iter->first;
0280     TrkrHitSet* hitset = iter->second;
0281 
0282     // does this hitset contain our hitkey?
0283     TrkrHit* hit = nullptr;
0284     hit = hitset->getHit(hit_key);
0285     if (hit)
0286     {
0287       // get g4hits for this hit
0288 
0289       std::multimap<TrkrDefs::hitsetkey, std::pair<TrkrDefs::hitkey, PHG4HitDefs::keytype> > temp_map;
0290       _hit_truth_map->getG4Hits(hitset_key, hit_key, temp_map);  // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only
0291       for (auto& htiter : temp_map)
0292       {
0293         // extract the g4 hit key here and add the g4hit to the set
0294         PHG4HitDefs::keytype g4hitkey = htiter.second.second;
0295         // std::cout << "           hitkey " << hitkey <<  " g4hitkey " << g4hitkey << std::endl;
0296         PHG4Hit* g4hit = nullptr;
0297         switch (trkrid)
0298         {
0299         case TrkrDefs::tpcId:
0300           g4hit = _g4hits_tpc->findHit(g4hitkey);
0301           break;
0302         case TrkrDefs::inttId:
0303           g4hit = _g4hits_intt->findHit(g4hitkey);
0304           break;
0305         case TrkrDefs::mvtxId:
0306           g4hit = _g4hits_mvtx->findHit(g4hitkey);
0307           break;
0308         case TrkrDefs::micromegasId:
0309           g4hit = _g4hits_mms->findHit(g4hitkey);
0310           break;
0311         default:
0312           break;
0313         }
0314         // fill output set
0315         if (g4hit)
0316         {
0317           truth_hits.insert(g4hit);
0318         }
0319       }
0320     }
0321   }
0322 
0323   if (_do_cache)
0324   {
0325     _cache_all_truth_hits.insert(std::make_pair(hit_key, truth_hits));
0326   }
0327 
0328   return truth_hits;
0329 }
0330 
0331 PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key)
0332 {
0333   if (!has_node_pointers())
0334   {
0335     ++_errors;
0336     if (_verbosity > 0)
0337     {
0338       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0339     }
0340     return nullptr;
0341   }
0342 
0343   if (_strict)
0344   {
0345     assert(hit_key);
0346   }
0347   else if (!hit_key)
0348   {
0349     ++_errors;
0350     if (_verbosity > 0)
0351     {
0352       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0353     }
0354     return nullptr;
0355   }
0356 
0357   if (_do_cache)
0358   {
0359     std::map<TrkrDefs::hitkey, PHG4Hit*>::iterator iter =
0360         _cache_max_truth_hit_by_energy.find(hit_key);
0361     if (iter != _cache_max_truth_hit_by_energy.end())
0362     {
0363       return iter->second;
0364     }
0365   }
0366 
0367   std::set<PHG4Hit*> hits = all_truth_hits(hit_key);
0368   PHG4Hit* max_hit = nullptr;
0369   float max_e = FLT_MAX * -1.0;
0370   for (auto hit : hits)
0371   {
0372     if (hit->get_edep() > max_e)
0373     {
0374       max_e = hit->get_edep();
0375       max_hit = hit;
0376     }
0377   }
0378 
0379   if (_do_cache)
0380   {
0381     _cache_max_truth_hit_by_energy.insert(std::make_pair(hit_key, max_hit));
0382   }
0383 
0384   return max_hit;
0385 }
0386 
0387 PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid)
0388 {
0389   if (!has_node_pointers())
0390   {
0391     ++_errors;
0392     if (_verbosity > 0)
0393     {
0394       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0395     }
0396     return nullptr;
0397   }
0398 
0399   if (_strict)
0400   {
0401     assert(hit_key);
0402   }
0403   else if (!hit_key)
0404   {
0405     ++_errors;
0406     if (_verbosity > 0)
0407     {
0408       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0409     }
0410     return nullptr;
0411   }
0412 
0413   if (_do_cache)
0414   {
0415     std::map<TrkrDefs::hitkey, PHG4Hit*>::iterator iter =
0416         _cache_max_truth_hit_by_energy.find(hit_key);
0417     if (iter != _cache_max_truth_hit_by_energy.end())
0418     {
0419       return iter->second;
0420     }
0421   }
0422 
0423   std::set<PHG4Hit*> hits = all_truth_hits(hit_key, trkrid);
0424   PHG4Hit* max_hit = nullptr;
0425   float max_e = FLT_MAX * -1.0;
0426   for (auto hit : hits)
0427   {
0428     if (hit->get_edep() > max_e)
0429     {
0430       max_e = hit->get_edep();
0431       max_hit = hit;
0432     }
0433   }
0434 
0435   if (_do_cache)
0436   {
0437     _cache_max_truth_hit_by_energy.insert(std::make_pair(hit_key, max_hit));
0438   }
0439 
0440   return max_hit;
0441 }
0442 
0443 std::set<PHG4Particle*> SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_key)
0444 {
0445   if (!has_node_pointers())
0446   {
0447     ++_errors;
0448     if (_verbosity > 0)
0449     {
0450       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0451     }
0452     return std::set<PHG4Particle*>();
0453   }
0454 
0455   if (_strict)
0456   {
0457     assert(hit_key);
0458   }
0459   else if (!hit_key)
0460   {
0461     ++_errors;
0462     if (_verbosity > 0)
0463     {
0464       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0465     }
0466     return std::set<PHG4Particle*>();
0467   }
0468 
0469   if (_do_cache)
0470   {
0471     std::map<TrkrDefs::hitkey, std::set<PHG4Particle*> >::iterator iter =
0472         _cache_all_truth_particles.find(hit_key);
0473     if (iter != _cache_all_truth_particles.end())
0474     {
0475       return iter->second;
0476     }
0477   }
0478 
0479   std::set<PHG4Particle*> truth_particles;
0480 
0481   std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key);
0482 
0483   for (auto g4hit : g4hits)
0484   {
0485     PHG4Particle* particle = get_truth_eval()->get_particle(g4hit);
0486 
0487     if (_strict)
0488     {
0489       assert(particle);
0490     }
0491     else if (!particle)
0492     {
0493       ++_errors;
0494       if (_verbosity > 0)
0495       {
0496         std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0497       }
0498       continue;
0499     }
0500 
0501     truth_particles.insert(particle);
0502   }
0503 
0504   if (_do_cache)
0505   {
0506     _cache_all_truth_particles.insert(std::make_pair(hit_key, truth_particles));
0507   }
0508 
0509   return truth_particles;
0510 }
0511 
0512 std::set<PHG4Particle*> SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid)
0513 {
0514   if (!has_node_pointers())
0515   {
0516     ++_errors;
0517     if (_verbosity > 0)
0518     {
0519       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0520     }
0521     return std::set<PHG4Particle*>();
0522   }
0523 
0524   if (_strict)
0525   {
0526     assert(hit_key);
0527   }
0528   else if (!hit_key)
0529   {
0530     ++_errors;
0531     if (_verbosity > 0)
0532     {
0533       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0534     }
0535     return std::set<PHG4Particle*>();
0536   }
0537 
0538   if (_do_cache)
0539   {
0540     std::map<TrkrDefs::hitkey, std::set<PHG4Particle*> >::iterator iter =
0541         _cache_all_truth_particles.find(hit_key);
0542     if (iter != _cache_all_truth_particles.end())
0543     {
0544       return iter->second;
0545     }
0546   }
0547 
0548   std::set<PHG4Particle*> truth_particles;
0549 
0550   std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key, trkrid);
0551 
0552   for (auto g4hit : g4hits)
0553   {
0554     PHG4Particle* particle = get_truth_eval()->get_particle(g4hit);
0555 
0556     if (_strict)
0557     {
0558       assert(particle);
0559     }
0560     else if (!particle)
0561     {
0562       ++_errors;
0563       if (_verbosity > 0)
0564       {
0565         std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0566       }
0567       continue;
0568     }
0569 
0570     truth_particles.insert(particle);
0571   }
0572 
0573   if (_do_cache)
0574   {
0575     _cache_all_truth_particles.insert(std::make_pair(hit_key, truth_particles));
0576   }
0577 
0578   return truth_particles;
0579 }
0580 
0581 PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key)
0582 {
0583   if (!has_node_pointers())
0584   {
0585     ++_errors;
0586     if (_verbosity > 0)
0587     {
0588       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0589     }
0590     return nullptr;
0591   }
0592 
0593   if (_strict)
0594   {
0595     assert(hit_key);
0596   }
0597   else if (!hit_key)
0598   {
0599     ++_errors;
0600     if (_verbosity > 0)
0601     {
0602       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0603     }
0604     return nullptr;
0605   }
0606 
0607   if (_do_cache)
0608   {
0609     std::map<TrkrDefs::hitkey, PHG4Particle*>::iterator iter =
0610         _cache_max_truth_particle_by_energy.find(hit_key);
0611     if (iter != _cache_max_truth_particle_by_energy.end())
0612     {
0613       return iter->second;
0614     }
0615   }
0616 
0617   // loop over all particles associated with this hit and
0618   // get the energy contribution for each one, record the max
0619   PHG4Particle* max_particle = nullptr;
0620   float max_e = FLT_MAX * -1.0;
0621   std::set<PHG4Particle*> particles = all_truth_particles(hit_key);
0622   for (auto particle : particles)
0623   {
0624     float e = get_energy_contribution(hit_key, particle);
0625     if (e > max_e)
0626     {
0627       max_e = e;
0628       max_particle = particle;
0629     }
0630   }
0631 
0632   if (_do_cache)
0633   {
0634     _cache_max_truth_particle_by_energy.insert(std::make_pair(hit_key, max_particle));
0635   }
0636 
0637   return max_particle;
0638 }
0639 
0640 PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid)
0641 {
0642   if (!has_node_pointers())
0643   {
0644     ++_errors;
0645     if (_verbosity > 0)
0646     {
0647       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0648     }
0649     return nullptr;
0650   }
0651 
0652   if (_strict)
0653   {
0654     assert(hit_key);
0655   }
0656   else if (!hit_key)
0657   {
0658     ++_errors;
0659     if (_verbosity > 0)
0660     {
0661       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0662     }
0663     return nullptr;
0664   }
0665 
0666   if (_do_cache)
0667   {
0668     std::map<TrkrDefs::hitkey, PHG4Particle*>::iterator iter =
0669         _cache_max_truth_particle_by_energy.find(hit_key);
0670     if (iter != _cache_max_truth_particle_by_energy.end())
0671     {
0672       return iter->second;
0673     }
0674   }
0675 
0676   // loop over all particles associated with this hit and
0677   // get the energy contribution for each one, record the max
0678   PHG4Particle* max_particle = nullptr;
0679   float max_e = FLT_MAX * -1.0;
0680   std::set<PHG4Particle*> particles = all_truth_particles(hit_key, trkrid);
0681   for (auto particle : particles)
0682   {
0683     float e = get_energy_contribution(hit_key, particle);
0684     if (e > max_e)
0685     {
0686       max_e = e;
0687       max_particle = particle;
0688     }
0689   }
0690 
0691   if (_do_cache)
0692   {
0693     _cache_max_truth_particle_by_energy.insert(std::make_pair(hit_key, max_particle));
0694   }
0695 
0696   return max_particle;
0697 }
0698 
0699 std::set<TrkrDefs::hitkey> SvtxHitEval::all_hits_from(PHG4Particle* g4particle)
0700 {
0701   if (!has_node_pointers())
0702   {
0703     ++_errors;
0704     if (_verbosity > 0)
0705     {
0706       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0707     }
0708     return std::set<TrkrDefs::hitkey>();
0709   }
0710 
0711   if (_strict)
0712   {
0713     assert(g4particle);
0714   }
0715   else if (!g4particle)
0716   {
0717     ++_errors;
0718     if (_verbosity > 0)
0719     {
0720       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0721     }
0722     return std::set<TrkrDefs::hitkey>();
0723   }
0724 
0725   if (_do_cache)
0726   {
0727     std::map<PHG4Particle*, std::set<TrkrDefs::hitkey> >::iterator iter =
0728         _cache_all_hits_from_particle.find(g4particle);
0729     if (iter != _cache_all_hits_from_particle.end())
0730     {
0731       return iter->second;
0732     }
0733   }
0734 
0735   std::set<TrkrDefs::hitkey> hits;
0736 
0737   // loop over all the hits
0738   TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets();
0739   for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first;
0740        iter != all_hitsets.second;
0741        ++iter)
0742   {
0743     TrkrHitSet::ConstRange range = iter->second->getHits();
0744     for (TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr)
0745     {
0746       TrkrDefs::hitkey hit_key = hitr->first;
0747 
0748       // loop over all truth hits connected to this hit
0749       std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key);
0750       for (auto candidate : g4hits)
0751       {
0752         PHG4Particle* particle = _truthinfo->GetParticle(candidate->get_trkid());
0753         if (g4particle->get_track_id() == particle->get_track_id())
0754         {
0755           hits.insert(hit_key);
0756         }
0757       }
0758     }
0759   }
0760 
0761   if (_do_cache)
0762   {
0763     _cache_all_hits_from_particle.insert(std::make_pair(g4particle, hits));
0764   }
0765 
0766   return hits;
0767 }
0768 
0769 std::set<TrkrDefs::hitkey> SvtxHitEval::all_hits_from(PHG4Hit* g4hit)
0770 {
0771   if (!has_node_pointers())
0772   {
0773     ++_errors;
0774     if (_verbosity > 0)
0775     {
0776       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0777     }
0778     return std::set<TrkrDefs::hitkey>();
0779   }
0780 
0781   if (_strict)
0782   {
0783     assert(g4hit);
0784   }
0785   else if (!g4hit)
0786   {
0787     ++_errors;
0788     if (_verbosity > 0)
0789     {
0790       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0791     }
0792     return std::set<TrkrDefs::hitkey>();
0793   }
0794 
0795   if (_do_cache)
0796   {
0797     std::map<PHG4Hit*, std::set<TrkrDefs::hitkey> >::iterator iter =
0798         _cache_all_hits_from_g4hit.find(g4hit);
0799     if (iter != _cache_all_hits_from_g4hit.end())
0800     {
0801       return iter->second;
0802     }
0803   }
0804 
0805   std::set<TrkrDefs::hitkey> hits;
0806 
0807   unsigned int hit_layer = g4hit->get_layer();
0808 
0809   // loop over all the hits
0810   TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets();
0811   for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first;
0812        iter != all_hitsets.second;
0813        ++iter)
0814   {
0815     TrkrHitSet::ConstRange range = iter->second->getHits();
0816     for (TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr)
0817     {
0818       TrkrDefs::hitkey hit_key = hitr->first;
0819 
0820       if (TrkrDefs::getLayer(hit_key) != hit_layer)
0821       {
0822         continue;
0823       }
0824 
0825       // loop over all truth hits connected to this hit
0826       std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key);
0827       for (auto candidate : g4hits)
0828       {
0829         if (candidate->get_hit_id() == g4hit->get_hit_id())
0830         {
0831           hits.insert(hit_key);
0832         }
0833       }
0834     }
0835   }
0836 
0837   if (_do_cache)
0838   {
0839     _cache_all_hits_from_g4hit.insert(std::make_pair(g4hit, hits));
0840   }
0841 
0842   return hits;
0843 }
0844 
0845 TrkrDefs::hitkey SvtxHitEval::best_hit_from(PHG4Hit* g4hit)
0846 {
0847   if (!has_node_pointers())
0848   {
0849     ++_errors;
0850     if (_verbosity > 0)
0851     {
0852       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0853     }
0854     return 0;
0855   }
0856 
0857   if (_strict)
0858   {
0859     assert(g4hit);
0860   }
0861   else if (!g4hit)
0862   {
0863     ++_errors;
0864     if (_verbosity > 0)
0865     {
0866       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0867     }
0868     return 0;
0869   }
0870 
0871   if (_do_cache)
0872   {
0873     std::map<PHG4Hit*, TrkrDefs::hitkey>::iterator iter =
0874         _cache_best_hit_from_g4hit.find(g4hit);
0875     if (iter != _cache_best_hit_from_g4hit.end())
0876     {
0877       return iter->second;
0878     }
0879   }
0880 
0881   TrkrDefs::hitkey best_hit = 0;
0882   float best_energy = 0.0;
0883   std::set<TrkrDefs::hitkey> hits = all_hits_from(g4hit);
0884   for (unsigned int hit_key : hits)
0885   {
0886     float energy = get_energy_contribution(hit_key, g4hit);
0887     if (energy > best_energy)
0888     {
0889       best_hit = hit_key;
0890       best_energy = energy;
0891     }
0892   }
0893 
0894   if (_do_cache)
0895   {
0896     _cache_best_hit_from_g4hit.insert(std::make_pair(g4hit, best_hit));
0897   }
0898 
0899   return best_hit;
0900 }
0901 
0902 // overlap calculations
0903 float SvtxHitEval::get_energy_contribution(TrkrDefs::hitkey hit_key, PHG4Particle* particle)
0904 {
0905   if (!has_node_pointers())
0906   {
0907     ++_errors;
0908     if (_verbosity > 0)
0909     {
0910       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0911     }
0912     return NAN;
0913   }
0914 
0915   if (_strict)
0916   {
0917     assert(hit_key);
0918     assert(particle);
0919   }
0920   else if (!hit_key || !particle)
0921   {
0922     ++_errors;
0923     if (_verbosity > 0)
0924     {
0925       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0926     }
0927     return NAN;
0928   }
0929 
0930   if (_do_cache)
0931   {
0932     std::map<std::pair<TrkrDefs::hitkey, PHG4Particle*>, float>::iterator iter =
0933         _cache_get_energy_contribution_g4particle.find(std::make_pair(hit_key, particle));
0934     if (iter != _cache_get_energy_contribution_g4particle.end())
0935     {
0936       return iter->second;
0937     }
0938   }
0939 
0940   float energy = 0.0;
0941   std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key);
0942   for (auto g4hit : g4hits)
0943   {
0944     if (get_truth_eval()->is_g4hit_from_particle(g4hit, particle))
0945     {
0946       energy += g4hit->get_edep();
0947     }
0948   }
0949 
0950   if (_do_cache)
0951   {
0952     _cache_get_energy_contribution_g4particle.insert(std::make_pair(std::make_pair(hit_key, particle), energy));
0953   }
0954 
0955   return energy;
0956 }
0957 
0958 float SvtxHitEval::get_energy_contribution(TrkrDefs::hitkey hit_key, PHG4Hit* g4hit)
0959 {
0960   if (!has_node_pointers())
0961   {
0962     ++_errors;
0963     if (_verbosity > 0)
0964     {
0965       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0966     }
0967     return NAN;
0968   }
0969 
0970   if (_strict)
0971   {
0972     assert(hit_key);
0973     assert(g4hit);
0974   }
0975   else if (!hit_key || !g4hit)
0976   {
0977     ++_errors;
0978     if (_verbosity > 0)
0979     {
0980       std::cout << PHWHERE << " nerr: " << _errors << std::endl;
0981     }
0982     return NAN;
0983   }
0984 
0985   if (_do_cache)
0986   {
0987     std::map<std::pair<TrkrDefs::hitkey, PHG4Hit*>, float>::iterator iter =
0988         _cache_get_energy_contribution_g4hit.find(std::make_pair(hit_key, g4hit));
0989     if (iter != _cache_get_energy_contribution_g4hit.end())
0990     {
0991       return iter->second;
0992     }
0993   }
0994 
0995   // this is a fairly simple existance check right now, but might be more
0996   // complex in the future, so this is here mostly as future-proofing.
0997 
0998   float energy = 0.0;
0999   std::set<PHG4Hit*> g4hits = all_truth_hits(hit_key);
1000   for (auto candidate : g4hits)
1001   {
1002     if (candidate->get_hit_id() != g4hit->get_hit_id())
1003     {
1004       continue;
1005     }
1006     energy += candidate->get_edep();
1007   }
1008 
1009   if (_do_cache)
1010   {
1011     _cache_get_energy_contribution_g4hit.insert(std::make_pair(std::make_pair(hit_key, g4hit), energy));
1012   }
1013 
1014   return energy;
1015 }
1016 
1017 void SvtxHitEval::get_node_pointers(PHCompositeNode* topNode)
1018 {
1019   // need things off of the DST...
1020   _hitmap = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
1021 
1022   _clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "CORRECTED_TRKR_CLUSTER");
1023   if (!_clustermap)
1024   {
1025     _clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
1026   }
1027 
1028   _hit_truth_map = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
1029 
1030   // need things off of the DST...
1031   _g4hits_tpc = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_TPC");
1032   _g4hits_intt = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_INTT");
1033   _g4hits_mvtx = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_MVTX");
1034   _g4hits_mms = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_MICROMEGAS");
1035 
1036   _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
1037 
1038   return;
1039 }
1040 
1041 bool SvtxHitEval::has_node_pointers()
1042 {
1043   if (_strict)
1044   {
1045     assert(_hitmap);
1046   }
1047   else if (!_hitmap)
1048   {
1049     return false;
1050   }
1051 
1052   if (_strict)
1053   {
1054     assert(_g4hits_mms || _g4hits_tpc || _g4hits_intt || _g4hits_mvtx);
1055   }
1056   else if (!_g4hits_mms && !_g4hits_tpc && !_g4hits_intt && !_g4hits_mvtx)
1057   {
1058     std::cout << "no hits" << std::endl;
1059     return false;
1060   }
1061   if (_strict)
1062   {
1063     assert(_truthinfo);
1064   }
1065   else if (!_truthinfo)
1066   {
1067     std::cout << " no truth" << std::endl;
1068     return false;
1069   }
1070 
1071   return true;
1072 }