Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SvtxClusterEval.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SvtxClusterEval.cc
1 #include "SvtxClusterEval.h"
2 
3 #include "SvtxHitEval.h"
4 #include "SvtxTruthEval.h"
5 
9 #include <trackbase/TrkrDefs.h>
10 #include <trackbase/TrkrHitSet.h>
13 
14 #include <g4main/PHG4Hit.h>
16 #include <g4main/PHG4HitDefs.h>
17 #include <g4main/PHG4Particle.h>
19 #include <g4main/PHG4VtxPoint.h>
20 
21 #include <phool/PHTimer.h>
22 #include <phool/getClass.h>
23 
24 #include <TVector3.h>
25 
26 #include <cassert>
27 #include <cfloat>
28 #include <cmath>
29 #include <iostream> // for operator<<, basic_ostream
30 #include <map>
31 #include <set>
32 
34  : _hiteval(topNode)
35 {
36  get_node_pointers(topNode);
37 }
38 
40 {
41  if (_verbosity > 0)
42  {
43  if ((_errors > 0) || (_verbosity > 1))
44  {
45  std::cout << "SvtxClusterEval::~SvtxClusterEval() - Error Count: " << _errors << std::endl;
46  }
47  }
48 }
49 
51 {
52  _cache_all_truth_hits.clear();
65  _clusters_per_layer.clear();
66  // _g4hits_per_layer.clear();
67  _hiteval.next_event(topNode);
68 
69  get_node_pointers(topNode);
70 }
71 
72 std::map<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>> SvtxClusterEval::all_truth_clusters(TrkrDefs::cluskey cluster_key)
73 {
74  if (_do_cache)
75  {
76  const auto iter = _cache_all_truth_clusters.find(cluster_key);
77  if (iter != _cache_all_truth_clusters.end())
78  {
79  return iter->second;
80  }
81  }
82 
83  std::map<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>> truth_clusters;
84 
85  unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
86  std::set<PHG4Particle*> particles = all_truth_particles(cluster_key);
87  for (auto particle : particles)
88  {
89  for (const auto& [ckey, cluster] : get_truth_eval()->all_truth_clusters(particle))
90  {
91  if (TrkrDefs::getLayer(ckey) == cluster_layer)
92  {
93  truth_clusters.insert(std::make_pair(ckey, cluster));
94  }
95  }
96  }
97 
98  return _cache_all_truth_clusters.insert(std::make_pair(cluster_key, truth_clusters)).first->second;
99 }
100 
101 std::pair<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>> SvtxClusterEval::max_truth_cluster_by_energy(TrkrDefs::cluskey cluster_key)
102 {
103  if (_do_cache)
104  {
105  const auto iter = _cache_max_truth_cluster_by_energy.find(cluster_key);
106  if (iter != _cache_max_truth_cluster_by_energy.end())
107  {
108  return iter->second;
109  }
110  }
111 
112  unsigned int cluster_layer = TrkrDefs::getLayer(cluster_key);
113 
114  PHG4Particle* max_particle = max_truth_particle_by_cluster_energy(cluster_key);
115  if (!max_particle)
116  {
117  return std::make_pair(0, nullptr);
118  }
119 
120  if (_verbosity > 0)
121  {
122  std::cout << " max truth particle by cluster energy has trackID " << max_particle->get_track_id() << std::endl;
123  }
124 
125  TrkrCluster* reco_cluster = _clustermap->findCluster(cluster_key);
126 
127  auto global = getGlobalPosition(cluster_key, reco_cluster);
128  double reco_x = global(0);
129  double reco_y = global(1);
130  double reco_z = global(2);
131  double r = sqrt(reco_x * reco_x + reco_y * reco_y);
132  // double reco_rphi = r*fast_approx_atan2(reco_y, reco_x);
133  double reco_rphi = r * atan2(reco_y, reco_x);
134 
135  const std::map<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>> gclusters = get_truth_eval()->all_truth_clusters(max_particle);
136  for (const auto& [ckey, candidate_truth_cluster] : gclusters)
137  {
138  if (TrkrDefs::getLayer(ckey) != cluster_layer)
139  {
140  continue;
141  }
142 
143  double gx = candidate_truth_cluster->getX();
144  double gy = candidate_truth_cluster->getY();
145  double gz = candidate_truth_cluster->getZ();
146  double gr = sqrt(gx * gx + gy * gy);
147  double grphi = gr * atan2(gy, gx);
148  // double grphi = gr*fast_approx_atan2(gy, gx);
149 
150  // Find the difference in position from the reco cluster
151  double dz = reco_z - gz;
152  double drphi = reco_rphi - grphi;
153 
154  // approximate 4 sigmas cut
155  if (cluster_layer > 6 && cluster_layer < 23)
156  {
157  if (fabs(drphi) < 4.0 * sig_tpc_rphi_inner &&
158  fabs(dz) < 4.0 * sig_tpc_z)
159  {
160  return std::make_pair(ckey, candidate_truth_cluster);
161  }
162  }
163  if (cluster_layer > 22 && cluster_layer < 39)
164  {
165  if (fabs(drphi) < 4.0 * sig_tpc_rphi_mid &&
166  fabs(dz) < 4.0 * sig_tpc_z)
167  {
168  return std::make_pair(ckey, candidate_truth_cluster);
169  }
170  }
171  if (cluster_layer > 38 && cluster_layer < 55)
172  {
173  if (fabs(drphi) < 4.0 * sig_tpc_rphi_outer &&
174  fabs(dz) < 4.0 * sig_tpc_z)
175  {
176  return std::make_pair(ckey, candidate_truth_cluster);
177  }
178  }
179  else if (cluster_layer < 3)
180  {
181  if (fabs(drphi) < 4.0 * sig_mvtx_rphi &&
182  fabs(dz) < 4.0 * sig_mvtx_z)
183  {
184  return std::make_pair(ckey, candidate_truth_cluster);
185  }
186  }
187  else if (cluster_layer == 55)
188  {
189  if (fabs(drphi) < 4.0 * sig_mms_rphi_55)
190  {
191  return std::make_pair(ckey, candidate_truth_cluster);
192  }
193  }
194  else if (cluster_layer == 56)
195  {
196  if (fabs(dz) < 4.0 * sig_mms_z_56)
197  {
198  return std::make_pair(ckey, candidate_truth_cluster);
199  }
200  }
201  else
202  {
203  if (fabs(drphi) < 4.0 * sig_intt_rphi &&
204  fabs(dz) < range_intt_z)
205  {
206  return std::make_pair(ckey, candidate_truth_cluster);
207  }
208  }
209  }
210 
211  return std::make_pair(0, nullptr);
212 }
213 
214 std::pair<TrkrDefs::cluskey, TrkrCluster*> SvtxClusterEval::reco_cluster_from_truth_cluster(TrkrDefs::cluskey ckey, const std::shared_ptr<TrkrCluster>& gclus)
215 {
216  if (_do_cache)
217  {
218  /* this does not work. Cache is not filled in the code below, so always remains empty */
219  const auto iter = _cache_reco_cluster_from_truth_cluster.find(gclus);
220  if (iter != _cache_reco_cluster_from_truth_cluster.end())
221  {
222  return iter->second;
223  }
224  }
225 
226  double gx = gclus->getX();
227  double gy = gclus->getY();
228  double gz = gclus->getZ();
229  double gr = sqrt(gx * gx + gy * gy);
230  double grphi = gr * atan2(gy, gx);
231  // double grphi = gr*fast_approx_atan2(gy, gx);
232 
233  unsigned int truth_layer = TrkrDefs::getLayer(ckey);
234 
235  std::set<TrkrDefs::cluskey> reco_cluskeys;
236  std::set<PHG4Hit*> contributing_hits = get_truth_eval()->get_truth_hits_from_truth_cluster(ckey);
237  for (auto cont_g4hit : contributing_hits)
238  {
239  std::set<TrkrDefs::cluskey> cluskeys = all_clusters_from(cont_g4hit); // this returns clusters from this hit in any layer using TrkrAssoc maps
240 
241  if (_verbosity > 0)
242  {
243  std::cout << " contributing g4hitID " << cont_g4hit->get_hit_id() << " g4trackID " << cont_g4hit->get_trkid() << std::endl;
244  }
245 
246  for (unsigned long iter : cluskeys)
247  {
248  unsigned int clus_layer = TrkrDefs::getLayer(iter);
249  if (clus_layer != truth_layer)
250  {
251  continue;
252  }
253 
254  reco_cluskeys.insert(iter);
255  }
256  }
257 
258  unsigned int nreco = reco_cluskeys.size();
259  if (nreco > 0)
260  {
261  // Find a matching reco cluster with position inside 4 sigmas, and replace reco_cluskey
262  for (const auto& this_ckey : reco_cluskeys)
263  {
264  // get the cluster
265  TrkrCluster* this_cluster = _clustermap->findCluster(this_ckey);
266  auto global = getGlobalPosition(this_ckey, this_cluster);
267  double this_x = global(0);
268  double this_y = global(1);
269  double this_z = global(2);
270  double this_rphi = gr * atan2(this_y, this_x);
271  // double this_rphi = gr*fast_approx_atan2(this_y, this_x);
272 
273  // Find the difference in position from the g4cluster
274  double dz = this_z - gz;
275  double drphi = this_rphi - grphi;
276 
277  // approximate 4 sigmas cut
278  if (truth_layer > 6 && truth_layer < 23)
279  {
280  if (fabs(drphi) < 4.0 * sig_tpc_rphi_inner &&
281  fabs(dz) < 4.0 * sig_tpc_z)
282  {
283  return std::make_pair(this_ckey, this_cluster);
284  }
285  }
286  if (truth_layer > 22 && truth_layer < 39)
287  {
288  if (fabs(drphi) < 4.0 * sig_tpc_rphi_mid &&
289  fabs(dz) < 4.0 * sig_tpc_z)
290  {
291  return std::make_pair(this_ckey, this_cluster);
292  }
293  }
294  if (truth_layer > 38 && truth_layer < 55)
295  {
296  if (fabs(drphi) < 4.0 * sig_tpc_rphi_outer &&
297  fabs(dz) < 4.0 * sig_tpc_z)
298  {
299  return std::make_pair(this_ckey, this_cluster);
300  }
301  }
302  else if (truth_layer < 3)
303  {
304  if (fabs(drphi) < 4.0 * sig_mvtx_rphi &&
305  fabs(dz) < 4.0 * sig_mvtx_z)
306  {
307  return std::make_pair(this_ckey, this_cluster);
308  }
309  }
310  else if (truth_layer == 55)
311  {
312  if (fabs(drphi) < 4.0 * sig_mms_rphi_55)
313  {
314  return std::make_pair(this_ckey, this_cluster);
315  }
316  }
317  else if (truth_layer == 56)
318  {
319  if (fabs(dz) < 4.0 * sig_mms_z_56)
320  {
321  return std::make_pair(this_ckey, this_cluster);
322  }
323  }
324  else
325  {
326  if (fabs(drphi) < 4.0 * sig_intt_rphi &&
327  fabs(dz) < range_intt_z)
328  {
329  return std::make_pair(this_ckey, this_cluster);
330  }
331  }
332  }
333  }
334 
335  return std::make_pair(0, nullptr);
336 }
337 
338 std::set<PHG4Hit*> SvtxClusterEval::all_truth_hits(TrkrDefs::cluskey cluster_key)
339 {
340  if (!has_node_pointers())
341  {
342  ++_errors;
343  return std::set<PHG4Hit*>();
344  }
345 
346  if (_do_cache)
347  {
348  std::map<TrkrDefs::cluskey, std::set<PHG4Hit*>>::iterator iter =
349  _cache_all_truth_hits.find(cluster_key);
350  if (iter != _cache_all_truth_hits.end())
351  {
352  return iter->second;
353  }
354  }
355 
356  std::set<PHG4Hit*> truth_hits;
357 
358  // get all truth hits for this cluster
359  //_cluster_hit_map->identify();
360  std::pair<std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator, std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator>
361  hitrange = _cluster_hit_map->getHits(cluster_key); // returns range of pairs {cluster key, hit key} for this cluskey
362 
363  for (std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator
364  clushititer = hitrange.first;
365  clushititer != hitrange.second; ++clushititer)
366  {
367  TrkrDefs::hitkey hitkey = clushititer->second;
368  // TrkrHitTruthAssoc uses a map with (hitsetkey, std::pair(hitkey, g4hitkey)) - get the hitsetkey from the cluskey
370 
371  // get all of the g4hits for this hitkey
372  std::multimap<TrkrDefs::hitsetkey, std::pair<TrkrDefs::hitkey, PHG4HitDefs::keytype>> temp_map;
373  _hit_truth_map->getG4Hits(hitsetkey, hitkey, temp_map);
374  // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only
375 
376  for (auto& htiter : temp_map)
377  {
378  // extract the g4 hit key here and add the hits to the set
379  PHG4HitDefs::keytype g4hitkey = htiter.second.second;
380  PHG4Hit* g4hit = nullptr;
381  unsigned int trkrid = TrkrDefs::getTrkrId(hitsetkey);
382  switch (trkrid)
383  {
384  case TrkrDefs::tpcId:
385  g4hit = _g4hits_tpc->findHit(g4hitkey);
386  break;
387  case TrkrDefs::inttId:
388  g4hit = _g4hits_intt->findHit(g4hitkey);
389  break;
390  case TrkrDefs::mvtxId:
391  g4hit = _g4hits_mvtx->findHit(g4hitkey);
392  break;
394  g4hit = _g4hits_mms->findHit(g4hitkey);
395  break;
396  default:
397  break;
398  }
399  if (g4hit)
400  {
401  truth_hits.insert(g4hit);
402  }
403  } // end loop over g4hits associated with hitsetkey and hitkey
404  } // end loop over hits associated with cluskey
405 
406  if (_do_cache)
407  {
408  _cache_all_truth_hits.insert(std::make_pair(cluster_key, truth_hits));
409  }
410 
411  return truth_hits;
412 }
413 
415 {
416  if (!has_node_pointers())
417  {
418  ++_errors;
419  return nullptr;
420  }
421 
422  // if (_strict)
423  // {
424  // assert(cluster_key);
425  // }
426  // else if (!cluster_key)
427  // {
428  // ++_errors;
429  // return std::set<PHG4Hit*>();
430  // }
431  /*
432  if (_do_cache)
433  {
434  std::map<TrkrDefs::cluskey, std::set<PHG4Hit*> >::iterator iter =
435  _cache_all_truth_hits.find(cluster_key);
436  if (iter != _cache_all_truth_hits.end())
437  {
438  return iter->second;
439  }
440  }
441  */
442  TrkrCluster* cluster = _clustermap->findCluster(cluster_key);
443  auto glob = getGlobalPosition(cluster_key, cluster);
444  TVector3 cvec(glob(0), glob(1), glob(2));
445  unsigned int layer = TrkrDefs::getLayer(cluster_key);
446  std::set<PHG4Hit*> truth_hits;
447 
448  std::multimap<PHG4HitDefs::keytype, TrkrDefs::hitkey> g4keyperhit;
449  std::vector<PHG4HitDefs::keytype> g4hitkeys;
450  // get all truth hits for this cluster
451  //_cluster_hit_map->identify();
453 
454  std::pair<std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator, std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator>
455  hitrange = _cluster_hit_map->getHits(cluster_key); // returns range of pairs {cluster key, hit key} for this cluskey
456  for (std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator
457  clushititer = hitrange.first;
458  clushititer != hitrange.second; ++clushititer)
459  {
460  TrkrDefs::hitkey hitkey = clushititer->second;
461  // TrkrHitTruthAssoc uses a map with (hitsetkey, std::pair(hitkey, g4hitkey)) - get the hitsetkey from the cluskey
462 
463  // get all of the g4hits for this hitkey
464  std::multimap<TrkrDefs::hitsetkey, std::pair<TrkrDefs::hitkey, PHG4HitDefs::keytype>> temp_map;
465  _hit_truth_map->getG4Hits(hitsetkey, hitkey, temp_map); // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only
466  for (auto& htiter : temp_map)
467  {
468  // extract the g4 hit key here and add the hits to the set
469  PHG4HitDefs::keytype g4hitkey = htiter.second.second;
470  if (_verbosity > 2)
471  {
472  std::cout << " g4key: " << g4hitkey << " layer: " << layer << std::endl;
473  }
474  TrkrDefs::hitkey local_hitkey = htiter.second.first;
475  /* if(layer>=7){
476  PHG4Hit *match_g4hit = _g4hits_tpc->findHit(g4hitkey);
477  if(layer != match_g4hit->get_layer() ) continue;
478  }
479  */
480  g4keyperhit.insert(std::pair<PHG4HitDefs::keytype, TrkrDefs::hitkey>(g4hitkey, local_hitkey));
481  std::vector<PHG4HitDefs::keytype>::iterator itg4keys = find(g4hitkeys.begin(), g4hitkeys.end(), g4hitkey);
482  if (itg4keys == g4hitkeys.end())
483  {
484  g4hitkeys.push_back(g4hitkey);
485  }
486  } // end loop over g4hits associated with hitsetkey and hitkey
487  } // end loop over hits associated with cluskey
488 
489  // if (_do_cache) _cache_all_truth_hits.insert(std::make_pair(cluster_key, truth_hits));
490  PHG4HitDefs::keytype max_key = 0;
491  unsigned int n_max = 0;
492 
493  if (g4hitkeys.size() == 1)
494  {
495  std::vector<PHG4HitDefs::keytype>::iterator it = g4hitkeys.begin();
496  max_key = *it;
497  }
498  else
499  {
500  for (unsigned long long& g4hitkey : g4hitkeys)
501  {
502  unsigned int ng4hit = g4keyperhit.count(g4hitkey);
503  PHG4Hit* this_g4hit = _g4hits_tpc->findHit(g4hitkey);
504 
505  if (layer >= 7)
506  { // in tpc
507  if (this_g4hit != nullptr)
508  {
509  unsigned int glayer = this_g4hit->get_layer();
510  if (layer != glayer)
511  {
512  continue;
513  }
514 
515  TVector3 vec(this_g4hit->get_avg_x(), this_g4hit->get_avg_y(), this_g4hit->get_avg_z());
516  // std::cout << "layer: " << layer << " (" << glayer << ") " << " gtrackID: " << this_g4hit->get_trkid() << " novlp: " << ng4hit << " phi: " << vec.Phi() << " z: " << this_g4hit->get_avg_z() << " r: " << vec.Perp() << " keyg4: " << *it << std::endl; //<< " keyrec: "<< *it.second << std::endl;
517  }
518  /*else{
519  std::cout << "g4hit == NULL " << std::endl;
520  }
521  */
522  }
523  if (ng4hit > n_max)
524  {
525  max_key = g4hitkey;
526  n_max = ng4hit;
527  }
528  }
529  }
530 
531  PHG4Hit* g4hit = nullptr;
532  unsigned int trkrid = TrkrDefs::getTrkrId(hitsetkey);
533  switch (trkrid)
534  {
535  case TrkrDefs::tpcId:
536  g4hit = _g4hits_tpc->findHit(max_key);
537  break;
538  case TrkrDefs::inttId:
539  g4hit = _g4hits_intt->findHit(max_key);
540  break;
541  case TrkrDefs::mvtxId:
542  g4hit = _g4hits_mvtx->findHit(max_key);
543  break;
545  g4hit = _g4hits_mms->findHit(max_key);
546  break;
547  default:
548  break;
549  }
550  if (g4hit)
551  {
552  truth_hits.insert(g4hit);
553  }
554 
555  return g4hit;
556 }
557 
559 {
560  if (!has_node_pointers())
561  {
562  ++_errors;
563  return std::make_pair(0, 0);
564  }
565 
566  // if (_strict)
567  // {
568  // assert(cluster_key);
569  // }
570  // else if (!cluster_key)
571  // {
572  // ++_errors;
573  // return std::set<PHG4Hit*>();
574  // }
575  /*
576  if (_do_cache)
577  {
578  std::map<TrkrDefs::cluskey, std::set<PHG4Hit*> >::iterator iter =
579  _cache_all_truth_hits.find(cluster_key);
580  if (iter != _cache_all_truth_hits.end())
581  {
582  return iter->second;
583  }
584  }
585  */
586 
587  std::pair<int, int> out_pair;
588  out_pair.first = 0;
589  out_pair.second = -1;
590 
591  TrkrCluster* cluster = _clustermap->findCluster(cluster_key);
592  auto global = getGlobalPosition(cluster_key, cluster);
593  TVector3 cvec(global(0), global(1), global(2));
594  unsigned int layer = TrkrDefs::getLayer(cluster_key);
595 
596  std::multimap<PHG4HitDefs::keytype, TrkrDefs::hitkey> g4keyperhit;
597  std::vector<PHG4HitDefs::keytype> g4hitkeys;
598  // get all truth hits for this cluster
599  //_cluster_hit_map->identify();
601 
602  std::pair<std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator, std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator>
603  hitrange = _cluster_hit_map->getHits(cluster_key); // returns range of pairs {cluster key, hit key} for this cluskey
604  for (std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator
605  clushititer = hitrange.first;
606  clushititer != hitrange.second; ++clushititer)
607  {
608  TrkrDefs::hitkey hitkey = clushititer->second;
609  // TrkrHitTruthAssoc uses a map with (hitsetkey, std::pair(hitkey, g4hitkey)) - get the hitsetkey from the cluskey
610 
611  // get all of the g4hits for this hitkey
612  std::multimap<TrkrDefs::hitsetkey, std::pair<TrkrDefs::hitkey, PHG4HitDefs::keytype>> temp_map;
613  _hit_truth_map->getG4Hits(hitsetkey, hitkey, temp_map); // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only
614 
615  for (auto& htiter : temp_map)
616  {
617  // extract the g4 hit key here and add the hits to the set
618  PHG4HitDefs::keytype g4hitkey = htiter.second.second;
619  if (_verbosity > 2)
620  {
621  std::cout << " g4key: " << g4hitkey << " layer: " << layer << std::endl;
622  }
623  TrkrDefs::hitkey local_hitkey = htiter.second.first;
624  /* if(layer>=7){
625  PHG4Hit *match_g4hit = _g4hits_tpc->findHit(g4hitkey);
626  if(layer != match_g4hit->get_layer() ) continue;
627  }
628  */
629  g4keyperhit.insert(std::pair<PHG4HitDefs::keytype, TrkrDefs::hitkey>(g4hitkey, local_hitkey));
630  std::vector<PHG4HitDefs::keytype>::iterator itg4keys = find(g4hitkeys.begin(), g4hitkeys.end(), g4hitkey);
631  if (itg4keys == g4hitkeys.end())
632  {
633  g4hitkeys.push_back(g4hitkey);
634  }
635  } // end loop over g4hits associated with hitsetkey and hitkey
636  } // end loop over hits associated with cluskey
637 
638  PHG4HitDefs::keytype max_key = 0;
639  unsigned int n_max = 0;
640  if (_verbosity > 2)
641  {
642  std::cout << " n matches found: " << g4hitkeys.size() << " phi: " << cvec.Phi() << " z: " << cvec.Z() << " ckey: " << cluster_key << std::endl;
643  }
644 
645  if (g4hitkeys.size() == 1)
646  {
647  std::vector<PHG4HitDefs::keytype>::iterator it = g4hitkeys.begin();
648  max_key = *it;
649  }
650  else
651  {
652  for (unsigned long long& g4hitkey : g4hitkeys)
653  {
654  unsigned int ng4hit = g4keyperhit.count(g4hitkey);
655  PHG4Hit* this_g4hit = _g4hits_tpc->findHit(g4hitkey);
656 
657  if (layer >= 7)
658  { // in tpc
659  if (this_g4hit != nullptr)
660  {
661  unsigned int glayer = this_g4hit->get_layer();
662  // if(layer != glayer) continue;
663 
664  TVector3 vec(this_g4hit->get_avg_x(), this_g4hit->get_avg_y(), this_g4hit->get_avg_z());
665  if (_verbosity > 2)
666  {
667  std::cout << "layer: " << layer << " (" << glayer << ") "
668  << " gtrackID: " << this_g4hit->get_trkid() << " novlp: " << ng4hit << " phi: " << vec.Phi() << " z: " << this_g4hit->get_avg_z() << " r: " << vec.Perp() << " keyg4: " << g4hitkey << " cz: " << cluster->getZ() << std::endl; //<< " keyrec: "<< *it.second << std::endl;
669  }
670  }
671  }
672  if (ng4hit > n_max)
673  {
674  max_key = g4hitkey;
675  n_max = ng4hit;
676  }
677  }
678  }
679  if (_verbosity > 2)
680  {
681  std::cout << "found in layer: " << layer << " n_max: " << n_max << " max_key: " << max_key << " ckey: " << cluster_key << std::endl;
682  }
683  if (max_key != 0)
684  {
685  PHG4Hit* g4hit = nullptr;
686  unsigned int trkrid = TrkrDefs::getTrkrId(hitsetkey);
687  switch (trkrid)
688  {
689  case TrkrDefs::tpcId:
690  g4hit = _g4hits_tpc->findHit(max_key);
691  break;
692  case TrkrDefs::inttId:
693  g4hit = _g4hits_intt->findHit(max_key);
694  break;
695  case TrkrDefs::mvtxId:
696  g4hit = _g4hits_mvtx->findHit(max_key);
697  break;
699  g4hit = _g4hits_mms->findHit(max_key);
700  break;
701  default:
702  break;
703  }
704 
705  // check if we on a looper
706  PHG4Particle* g4particle = _truthinfo->GetParticle(g4hit->get_trkid());
707 
708  PHG4VtxPoint* vtx = _truthinfo->GetVtx(g4particle->get_vtx_id());
709  float vtx_z = vtx->get_z();
710  float gpx = g4particle->get_px();
711  float gpy = g4particle->get_py();
712  float gpz = g4particle->get_pz();
713  float gpeta = NAN;
714 
715  TVector3 gv(gpx, gpy, gpz);
716  gpeta = gv.Eta();
717  TVector3 this_vec(g4hit->get_avg_x(),
718  g4hit->get_avg_y(),
719  g4hit->get_avg_z() - vtx_z);
720  double deta = TMath::Abs(gpeta - this_vec.Eta());
721 
722  int is_loop = 0;
723 
724  if (layer >= 7)
725  {
726  // std::cout << " in tpc " << std::endl;
727  if (deta > 0.1)
728  {
729  is_loop = 1;
730  }
731  }
732 
733  out_pair.first = g4hit->get_trkid();
734  if (!is_loop)
735  {
736  out_pair.second = layer;
737  }
738  }
739  return out_pair;
740 }
741 
743 {
744  if (!has_node_pointers())
745  {
746  ++_errors;
747  return nullptr;
748  }
749 
750  if (_do_cache)
751  {
752  std::map<TrkrDefs::cluskey, PHG4Hit*>::iterator iter =
753  _cache_max_truth_hit_by_energy.find(cluster_key);
754  if (iter != _cache_max_truth_hit_by_energy.end())
755  {
756  return iter->second;
757  }
758  }
759 
760  std::set<PHG4Hit*> hits = all_truth_hits(cluster_key);
761  PHG4Hit* max_hit = nullptr;
762  float max_e = FLT_MAX * -1.0;
763  for (auto hit : hits)
764  {
765  if (hit->get_edep() > max_e)
766  {
767  max_e = hit->get_edep();
768  max_hit = hit;
769  }
770  }
771 
772  if (_do_cache)
773  {
774  _cache_max_truth_hit_by_energy.insert(std::make_pair(cluster_key, max_hit));
775  }
776 
777  return max_hit;
778 }
779 
780 std::set<PHG4Particle*> SvtxClusterEval::all_truth_particles(TrkrDefs::cluskey cluster_key)
781 {
782  if (!has_node_pointers())
783  {
784  ++_errors;
785  return std::set<PHG4Particle*>();
786  }
787 
788  if (_do_cache)
789  {
790  std::map<TrkrDefs::cluskey, std::set<PHG4Particle*>>::iterator iter =
791  _cache_all_truth_particles.find(cluster_key);
792  if (iter != _cache_all_truth_particles.end())
793  {
794  return iter->second;
795  }
796  }
797 
798  std::set<PHG4Particle*> truth_particles;
799 
800  std::set<PHG4Hit*> g4hits = all_truth_hits(cluster_key);
801 
802  for (auto hit : g4hits)
803  {
805  // std::cout << "cluster key " << cluster_key << " has hit " << hit->get_hit_id() << " and has particle " << particle->get_track_id() << std::endl;
806 
807  if (_strict)
808  {
809  assert(particle);
810  }
811  else if (!particle)
812  {
813  ++_errors;
814  continue;
815  }
816 
817  truth_particles.insert(particle);
818  }
819 
820  if (_do_cache)
821  {
822  _cache_all_truth_particles.insert(std::make_pair(cluster_key, truth_particles));
823  }
824 
825  return truth_particles;
826 }
827 
829 {
830  if (!has_node_pointers())
831  {
832  ++_errors;
833  return nullptr;
834  }
835 
836  if (_do_cache)
837  {
838  std::map<TrkrDefs::cluskey, PHG4Particle*>::iterator iter =
841  {
842  return iter->second;
843  }
844  }
845 
846  unsigned int layer = TrkrDefs::getLayer(cluster_key);
847 
848  // loop over all particles associated with this cluster and
849  // get the energy contribution for each one, record the max
850  PHG4Particle* max_particle = nullptr;
851  float max_e = FLT_MAX * -1.0;
852  std::set<PHG4Particle*> particles = all_truth_particles(cluster_key);
853  for (auto particle : particles)
854  {
855  std::map<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>> truth_clus = get_truth_eval()->all_truth_clusters(particle);
856  for (const auto& [ckey, cluster] : truth_clus)
857  {
858  if (TrkrDefs::getLayer(ckey) == layer)
859  {
860  float e = cluster->getError(0, 0);
861  if (e > max_e)
862  {
863  max_e = e;
864  max_particle = particle;
865  }
866  }
867  }
868  }
869 
870  if (_do_cache)
871  {
872  _cache_max_truth_particle_by_cluster_energy.insert(std::make_pair(cluster_key, max_particle));
873  }
874 
875  return max_particle;
876 }
877 
879 {
880  // Note: this does not quite work correctly for the TPC - it assumes one g4hit per layer
881  // use max_truth_particle_by_cluster_energy instead
882 
883  if (!has_node_pointers())
884  {
885  ++_errors;
886  return nullptr;
887  }
888 
889  if (_do_cache)
890  {
891  std::map<TrkrDefs::cluskey, PHG4Particle*>::iterator iter =
892  _cache_max_truth_particle_by_energy.find(cluster_key);
893  if (iter != _cache_max_truth_particle_by_energy.end())
894  {
895  return iter->second;
896  }
897  }
898 
899  // loop over all particles associated with this cluster and
900  // get the energy contribution for each one, record the max
901  PHG4Particle* max_particle = nullptr;
902  float max_e = FLT_MAX * -1.0;
903  std::set<PHG4Particle*> particles = all_truth_particles(cluster_key);
904  for (auto particle : particles)
905  {
906  float e = get_energy_contribution(cluster_key, particle);
907  if (e > max_e)
908  {
909  max_e = e;
910  max_particle = particle;
911  }
912  }
913 
914  if (_do_cache)
915  {
916  _cache_max_truth_particle_by_energy.insert(std::make_pair(cluster_key, max_particle));
917  }
918 
919  return max_particle;
920 }
921 
922 std::set<TrkrDefs::cluskey> SvtxClusterEval::all_clusters_from(PHG4Particle* truthparticle)
923 {
924  if (!has_node_pointers())
925  {
926  ++_errors;
927  return std::set<TrkrDefs::cluskey>();
928  }
929 
930  if (_strict)
931  {
932  assert(truthparticle);
933  }
934  else if (!truthparticle)
935  {
936  ++_errors;
937  return std::set<TrkrDefs::cluskey>();
938  }
939  // check if cache is filled, if not fill it.
940  // if(_cache_all_clusters_from_particle.count(truthparticle)==0){
942  {
944  }
945 
946  if (_do_cache)
947  {
948  std::map<PHG4Particle*, std::set<TrkrDefs::cluskey>>::iterator iter =
949  _cache_all_clusters_from_particle.find(truthparticle);
950  if (iter != _cache_all_clusters_from_particle.end())
951  {
952  return iter->second;
953  }
954  }
955  std::set<TrkrDefs::cluskey> clusters;
956  return clusters;
957 }
958 
960 {
961  auto Mytimer = std::make_unique<PHTimer>("ReCl_timer");
962  Mytimer->stop();
963  Mytimer->restart();
964 
965  std::multimap<PHG4Particle*, TrkrDefs::cluskey> temp_clusters_from_particles;
966  // loop over all the clusters
967  for (const auto& hitsetkey : _clustermap->getHitSetKeys())
968  {
969  auto range = _clustermap->getClusters(hitsetkey);
970  for (auto iter = range.first; iter != range.second; ++iter)
971  {
972  TrkrDefs::cluskey cluster_key = iter->first;
973 
974  // loop over all truth particles connected to this cluster
975  std::set<PHG4Particle*> particles = all_truth_particles(cluster_key);
976  for (auto candidate : particles)
977  {
978  temp_clusters_from_particles.insert(std::make_pair(candidate, cluster_key));
979  }
980  }
981  }
982  // Loop over particles and fill cache
984  for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
985  iter != range.second; ++iter)
986  {
987  PHG4Particle* g4particle = iter->second;
988  std::set<TrkrDefs::cluskey> clusters;
989  std::multimap<PHG4Particle*, TrkrDefs::cluskey>::const_iterator lower_bound = temp_clusters_from_particles.lower_bound(g4particle);
990  std::multimap<PHG4Particle*, TrkrDefs::cluskey>::const_iterator upper_bound = temp_clusters_from_particles.upper_bound(g4particle);
991  std::multimap<PHG4Particle*, TrkrDefs::cluskey>::const_iterator cfp_iter;
992  for (cfp_iter = lower_bound; cfp_iter != upper_bound; ++cfp_iter)
993  {
994  TrkrDefs::cluskey cluster_key = cfp_iter->second;
995  clusters.insert(cluster_key);
996  }
997  _cache_all_clusters_from_particle.insert(std::make_pair(g4particle, clusters));
998  }
999 
1000  Mytimer->stop();
1001 }
1002 
1003 std::set<TrkrDefs::cluskey> SvtxClusterEval::all_clusters_from(PHG4Hit* truthhit)
1004 {
1005  if (!has_node_pointers())
1006  {
1007  ++_errors;
1008  return std::set<TrkrDefs::cluskey>();
1009  }
1010 
1011  if (_strict)
1012  {
1013  assert(truthhit);
1014  }
1015  else if (!truthhit)
1016  {
1017  ++_errors;
1018  return std::set<TrkrDefs::cluskey>();
1019  }
1020 
1021  // one time, fill cache of g4hit/cluster pairs
1022  if (_cache_all_clusters_from_g4hit.size() == 0)
1023  {
1024  // make a map of truthhit, cluster_key inside this loop
1025  std::multimap<PHG4HitDefs::keytype, TrkrDefs::cluskey> truth_cluster_map;
1026  std::set<PHG4HitDefs::keytype> all_g4hits_set;
1027  std::map<PHG4HitDefs::keytype, PHG4Hit*> all_g4hits_map;
1028 
1029  // get all reco clusters
1030  if (_verbosity > 1)
1031  {
1032  std::cout << "all_clusters_from_g4hit: list all reco clusters " << std::endl;
1033  }
1034 
1035  for (const auto& hitsetkey : _clustermap->getHitSetKeys())
1036  {
1037  auto range = _clustermap->getClusters(hitsetkey);
1038  for (auto iter = range.first; iter != range.second; ++iter)
1039  {
1040  TrkrDefs::cluskey cluster_key = iter->first;
1041  int layer = TrkrDefs::getLayer(cluster_key);
1042  TrkrCluster* clus = iter->second;
1043  if (_verbosity > 1)
1044  {
1045  std::cout << " layer " << layer << " cluster_key " << cluster_key << " adc " << clus->getAdc()
1046  << " localx " << clus->getLocalX()
1047  << " localy " << clus->getLocalY()
1048  << std::endl;
1049  std::cout << " associated hits:";
1050  std::pair<std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator, std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator>
1051  hitrange = _cluster_hit_map->getHits(cluster_key); // returns range of pairs {cluster key, hit key} for this cluskey
1052  for (std::multimap<TrkrDefs::cluskey, TrkrDefs::hitkey>::const_iterator
1053  clushititer = hitrange.first;
1054  clushititer != hitrange.second; ++clushititer)
1055  {
1056  TrkrDefs::hitkey hitkey = clushititer->second;
1057  std::cout << " " << hitkey;
1058  }
1059  std::cout << std::endl;
1060  }
1061 
1062  // the returned truth hits were obtained from TrkrAssoc maps
1063  std::set<PHG4Hit*> hits = all_truth_hits(cluster_key);
1064  for (auto candidate : hits)
1065  {
1066  PHG4HitDefs::keytype g4hit_key = candidate->get_hit_id();
1067 
1068  if (_verbosity > 5)
1069  {
1070  int gtrackID = candidate->get_trkid();
1071  std::cout << " adding cluster with cluster_key " << cluster_key << " g4hit with g4hit_key " << g4hit_key
1072  << " gtrackID " << gtrackID
1073  << std::endl;
1074  }
1075 
1076  all_g4hits_set.insert(g4hit_key);
1077  all_g4hits_map.insert(std::make_pair(g4hit_key, candidate));
1078 
1079  truth_cluster_map.insert(std::make_pair(g4hit_key, cluster_key));
1080  }
1081  }
1082  }
1083 
1084  // now fill the cache
1085  // loop over all entries in all_g4hits
1086  for (unsigned long long g4hit_key : all_g4hits_set)
1087  {
1088  if (_verbosity > 5)
1089  {
1090  std::cout << " associations for g4hit_key " << g4hit_key << std::endl;
1091  }
1092 
1093  std::map<PHG4HitDefs::keytype, PHG4Hit*>::iterator it = all_g4hits_map.find(g4hit_key);
1094  PHG4Hit* g4hit = it->second;
1095 
1096  std::set<TrkrDefs::cluskey> assoc_clusters;
1097 
1098  std::pair<std::multimap<PHG4HitDefs::keytype, TrkrDefs::cluskey>::iterator,
1099  std::multimap<PHG4HitDefs::keytype, TrkrDefs::cluskey>::iterator>
1100  ret = truth_cluster_map.equal_range(g4hit_key);
1101  for (std::multimap<PHG4HitDefs::keytype, TrkrDefs::cluskey>::iterator jter = ret.first; jter != ret.second; ++jter)
1102  {
1103  assoc_clusters.insert(jter->second);
1104 
1105  if (_verbosity > 5)
1106  {
1107  std::cout << " g4hit_key " << g4hit_key << " associated with cluster_key " << jter->second << std::endl;
1108  }
1109  }
1110  // done with this g4hit
1111  _cache_all_clusters_from_g4hit.insert(std::make_pair(g4hit, assoc_clusters));
1112  }
1113  }
1114 
1115  // get the clusters
1116  std::set<TrkrDefs::cluskey> clusters;
1117  std::map<PHG4Hit*, std::set<TrkrDefs::cluskey>>::iterator iter =
1118  _cache_all_clusters_from_g4hit.find(truthhit);
1119  if (iter != _cache_all_clusters_from_g4hit.end())
1120  {
1121  return iter->second;
1122  }
1123 
1124  if (_clusters_per_layer.size() == 0)
1125  {
1127  }
1128 
1129  return clusters;
1130 }
1131 
1133 {
1134  TrkrDefs::cluskey val = 0;
1135  if (!has_node_pointers())
1136  {
1137  ++_errors;
1138  return val;
1139  }
1140 
1141  /* if (_strict)
1142  {
1143  assert(truthhit);
1144  }
1145  else if (!truthhit)
1146  {
1147  ++_errors;
1148  return val;
1149  }
1150  */
1151  // one time, fill cache of g4hit/cluster pairs
1153  {
1154  // get all reco clusters
1155  // std::cout << "cache size ==0" << std::endl;
1156  if (_verbosity > 1)
1157  {
1158  std::cout << "all_clusters: found # " << _clustermap->size() << std::endl;
1159  }
1160 
1161  for (const auto& hitsetkey : _clustermap->getHitSetKeys())
1162  {
1163  auto range = _clustermap->getClusters(hitsetkey);
1164  for (auto iter = range.first; iter != range.second; ++iter)
1165  {
1166  TrkrDefs::cluskey cluster_key = iter->first;
1167  int layer_in = TrkrDefs::getLayer(cluster_key);
1168 
1169  if (layer_in < 0)
1170  {
1171  continue;
1172  }
1173  // TrkrCluster *clus = iter->second;
1174 
1175  std::pair<int, int> gid_lay = gtrackid_and_layer_by_nhit(cluster_key);
1176 
1177  // std::map<std::pair<int, unsigned int>, TrkrDefs::cluskey>::iterator it_exists;
1178  // it_exists =
1179  if (_cache_best_cluster_from_gtrackid_layer.count(gid_lay) == 0)
1180  {
1181  if (gid_lay.second >= 0)
1182  {
1183  _cache_best_cluster_from_gtrackid_layer.insert(std::make_pair(gid_lay, cluster_key));
1184  }
1185  }
1186  else if (_verbosity > 2)
1187  {
1188  std::cout << "found doublematch" << std::endl;
1189  std::cout << "ckey: " << cluster_key << " gtrackID: " << gid_lay.first << " layer: " << gid_lay.second << std::endl;
1190  }
1191  }
1192  }
1193  }
1194 
1195  // get the clusters
1196  TrkrDefs::cluskey best_cluster = 0;
1197  // PHG4Hit*, std::set<TrkrDefs::cluskey> >::iterator iter =
1198 
1199  std::map<std::pair<int, int>, TrkrDefs::cluskey>::iterator iter = _cache_best_cluster_from_gtrackid_layer.find(std::make_pair(gid, layer));
1200  if (iter != _cache_best_cluster_from_gtrackid_layer.end())
1201  {
1202  return iter->second;
1203  }
1204 
1205  return best_cluster;
1206 }
1207 
1209 {
1210  if (!has_node_pointers())
1211  {
1212  ++_errors;
1213  return 0;
1214  }
1215 
1216  if (_strict)
1217  {
1218  assert(truthhit);
1219  }
1220  else if (!truthhit)
1221  {
1222  ++_errors;
1223  return 0;
1224  }
1225 
1226  if (_do_cache)
1227  {
1228  std::map<PHG4Hit*, TrkrDefs::cluskey>::iterator iter =
1229  _cache_best_cluster_from_g4hit.find(truthhit);
1230  if (iter != _cache_best_cluster_from_g4hit.end())
1231  {
1232  return iter->second;
1233  }
1234  }
1235 
1236  TrkrDefs::cluskey best_cluster = 0;
1237  float best_energy = 0.0;
1238  std::set<TrkrDefs::cluskey> clusters = all_clusters_from(truthhit);
1239  for (unsigned long cluster_key : clusters)
1240  {
1241  float energy = get_energy_contribution(cluster_key, truthhit);
1242  if (energy > best_energy)
1243  {
1244  best_cluster = cluster_key;
1245  best_energy = energy;
1246  }
1247  }
1248 
1249  if (_do_cache)
1250  {
1251  _cache_best_cluster_from_g4hit.insert(std::make_pair(truthhit, best_cluster));
1252  }
1253 
1254  return best_cluster;
1255 }
1256 
1257 // overlap calculations
1259 {
1260  // Note: this does not work correctly for the TPC
1261  // It assumes one g4hit per layer. Use the truth cluster energy instead.
1262 
1263  if (!has_node_pointers())
1264  {
1265  ++_errors;
1266  return NAN;
1267  }
1268 
1269  if (_strict)
1270  {
1271  // assert(cluster_key);
1272  assert(particle);
1273  }
1274  else if (!particle)
1275  {
1276  ++_errors;
1277  return NAN;
1278  }
1279 
1280  if (_do_cache)
1281  {
1282  std::map<std::pair<TrkrDefs::cluskey, PHG4Particle*>, float>::iterator iter =
1283  _cache_get_energy_contribution_g4particle.find(std::make_pair(cluster_key, particle));
1285  {
1286  return iter->second;
1287  }
1288  }
1289 
1290  float energy = 0.0;
1291  std::set<PHG4Hit*> hits = all_truth_hits(cluster_key);
1292  for (auto hit : hits)
1293  {
1294  if (get_truth_eval()->is_g4hit_from_particle(hit, particle))
1295  {
1296  energy += hit->get_edep();
1297  }
1298  }
1299 
1300  if (_do_cache)
1301  {
1302  _cache_get_energy_contribution_g4particle.insert(std::make_pair(std::make_pair(cluster_key, particle), energy));
1303  }
1304 
1305  return energy;
1306 }
1307 
1309 {
1310  if (!has_node_pointers())
1311  {
1312  ++_errors;
1313  return NAN;
1314  }
1315 
1316  if (_strict)
1317  {
1318  // assert(cluster_key);
1319  assert(g4hit);
1320  }
1321  else if (!g4hit)
1322  {
1323  ++_errors;
1324  return NAN;
1325  }
1326 
1327  if ((_do_cache) &&
1328  (_cache_get_energy_contribution_g4hit.find(std::make_pair(cluster_key, g4hit)) !=
1330  {
1331  return _cache_get_energy_contribution_g4hit[std::make_pair(cluster_key, g4hit)];
1332  }
1333 
1334  // this is a fairly simple existance check right now, but might be more
1335  // complex in the future, so this is here mostly as future-proofing.
1336 
1337  float energy = 0.0;
1338  std::set<PHG4Hit*> g4hits = all_truth_hits(cluster_key);
1339  for (auto candidate : g4hits)
1340  {
1341  if (candidate->get_hit_id() != g4hit->get_hit_id())
1342  {
1343  continue;
1344  }
1345  energy += candidate->get_edep();
1346  }
1347 
1348  if (_do_cache)
1349  {
1350  _cache_get_energy_contribution_g4hit.insert(std::make_pair(std::make_pair(cluster_key, g4hit), energy));
1351  }
1352 
1353  return energy;
1354 }
1355 
1357 {
1358  // need things off of the DST...
1359 
1360  _clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "CORRECTED_TRKR_CLUSTER");
1361  if (!_clustermap)
1362  {
1363  _clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
1364  }
1365  else
1366  {
1369  if (_clustermap->size() == 0)
1370  {
1371  _clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
1372  }
1373  }
1374 
1375  _cluster_hit_map = findNode::getClass<TrkrClusterHitAssoc>(topNode, "TRKR_CLUSTERHITASSOC");
1376  _hit_truth_map = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
1377  _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
1378 
1379  _g4hits_tpc = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_TPC");
1380  _g4hits_intt = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_INTT");
1381  _g4hits_mvtx = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_MVTX");
1382  _g4hits_mms = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_MICROMEGAS");
1383  _tgeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
1384 
1385  return;
1386 }
1387 
1389 {
1390  // loop over all the clusters
1391  for (const auto& hitsetkey : _clustermap->getHitSetKeys())
1392  {
1393  auto range = _clustermap->getClusters(hitsetkey);
1394  for (auto iter = range.first; iter != range.second; ++iter)
1395  {
1396  TrkrDefs::cluskey cluster_key = iter->first;
1397  unsigned int ilayer = TrkrDefs::getLayer(cluster_key);
1398  TrkrCluster* cluster = iter->second;
1399  auto glob = getGlobalPosition(cluster_key, cluster);
1400  float clus_phi = atan2(glob(1), glob(0));
1401 
1402  std::multimap<unsigned int, innerMap>::iterator it = _clusters_per_layer.find(ilayer);
1403  if (it == _clusters_per_layer.end())
1404  {
1405  it = _clusters_per_layer.insert(std::make_pair(ilayer, innerMap()));
1406  }
1407  it->second.insert(std::make_pair(clus_phi, cluster_key));
1408 
1409  // address wrapping along +/-PI by filling larger area of the map
1410  if (clus_phi - (-M_PI) < _clusters_searching_window)
1411  {
1412  it->second.insert(std::make_pair(clus_phi + 2 * M_PI, cluster_key));
1413  }
1414  if (M_PI - clus_phi < _clusters_searching_window)
1415  {
1416  it->second.insert(std::make_pair(clus_phi - 2 * M_PI, cluster_key));
1417  }
1418  }
1419  }
1420  return;
1421 }
1422 
1424 {
1425  if (_strict)
1426  {
1428  }
1429  else if (!_clustermap)
1430  {
1431  return false;
1432  }
1433 
1434  if (_strict)
1435  {
1436  assert(_truthinfo);
1437  }
1438  else if (!_truthinfo)
1439  {
1440  return false;
1441  }
1442 
1443  return true;
1444 }
1445 
1447 {
1448  if (x != 0.0F)
1449  {
1450  if (fabsf(x) > fabsf(y))
1451  {
1452  const float z = y / x;
1453  if (x > 0.0)
1454  {
1455  // atan2(y,x) = atan(y/x) if x > 0
1456  return fast_approx_atan2(z);
1457  }
1458  else if (y >= 0.0)
1459  {
1460  // atan2(y,x) = atan(y/x) + PI if x < 0, y >= 0
1461  return fast_approx_atan2(z) + M_PI;
1462  }
1463  else
1464  {
1465  // atan2(y,x) = atan(y/x) - PI if x < 0, y < 0
1466  return fast_approx_atan2(z) - M_PI;
1467  }
1468  }
1469  else // Use property atan(y/x) = PI/2 - atan(x/y) if |y/x| > 1.
1470  {
1471  const float z = x / y;
1472  if (y > 0.0)
1473  {
1474  // atan2(y,x) = PI/2 - atan(x/y) if |y/x| > 1, y > 0
1475  return -fast_approx_atan2(z) + M_PI_2;
1476  }
1477  else
1478  {
1479  // atan2(y,x) = -PI/2 - atan(x/y) if |y/x| > 1, y < 0
1480  return -fast_approx_atan2(z) - M_PI_2;
1481  }
1482  }
1483  }
1484  else
1485  {
1486  if (y > 0.0F) // x = 0, y > 0
1487  {
1488  return M_PI_2;
1489  }
1490  else if (y < 0.0F) // x = 0, y < 0
1491  {
1492  return -M_PI_2;
1493  }
1494  }
1495  return 0.0F; // x,y = 0. Could return NaN instead.
1496 }
1497 
1499 {
1500  // Polynomial approximating arctangenet on the range -1,1.
1501  // Max error < 0.005 (or 0.29 degrees)
1502  const float n1 = 0.97239411F;
1503  const float n2 = -0.19194795F;
1504  return (n1 + n2 * z * z) * z;
1505 }
1506 
1508 {
1509  Acts::Vector3 glob;
1510  glob = _tgeometry->getGlobalPosition(cluster_key, cluster);
1511 
1512  return glob;
1513 }