Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHCosmicsTrkFitter.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHCosmicsTrkFitter.cc
1 #include "PHCosmicsTrkFitter.h"
2 #include "MakeSourceLinks.h"
3 
5 #include <trackbase/Calibrator.h>
7 #include <trackbase/InttDefs.h>
8 #include <trackbase/MvtxDefs.h>
9 #include <trackbase/TpcDefs.h>
11 #include <trackbase/TrkrCluster.h>
13 
21 
23 
25 
27 #include <phool/PHCompositeNode.h>
28 #include <phool/PHDataNode.h>
29 #include <phool/PHNode.h>
30 #include <phool/PHNodeIterator.h>
31 #include <phool/PHObject.h>
32 #include <phool/PHTimer.h>
33 #include <phool/getClass.h>
34 #include <phool/phool.h>
35 
37 
46 
47 #include <TDatabasePDG.h>
48 #include <TVector3.h>
49 
50 #include <cmath>
51 #include <iostream>
52 #include <vector>
53 
54 namespace
55 {
56  // check vector validity
57  inline bool is_valid(const Acts::Vector3 vec)
58  {
59  return !(std::isnan(vec.x()) || std::isnan(vec.y()) || std::isnan(vec.z()));
60  }
61  template <class T>
62  inline T square(const T& x)
63  {
64  return x * x;
65  }
66 
68  template<class T> T radius(const T& x, const T& y)
69  { return std::sqrt(square(x) + square(y));}
70 
71 } // namespace
72 
74 #include <Eigen/Dense>
75 #include <Eigen/Geometry>
76 
78  : SubsysReco(name)
79  , m_trajectories(nullptr)
80 {
81 }
82 
84 {
85  if (Verbosity() > 1)
86  {
87  std::cout << "Setup PHCosmicsTrkFitter" << std::endl;
88  }
89 
91  {
93  }
94 
95  if (getNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
96  {
98  }
99 
106 
110 
112  std::map<long unsigned int, float> chi2Cuts;
113  chi2Cuts.insert(std::make_pair(10, 4));
114  chi2Cuts.insert(std::make_pair(12, 4));
115  chi2Cuts.insert(std::make_pair(14, 9));
116  chi2Cuts.insert(std::make_pair(16, 4));
117  m_outlierFinder.chi2Cuts = chi2Cuts;
118  if (m_useOutlierFinder)
119  {
120  m_fitCfg.fit->outlierFinder(m_outlierFinder);
121  }
122 
123  auto cellgeo =
124  findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, "CYLINDERCELLGEOM_SVTX");
125 
126  if (cellgeo)
127  {
128  // _clusterMover.initialize_geometry(cellgeo);
129  }
130 
131  if (m_actsEvaluator)
132  {
133  m_evaluator = std::make_unique<ActsEvaluator>(m_evalname);
134  m_evaluator->Init(topNode);
135  m_evaluator->verbosity(Verbosity());
136  }
137 
139  {
140  m_outfile = std::make_unique<TFile>(m_evalname.c_str(),"RECREATE");
141  m_tree = std::make_unique<TTree>("seedclustree","Tree with cosmic seeds and their clusters");
142  makeBranches();
143 
144  }
145 
146  if (Verbosity() > 1)
147  {
148  std::cout << "Finish PHCosmicsTrkFitter Setup" << std::endl;
149  }
150 
152 }
153 
155 {
156  m_event++;
157 
159 
160  if (m_actsEvaluator)
161  {
162  m_evaluator->next_event(topNode);
163  }
164 
165  if (Verbosity() > 1)
166  {
167  std::cout << PHWHERE << "Events processed: " << m_event << std::endl;
168  std::cout << "Start PHCosmicsTrkFitter::process_event" << std::endl;
169  if (Verbosity() > 30)
171  }
172 
175  if (m_actsEvaluator)
176  {
179  m_seedTracks->clear();
180  for (const auto& [key, track] : *m_trackMap)
181  {
182  m_seedTracks->insert(track);
183  }
184  }
185 
187 
188  // put this in the output file
189  if (Verbosity() > 0)
190  {
191  std::cout << " SvtxTrackMap size is now " << m_trackMap->size()
192  << std::endl;
193  }
194 
196 }
197 
199 {
200  if (Verbosity() > 1)
201  {
202  std::cout << "Reset PHCosmicsTrkFitter" << std::endl;
203  }
204 
205  m_trajectories->clear();
206 
208 }
209 
211 {
212  if (m_actsEvaluator)
213  {
214  m_evaluator->End();
215  }
216  if( m_seedClusAnalysis)
217  {
218  m_outfile->cd();
219  m_tree->Write();
220  m_outfile->Close();
221  }
222  if (Verbosity() > 0)
223  {
224  std::cout << "The Acts track fitter had " << m_nBadFits
225  << " fits return an error" << std::endl;
226 
227  std::cout << "Finished PHCosmicsTrkFitter" << std::endl;
228  }
230 }
231 
233 {
234  auto logger = Acts::getDefaultLogger("PHCosmicsTrkFitter", logLevel);
235 
236  if (Verbosity() > 0)
237  {
238  std::cout << " seed map size " << m_seedMap->size() << std::endl;
239  }
240 
241  for (auto trackiter = m_seedMap->begin(); trackiter != m_seedMap->end();
242  ++trackiter)
243  {
244  TrackSeed* track = *trackiter;
245  if (!track)
246  {
247  continue;
248  }
249 
250  unsigned int tpcid = track->get_tpc_seed_index();
251  unsigned int siid = track->get_silicon_seed_index();
252 
253  // get the crossing number
254  auto siseed = m_siliconSeeds->get(siid);
255  short crossing = 0;
256 
257  auto tpcseed = m_tpcSeeds->get(tpcid);
258  if (Verbosity() > 1)
259  {
260  std::cout << "TPC id " << tpcid << std::endl;
261  std::cout << "Silicon id " << siid << std::endl;
262  }
263 
265  if (!tpcseed)
266  {
267  continue;
268  }
269 
270  if (Verbosity() > 0)
271  {
272  if (siseed) std::cout << " silicon seed position is (x,y,z) = " << siseed->get_x() << " " << siseed->get_y() << " " << siseed->get_z() << std::endl;
273  std::cout << " tpc seed position is (x,y,z) = " << tpcseed->get_x() << " " << tpcseed->get_y() << " " << tpcseed->get_z() << std::endl;
274  }
275 
277 
278  SourceLinkVec sourceLinks;
279 
280  MakeSourceLinks makeSourceLinks;
281  makeSourceLinks.setVerbosity(Verbosity());
282  makeSourceLinks.set_pp_mode(false);
283 
284  makeSourceLinks.resetTransientTransformMap(
287  m_tGeometry);
288 
289  if (siseed) sourceLinks = makeSourceLinks.getSourceLinks(
290  siseed,
291  measurements,
293  m_tGeometry,
296  crossing);
297  const auto tpcSourceLinks = makeSourceLinks.getSourceLinks(
298  tpcseed,
299  measurements,
301  m_tGeometry,
304  crossing);
305  sourceLinks.insert(sourceLinks.end(), tpcSourceLinks.begin(), tpcSourceLinks.end());
306 
307  int charge = 0;
308  float cosmicslope = 0;
309 
310  getCharge(tpcseed, charge, cosmicslope);
311 
312  // copy transient map for this track into transient geoContext
314 
315 
316  tpcseed->circleFitByTaubin(m_clusterContainer, m_tGeometry, 0, 58);
317 
318  float tpcR = fabs(1. / tpcseed->get_qOverR());
319  float tpcx = tpcseed->get_X0();
320  float tpcy = tpcseed->get_Y0();
321 
322  const auto intersect =
324  tpcR, tpcx, tpcy);
325  float intx, inty;
326 
327  if (std::get<1>(intersect) > std::get<3>(intersect))
328  {
329  intx = std::get<0>(intersect);
330  inty = std::get<1>(intersect);
331  }
332  else
333  {
334  intx = std::get<2>(intersect);
335  inty = std::get<3>(intersect);
336  }
337 
338  float slope = tpcseed->get_slope();
339  float intz = m_vertexRadius * slope + tpcseed->get_Z0();
340 
341  Acts::Vector3 inter(intx, inty, intz);
342 
343  std::vector<float> tpcparams{tpcR, tpcx, tpcy, tpcseed->get_slope(),
344  tpcseed->get_Z0()};
345  auto tangent = TrackFitUtils::get_helix_tangent(tpcparams,
346  inter);
347 
348  auto tan = tangent.second;
349  auto pca = tangent.first;
350 
351  float p;
352  if (m_fieldMap.find(".root") != std::string::npos)
353  {
354  p = tpcseed->get_p();
355  }
356  else
357  {
358  p = cosh(tpcseed->get_eta()) * fabs(1. / tpcseed->get_qOverR()) * (0.3 / 100) * std::stod(m_fieldMap);
359  }
360 
361  tan *= p;
362 
368 
369  Acts::Vector3 momentum(charge < 0 ? tan.x() : tan.x() * -1,
370  charge < 0 ? tan.y() : tan.y() * -1,
371  cosmicslope > 0 ? fabs(tan.z()) : -1 * fabs(tan.z()));
372  Acts::Vector3 position(pca.x(), pca.y(),
373  momentum.z() > 0 ? (slope < 0 ? intz : m_vertexRadius * slope * -1 + tpcseed->get_Z0()) : (slope > 0 ? intz : m_vertexRadius * slope * -1 + tpcseed->get_Z0()));
374 
375  position *= Acts::UnitConstants::cm;
376  if (!is_valid(momentum)) continue;
377 
378  auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
380  auto actsFourPos = Acts::Vector4(position(0), position(1),
381  position(2),
383 
386  {
387  clearVectors();
388  m_seed = tpcid;
389  m_R = tpcR;
390  m_X0 = tpcx;
391  m_Y0 = tpcy;
392  m_Z0 = tpcseed->get_Z0();
393  m_slope = slope;
394  m_pcax = position(0);
395  m_pcay = position(1);
396  m_pcaz = position(2);
397  m_px = momentum(0);
398  m_py = momentum(1);
399  m_pz = momentum(2);
400  m_charge = charge;
401  fillVectors(siseed, tpcseed);
402  m_tree->Fill();
403  }
406  pSurface,
408  actsFourPos,
409  momentum,
410  charge / momentum.norm(),
411  cov,
414  if(!seed.ok())
415  {
416  std::cout << "Could not create track params, skipping track" << std::endl;
417  continue;
418  }
419 
420 
421  if (Verbosity() > 2)
422  {
423  printTrackSeed(seed.value());
424  }
425 
427  Acts::PropagatorPlainOptions ppPlainOptions;
428 
429  auto calibptr = std::make_unique<Calibrator>();
430  CalibratorAdapter calibrator{*calibptr, measurements};
431 
432  auto magcontext = m_tGeometry->geometry().magFieldContext;
433  auto calibcontext = m_tGeometry->geometry().calibContext;
434 
436  kfOptions{
438  magcontext,
439  calibcontext,
440  &(*pSurface),
441  ppPlainOptions};
442 
443  auto trackContainer =
444  std::make_shared<Acts::VectorTrackContainer>();
445  auto trackStateContainer =
446  std::make_shared<Acts::VectorMultiTrajectory>();
448  tracks(trackContainer, trackStateContainer);
449  auto result = fitTrack(sourceLinks, seed.value(), kfOptions,
450  calibrator, tracks);
451 
453  if (result.ok())
454  {
455  SvtxTrack_v4 newTrack;
456  newTrack.set_tpc_seed(tpcseed);
457  newTrack.set_crossing(crossing);
458  newTrack.set_silicon_seed(siseed);
459 
460  unsigned int trid = m_trackMap->size();
461  newTrack.set_id(trid);
462 
463  if (getTrackFitResult(result, track, &newTrack, tracks, measurements))
464  {
465  m_trackMap->insertWithKey(&newTrack, trid);
466  }
467  }
468  else
469  {
470  m_nBadFits++;
471  if (Verbosity() > 1)
472  {
473  std::cout << "Track fit failed for track " << m_seedMap->find(track)
474  << " with Acts error message "
475  << result.error() << ", " << result.error().message()
476  << std::endl;
477  }
478  }
479  }
480 
481  return;
482 }
483 
485  TrackSeed* seed, SvtxTrack* track,
488 {
491  auto& outtrack = fitOutput.value();
492  std::vector<Acts::MultiTrajectoryTraits::IndexType> trackTips;
493  trackTips.reserve(1);
494  trackTips.emplace_back(outtrack.tipIndex());
495  Trajectory::IndexedParameters indexedParams;
496 
497  indexedParams.emplace(std::pair{outtrack.tipIndex(),
499  outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()}});
500 
501  if (Verbosity() > 2)
502  {
503  std::cout << "Fitted parameters for track" << std::endl;
504  std::cout << " position : " << outtrack.referenceSurface().localToGlobal(m_transient_geocontext, Acts::Vector2(outtrack.loc0(), outtrack.loc1()), Acts::Vector3(1, 1, 1)).transpose()
505 
506  << std::endl;
507 
508  int otcharge = outtrack.qOverP() > 0 ? 1 : -1;
509  std::cout << "charge: " << otcharge << std::endl;
510  std::cout << " momentum : " << outtrack.momentum().transpose()
511  << std::endl;
512  std::cout << "For trackTip == " << outtrack.tipIndex() << std::endl;
513  }
514 
515  Trajectory trajectory(tracks.trackStateContainer(),
516  trackTips, indexedParams);
517 
518  m_trajectories->insert(std::make_pair(track->get_id(), trajectory));
519 
522  updateSvtxTrack(trackTips, indexedParams, tracks, track);
523 
524  if (m_commissioning)
525  {
526  if (track->get_silicon_seed() && track->get_tpc_seed())
527  {
528  m_alignStates.fillAlignmentStateMap(tracks, trackTips,
529  track, measurements);
530  }
531  }
532 
533  if (m_actsEvaluator)
534  {
535  m_evaluator->evaluateTrackFit(tracks, trackTips, indexedParams, track,
536  seed, measurements);
537  }
538 
539  return true;
540 }
541 
543  const std::vector<Acts::SourceLink>& sourceLinks,
546  const CalibratorAdapter& calibrator,
548 {
549  return (*m_fitCfg.fit)(sourceLinks, seed, kfOptions, calibrator, tracks);
550 }
551 
553  std::vector<Acts::MultiTrajectoryTraits::IndexType>& tips,
556  SvtxTrack* track)
557 {
558  const auto& mj = tracks.trackStateContainer();
559 
561  auto& trackTip = tips.front();
562 
563  if (Verbosity() > 2)
564  {
565  std::cout << "Identify (proto) track before updating with acts results " << std::endl;
566  track->identify();
567  }
568 
569  // create a state at pathlength = 0.0
570  // This state holds the track parameters, which will be updated below
571  float pathlength = 0.0;
572  SvtxTrackState_v1 out(pathlength);
573  out.set_x(0.0);
574  out.set_y(0.0);
575  out.set_z(0.0);
576  track->insert_state(&out);
577 
578  auto trajState =
580 
581  const auto& params = paramsMap.find(trackTip)->second;
582 
584  track->set_x(params.position(m_transient_geocontext)(0) / Acts::UnitConstants::cm);
585  track->set_y(params.position(m_transient_geocontext)(1) / Acts::UnitConstants::cm);
586  track->set_z(params.position(m_transient_geocontext)(2) / Acts::UnitConstants::cm);
587 
588  track->set_px(params.momentum()(0));
589  track->set_py(params.momentum()(1));
590  track->set_pz(params.momentum()(2));
591 
592  track->set_charge(params.charge());
593  track->set_chisq(trajState.chi2Sum);
594  track->set_ndf(trajState.NDF);
595 
596  ActsTransformations rotater;
597  rotater.setVerbosity(Verbosity());
598 
599  if (params.covariance())
600  {
601  auto rotatedCov = rotater.rotateActsCovToSvtxTrack(params);
602 
603  for (int i = 0; i < 6; i++)
604  {
605  for (int j = 0; j < 6; j++)
606  {
607  track->set_error(i, j, rotatedCov(i, j));
608  }
609  }
610  }
611 
612  // Also need to update the state list and cluster ID list for all measurements associated with the acts track
613  // loop over acts track states, copy over to SvtxTrackStates, and add to SvtxTrack
614 
616  {
617  rotater.fillSvtxTrackStates(mj, trackTip, track,
619  }
620 
621  if (Verbosity() > 2)
622  {
623  std::cout << " Identify fitted track after updating track states:"
624  << std::endl;
625  track->identify();
626  }
627 
628  return;
629 }
630 
632 {
633  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Zero();
634 
642 
643  // cppcheck-suppress duplicateAssignExpression
644  double sigmaD0 = 300 * Acts::UnitConstants::um;
645  double sigmaZ0 = 300 * Acts::UnitConstants::um;
646  // cppcheck-suppress duplicateAssignExpression
647  double sigmaPhi = 1 * Acts::UnitConstants::degree;
648  double sigmaTheta = 1 * Acts::UnitConstants::degree;
649  double sigmaT = 1. * Acts::UnitConstants::ns;
650 
651  cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = sigmaD0 * sigmaD0;
652  cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = sigmaZ0 * sigmaZ0;
653  cov(Acts::eBoundTime, Acts::eBoundTime) = sigmaT * sigmaT;
654  cov(Acts::eBoundPhi, Acts::eBoundPhi) = sigmaPhi * sigmaPhi;
655  cov(Acts::eBoundTheta, Acts::eBoundTheta) = sigmaTheta * sigmaTheta;
658 
659  return cov;
660 }
661 
663 {
664  std::cout
665  << PHWHERE
666  << " Processing proto track:"
667  << std::endl;
668 
669  std::cout
670  << "position: " << seed.position(m_transient_geocontext).transpose()
671  << std::endl
672  << "momentum: " << seed.momentum().transpose()
673  << std::endl;
674 
675  std::cout << "charge : " << seed.charge() << std::endl;
676  std::cout << "absolutemom : " << seed.absoluteMomentum() << std::endl;
677 }
678 
680 {
681  PHNodeIterator iter(topNode);
682 
683  PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
684 
685  if (!dstNode)
686  {
687  std::cerr << "DST node is missing, quitting" << std::endl;
688  throw std::runtime_error("Failed to find DST node in PHCosmicsTrkFitter::createNodes");
689  }
690 
691  PHNodeIterator dstIter(topNode);
692  PHCompositeNode* svtxNode = dynamic_cast<PHCompositeNode*>(dstIter.findFirst("PHCompositeNode", "SVTX"));
693 
694  if (!svtxNode)
695  {
696  svtxNode = new PHCompositeNode("SVTX");
697  dstNode->addNode(svtxNode);
698  }
699 
700  m_trajectories = findNode::getClass<std::map<const unsigned int, Trajectory>>(topNode, "ActsTrajectories");
701  if (!m_trajectories)
702  {
703  m_trajectories = new std::map<const unsigned int, Trajectory>;
704  auto node =
706  svtxNode->addNode(node);
707  }
708 
709  m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, _track_map_name);
710 
711  if (!m_trackMap)
712  {
715  svtxNode->addNode(node);
716  }
717 
718  m_alignmentStateMap = findNode::getClass<SvtxAlignmentStateMap>(topNode, "SvtxAlignmentStateMap");
719  if (!m_alignmentStateMap)
720  {
722  auto node = new PHDataNode<SvtxAlignmentStateMap>(m_alignmentStateMap, "SvtxAlignmentStateMap", "PHObject");
723  svtxNode->addNode(node);
724  }
725 
726  m_alignmentTransformationMapTransient = findNode::getClass<alignmentTransformationContainer>(topNode, "alignmentTransformationContainerTransient");
728  {
729  std::cout << PHWHERE << "alignmentTransformationContainerTransient not on node tree. Bailing"
730  << std::endl;
732  }
733 
734  if (m_actsEvaluator)
735  {
736  m_seedTracks = findNode::getClass<SvtxTrackMap>(topNode, _seed_track_map_name);
737 
738  if (!m_seedTracks)
739  {
741 
742  PHIODataNode<PHObject>* seedNode =
744  svtxNode->addNode(seedNode);
745  }
746  }
747 
749 }
750 
752 {
753  m_tpcSeeds = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
754  if (!m_tpcSeeds)
755  {
756  std::cout << PHWHERE << "TpcTrackSeedContainer not on node tree. Bailing"
757  << std::endl;
759  }
760 
761  m_siliconSeeds = findNode::getClass<TrackSeedContainer>(topNode, "SiliconTrackSeedContainer");
762  if (!m_siliconSeeds)
763  {
764  std::cout << PHWHERE << "SiliconTrackSeedContainer not on node tree. Bailing"
765  << std::endl;
767  }
768 
769  m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
770  if (!m_clusterContainer)
771  {
772  std::cout << PHWHERE
773  << "No trkr cluster container, exiting." << std::endl;
775  }
776 
777  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
778  if (!m_tGeometry)
779  {
780  std::cout << "ActsGeometry not on node tree. Exiting."
781  << std::endl;
782 
784  }
785 
786  m_seedMap = findNode::getClass<TrackSeedContainer>(topNode, "SvtxTrackSeedContainer");
787  if (!m_seedMap)
788  {
789  std::cout << "No Svtx seed map on node tree. Exiting."
790  << std::endl;
792  }
793 
794  // tpc distortion corrections
795  _dcc_static = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerStatic");
796  if (_dcc_static)
797  {
798  std::cout << PHWHERE << " found static TPC distortion correction container" << std::endl;
799  }
800  _dcc_average = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerAverage");
801  if (_dcc_average)
802  {
803  std::cout << PHWHERE << " found average TPC distortion correction container" << std::endl;
804  }
805  _dcc_fluctuation = findNode::getClass<TpcDistortionCorrectionContainer>(topNode, "TpcDistortionCorrectionContainerFluctuation");
806  if (_dcc_fluctuation)
807  {
808  std::cout << PHWHERE << " found fluctuation TPC distortion correction container" << std::endl;
809  }
810 
812 }
813 
814 
816 {
817  m_tree->Branch("seed",&m_seed,"m_seed/I");
818  m_tree->Branch("event",&m_event,"m_event/I");
819  m_tree->Branch("R",&m_R,"m_R/F");
820  m_tree->Branch("X0",&m_X0,"m_X0/F");
821  m_tree->Branch("Y0",&m_Y0,"m_Y0/F");
822  m_tree->Branch("Z0",&m_Z0,"m_Z0/F");
823  m_tree->Branch("slope",&m_slope,"m_slope/F");
824  m_tree->Branch("pcax",&m_pcax,"m_pcax/F");
825  m_tree->Branch("pcay",&m_pcay,"m_pcay/F");
826  m_tree->Branch("pcaz",&m_pcaz,"m_pcaz/F");
827  m_tree->Branch("px",&m_px,"m_px/F");
828  m_tree->Branch("py",&m_py,"m_py/F");
829  m_tree->Branch("pz",&m_pz,"m_pz/F");
830  m_tree->Branch("charge",&m_charge,"m_charge/I");
831  m_tree->Branch("nmaps",&m_nmaps,"m_nmaps/I");
832  m_tree->Branch("nintt",&m_nintt,"m_nintt/I");
833  m_tree->Branch("ntpc",&m_ntpc,"m_ntpc/I");
834  m_tree->Branch("nmm",&m_nmm,"m_nmm/I");
835  m_tree->Branch("locx",&m_locx);
836  m_tree->Branch("locy",&m_locy);
837  m_tree->Branch("x",&m_x);
838  m_tree->Branch("y",&m_y);
839  m_tree->Branch("z",&m_z);
840  m_tree->Branch("r",&m_r);
841  m_tree->Branch("layer",&m_layer);
842  m_tree->Branch("phi",&m_phi);
843  m_tree->Branch("eta",&m_eta);
844  m_tree->Branch("phisize",&m_phisize);
845  m_tree->Branch("zsize",&m_zsize);
846  m_tree->Branch("ephi",&m_ephi);
847  m_tree->Branch("ez",&m_ez);
848 
849 
850 
851 }
853 {
854  for(auto seed : {tpcseed, siseed})
855  {
856  for(auto it = seed->begin_cluster_keys(); it != seed->end_cluster_keys();
857  ++it)
858  {
859  auto key = *it;
860  auto cluster = m_clusterContainer->findCluster(key);
861  m_locx.push_back(cluster->getLocalX());
862  float ly = cluster->getLocalY();
864  {
865  double drift_velocity = m_tGeometry->get_drift_velocity();
866  double zdriftlength = cluster->getLocalY() * drift_velocity;
867  double surfCenterZ = 52.89; // 52.89 is where G4 thinks the surface center is
868  double zloc = surfCenterZ - zdriftlength; // converts z drift length to local z position in the TPC in north
869  unsigned int side = TpcDefs::getSide(key);
870  if (side == 0) zloc = -zloc;
871  ly = zloc * 10;
872  }
873  m_locy.push_back(ly);
874  auto glob = m_tGeometry->getGlobalPosition(key, cluster);
875  m_x.push_back(glob.x());
876  m_y.push_back(glob.y());
877  m_z.push_back(glob.z());
878  float r = std::sqrt(glob.x()*glob.x()+glob.y()*glob.y());
879  m_r.push_back(r);
880  TVector3 globt(glob.x(), glob.y(), glob.z());
881  m_phi.push_back(globt.Phi());
882  m_eta.push_back(globt.Eta());
883  m_phisize.push_back(cluster->getPhiSize());
884  m_zsize.push_back(cluster->getZSize());
885  auto para_errors =
887 
888  m_ephi.push_back(std::sqrt(para_errors.first));
889  m_ez.push_back(std::sqrt(para_errors.second));
890  }
891  }
892 }
894 {
895  m_locx.clear();
896  m_locy.clear();
897  m_x.clear();
898  m_y.clear();
899  m_z.clear();
900  m_layer.clear();
901  m_r.clear();
902  m_phi.clear();
903  m_eta.clear();
904  m_phisize.clear();
905  m_zsize.clear();
906  m_ephi.clear();
907  m_ez.clear();
908 }
909 
911  TrackSeed* track,
912  //TrkrClusterContainer* clusterContainer,
913  //ActsGeometry* tGeometry,
914  //alignmentTransformationContainer* transformMapTransient,
915  //float vertexRadius,
916  int& charge,
917  float& cosmicslope )
918 {
919 
920  Acts::GeometryContext transient_geocontext;
921  transient_geocontext = m_alignmentTransformationMapTransient; // set local/global transforms to distortion corrected ones for this track
922 
923  std::vector<Acts::Vector3> global_vec;
924 
925  for (auto clusIter = track->begin_cluster_keys();
926  clusIter != track->end_cluster_keys();
927  ++clusIter)
928  {
929  auto key = *clusIter;
930  auto cluster = m_clusterContainer->findCluster(key);
931  if (!cluster)
932  {
933  std::cout << "MakeSourceLinks::getCharge: Failed to get cluster with key " << key << " for track seed" << std::endl;
934  continue;
935  }
936 
937  auto surf = m_tGeometry->maps().getSurface(key, cluster);
938  if (!surf) { continue; }
939 
940  // get cluster global positions
941  Acts::Vector2 local = m_tGeometry->getLocalCoords(key, cluster); // converts TPC time to z
942  Acts::Vector3 glob = surf->localToGlobal(transient_geocontext,
943  local * Acts::UnitConstants::cm,
944  Acts::Vector3(1,1,1));
945  glob /= Acts::UnitConstants::cm;
946 
947  global_vec.push_back(glob);
948  }
949 
950  Acts::Vector3 globalMostOuter;
951  Acts::Vector3 globalSecondMostOuter(0, 999999, 0);
952  float largestR = 0;
953  // loop over global positions
954  for (int i = 0; i < global_vec.size(); ++i)
955  {
956  Acts::Vector3 global = global_vec[i];
957  //float r = std::sqrt(square(global.x()) + square(global.y()));
958  float r = radius(global.x(), global.y());
959 
961  if (r > largestR && global.y() > 0)
962  {
963  globalMostOuter = global_vec[i];
964  largestR = r;
965  }
966  }
967 
969  float maxdr = std::numeric_limits<float>::max();
970  for (int i = 0; i < global_vec.size(); i++)
971  {
972  if (global_vec[i].y() < 0) continue;
973 
974  float dr = std::sqrt(square(globalMostOuter.x()) + square(globalMostOuter.y())) - std::sqrt(square(global_vec[i].x()) + square(global_vec[i].y()));
977  if (dr < maxdr && dr > 10)
978  {
979  maxdr = dr;
980  globalSecondMostOuter = global_vec[i];
981  }
982  }
983 
987  globalMostOuter -= vertex;
988  globalSecondMostOuter -= vertex;
989 
990  const auto firstphi = atan2(globalMostOuter.y(), globalMostOuter.x());
991  const auto secondphi = atan2(globalSecondMostOuter.y(),
992  globalSecondMostOuter.x());
993  auto dphi = secondphi - firstphi;
994 
995  if (dphi > M_PI) dphi = 2. * M_PI - dphi;
996  if (dphi < -M_PI) dphi = 2 * M_PI + dphi;
997 
998  if (dphi > 0)
999  {
1000  charge = -1;
1001  }
1002  else
1003  {
1004  charge = 1;
1005  }
1006 
1007  float r1 = std::sqrt(square(globalMostOuter.x()) + square(globalMostOuter.y()));
1008  float r2 = std::sqrt(square(globalSecondMostOuter.x()) + square(globalSecondMostOuter.y()));
1009  float z1 = globalMostOuter.z();
1010  float z2 = globalSecondMostOuter.z();
1011  cosmicslope = (r2 - r1) / (z2 - z1);
1012 
1013  return;
1014 }
1015