Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHCosmicSeeder.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHCosmicSeeder.cc
1 
2 #include "PHCosmicSeeder.h"
3 
6 #include <phool/PHDataNode.h>
7 #include <phool/PHNode.h>
8 #include <phool/PHNodeIterator.h>
9 #include <phool/PHObject.h>
10 #include <phool/PHTimer.h>
11 #include <phool/getClass.h>
12 #include <phool/phool.h>
13 
14 #include <trackbase/TrkrCluster.h>
20 
21 #include <TFile.h>
22 #include <TNtuple.h>
23 namespace
24 {
25  template <class T>
26  inline constexpr T square(const T& x)
27  {
28  return x * x;
29  }
30  template <class T>
31  inline constexpr T r(const T& x, const T& y)
32  {
33  return std::sqrt(square(x) + square(y));
34  }
35 } // namespace
36 //____________________________________________________________________________..
38  : SubsysReco(name)
39 {
40 }
41 
42 //____________________________________________________________________________..
44 {
45 }
46 
47 //____________________________________________________________________________..
49 {
51 }
52 
53 //____________________________________________________________________________..
55 {
56  int ret = getNodes(topNode);
58  {
59  return ret;
60  }
61  ret = createNodes(topNode);
62 
63  if (m_analysis)
64  {
65  m_outfile = new TFile("PHCosmicSeeder.root", "recreate");
66  m_tup = new TNtuple("ntp_seed", "seed",
67  "event:seed:nclus:xyint:xyslope:rzint:rzslope:"
68  "longestxyint:longestxyslope:longestrzint:longestrzslope");
69  }
70 
71  return ret;
72 }
73 
74 //____________________________________________________________________________..
76 {
77  PHCosmicSeeder::PositionMap clusterPositions;
79  {
81  for (auto citer = range.first; citer != range.second; ++citer)
82  {
83  const auto ckey = citer->first;
84  const auto cluster = citer->second;
85  const auto global = m_tGeometry->getGlobalPosition(ckey, cluster);
86  clusterPositions.insert(std::make_pair(ckey, global));
87  }
88  }
89  if (Verbosity() > 2)
90  {
91  std::cout << "cluster map size is " << clusterPositions.size() << std::endl;
92  }
93  auto seeds = makeSeeds(clusterPositions);
94 
95  if (Verbosity() > 1)
96  {
97  std::cout << "Initial seed candidate size is " << seeds.size() << std::endl;
98  }
99  std::sort(seeds.begin(), seeds.end(),
100  [](seed a, seed b)
101  { return a.ckeys.size() > b.ckeys.size(); });
102 
103  auto prunedSeeds = combineSeeds(seeds, clusterPositions);
104  if (Verbosity() > 1)
105  {
106  std::cout << "Pruned seed size is " << prunedSeeds.size() << std::endl;
107  }
108  std::sort(prunedSeeds.begin(), prunedSeeds.end(),
109  [](seed a, seed b)
110  { return a.ckeys.size() > b.ckeys.size(); });
111 
112  auto finalSeeds = findIntersections(prunedSeeds);
113  if (Verbosity() > 1)
114  {
115  std::cout << "final seeds are " << finalSeeds.size() << std::endl;
116  }
117  for (auto& seed1 : finalSeeds)
118  {
119  recalculateSeedLineParameters(seed1, clusterPositions, true);
120 
121  recalculateSeedLineParameters(seed1, clusterPositions, false);
122  }
123  auto chainedSeeds = chainSeeds(finalSeeds, clusterPositions);
124  // auto chainedSeeds = finalSeeds;
125  if (Verbosity() > 1)
126  {
127  std::cout << "Total seeds found is " << chainedSeeds.size() << std::endl;
128  }
129  int iseed = 0;
130 
131  auto longestseedit = chainedSeeds.begin();
132  seed longestseed;
133  if (longestseedit != chainedSeeds.end())
134  {
135  longestseed = chainedSeeds.front();
136  }
137  for (auto& seed : chainedSeeds)
138  {
139  if (m_analysis)
140  {
141  float seed_data[] = {
142  (float) m_event,
143  (float) iseed,
144  (float) seed.ckeys.size(),
146  seed.xyslope,
148  seed.rzslope,
149  longestseed.xyintercept,
150  longestseed.xyslope,
151  longestseed.rzintercept,
152  longestseed.rzslope};
153  m_tup->Fill(seed_data);
154  }
155  auto svtxseed = std::make_unique<TrackSeed_v1>();
156  for (auto& key : seed.ckeys)
157  {
158  svtxseed->insert_cluster_key(key);
159  }
160  m_seedContainer->insert(svtxseed.get());
161  ++iseed;
162  }
163  ++m_event;
165 }
167 {
168  std::set<int> seedsToDelete;
170  for (int i = 0; i < initialSeeds.size(); ++i)
171  {
172  auto& seed1 = initialSeeds[i];
173  for (int j = i; j < initialSeeds.size(); ++j)
174  {
175  if (i == j)
176  {
177  continue;
178  }
179  auto& seed2 = initialSeeds[j];
180  std::vector<TrkrDefs::cluskey> intersection;
181  std::set_intersection(seed1.ckeys.begin(), seed1.ckeys.end(),
182  seed2.ckeys.begin(), seed2.ckeys.end(), std::back_inserter(intersection));
183  if (intersection.size() > 3)
184  {
187  for (auto key : seed2.ckeys)
188  {
189  seed1.ckeys.insert(key);
190  }
191  seedsToDelete.insert(j);
192  }
193  }
194  }
195 
196  SeedVector finalSeeds;
197  for (int i = 0; i < initialSeeds.size(); ++i)
198  {
199  if (seedsToDelete.find(i) != seedsToDelete.end())
200  {
201  continue;
202  }
203  if (initialSeeds[i].ckeys.size() < 4)
204  {
205  continue;
206  }
207  finalSeeds.push_back(initialSeeds[i]);
208  }
209  return finalSeeds;
210 }
212  PositionMap& clusterPositions)
213 {
214  PHCosmicSeeder::SeedVector returnseeds;
215  std::set<int> seedsToDelete;
216  for (int i = 0; i < initialSeeds.size(); ++i)
217  {
218  auto& seed1 = initialSeeds[i];
219  for (int j = i; j < initialSeeds.size(); ++j)
220  {
221  if (i == j)
222  {
223  continue;
224  }
225  auto& seed2 = initialSeeds[j];
226  recalculateSeedLineParameters(seed1, clusterPositions, true);
227  recalculateSeedLineParameters(seed2, clusterPositions, true);
228  recalculateSeedLineParameters(seed1, clusterPositions, false);
229  recalculateSeedLineParameters(seed2, clusterPositions, false);
230 
231  float longestxyslope = seed1.xyslope;
232  float longestxyint = seed1.xyintercept;
233  float longestrzslope = seed1.rzslope;
234  float longestrzint = seed1.rzintercept;
235  if (seed1.ckeys.size() < seed2.ckeys.size())
236  {
237  longestxyint = seed2.xyintercept;
238  longestxyslope = seed2.xyslope;
239  longestrzint = seed2.rzintercept;
240  longestrzslope = seed2.rzslope;
241  }
242 
243  float pdiff = fabs((seed1.xyslope - seed2.xyslope) / longestxyslope);
244  float pdiff2 = fabs((seed1.xyintercept - seed2.xyintercept) / longestxyint);
245  float pdiff3 = fabs((seed1.rzintercept - seed2.rzintercept) / longestrzint);
246  float pdiff4 = fabs((seed1.rzslope - seed2.rzslope) / longestrzslope);
247  if (pdiff < 1. && pdiff2 < 1. && pdiff3 < 1. && pdiff4 < 1.)
248  {
249  seedsToDelete.insert(j);
250  for (auto& key : seed2.ckeys)
251  {
252  seed1.ckeys.insert(key);
253  }
254  }
255  }
256  }
257  for (int i = 0; i < initialSeeds.size(); ++i)
258  {
259  if (seedsToDelete.find(i) != seedsToDelete.end())
260  {
261  continue;
262  }
263  returnseeds.push_back(initialSeeds[i]);
264  }
265 
266  return returnseeds;
267 }
269  PHCosmicSeeder::PositionMap& clusterPositions)
270 {
271  SeedVector prunedSeeds;
272  std::set<int> seedsToDelete;
273 
274  for (int i = 0; i < initialSeeds.size(); ++i)
275  {
276  for (int j = i; j < initialSeeds.size(); ++j)
277  {
278  if (i == j)
279  {
280  continue;
281  }
282  auto& seed1 = initialSeeds[i];
283  auto& seed2 = initialSeeds[j];
284 
285  // recalculate seed parameters
286  recalculateSeedLineParameters(seed1, clusterPositions, true);
287  recalculateSeedLineParameters(seed2, clusterPositions, true);
288  recalculateSeedLineParameters(seed1, clusterPositions, false);
289  recalculateSeedLineParameters(seed2, clusterPositions, false);
291  if (fabs(seed1.xyslope - seed2.xyslope) < 0.1 &&
292  fabs(seed1.xyintercept - seed2.xyintercept) < 3. &&
293  fabs(seed1.rzslope - seed2.rzslope) < 0.1 &&
294  fabs(seed1.rzintercept - seed2.rzintercept) < 3.)
295  {
296  for (auto& key : seed2.ckeys)
297  {
298  seed1.ckeys.insert(key);
299  }
300  seedsToDelete.insert(j);
301  }
302  }
303  }
304  if (Verbosity() > 4)
305  {
306  std::cout << "seeds to delete size is " << seedsToDelete.size() << std::endl;
307  }
308  for (int i = 0; i < initialSeeds.size(); ++i)
309  {
310  if (seedsToDelete.find(i) != seedsToDelete.end())
311  {
312  continue;
313  }
314  prunedSeeds.push_back(initialSeeds[i]);
315  }
316 
317  return prunedSeeds;
318 }
321 {
323  std::set<TrkrDefs::cluskey> keys;
324  int seednum = 0;
325  for (auto& [key1, pos1] : clusterPositions)
326  {
327  for (auto& [key2, pos2] : clusterPositions)
328  {
329  if (key1 == key2)
330  {
331  continue;
332  }
333  // make a cut on clusters to at least be close to each other within a few cm
334  float dist = (pos2 - pos1).norm();
335  if (Verbosity() > 5)
336  {
337  std::cout << "checking keys " << key1 << ", " << key2 << " with dist apart " << dist << std::endl;
338  std::cout << "positions are " << pos1.transpose() << " , "
339  << pos2.transpose() << std::endl;
340  }
341  if (dist > 2.)
342  {
343  continue;
344  }
346 
347  doub.xyslope = (pos2.y() - pos1.y()) / (pos2.x() - pos1.x());
348  doub.xyintercept = pos1.y() - doub.xyslope * pos1.x();
349  doub.rzslope = (r(pos2.x(), pos2.y()) - r(pos1.x(), pos1.y())) / (pos2.z() - pos1.z());
350  doub.rzintercept = pos1.z() * doub.rzslope + r(pos1.x(), pos1.y());
351 
352  keys.insert(key1);
353  keys.insert(key2);
354  doub.ckeys = keys;
355  keys.clear();
356  seeds.push_back(doub);
357  seednum++;
358  }
359  }
360  if (Verbosity() > 2)
361  {
362  std::cout << "odublet sizes " << seeds.size() << std::endl;
363  }
364  for (auto& dub : seeds)
365  {
366  if (Verbosity() > 2)
367  {
368  std::cout << "doublet has " << dub.ckeys.size() << " keys " << std::endl;
369  for (auto key : dub.ckeys)
370  {
371  std::cout << "position is " << clusterPositions.find(key)->second.transpose() << std::endl;
372  }
373  }
374  auto begin = dub.ckeys.begin();
375  auto pos1 = clusterPositions.find(*(begin))->second;
376  std::advance(begin, 1);
377  auto pos2 = clusterPositions.find(*(begin))->second;
378 
379  for (auto& [key, pos] : clusterPositions)
380  {
382  if (std::find(dub.ckeys.begin(), dub.ckeys.end(), key) != dub.ckeys.end())
383  {
384  continue;
385  }
386  // only look at the cluster that is within 2cm of the doublet clusters
387  float dist1 = (pos1 - pos).norm();
388  float dist2 = (pos2 - pos).norm();
389  if (dist1 < dist2)
390  {
391  if (dist1 > 2.)
392  continue;
393  }
394  else
395  {
396  if (dist2 > 2.)
397  continue;
398  }
399 
400  float predy = dub.xyslope * pos.x() + dub.xyintercept;
401  float predr = dub.rzslope * pos.z() + dub.rzintercept;
402  if (Verbosity() > 2)
403  {
404  std::cout << "testing ckey " << key << " with box dca "
405  << predy << ", " << pos.transpose() << " and " << predr << ", " << r(pos.x(), pos.y())
406  << std::endl;
407  }
408  if (fabs(predy - pos.y()) < m_xyTolerance)
409  {
410  if (Verbosity() > 2)
411  {
412  std::cout << " adding ckey " << key << " with box dca "
413  << predy << ", " << pos.y() << " and " << predr << ", " << r(pos.x(), pos.y())
414  << std::endl;
415  }
416  dub.ckeys.insert(key);
417  }
418  }
419  }
420 
422  std::set<int> seedsToDelete;
423  for (int i = 0; i < seeds.size(); ++i)
424  {
425  auto seed = seeds[i];
426  if (Verbosity() > 2)
427  {
428  std::cout << "keys in seed " << std::endl;
429  for (auto& key : seed.ckeys)
430  {
431  std::cout << key << ", ";
432  }
433  std::cout << std::endl
434  << "seed pos " << std::endl;
435  for (auto& key : seed.ckeys)
436  {
437  std::cout << clusterPositions.find(key)->second.transpose() << std::endl;
438  }
439  std::cout << "Done printing seed info" << std::endl;
440  }
441  if (seed.ckeys.size() < 3)
442  {
443  seedsToDelete.insert(i);
444  }
445  }
446 
447  PHCosmicSeeder::SeedVector returnSeeds;
448  for (int i = 0; i < seeds.size(); i++)
449  {
450  if (seedsToDelete.find(i) != seedsToDelete.end())
451  {
452  continue;
453  }
454  returnSeeds.push_back(seeds[i]);
455  }
456  return returnSeeds;
457 }
460 {
461  float avgx = 0;
462  float avgy = 0;
463  PHCosmicSeeder::PositionMap seedClusters;
464  for (auto& key : seed.ckeys)
465  {
466  auto glob = clusters.find(key)->second;
467  if (isXY)
468  {
469  avgx += glob.x();
470  avgy += glob.y();
471  }
472  else
473  {
474  avgx += glob.z();
475  avgy += r(glob.x(), glob.y());
476  }
477  seedClusters.insert(std::make_pair(key, glob));
478  }
479 
480  avgx /= seed.ckeys.size();
481  avgy /= seed.ckeys.size();
482  float num = 0;
483  float denom = 0;
484  for (auto& [key, glob] : seedClusters)
485  {
486  if (isXY)
487  {
488  num += (glob.x() - avgx) * (glob.y() - avgy);
489  denom += square(glob.x() - avgx);
490  }
491  else
492  {
493  num += (glob.z() - avgx) * (r(glob.x(), glob.y()) - avgy);
494  denom += square(glob.z() - avgx);
495  }
496  }
497  if (isXY)
498  {
499  seed.xyslope = num / denom;
500  seed.xyintercept = avgy - seed.xyslope * avgx;
501  }
502  else
503  {
504  seed.rzslope = num / denom;
505  seed.rzintercept = avgy - seed.rzslope * avgx;
506  }
507 }
509 {
510  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
511  if (!m_tGeometry)
512  {
513  std::cout << PHWHERE << "No acts reco geometry, bailing."
514  << std::endl;
516  }
517  m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
518  if (!m_clusterContainer)
519  {
520  std::cout << PHWHERE << "No cluster container on node tree, bailing."
521  << std::endl;
523  }
525 }
526 
528 {
529  PHNodeIterator iter(topNode);
530 
531  PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
532 
533  if (!dstNode)
534  {
535  std::cerr << "DST node is missing, quitting" << std::endl;
536  throw std::runtime_error("Failed to find DST node in PHCosmicSeeder::createNodes");
537  }
538 
539  PHNodeIterator dstIter(dstNode);
540  PHCompositeNode* svtxNode = dynamic_cast<PHCompositeNode*>(dstIter.findFirst("PHCompositeNode", "SVTX"));
541 
542  if (!svtxNode)
543  {
544  svtxNode = new PHCompositeNode("SVTX");
545  dstNode->addNode(svtxNode);
546  }
547 
548  m_seedContainer = findNode::getClass<TrackSeedContainer>(topNode, m_trackMapName);
549  if (!m_seedContainer)
550  {
552  PHIODataNode<PHObject>* trackNode =
554  svtxNode->addNode(trackNode);
555  }
556 
558 }
559 //____________________________________________________________________________..
561 {
562  if (m_outfile)
563  {
564  m_outfile->cd();
565  m_tup->Write();
566  m_outfile->Close();
567  }
569 }