22#include " SvtxTruthRecoTableEval.h"
33#include " SvtxEvalStack.h"
44#include " SvtxTrackEval.h"
5- #include " SvtxTruthEval.h"
5+
6+ #include " SvtxClusterEval.h"
67
78#include < fun4all/Fun4AllReturnCodes.h>
89#include < phool/PHCompositeNode.h>
1920#include < trackbase_historic/PHG4ParticleSvtxMap_v1.h>
2021#include < trackbase_historic/SvtxPHG4ParticleMap_v1.h>
2122#include < trackbase_historic/SvtxTrack.h>
23+ #include < trackbase_historic/SvtxTrack_FastSim.h>
2224#include < trackbase_historic/SvtxTrackMap.h>
2325
24- #include < CLHEP/Vector/ThreeVector.h>
25-
26+ #include < cassert>
27+ #include < cstddef>
28+ #include < iostream>
29+ #include < map>
30+ #include < set>
31+ #include < unordered_map>
32+ #include < unordered_set>
33+ #include < utility>
34+ #include < vector>
2635
2736// ____________________________________________________________________________..
2837SvtxTruthRecoTableEval::SvtxTruthRecoTableEval (const std::string &name)
@@ -53,11 +62,13 @@ int SvtxTruthRecoTableEval::InitRun(PHCompositeNode *topNode)
5362// ____________________________________________________________________________..
5463int SvtxTruthRecoTableEval::process_event (PHCompositeNode *topNode)
5564{
65+ const int verbosity = Verbosity ();
66+
5667 if (!m_svtxevalstack)
5768 {
5869 m_svtxevalstack = std::make_unique<SvtxEvalStack>(topNode);
5970 m_svtxevalstack->set_strict (false );
60- m_svtxevalstack->set_verbosity (Verbosity () );
71+ m_svtxevalstack->set_verbosity (verbosity );
6172 m_svtxevalstack->set_use_initial_vertex (true );
6273 m_svtxevalstack->set_use_genfit_vertex (false );
6374 m_svtxevalstack->next_event (topNode);
@@ -67,17 +78,15 @@ int SvtxTruthRecoTableEval::process_event(PHCompositeNode *topNode)
6778 m_svtxevalstack->next_event (topNode);
6879 }
6980
70- if (Verbosity () > 1 )
71- {
72- std::cout << " Fill truth map " << std::endl;
73- }
74- fillTruthMap (topNode);
81+ SvtxTrackEval *trackeval = m_svtxevalstack->get_track_eval ();
82+ assert (trackeval);
83+ trackeval->set_verbosity (verbosity);
7584
76- if (Verbosity () > 1 )
85+ if (verbosity > 1 )
7786 {
78- std::cout << " Fill reco map " << std::endl;
87+ std::cout << " Fill truth/ reco maps " << std::endl;
7988 }
80- fillRecoMap (topNode);
89+ fillTruthRecoMaps (topNode, trackeval, verbosity );
8190
8291 return Fun4AllReturnCodes::EVENT_OK ;
8392}
@@ -102,111 +111,138 @@ int SvtxTruthRecoTableEval::End(PHCompositeNode * /*unused*/)
102111 return Fun4AllReturnCodes::EVENT_OK ;
103112}
104113
105- void SvtxTruthRecoTableEval::fillTruthMap (PHCompositeNode *topNode)
114+ void SvtxTruthRecoTableEval::fillTruthRecoMaps (PHCompositeNode *topNode, SvtxTrackEval *trackeval, const int verbosity )
106115{
107116 PHG4TruthInfoContainer *truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, " G4TruthInfo" );
108117 assert (truthinfo);
109118
110- SvtxTrackEval *trackeval = m_svtxevalstack->get_track_eval ();
111- trackeval->set_verbosity (Verbosity ());
112- assert (trackeval);
119+ SvtxTrackMap *trackMap = findNode::getClass<SvtxTrackMap>(topNode, " SvtxTrackMap" );
120+ assert (trackMap);
113121
114122 PHG4TruthInfoContainer::ConstRange range = truthinfo->GetParticleRange ();
115123 if (m_scanForPrimaries)
116124 {
117125 range = truthinfo->GetPrimaryParticleRange ();
118126 }
119127
128+ std::vector<int > selectedTruthIds;
129+ std::unordered_set<int > selectedTruthIdSet;
130+ const double minMomentumTruthMap2 = m_minMomentumTruthMap * m_minMomentumTruthMap;
131+
120132 for (auto iter = range.first ; iter != range.second ; ++iter)
121133 {
122134 PHG4Particle *g4particle = iter->second ;
123135
124- const double momentum = CLHEP ::
125- Hep3Vector (g4particle->get_px (), g4particle->get_py (), g4particle->get_pz ())
126- .mag ();
136+ const double px = g4particle->get_px ();
137+ const double py = g4particle->get_py ();
138+ const double pz = g4particle->get_pz ();
139+ const double momentum2 = px * px + py * py + pz * pz;
127140
128- // only record particle above minimal momentum requirement.
129- if (momentum < m_minMomentumTruthMap)
141+ // only record particle above minimal momentum (square) requirement.
142+ // doing this saves us a slow sqrt operation to calculate the momentum itself
143+ if (momentum2 < minMomentumTruthMap2)
130144 {
131145 continue ;
132146 }
133147
134- int gtrackID = g4particle->get_track_id ();
135- const std::set<SvtxTrack *> &alltracks = trackeval->all_tracks_from (g4particle);
148+ const int gtrackID = g4particle->get_track_id ();
149+ selectedTruthIds.push_back (gtrackID);
150+ selectedTruthIdSet.insert (gtrackID);
151+ }
152+
153+ SvtxClusterEval *clustereval = trackeval->get_cluster_eval ();
154+ std::map<int , PHG4ParticleSvtxMap::WeightedRecoTrackMap> truthMaps;
136155
137- // not to record zero associations
138- if (alltracks.empty ())
156+ for (const auto &[key, track] : *trackMap)
157+ {
158+ TrackSeed *siliconSeed = track->get_silicon_seed ();
159+ TrackSeed *tpcSeed = track->get_tpc_seed ();
160+
161+ std::size_t nclusterKeys = 0 ;
162+ if (siliconSeed)
139163 {
140- continue ;
164+ nclusterKeys += siliconSeed->size_cluster_keys ();
165+ }
166+ if (tpcSeed)
167+ {
168+ nclusterKeys += tpcSeed->size_cluster_keys ();
141169 }
142170
143- PHG4ParticleSvtxMap::WeightedRecoTrackMap recomap;
171+ std::unordered_map<int , unsigned int > nclustersByTruthId;
172+ nclustersByTruthId.reserve (nclusterKeys);
144173
145- for ( auto *track : alltracks )
174+ const auto add_cluster_contributions = [&](TrackSeed *seed )
146175 {
147- // / We fill the map with a key corresponding to the ncluster contribution.
148- // / This weight could in principle be anything we choose
149- float clusCont = trackeval->get_nclusters_contribution (track, g4particle);
176+ if (!seed)
177+ {
178+ return ;
179+ }
180+
181+ for (auto clusterIter = seed->begin_cluster_keys ();
182+ clusterIter != seed->end_cluster_keys ();
183+ ++clusterIter)
184+ {
185+ const std::set<PHG4Particle *> particles = clustereval->all_truth_particles (*clusterIter);
186+ for (PHG4Particle *g4particle : particles)
187+ {
188+ ++nclustersByTruthId[g4particle->get_track_id ()];
189+ }
190+ }
191+ };
192+
193+ // Match SvtxTrackEval::get_track_ckeys ordering.
194+ add_cluster_contributions (siliconSeed);
195+ add_cluster_contributions (tpcSeed);
196+
197+ SvtxPHG4ParticleMap::WeightedTruthTrackMap truthmap;
198+ SvtxTrack_FastSim *fastsim_track = dynamic_cast <SvtxTrack_FastSim *>(track);
150199
151- auto iterator = recomap.find (clusCont);
152- if (iterator == recomap.end ())
200+ const unsigned int trackID = track->get_id ();
201+ for (const auto &[gtrackID, nclusters] : nclustersByTruthId)
202+ {
203+ const float clusCont = static_cast <float >(nclusters);
204+ if (selectedTruthIdSet.contains (gtrackID))
153205 {
154- std::set<unsigned int > dumset;
155- dumset.insert (track->get_id ());
156- recomap.insert (std::make_pair (clusCont, dumset));
206+ truthMaps[gtrackID][clusCont].insert (trackID);
157207 }
158- else
208+ if (!fastsim_track)
159209 {
160- iterator-> second .insert (track-> get_id () );
210+ truthmap[clusCont] .insert (gtrackID );
161211 }
162212 }
163213
164- if (Verbosity () > 1 )
214+ if (fastsim_track )
165215 {
166- std::cout << " Inserting gtrack id " << gtrackID << " with map size " << recomap.size () << std::endl;
216+ // Preserve SvtxTrackEval::all_truth_particles fast-sim special case for reco->truth maps only.
217+ PHG4Particle *g4particle = truthinfo->GetParticle (fastsim_track->get_truth_track_id ());
218+ const float clusCont = trackeval->get_nclusters_contribution (track, g4particle);
219+ truthmap[clusCont].insert (g4particle->get_track_id ());
167220 }
168221
169- m_truthMap->insert (gtrackID, recomap);
222+ if (verbosity > 1 )
223+ {
224+ std::cout << " Inserting track id " << key << " with truth map size " << truthmap.size () << std::endl;
225+ }
226+ m_recoMap->insert (key, std::move (truthmap));
170227 }
171228
172- m_truthMap->setProcessed (true );
173- }
174-
175- void SvtxTruthRecoTableEval::fillRecoMap (PHCompositeNode *topNode)
176- {
177- SvtxTrackMap *trackMap = findNode::getClass<SvtxTrackMap>(topNode, " SvtxTrackMap" );
178-
179- assert (trackMap);
180-
181- SvtxTrackEval *trackeval = m_svtxevalstack->get_track_eval ();
182- assert (trackeval);
183-
184- for (const auto &[key, track] : *trackMap)
229+ for (const int gtrackID : selectedTruthIds)
185230 {
186- const std::set<PHG4Particle *> &allparticles = trackeval->all_truth_particles (track);
187- SvtxPHG4ParticleMap::WeightedTruthTrackMap truthmap;
188- for (PHG4Particle *g4particle : allparticles)
231+ auto truthMapIter = truthMaps.find (gtrackID);
232+ if (truthMapIter == truthMaps.end () || truthMapIter->second .empty ())
189233 {
190- float clusCont = trackeval->get_nclusters_contribution (track, g4particle);
191- auto iterator = truthmap.find (clusCont);
192- if (iterator == truthmap.end ())
193- {
194- std::set<int > dumset;
195- dumset.insert (g4particle->get_track_id ());
196- truthmap.insert (std::make_pair (clusCont, dumset));
197- }
198- else
199- {
200- iterator->second .insert (g4particle->get_track_id ());
201- }
234+ continue ;
202235 }
203- if (Verbosity () > 1 )
236+
237+ if (verbosity > 1 )
204238 {
205- std::cout << " Inserting track id " << key << " with truth map size " << truthmap .size () << std::endl;
239+ std::cout << " Inserting gtrack id " << gtrackID << " with map size " << truthMapIter-> second .size () << std::endl;
206240 }
207- m_recoMap->insert (key, truthmap);
241+
242+ m_truthMap->insert (gtrackID, std::move (truthMapIter->second ));
208243 }
209244
245+ m_truthMap->setProcessed (true );
210246 m_recoMap->setProcessed (true );
211247}
212248
0 commit comments