Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:19:12

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.size() == 0)
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.size() == 0)
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     else
0573     {
0574       return tracks;
0575     }
0576   }
0577 
0578   // loop over all SvtxTracks
0579   for (auto& iter : *_trackmap)
0580   {
0581     SvtxTrack* track = iter.second;
0582     std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0583 
0584     // loop over all clusters
0585     for (const auto& candidate : cluster_keys)
0586     {
0587       //      if (_strict)
0588       //      {
0589       //        assert(candidate);
0590       //      }
0591       //      else if (!candidate)
0592       //      {
0593       //        ++_errors;
0594       //        continue;
0595       //      }
0596 
0597       if (cluster_key == candidate)
0598       {
0599         tracks.insert(track);
0600       }
0601     }
0602   }
0603 
0604   if (_do_cache)
0605   {
0606     _cache_all_tracks_from_cluster.insert(std::make_pair(cluster_key, tracks));
0607   }
0608 
0609   return tracks;
0610 }
0611 
0612 SvtxTrack* SvtxTrackEval::best_track_from(TrkrDefs::cluskey cluster_key)
0613 {
0614   if (!has_node_pointers())
0615   {
0616     ++_errors;
0617     return nullptr;
0618   }
0619 
0620   //  if (_strict)
0621   //  {
0622   //    assert(cluster_key);
0623   //  }
0624   //  else if (!cluster_key)
0625   //  {
0626   //    ++_errors;
0627   //    return nullptr;
0628   //  }
0629 
0630   if (_do_cache)
0631   {
0632     std::map<TrkrDefs::cluskey, SvtxTrack*>::iterator iter =
0633         _cache_best_track_from_cluster.find(cluster_key);
0634     if (iter != _cache_best_track_from_cluster.end())
0635     {
0636       return iter->second;
0637     }
0638   }
0639 
0640   SvtxTrack* best_track = nullptr;
0641   float best_quality = FLT_MAX;
0642 
0643   std::set<SvtxTrack*> tracks = all_tracks_from(cluster_key);
0644   // loop over all SvtxTracks
0645   for (auto candidate : tracks)
0646   {
0647     if (candidate->get_quality() < best_quality)
0648     {
0649       best_quality = candidate->get_quality();
0650       best_track = candidate;
0651     }
0652   }
0653 
0654   if (_do_cache)
0655   {
0656     _cache_best_track_from_cluster.insert(std::make_pair(cluster_key, best_track));
0657   }
0658   return best_track;
0659 }
0660 
0661 // overlap calculations
0662 unsigned int SvtxTrackEval::get_nclusters_contribution(SvtxTrack* track, PHG4Particle* particle)
0663 {
0664   if (!has_node_pointers())
0665   {
0666     ++_errors;
0667     return 0;
0668   }
0669 
0670   if (_strict)
0671   {
0672     assert(track);
0673     assert(particle);
0674   }
0675   else if (!track || !particle)
0676   {
0677     ++_errors;
0678     return 0;
0679   }
0680 
0681   calc_cluster_contribution(track, particle);
0682 
0683   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0684       _cache_get_nclusters_contribution.find(std::make_pair(track, particle));
0685   if (iter != _cache_get_nclusters_contribution.end())
0686   {
0687     return iter->second;
0688   }
0689 
0690   return 0;
0691 }
0692 unsigned int SvtxTrackEval::get_nwrongclusters_contribution(SvtxTrack* track, PHG4Particle* particle)
0693 {
0694   if (!has_node_pointers())
0695   {
0696     ++_errors;
0697     return 0;
0698   }
0699 
0700   if (_strict)
0701   {
0702     assert(track);
0703     assert(particle);
0704   }
0705   else if (!track || !particle)
0706   {
0707     ++_errors;
0708     return 0;
0709   }
0710 
0711   calc_cluster_contribution(track, particle);
0712 
0713   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0714       _cache_get_nwrongclusters_contribution.find(std::make_pair(track, particle));
0715   if (iter != _cache_get_nwrongclusters_contribution.end())
0716   {
0717     return iter->second;
0718   }
0719 
0720   return 0;
0721 }
0722 
0723 // overlap calculations
0724 void SvtxTrackEval::calc_cluster_contribution(SvtxTrack* track, PHG4Particle* particle)
0725 {
0726   if (!has_node_pointers())
0727   {
0728     ++_errors;
0729     return;
0730   }
0731 
0732   if (_strict)
0733   {
0734     assert(track);
0735     assert(particle);
0736   }
0737   else if (!track || !particle)
0738   {
0739     ++_errors;
0740     return;
0741   }
0742 
0743   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0744       _cache_get_nclusters_contribution.find(std::make_pair(track, particle));
0745   std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator witer =
0746       _cache_get_nwrongclusters_contribution.find(std::make_pair(track, particle));
0747 
0748   if (iter != _cache_get_nclusters_contribution.end() &&
0749       witer != _cache_get_nwrongclusters_contribution.end())
0750   {
0751     return;
0752   }
0753 
0754   unsigned int nclusters = 0;
0755   unsigned int nwrong = 0;
0756   // loop over all clusters
0757   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0758   for (const auto& cluster_key : cluster_keys)
0759   {
0760     //    if (_strict)
0761     //    {
0762     //      assert(cluster_key);
0763     //    }
0764     //    else if (!cluster_key)
0765     //    {
0766     //      ++_errors;
0767     //      continue;
0768     //    }
0769     int matched = 0;
0770     // loop over all particles
0771     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0772     for (auto candidate : particles)
0773     {
0774       if (get_truth_eval()->are_same_particle(candidate, particle))
0775       {
0776         ++nclusters;
0777         matched = 1;
0778       }
0779     }
0780     if (matched == 0)
0781     {
0782       nwrong++;
0783     }
0784   }
0785 
0786   _cache_get_nclusters_contribution.insert(std::make_pair(std::make_pair(track, particle), nclusters));
0787   _cache_get_nwrongclusters_contribution.insert(std::make_pair(std::make_pair(track, particle), nwrong));
0788 
0789   return;
0790 }
0791 
0792 unsigned int SvtxTrackEval::get_nclusters_contribution_by_layer(SvtxTrack* track, PHG4Particle* particle)
0793 {
0794   if (!has_node_pointers())
0795   {
0796     ++_errors;
0797     return 0;
0798   }
0799 
0800   if (_strict)
0801   {
0802     assert(track);
0803     assert(particle);
0804   }
0805   else if (!track || !particle)
0806   {
0807     ++_errors;
0808     return 0;
0809   }
0810 
0811   if (_do_cache)
0812   {
0813     std::map<std::pair<SvtxTrack*, PHG4Particle*>, unsigned int>::iterator iter =
0814         _cache_get_nclusters_contribution_by_layer.find(std::make_pair(track, particle));
0815     if (iter != _cache_get_nclusters_contribution_by_layer.end())
0816     {
0817       return iter->second;
0818     }
0819   }
0820 
0821   unsigned int nclusters_by_layer = 0;
0822   int layer_occupied[100];
0823   for (int& i : layer_occupied)
0824   {
0825     i = 0;
0826   }
0827 
0828   // loop over all clusters
0829   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0830   for (const auto& cluster_key : cluster_keys)
0831   {
0832     unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
0833 
0834     //    if (_strict)
0835     //    {
0836     //      assert(cluster_key);
0837     //    }
0838     //    else if (!cluster_key)
0839     //    {
0840     //      ++_errors;
0841     //      continue;
0842     //    }
0843 
0844     // loop over all particles
0845     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0846 
0847     for (auto candidate : particles)
0848     {
0849       if (get_truth_eval()->are_same_particle(candidate, particle))
0850       {
0851         layer_occupied[cluster_layer]++;
0852       }
0853     }
0854   }
0855   for (int i : layer_occupied)
0856   {
0857     if (i > 0)
0858     {
0859       nclusters_by_layer++;
0860     }
0861   }
0862   if (_do_cache)
0863   {
0864     _cache_get_nclusters_contribution_by_layer.insert(std::make_pair(std::make_pair(track, particle), nclusters_by_layer));
0865   }
0866 
0867   return nclusters_by_layer;
0868 }
0869 
0870 std::pair<unsigned int, unsigned int> SvtxTrackEval::get_layer_range_contribution(SvtxTrack* track, PHG4Particle* particle, unsigned int start_layer, unsigned int end_layer)
0871 {
0872   if (!has_node_pointers())
0873   {
0874     ++_errors;
0875     return std::make_pair(0,0);
0876   }
0877 
0878   if (_strict)
0879   {
0880     assert(track);
0881     assert(particle);
0882   }
0883   else if (!track || !particle)
0884   {
0885     ++_errors;
0886     return std::make_pair(0,0);
0887   }
0888 
0889   unsigned int nmatches = 0;
0890   unsigned int nwrong = 0;
0891   unsigned int nlayers = end_layer - start_layer;
0892 
0893   std::vector<int> layers(nlayers,0);
0894   std::vector<int> layers_wrong(nlayers,0);
0895   // loop over all clusters
0896   std::vector<TrkrDefs::cluskey> cluster_keys = get_track_ckeys(track);
0897   for (const auto& cluster_key : cluster_keys)
0898   {
0899     unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
0900     if (cluster_layer >= end_layer)
0901     {
0902       continue;
0903     }
0904     if (cluster_layer < start_layer)
0905     {
0906       continue;
0907     }
0908 
0909     //    if (_strict)
0910     //    {
0911     //      assert(cluster_key);
0912     //    }
0913     //    else if (!cluster_key)
0914     //    {
0915     //      ++_errors;
0916     //      continue;
0917     //    }
0918 
0919     // loop over all particles
0920     std::set<PHG4Particle*> particles = _clustereval.all_truth_particles(cluster_key);
0921     int matched = 0;
0922     for (auto candidate : particles)
0923     {
0924       if (get_truth_eval()->are_same_particle(candidate, particle))
0925       {
0926         //  nmatches |= (0x3FFFFFFF & (0x1 << cluster_layer));
0927         layers[cluster_layer - start_layer] = 1;
0928     matched = 1;
0929       }
0930     }
0931     if(matched == 0)
0932       {
0933     layers_wrong[cluster_layer - start_layer] = 1;
0934       }
0935   }
0936   for (unsigned int i = 0; i < nlayers; i++)
0937   {
0938     if (layers[i] == 1)
0939     {
0940       nmatches++;
0941     }
0942     if(layers_wrong[i] == 1)
0943       {
0944     nwrong++;
0945       }
0946   }
0947   
0948   return std::make_pair(nmatches,nwrong);
0949 }
0950 
0951 void SvtxTrackEval::get_node_pointers(PHCompositeNode* topNode)
0952 {
0953   // need things off of the DST...
0954   _trackmap = findNode::getClass<SvtxTrackMap>(topNode, m_TrackNodeName);
0955 
0956   _truthRecoMap = findNode::getClass<PHG4ParticleSvtxMap>(topNode, "PHG4ParticleSvtxMap");
0957 
0958   _recoTruthMap = findNode::getClass<SvtxPHG4ParticleMap>(topNode, "SvtxPHG4ParticleMap");
0959 
0960   _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0961 
0962   return;
0963 }
0964 
0965 bool SvtxTrackEval::has_node_pointers()
0966 {
0967   // need things off of the DST...
0968   if (_strict)
0969   {
0970     assert(_trackmap);
0971   }
0972   else if (!_trackmap)
0973   {
0974     return false;
0975   }
0976   return true;
0977 }
0978 
0979 std::vector<TrkrDefs::cluskey> SvtxTrackEval::get_track_ckeys(SvtxTrack* track)
0980 {
0981   std::vector<TrkrDefs::cluskey> cluster_keys;
0982   TrackSeed* tpcseed = track->get_tpc_seed();
0983   TrackSeed* silseed = track->get_silicon_seed();
0984   if (silseed)
0985   {
0986     for (auto iter = silseed->begin_cluster_keys();
0987          iter != silseed->end_cluster_keys();
0988          ++iter)
0989     {
0990       cluster_keys.push_back(*iter);
0991     }
0992   }
0993   if (tpcseed)
0994   {
0995     for (auto iter = tpcseed->begin_cluster_keys();
0996          iter != tpcseed->end_cluster_keys();
0997          ++iter)
0998     {
0999       cluster_keys.push_back(*iter);
1000     }
1001   }
1002 
1003   return cluster_keys;
1004 }