Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackSeedTrackMapConverter.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackSeedTrackMapConverter.cc
1 
3 
8 
13 
15 
16 #include <phool/PHCompositeNode.h>
17 #include <phool/PHIODataNode.h>
18 #include <phool/PHNode.h> // for PHNode
19 #include <phool/PHNodeIterator.h>
20 #include <phool/PHObject.h> // for PHObject
21 #include <phool/getClass.h>
22 #include <phool/phool.h>
23 namespace
24 {
25  template <class T>
26  inline T square(const T& x)
27  {
28  return x * x;
29  }
30 } // namespace
31 //____________________________________________________________________________..
33  : SubsysReco(name)
34 {
35 }
36 
37 //____________________________________________________________________________..
39 
40 //____________________________________________________________________________..
42 {
43  int ret = getNodes(topNode);
44  return ret;
45 }
46 
47 //____________________________________________________________________________..
49 {
50  if (Verbosity() > 1)
51  {
52  std::cout << "silicon seed map size " << m_siContainer->size() << std::endl;
53  for (auto iter = m_siContainer->begin(); iter != m_siContainer->end();
54  ++iter)
55  {
56  auto seed = *iter;
57  if (!seed)
58  {
59  std::cout << "no seed at index " << m_siContainer->index(iter)
60  << std::endl;
61  continue;
62  }
63  seed->identify();
64  }
65  if (m_tpcContainer)
66  {
67  std::cout << "tpc seed map size " << m_tpcContainer->size() << std::endl;
68  for (auto iter = m_tpcContainer->begin(); iter != m_tpcContainer->end();
69  ++iter)
70  {
71  auto seed = *iter;
72  if (!seed)
73  {
74  std::cout << "no tpc seed at entry " << m_tpcContainer->index(iter)
75  << std::endl;
76  continue;
77  }
78  seed->identify();
79  }
80  }
81  }
82 
84  m_trackMap->Reset();
85 
86  unsigned int trackid = 0;
87  for (const auto& trackSeed : *m_seedContainer)
88  {
90  if (!trackSeed)
91  {
92  continue;
93  }
94 
95  if (m_trackSeedName.find("SvtxTrackSeed") != std::string::npos)
96  {
98  unsigned int tpcindex = trackSeed->get_tpc_seed_index();
99  TrackSeed* seed = m_tpcContainer->get(tpcindex);
100  if (!seed)
101  {
102  continue;
103  }
104  }
105 
106  auto svtxtrack = std::make_unique<SvtxTrack_v4>();
107 
108  if (Verbosity() > 0)
109  {
110  std::cout << "iterating track seed " << trackid << std::endl;
111  }
112 
113  svtxtrack->set_id(trackid);
114  trackid++;
115 
117  if (m_trackSeedName.find("SvtxTrackSeed") != std::string::npos)
118  {
119  if (Verbosity() > 0)
120  {
121  std::cout << "tpc seed id " << trackSeed->get_tpc_seed_index() << std::endl;
122  std::cout << "si seed id " << trackSeed->get_silicon_seed_index() << std::endl;
123  }
124 
125  unsigned int seedindex = trackSeed->get_tpc_seed_index();
126  TrackSeed* tpcseed = m_tpcContainer->get(seedindex);
127  if (!m_cosmics)
128  {
129  if (trackSeed->get_silicon_seed_index() == std::numeric_limits<unsigned int>::max())
130  {
132  svtxtrack->set_x(tpcseed->get_x());
133  svtxtrack->set_y(tpcseed->get_y());
134  svtxtrack->set_z(tpcseed->get_z());
135  }
136  else
137  {
138  TrackSeed* siseed = m_siContainer->get(trackSeed->get_silicon_seed_index());
139  svtxtrack->set_x(siseed->get_x());
140  svtxtrack->set_y(siseed->get_y());
141  svtxtrack->set_z(siseed->get_z());
142  addKeys(svtxtrack, siseed);
143  svtxtrack->set_silicon_seed(siseed);
144  }
145 
146  svtxtrack->set_charge(tpcseed->get_qOverR() > 0 ? 1 : -1);
147  if (m_fieldMap.find(".root") != std::string::npos)
148  {
149  svtxtrack->set_px(tpcseed->get_px(m_clusters, m_tGeometry));
150  svtxtrack->set_py(tpcseed->get_py(m_clusters, m_tGeometry));
151  svtxtrack->set_pz(tpcseed->get_pz());
152  }
153  else
154  {
155  float pt = fabs(1. / tpcseed->get_qOverR()) * (0.3 / 100) * std::stod(m_fieldMap);
156  float phi = tpcseed->get_phi(m_clusters, m_tGeometry);
157  svtxtrack->set_px(pt * std::cos(phi));
158  svtxtrack->set_py(pt * std::sin(phi));
159  svtxtrack->set_pz(pt * std::cosh(tpcseed->get_eta()) * std::cos(tpcseed->get_theta()));
160  }
161  }
162  else
163  {
164  unsigned int silseedindex = trackSeed->get_silicon_seed_index();
165  TrackSeed* silseed = m_siContainer->get(silseedindex);
166 
167  tpcseed->circleFitByTaubin(m_clusters, m_tGeometry, 0, 58);
168 
169  float tpcR = fabs(1. / tpcseed->get_qOverR());
170  float tpcx = tpcseed->get_X0();
171  float tpcy = tpcseed->get_Y0();
172  float vertexradius = 80;
173  const auto intersect =
175  tpcR, tpcx, tpcy);
176  float intx, inty;
177 
178  if (std::get<1>(intersect) < std::get<3>(intersect))
179  {
180  intx = std::get<0>(intersect);
181  inty = std::get<1>(intersect);
182  }
183  else
184  {
185  intx = std::get<2>(intersect);
186  inty = std::get<3>(intersect);
187  }
188  float slope = tpcseed->get_slope();
189 
190  float intz = vertexradius * slope + tpcseed->get_Z0();
191 
192  Acts::Vector3 inter(intx, inty, intz);
193 
194  std::vector<float> tpcparams{tpcR, tpcx, tpcy, tpcseed->get_slope(),
195  tpcseed->get_Z0()};
196  auto tangent = TrackFitUtils::get_helix_tangent(tpcparams,
197  inter);
198 
199  auto tan = tangent.second;
200  auto pca = tangent.first;
201 
202  svtxtrack->set_x(pca.x());
203  svtxtrack->set_y(pca.y());
204 
205  float p;
206  if (m_fieldMap.find(".root") != std::string::npos)
207  {
208  p = tpcseed->get_p();
209  }
210  else
211  {
212  p = cosh(tpcseed->get_eta()) * fabs(1. / tpcseed->get_qOverR()) * (0.3 / 100) * std::stod(m_fieldMap);
213  }
214 
215  tan *= p;
216  auto [charge, cosmicslope] = getCosmicCharge(tpcseed, vertexradius);
217 
218  svtxtrack->set_px(charge < 0 ? tan.x() : tan.x() * -1);
219  svtxtrack->set_py(charge < 0 ? tan.y() : tan.y() * -1);
220  svtxtrack->set_pz(cosmicslope > 0 ? fabs(tan.z()) : -1 * fabs(tan.z()));
221  svtxtrack->set_z(svtxtrack->get_pz() > 0 ? (slope < 0 ? intz : vertexradius * slope * -1 + tpcseed->get_Z0()) : (slope > 0 ? intz : vertexradius * slope * -1 + tpcseed->get_Z0()));
222  svtxtrack->set_charge(charge);
223  addKeys(svtxtrack, tpcseed);
224  if (silseed) addKeys(svtxtrack, silseed);
225 
226  svtxtrack->set_tpc_seed(tpcseed);
227  svtxtrack->set_silicon_seed(silseed);
228  if (Verbosity() > 5)
229  svtxtrack->identify();
230  }
231  addKeys(svtxtrack, tpcseed);
232  svtxtrack->set_tpc_seed(tpcseed);
233  }
234 
235  else
236  {
238 
239  svtxtrack->set_x(trackSeed->get_x());
240  svtxtrack->set_y(trackSeed->get_y());
241  svtxtrack->set_z(trackSeed->get_z());
242  svtxtrack->set_charge(trackSeed->get_qOverR() > 0 ? 1 : -1);
243  if (m_fieldMap.find(".root") != std::string::npos)
244  {
245  svtxtrack->set_px(trackSeed->get_px(m_clusters, m_tGeometry));
246  svtxtrack->set_py(trackSeed->get_py(m_clusters, m_tGeometry));
247  svtxtrack->set_pz(trackSeed->get_pz());
248  }
249  else
250  {
251  float pt = fabs(1. / trackSeed->get_qOverR()) * (0.3 / 100) * std::stod(m_fieldMap);
252 
253  float phi = trackSeed->get_phi(m_clusters, m_tGeometry);
254  svtxtrack->set_px(pt * std::cos(phi));
255  svtxtrack->set_py(pt * std::sin(phi));
256  svtxtrack->set_pz(pt * std::cosh(trackSeed->get_eta()) * std::cos(trackSeed->get_theta()));
257  }
258 
259  // calculate chisq and ndf
260  double R = 1. / std::fabs(trackSeed->get_qOverR());
261  double X0 = trackSeed->get_X0();
262  double Y0 = trackSeed->get_Y0();
263  double Z0 = trackSeed->get_Z0();
264  double slope = trackSeed->get_slope();
265  std::vector<double> xy_error2;
266  std::vector<double> rz_error2;
267  std::vector<double> xy_residuals;
268  std::vector<double> rz_residuals;
269  std::vector<double> x_circle;
270  std::vector<double> y_circle;
271  std::vector<double> z_line;
272  for (auto c_iter = trackSeed->begin_cluster_keys();
273  c_iter != trackSeed->end_cluster_keys();
274  ++c_iter)
275  {
276  TrkrCluster* c = m_clusters->findCluster(*c_iter);
278  double x = pos(0);
279  double y = pos(1);
280  double z = pos(2);
281  double r = sqrt(x * x + y * y);
282  double dx = x - X0;
283  double dy = y - Y0;
284  double xy_centerdist = sqrt(dx * dx + dy * dy);
285  // method lifted from ALICEKF::GetCircleClusterResiduals
286  xy_residuals.push_back(xy_centerdist - R);
287  // method lifted from ALICEKF::GetLineClusterResiduals
288  rz_residuals.push_back(fabs(-slope * r + z - Z0) / sqrt(slope * slope + 1));
289 
290  // ignoring covariance for simplicity
291  xy_error2.push_back(c->getActsLocalError(0, 0) + c->getActsLocalError(1, 1));
292  rz_error2.push_back(c->getActsLocalError(2, 2));
293  double phi = atan2(dy, dx);
294  x_circle.push_back(R * cos(phi) + X0);
295  y_circle.push_back(R * sin(phi) + Y0);
296  z_line.push_back(R * slope + Z0);
297  }
298  double chi2 = 0.;
299  for (unsigned int i = 0; i < xy_residuals.size(); i++)
300  {
301  if (std::isnan(xy_error2[i]))
302  {
303  xy_error2[i] = 0.01;
304  }
305  if (std::isnan(rz_error2[i]))
306  {
307  rz_error2[i] = 0.01;
308  }
309  // method lifted from GPUTPCTrackParam::Filter
310  chi2 += xy_residuals[i] * xy_residuals[i] / xy_error2[i] + rz_residuals[i] * rz_residuals[i] / rz_error2[i];
311  }
312  svtxtrack->set_chisq(chi2);
313  // GPUTPCTrackParam initially sets NDF to -3 on first cluster and increments by 2 with every application of filter
314  svtxtrack->set_ndf(2 * xy_residuals.size() - 5);
315 
316  addKeys(svtxtrack, trackSeed);
317  if (m_trackSeedName.find("SiliconTrackSeed") != std::string::npos)
318  {
319  svtxtrack->set_silicon_seed(trackSeed);
320  svtxtrack->set_tpc_seed(nullptr);
321  }
322  else if (m_trackSeedName.find("TpcTrackSeed") != std::string::npos)
323  {
324  svtxtrack->set_tpc_seed(trackSeed);
325  svtxtrack->set_silicon_seed(nullptr);
326  }
327  }
328 
329  if (Verbosity() > 0)
330  {
331  std::cout << "Inserting svtxtrack into map " << std::endl;
332  svtxtrack->identify();
333  }
334 
335  m_trackMap->insert(svtxtrack.get());
336  }
337 
339 }
340 
341 //____________________________________________________________________________..
343 {
345 }
347  TrackSeed* seedToAdd)
348 {
349  for (auto iter = seedToAdd->begin_cluster_keys();
350  iter != seedToAdd->end_cluster_keys();
351  ++iter)
352  {
353  seedToAddTo->insert_cluster_key(*iter);
354  }
355 }
356 void TrackSeedTrackMapConverter::addKeys(std::unique_ptr<SvtxTrack_v4>& track, TrackSeed* seed)
357 {
359  iter != seed->end_cluster_keys();
360  ++iter)
361  {
362  track->insert_cluster_key(*iter);
363  }
364 }
365 
367 {
368  m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
369  if (!m_trackMap)
370  {
371  // create it
372  PHNodeIterator iter(topNode);
373 
374  PHCompositeNode* dstNode = static_cast<PHCompositeNode*>(iter.findFirst(
375  "PHCompositeNode", "DST"));
376  if (!dstNode)
377  {
378  std::cerr << PHWHERE << "DST Node missing, doing nothing." << std::endl;
380  }
381  PHNodeIterator iter_dst(dstNode);
382 
383  // Create the SVTX node
384  PHCompositeNode* tb_node =
385  dynamic_cast<PHCompositeNode*>(iter_dst.findFirst("PHCompositeNode",
386  "SVTX"));
387  if (!tb_node)
388  {
389  tb_node = new PHCompositeNode("SVTX");
390  dstNode->addNode(tb_node);
391  if (Verbosity() > 0)
392  {
393  std::cout << PHWHERE << "SVTX node added" << std::endl;
394  }
395  }
396 
397  m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_trackMapName);
398  if (!m_trackMap)
399  {
401  PHIODataNode<PHObject>* tracks_node =
403  tb_node->addNode(tracks_node);
404  if (Verbosity() > 0)
405  {
406  std::cout << PHWHERE << "Svtx/" << m_trackMapName << " node added" << std::endl;
407  }
408  }
409  }
410 
411  m_seedContainer = findNode::getClass<TrackSeedContainer>(topNode, m_trackSeedName);
412  if (!m_seedContainer)
413  {
414  std::cout << PHWHERE << " Can't find track seed container " << m_trackSeedName << ", can't continue."
415  << std::endl;
417  }
418 
419  m_tpcContainer = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
420  if (!m_tpcContainer)
421  {
422  std::cout << PHWHERE << "WARNING, TrackSeedTrackMapConverter may seg fault depending on what seeding algorithm this is run after" << std::endl;
423  }
424 
425  m_siContainer = findNode::getClass<TrackSeedContainer>(topNode, "SiliconTrackSeedContainer");
426  if (!m_siContainer)
427  {
428  std::cout << PHWHERE << "WARNING, TrackSeedTrackMapConverter may seg fault depending on what seeding algorithm this is run after" << std::endl;
429  }
430 
431  m_clusters = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
432  if (!m_clusters)
433  {
434  std::cout << PHWHERE << " Can't find cluster container, can't continue."
435  << std::endl;
437  }
438 
439  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
440  if (!m_tGeometry)
441  {
442  std::cout << PHWHERE << " Can't find ActsGeometry, can't continue."
443  << std::endl;
445  }
447 }
448 
450  float vertexradius) const
451 {
452  Acts::Vector3 globalMostOuter = Acts::Vector3::Zero();
453  Acts::Vector3 globalSecondMostOuter(0, 999999, 0);
454  std::vector<Acts::Vector3> globpos;
455  float largestR = 0;
456  for (auto it = seed->begin_cluster_keys();
457  it != seed->end_cluster_keys();
458  ++it)
459  {
460  auto ckey = *it;
461  auto clus = m_clusters->findCluster(ckey);
462  auto glob = m_tGeometry->getGlobalPosition(ckey, clus);
463  globpos.push_back(glob);
464  float r = std::sqrt(square(glob.x()) + square(glob.y()));
465  if (r > largestR && glob.y() < 0)
466  {
467  globalMostOuter = glob;
468  largestR = r;
469  }
470  }
471 
472  float maxdr = std::numeric_limits<float>::max();
473  for (auto& glob : globpos)
474  {
475  if (glob.y() > 0) continue;
476  float dr = std::sqrt(square(globalMostOuter.x()) + square(globalMostOuter.y())) - std::sqrt(square(glob.x()) + square(glob.y()));
477  if (dr < maxdr && dr > 10)
478  {
479  maxdr = dr;
480  globalSecondMostOuter = glob;
481  }
482  }
483 
484  Acts::Vector3 vertex(0, -1 * vertexradius, 0);
485  globalMostOuter -= vertex;
486  globalSecondMostOuter -= vertex;
487 
488  const auto firstphi = atan2(globalMostOuter.y(), globalMostOuter.x());
489  const auto secondphi = atan2(globalSecondMostOuter.y(),
490  globalSecondMostOuter.x());
491  auto dphi = secondphi - firstphi;
492  if (dphi > M_PI) dphi = 2. * M_PI - dphi;
493  if (dphi < -M_PI) dphi = 2. * M_PI + dphi;
494 
495  float r1 = std::sqrt(square(globalMostOuter.x()) + square(globalMostOuter.y()));
496  float r2 = std::sqrt(square(globalSecondMostOuter.x()) + square(globalSecondMostOuter.y()));
497  float z1 = globalMostOuter.z();
498  float z2 = globalSecondMostOuter.z();
499 
500  float slope = (r2 - r1) / (z2 - z1);
501  int charge = 1;
502 
503  if (dphi > 0)
504  {
505  charge = -1;
506  }
507 
508  return std::make_pair(charge, slope);
509  ;
510 }