Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:21:52

0001 #include "SvtxTrackEval.h"
0002 
0003 #include "SvtxClusterEval.h"
0004 #include "SvtxTruthEval.h"
0005 
0006 #include <g4main/PHG4Hit.h>
0007 #include <g4main/PHG4Particle.h>
0008 #include <g4main/PHG4TruthInfoContainer.h>
0009 
0010 #include <trackbase/TrkrDefs.h>  // for cluskey, getLayer
0011 
0012 #include <trackbase_historic/PHG4ParticleSvtxMap.h>
0013 #include <trackbase_historic/SvtxPHG4ParticleMap.h>
0014 #include <trackbase_historic/SvtxTrack.h>
0015 #include <trackbase_historic/SvtxTrackMap.h>
0016 #include <trackbase_historic/SvtxTrack_FastSim.h>
0017 
0018 #include <phool/getClass.h>
0019 
0020 #include <cassert>
0021 #include <cfloat>
0022 #include <iostream>
0023 #include <set>
0024 
0025 SvtxTrackEval::SvtxTrackEval(PHCompositeNode* topNode)
0026   : _clustereval(topNode)
0027 {
0028   get_node_pointers(topNode);
0029 }
0030 
0031 SvtxTrackEval::~SvtxTrackEval()
0032 {
0033   if (_verbosity > 0)
0034   {
0035     if ((_errors > 0) || (_verbosity > 1))
0036     {
0037       std::cout << "SvtxTrackEval::~SvtxTrackEval() - Error Count: " << _errors << std::endl;
0038     }
0039   }
0040 }
0041 
0042 void SvtxTrackEval::next_event(PHCompositeNode* topNode)
0043 {
0044   _cache_all_truth_hits.clear();
0045   _cache_all_truth_particles.clear();
0046   _cache_max_truth_particle_by_nclusters.clear();
0047   _cache_all_tracks_from_particle.clear();
0048   _cache_best_track_from_particle.clear();
0049   _cache_all_tracks_from_g4hit.clear();
0050   _cache_all_tracks_from_cluster.clear();
0051   _cache_best_track_from_cluster.clear();
0052   _cache_get_nclusters_contribution.clear();
0053   _cache_get_nclusters_contribution_by_layer.clear();
0054   _cache_get_nwrongclusters_contribution.clear();
0055   _clustereval.next_event(topNode);
0056 
0057   get_node_pointers(topNode);
0058 }
0059 
0060 std::set<PHG4Hit*> SvtxTrackEval::all_truth_hits(SvtxTrack* track)
0061 {
0062   if (!has_node_pointers())
0063   {
0064     return std::set<PHG4Hit*>();
0065   }
0066 
0067   if (_strict)
0068   {
0069     assert(track);
0070   }
0071   else if (!track)
0072   {
0073     ++_errors;
0074     return std::set<PHG4Hit*>();
0075   }
0076 
0077   if (_do_cache)
0078   {
0079     std::map<SvtxTrack*, std::set<PHG4Hit*> >::iterator iter =
0080         _cache_all_truth_hits.find(track);
0081     if (iter != _cache_all_truth_hits.end())
0082     {
0083       return iter->second;
0084     }
0085   }
0086 
0087   std::set<PHG4Hit*> truth_hits;
0088   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0089 
0090   // loop over all clusters...
0091   for (const auto& cluster_key : cluster_keys)
0092   {
0093     //    if (_strict)
0094     //    {
0095     //      assert(cluster_key);
0096     //    }
0097     //    else if (!cluster_key)
0098     //    {
0099     //      ++_errors;
0100     //      continue;
0101     //    }
0102 
0103     std::set<PHG4Hit*> new_hits = _clustereval.all_truth_hits(cluster_key);
0104 
0105     for (auto* new_hit : new_hits)
0106     {
0107       truth_hits.insert(new_hit);
0108     }
0109   }
0110 
0111   if (_do_cache)
0112   {
0113     _cache_all_truth_hits.insert(std::make_pair(track, truth_hits));
0114   }
0115 
0116   return truth_hits;
0117 }
0118 
0119 std::set<PHG4Particle*> SvtxTrackEval::all_truth_particles(SvtxTrack* track)
0120 {
0121   if (!has_node_pointers())
0122   {
0123     return std::set<PHG4Particle*>();
0124   }
0125   if (_strict)
0126   {
0127     assert(track);
0128   }
0129 
0130   else if (!track)
0131   {
0132     ++_errors;
0133     return std::set<PHG4Particle*>();
0134   }
0135 
0136   if (_recoTruthMap && _recoTruthMap->processed())
0137   {
0138     SvtxPHG4ParticleMap::WeightedTruthTrackMap map = _recoTruthMap->get(track->get_id());
0139     std::set<PHG4Particle*> returnset;
0140 
0141     for (const auto& [weight, truthTrackSet] : map)
0142     {
0143       for (const int& g4partid : truthTrackSet)
0144       {
0145         returnset.insert(_truthinfo->GetParticle(g4partid));
0146       }
0147     }
0148     return returnset;
0149   }
0150 
0151   if (_do_cache)
0152   {
0153     std::map<SvtxTrack*, std::set<PHG4Particle*> >::iterator iter =
0154         _cache_all_truth_particles.find(track);
0155     if (iter != _cache_all_truth_particles.end())
0156     {
0157       return iter->second;
0158     }
0159   }
0160   std::set<PHG4Particle*> truth_particles;
0161   SvtxTrack_FastSim* fastsim_track = dynamic_cast<SvtxTrack_FastSim*>(track);
0162 
0163   if (fastsim_track)
0164   {
0165     // exception for fast sim track
0166     unsigned int track_id = fastsim_track->get_truth_track_id();
0167     truth_particles.insert(get_truth_eval()->get_particle(track_id));
0168   }
0169   else
0170   {
0171     // loop over all clusters...
0172     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0173     for (const auto& cluster_key : cluster_keys)
0174     {
0175       //    if (_strict)
0176       //    {
0177       //      assert(cluster_key);
0178       //    }
0179       //    else if (!cluster_key)
0180       //    {
0181       //      ++_errors;
0182       //      continue;
0183       //    }
0184 
0185       std::set<PHG4Particle*> new_particles = _clustereval.all_truth_particles(cluster_key);
0186 
0187       for (auto* new_particle : new_particles)
0188       {
0189         truth_particles.insert(new_particle);
0190       }
0191     }
0192   }
0193 
0194   if (_do_cache)
0195   {
0196     _cache_all_truth_particles.insert(std::make_pair(track, truth_particles));
0197   }
0198 
0199   return truth_particles;
0200 }
0201 
0202 PHG4Particle* SvtxTrackEval::max_truth_particle_by_nclusters(SvtxTrack* track)
0203 {
0204   if (!has_node_pointers())
0205   {
0206     return nullptr;
0207   }
0208 
0209   if (_strict)
0210   {
0211     assert(track);
0212   }
0213   else if (!track)
0214   {
0215     ++_errors;
0216     return nullptr;
0217   }
0218 
0219   if (_recoTruthMap && _recoTruthMap->processed())
0220   {
0221     const SvtxPHG4ParticleMap::WeightedTruthTrackMap map = _recoTruthMap->get(track->get_id());
0222     if (map.empty())
0223     {
0224       return nullptr;
0225     }
0226     auto itr = map.end();
0227     --itr;
0228     std::set<int> bestPartSet = itr->second;
0229     int bestpart = *bestPartSet.begin();
0230     return _truthinfo->GetParticle(bestpart);
0231   }
0232 
0233   if (_do_cache)
0234   {
0235     std::map<SvtxTrack*, PHG4Particle*>::iterator iter =
0236         _cache_max_truth_particle_by_nclusters.find(track);
0237     if (iter != _cache_max_truth_particle_by_nclusters.end())
0238     {
0239       return iter->second;
0240     }
0241   }
0242 
0243   std::set<PHG4Particle*> particles = all_truth_particles(track);
0244   PHG4Particle* max_particle = nullptr;
0245 
0246   SvtxTrack_FastSim* fastsim_track = dynamic_cast<SvtxTrack_FastSim*>(track);
0247   if (fastsim_track)
0248   {
0249     // exception for fast sim track
0250     unsigned int track_id = fastsim_track->get_truth_track_id();
0251     max_particle = get_truth_eval()->get_particle(track_id);
0252   }
0253   else
0254   {
0255     unsigned int max_nclusters = 0;
0256 
0257     for (auto* candidate : particles)
0258     {
0259       unsigned int nclusters = get_nclusters_contribution(track, candidate);
0260       if (nclusters > max_nclusters)
0261       {
0262         max_nclusters = nclusters;
0263         max_particle = candidate;
0264       }
0265     }
0266   }
0267 
0268   if (_do_cache)
0269   {
0270     _cache_max_truth_particle_by_nclusters.insert(std::make_pair(track, max_particle));
0271   }
0272 
0273   return max_particle;
0274 }
0275 
0276 std::set<SvtxTrack*> SvtxTrackEval::all_tracks_from(PHG4Particle* truthparticle)
0277 {
0278   if (!has_node_pointers())
0279   {
0280     return std::set<SvtxTrack*>();
0281   }
0282 
0283   if (_strict)
0284   {
0285     assert(truthparticle);
0286   }
0287   else if (!truthparticle)
0288   {
0289     ++_errors;
0290     return std::set<SvtxTrack*>();
0291   }
0292 
0293   if (_truthRecoMap && _truthRecoMap->processed())
0294   {
0295     std::set<SvtxTrack*> returnset;
0296 
0297     PHG4ParticleSvtxMap::WeightedRecoTrackMap map = _truthRecoMap->get(truthparticle->get_track_id());
0298 
0299     for (const auto& [weight, recoTrackSet] : map)
0300     {
0301       for (const unsigned int& trackid : recoTrackSet)
0302       {
0303         returnset.insert(_trackmap->get(trackid));
0304       }
0305     }
0306     return returnset;
0307   }
0308 
0309   if (_do_cache)
0310   {
0311     std::map<PHG4Particle*, std::set<SvtxTrack*> >::iterator iter =
0312         _cache_all_tracks_from_particle.find(truthparticle);
0313     if (iter != _cache_all_tracks_from_particle.end())
0314     {
0315       return iter->second;
0316     }
0317   }
0318 
0319   std::set<SvtxTrack*> tracks;
0320 
0321   // loop over all SvtxTracks
0322   for (auto& iter : *_trackmap)
0323   {
0324     SvtxTrack* track = iter.second;
0325     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0326     for (const auto& cluster_key : cluster_keys)
0327     {
0328       // remove this check as cluster key = 0 is MVTX layer 0 cluster #0.
0329       //      if (_strict)
0330       //      {
0331       //        assert(cluster_key);
0332       //      }
0333       //      else if (!cluster_key)
0334       //      {
0335       //        ++_errors;
0336       //        continue;
0337       //      }
0338 
0339       // loop over all particles
0340       std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0341       for (auto* candidate : particles)
0342       {
0343         if (get_truth_eval()->are_same_particle(candidate, truthparticle))
0344         {
0345           tracks.insert(track);
0346         }
0347       }
0348     }
0349   }
0350 
0351   if (_do_cache)
0352   {
0353     _cache_all_tracks_from_particle.insert(std::make_pair(truthparticle, tracks));
0354   }
0355 
0356   return tracks;
0357 }
0358 
0359 std::set<SvtxTrack*> SvtxTrackEval::all_tracks_from(PHG4Hit* truthhit)
0360 {
0361   if (!has_node_pointers())
0362   {
0363     ++_errors;
0364     return std::set<SvtxTrack*>();
0365   }
0366 
0367   if (_strict)
0368   {
0369     assert(truthhit);
0370   }
0371   else if (!truthhit)
0372   {
0373     ++_errors;
0374     return std::set<SvtxTrack*>();
0375   }
0376 
0377   if (_do_cache)
0378   {
0379     std::map<PHG4Hit*, std::set<SvtxTrack*> >::iterator iter =
0380         _cache_all_tracks_from_g4hit.find(truthhit);
0381     if (iter != _cache_all_tracks_from_g4hit.end())
0382     {
0383       return iter->second;
0384     }
0385   }
0386 
0387   std::set<SvtxTrack*> tracks;
0388 
0389   // loop over all SvtxTracks
0390   for (auto& iter : *_trackmap)
0391   {
0392     SvtxTrack* track = iter.second;
0393     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0394     // loop over all clusters
0395     for (const auto& cluster_key : cluster_keys)
0396     {
0397       //      if (_strict)
0398       //      {
0399       //        assert(cluster_key);
0400       //      }
0401       //      else if (!cluster_key)
0402       //      {
0403       //        ++_errors;
0404       //        continue;
0405       //      }
0406 
0407       // loop over all hits
0408       std::set<PHG4Hit*> hits = _clustereval.all_truth_hits(cluster_key);
0409       for (auto* candidate : hits)
0410       {
0411         // if track id matches argument add to output
0412         if (candidate->get_trkid() == truthhit->get_trkid())
0413         {
0414           tracks.insert(track);
0415         }
0416       }
0417     }
0418   }
0419 
0420   if (_do_cache)
0421   {
0422     _cache_all_tracks_from_g4hit.insert(std::make_pair(truthhit, tracks));
0423   }
0424 
0425   return tracks;
0426 }
0427 
0428 SvtxTrack* SvtxTrackEval::best_track_from(PHG4Particle* truthparticle)
0429 {
0430   if (!has_node_pointers())
0431   {
0432     ++_errors;
0433     return nullptr;
0434   }
0435 
0436   if (_strict)
0437   {
0438     assert(truthparticle);
0439   }
0440   else if (!truthparticle)
0441   {
0442     ++_errors;
0443     return nullptr;
0444   }
0445 
0446   if (_truthRecoMap && _truthRecoMap->processed())
0447   {
0448     const PHG4ParticleSvtxMap::WeightedRecoTrackMap map = _truthRecoMap->get(truthparticle->get_track_id());
0449     /// No reco tracks found
0450     if (map.empty())
0451     {
0452       return nullptr;
0453     }
0454     auto itr = map.end();
0455     --itr;
0456     std::set<unsigned int> bestPartSet = itr->second;
0457     int bestpart = *bestPartSet.begin();
0458     return _trackmap->get(bestpart);
0459   }
0460 
0461   if (_do_cache)
0462   {
0463     std::map<PHG4Particle*, SvtxTrack*>::iterator iter =
0464         _cache_best_track_from_particle.find(truthparticle);
0465     if (iter != _cache_best_track_from_particle.end())
0466     {
0467       return iter->second;
0468     }
0469   }
0470 
0471   SvtxTrack* best_track = nullptr;
0472   unsigned int best_count = 0;
0473   std::set<SvtxTrack*> tracks = all_tracks_from(truthparticle);
0474   for (auto* track : tracks)
0475   {
0476     unsigned int count = get_nclusters_contribution(track, truthparticle);
0477     if (count > best_count)
0478     {
0479       best_track = track;
0480       best_count = count;
0481     }
0482   }
0483 
0484   if (_do_cache)
0485   {
0486     _cache_best_track_from_particle.insert(std::make_pair(truthparticle, best_track));
0487   }
0488 
0489   return best_track;
0490 }
0491 
0492 void SvtxTrackEval::create_cache_track_from_cluster()
0493 {
0494   if (!has_node_pointers())
0495   {
0496     ++_errors;
0497     return;
0498   }
0499 
0500   // loop over all SvtxTracks
0501   for (auto& iter : *_trackmap)
0502   {
0503     SvtxTrack* track = iter.second;
0504     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0505 
0506     // loop over all clusters
0507     for (const auto& candidate_key : cluster_keys)
0508     {
0509       // unsigned int cluster_layer = TrkrDefs::getLayer(candidate_key);
0510       //      if (_strict)
0511       //      {
0512       //        assert(candidate_key);
0513       //      }
0514       //      else if (!candidate_key)
0515       //      {
0516       //        ++_errors;
0517       //        continue;
0518       //      }
0519 
0520       // check if cluster has an entry in cache
0521       std::map<TrkrDefs::cluskey, std::set<SvtxTrack*> >::iterator cliter =
0522           _cache_all_tracks_from_cluster.find(candidate_key);
0523       if (cliter != _cache_all_tracks_from_cluster.end())
0524       {                                // got entry
0525         cliter->second.insert(track);  // add track to list;
0526       }
0527       else
0528       {
0529         std::set<SvtxTrack*> tracks;
0530         tracks.insert(track);
0531         _cache_all_tracks_from_cluster.insert(std::make_pair(candidate_key, tracks));
0532       }
0533     }
0534   }
0535   _cache_track_from_cluster_exists = true;
0536 
0537   return;
0538 }
0539 
0540 std::set<SvtxTrack*> SvtxTrackEval::all_tracks_from(TrkrDefs::cluskey cluster_key)
0541 {
0542   if (!has_node_pointers())
0543   {
0544     ++_errors;
0545     return std::set<SvtxTrack*>();
0546   }
0547 
0548   //  if (_strict)
0549   //  {
0550   //    assert(cluster_key);
0551   //  }
0552   //  else if (!cluster_key)
0553   //  {
0554   //    ++_errors;
0555   //    return std::set<SvtxTrack*>();
0556   //  }
0557 
0558   std::set<SvtxTrack*> tracks;
0559 
0560   if (_do_cache)
0561   {
0562     if (_cache_track_from_cluster_exists == false)
0563     {
0564       create_cache_track_from_cluster();
0565     }
0566     std::map<TrkrDefs::cluskey, std::set<SvtxTrack*> >::iterator iter =
0567         _cache_all_tracks_from_cluster.find(cluster_key);
0568     if (iter != _cache_all_tracks_from_cluster.end())
0569     {
0570       return iter->second;
0571     }
0572 
0573     return tracks;
0574   }
0575 
0576   // loop over all SvtxTracks
0577   for (auto& iter : *_trackmap)
0578   {
0579     SvtxTrack* track = iter.second;
0580     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0581 
0582     // loop over all clusters
0583     for (const auto& candidate : cluster_keys)
0584     {
0585       //      if (_strict)
0586       //      {
0587       //        assert(candidate);
0588       //      }
0589       //      else if (!candidate)
0590       //      {
0591       //        ++_errors;
0592       //        continue;
0593       //      }
0594 
0595       if (cluster_key == candidate)
0596       {
0597         tracks.insert(track);
0598       }
0599     }
0600   }
0601 
0602   if (_do_cache)
0603   {
0604     _cache_all_tracks_from_cluster.insert(std::make_pair(cluster_key, tracks));
0605   }
0606 
0607   return tracks;
0608 }
0609 
0610 SvtxTrack* SvtxTrackEval::best_track_from(TrkrDefs::cluskey cluster_key)
0611 {
0612   if (!has_node_pointers())
0613   {
0614     ++_errors;
0615     return nullptr;
0616   }
0617 
0618   //  if (_strict)
0619   //  {
0620   //    assert(cluster_key);
0621   //  }
0622   //  else if (!cluster_key)
0623   //  {
0624   //    ++_errors;
0625   //    return nullptr;
0626   //  }
0627 
0628   if (_do_cache)
0629   {
0630     std::map<TrkrDefs::cluskey, SvtxTrack*>::iterator iter =
0631         _cache_best_track_from_cluster.find(cluster_key);
0632     if (iter != _cache_best_track_from_cluster.end())
0633     {
0634       return iter->second;
0635     }
0636   }
0637 
0638   SvtxTrack* best_track = nullptr;
0639   float best_quality = std::numeric_limits<float>::max();
0640 
0641   std::set<SvtxTrack*> tracks = all_tracks_from(cluster_key);
0642   // loop over all SvtxTracks
0643   for (auto* candidate : tracks)
0644   {
0645     if (candidate->get_quality() < best_quality)
0646     {
0647       best_quality = candidate->get_quality();
0648       best_track = candidate;
0649     }
0650   }
0651 
0652   if (_do_cache)
0653   {
0654     _cache_best_track_from_cluster.insert(std::make_pair(cluster_key, best_track));
0655   }
0656   return best_track;
0657 }
0658 
0659 // overlap calculations
0660 unsigned int SvtxTrackEval::get_nclusters_contribution(SvtxTrack* track, PHG4Particle* particle)
0661 {
0662   if (!has_node_pointers())
0663   {
0664     ++_errors;
0665     return 0;
0666   }
0667 
0668   if (_strict)
0669   {
0670     assert(track);
0671     assert(particle);
0672   }
0673   else if (!track || !particle)
0674   {
0675     ++_errors;
0676     return 0;
0677   }
0678 
0679   calc_cluster_contribution(track, particle);
0680 
0681   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0682       _cache_get_nclusters_contribution.find(std::make_pair(track, particle));
0683   if (iter != _cache_get_nclusters_contribution.end())
0684   {
0685     return iter->second;
0686   }
0687 
0688   return 0;
0689 }
0690 unsigned int SvtxTrackEval::get_nwrongclusters_contribution(SvtxTrack* track, PHG4Particle* particle)
0691 {
0692   if (!has_node_pointers())
0693   {
0694     ++_errors;
0695     return 0;
0696   }
0697 
0698   if (_strict)
0699   {
0700     assert(track);
0701     assert(particle);
0702   }
0703   else if (!track || !particle)
0704   {
0705     ++_errors;
0706     return 0;
0707   }
0708 
0709   calc_cluster_contribution(track, particle);
0710 
0711   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0712       _cache_get_nwrongclusters_contribution.find(std::make_pair(track, particle));
0713   if (iter != _cache_get_nwrongclusters_contribution.end())
0714   {
0715     return iter->second;
0716   }
0717 
0718   return 0;
0719 }
0720 
0721 // overlap calculations
0722 void SvtxTrackEval::calc_cluster_contribution(SvtxTrack* track, PHG4Particle* particle)
0723 {
0724   if (!has_node_pointers())
0725   {
0726     ++_errors;
0727     return;
0728   }
0729 
0730   if (_strict)
0731   {
0732     assert(track);
0733     assert(particle);
0734   }
0735   else if (!track || !particle)
0736   {
0737     ++_errors;
0738     return;
0739   }
0740 
0741   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0742       _cache_get_nclusters_contribution.find(std::make_pair(track, particle));
0743   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator witer =
0744       _cache_get_nwrongclusters_contribution.find(std::make_pair(track, particle));
0745 
0746   if (iter != _cache_get_nclusters_contribution.end() &&
0747       witer != _cache_get_nwrongclusters_contribution.end())
0748   {
0749     return;
0750   }
0751 
0752   unsigned int nclusters = 0;
0753   unsigned int nwrong = 0;
0754   // loop over all clusters
0755   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0756   for (const auto& cluster_key : cluster_keys)
0757   {
0758     //    if (_strict)
0759     //    {
0760     //      assert(cluster_key);
0761     //    }
0762     //    else if (!cluster_key)
0763     //    {
0764     //      ++_errors;
0765     //      continue;
0766     //    }
0767     int matched = 0;
0768     // loop over all particles
0769     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0770     for (auto* candidate : particles)
0771     {
0772       if (get_truth_eval()->are_same_particle(candidate, particle))
0773       {
0774         ++nclusters;
0775         matched = 1;
0776       }
0777     }
0778     if (matched == 0)
0779     {
0780       nwrong++;
0781     }
0782   }
0783 
0784   _cache_get_nclusters_contribution.insert(std::make_pair(std::make_pair(track, particle), nclusters));
0785   _cache_get_nwrongclusters_contribution.insert(std::make_pair(std::make_pair(track, particle), nwrong));
0786 
0787   return;
0788 }
0789 
0790 unsigned int SvtxTrackEval::get_nclusters_contribution_by_layer(SvtxTrack* track, PHG4Particle* particle)
0791 {
0792   if (!has_node_pointers())
0793   {
0794     ++_errors;
0795     return 0;
0796   }
0797 
0798   if (_strict)
0799   {
0800     assert(track);
0801     assert(particle);
0802   }
0803   else if (!track || !particle)
0804   {
0805     ++_errors;
0806     return 0;
0807   }
0808 
0809   if (_do_cache)
0810   {
0811     std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0812         _cache_get_nclusters_contribution_by_layer.find(std::make_pair(track, particle));
0813     if (iter != _cache_get_nclusters_contribution_by_layer.end())
0814     {
0815       return iter->second;
0816     }
0817   }
0818 
0819   unsigned int nclusters_by_layer = 0;
0820   int layer_occupied[100];
0821   for (int& i : layer_occupied)
0822   {
0823     i = 0;
0824   }
0825 
0826   // loop over all clusters
0827   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0828   for (const auto& cluster_key : cluster_keys)
0829   {
0830     unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
0831 
0832     //    if (_strict)
0833     //    {
0834     //      assert(cluster_key);
0835     //    }
0836     //    else if (!cluster_key)
0837     //    {
0838     //      ++_errors;
0839     //      continue;
0840     //    }
0841 
0842     // loop over all particles
0843     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0844 
0845     for (auto* candidate : particles)
0846     {
0847       if (get_truth_eval()->are_same_particle(candidate, particle))
0848       {
0849         layer_occupied[cluster_layer]++;
0850       }
0851     }
0852   }
0853   for (int i : layer_occupied)
0854   {
0855     if (i > 0)
0856     {
0857       nclusters_by_layer++;
0858     }
0859   }
0860   if (_do_cache)
0861   {
0862     _cache_get_nclusters_contribution_by_layer.insert(std::make_pair(std::make_pair(track, particle), nclusters_by_layer));
0863   }
0864 
0865   return nclusters_by_layer;
0866 }
0867 
0868 std::pair<unsigned int, unsigned int> SvtxTrackEval::get_layer_range_contribution(SvtxTrack* track, PHG4Particle* particle, unsigned int start_layer, unsigned int end_layer)
0869 {
0870   if (!has_node_pointers())
0871   {
0872     ++_errors;
0873     return std::make_pair(0, 0);
0874   }
0875 
0876   if (_strict)
0877   {
0878     assert(track);
0879     assert(particle);
0880   }
0881   else if (!track || !particle)
0882   {
0883     ++_errors;
0884     return std::make_pair(0, 0);
0885   }
0886 
0887   unsigned int nmatches = 0;
0888   unsigned int nwrong = 0;
0889   unsigned int nlayers = end_layer - start_layer;
0890 
0891   std::vector<int> layers(nlayers, 0);
0892   std::vector<int> layers_wrong(nlayers, 0);
0893   // loop over all clusters
0894   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0895   for (const auto& cluster_key : cluster_keys)
0896   {
0897     unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
0898     if (cluster_layer >= end_layer)
0899     {
0900       continue;
0901     }
0902     if (cluster_layer < start_layer)
0903     {
0904       continue;
0905     }
0906 
0907     //    if (_strict)
0908     //    {
0909     //      assert(cluster_key);
0910     //    }
0911     //    else if (!cluster_key)
0912     //    {
0913     //      ++_errors;
0914     //      continue;
0915     //    }
0916 
0917     // loop over all particles
0918     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0919     int matched = 0;
0920     for (auto* candidate : particles)
0921     {
0922       if (get_truth_eval()->are_same_particle(candidate, particle))
0923       {
0924         //  nmatches |= (0x3FFFFFFF & (0x1 << cluster_layer));
0925         layers[cluster_layer - start_layer] = 1;
0926         matched = 1;
0927       }
0928     }
0929     if (matched == 0)
0930     {
0931       layers_wrong[cluster_layer - start_layer] = 1;
0932     }
0933   }
0934   for (unsigned int i = 0; i < nlayers; i++)
0935   {
0936     if (layers[i] == 1)
0937     {
0938       nmatches++;
0939     }
0940     if (layers_wrong[i] == 1)
0941     {
0942       nwrong++;
0943     }
0944   }
0945 
0946   return std::make_pair(nmatches, nwrong);
0947 }
0948 
0949 void SvtxTrackEval::get_node_pointers(PHCompositeNode* topNode)
0950 {
0951   // need things off of the DST...
0952   _trackmap = findNode::getClass<SvtxTrackMap>(topNode, m_TrackNodeName);
0953 
0954   _truthRecoMap = findNode::getClass<PHG4ParticleSvtxMap>(topNode, "PHG4ParticleSvtxMap");
0955 
0956   _recoTruthMap = findNode::getClass<SvtxPHG4ParticleMap>(topNode, "SvtxPHG4ParticleMap");
0957 
0958   _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0959 
0960   return;
0961 }
0962 
0963 bool SvtxTrackEval::has_node_pointers()
0964 {
0965   // need things off of the DST...
0966   if (_strict)
0967   {
0968     assert(_trackmap);
0969   }
0970   else if (!_trackmap)
0971   {
0972     return false;
0973   }
0974   return true;
0975 }
0976 
0977 std::vector<TrkrDefs::cluskey> SvtxTrackEval::get_track_ckeys(SvtxTrack* track)
0978 {
0979   std::vector<TrkrDefs::cluskey> cluster_keys;
0980   TrackSeed* tpcseed = track->get_tpc_seed();
0981   TrackSeed* silseed = track->get_silicon_seed();
0982   if (silseed)
0983   {
0984     for (auto iter = silseed->begin_cluster_keys();
0985          iter != silseed->end_cluster_keys();
0986          ++iter)
0987     {
0988       cluster_keys.push_back(*iter);
0989     }
0990   }
0991   if (tpcseed)
0992   {
0993     for (auto iter = tpcseed->begin_cluster_keys();
0994          iter != tpcseed->end_cluster_keys();
0995          ++iter)
0996     {
0997       cluster_keys.push_back(*iter);
0998     }
0999   }
1000 
1001   return cluster_keys;
1002 }