Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RootTrajectorySummaryWriter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RootTrajectorySummaryWriter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019-2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
25 
26 #include <array>
27 #include <cmath>
28 #include <cstddef>
29 #include <cstdint>
30 #include <ios>
31 #include <limits>
32 #include <memory>
33 #include <optional>
34 #include <ostream>
35 #include <stdexcept>
36 
37 #include <TFile.h>
38 #include <TTree.h>
39 
44 
48  : WriterT(config.inputTrajectories, "RootTrajectorySummaryWriter", level),
49  m_cfg(config) {
50  // trajectories collection name is already checked by base ctor
51  if (m_cfg.inputParticles.empty()) {
52  throw std::invalid_argument("Missing particles input collection");
53  }
54  if (m_cfg.inputMeasurementParticlesMap.empty()) {
55  throw std::invalid_argument("Missing hit-particles map input collection");
56  }
57  if (m_cfg.filePath.empty()) {
58  throw std::invalid_argument("Missing output filename");
59  }
60  if (m_cfg.treeName.empty()) {
61  throw std::invalid_argument("Missing tree name");
62  }
63 
66 
67  // Setup ROOT I/O
68  auto path = m_cfg.filePath;
69  m_outputFile = TFile::Open(path.c_str(), m_cfg.fileMode.c_str());
70  if (m_outputFile == nullptr) {
71  throw std::ios_base::failure("Could not open '" + path);
72  }
73  m_outputFile->cd();
74  m_outputTree = new TTree(m_cfg.treeName.c_str(), m_cfg.treeName.c_str());
75  if (m_outputTree == nullptr) {
76  throw std::bad_alloc();
77  } else {
78  // I/O parameters
79  m_outputTree->Branch("event_nr", &m_eventNr);
80  m_outputTree->Branch("multiTraj_nr", &m_multiTrajNr);
81  m_outputTree->Branch("subTraj_nr", &m_subTrajNr);
82 
83  m_outputTree->Branch("nStates", &m_nStates);
84  m_outputTree->Branch("nMeasurements", &m_nMeasurements);
85  m_outputTree->Branch("nOutliers", &m_nOutliers);
86  m_outputTree->Branch("nHoles", &m_nHoles);
87  m_outputTree->Branch("nSharedHits", &m_nSharedHits);
88  m_outputTree->Branch("chi2Sum", &m_chi2Sum);
89  m_outputTree->Branch("NDF", &m_NDF);
90  m_outputTree->Branch("measurementChi2", &m_measurementChi2);
91  m_outputTree->Branch("outlierChi2", &m_outlierChi2);
92  m_outputTree->Branch("measurementVolume", &m_measurementVolume);
93  m_outputTree->Branch("measurementLayer", &m_measurementLayer);
94  m_outputTree->Branch("outlierVolume", &m_outlierVolume);
95  m_outputTree->Branch("outlierLayer", &m_outlierLayer);
96 
97  m_outputTree->Branch("nMajorityHits", &m_nMajorityHits);
98  m_outputTree->Branch("majorityParticleId", &m_majorityParticleId);
99  m_outputTree->Branch("t_charge", &m_t_charge);
100  m_outputTree->Branch("t_time", &m_t_time);
101  m_outputTree->Branch("t_vx", &m_t_vx);
102  m_outputTree->Branch("t_vy", &m_t_vy);
103  m_outputTree->Branch("t_vz", &m_t_vz);
104  m_outputTree->Branch("t_px", &m_t_px);
105  m_outputTree->Branch("t_py", &m_t_py);
106  m_outputTree->Branch("t_pz", &m_t_pz);
107  m_outputTree->Branch("t_theta", &m_t_theta);
108  m_outputTree->Branch("t_phi", &m_t_phi);
109  m_outputTree->Branch("t_eta", &m_t_eta);
110  m_outputTree->Branch("t_p", &m_t_p);
111  m_outputTree->Branch("t_pT", &m_t_pT);
112  m_outputTree->Branch("t_d0", &m_t_d0);
113  m_outputTree->Branch("t_z0", &m_t_z0);
114 
115  m_outputTree->Branch("hasFittedParams", &m_hasFittedParams);
116  m_outputTree->Branch("eLOC0_fit", &m_eLOC0_fit);
117  m_outputTree->Branch("eLOC1_fit", &m_eLOC1_fit);
118  m_outputTree->Branch("ePHI_fit", &m_ePHI_fit);
119  m_outputTree->Branch("eTHETA_fit", &m_eTHETA_fit);
120  m_outputTree->Branch("eQOP_fit", &m_eQOP_fit);
121  m_outputTree->Branch("eT_fit", &m_eT_fit);
122  m_outputTree->Branch("err_eLOC0_fit", &m_err_eLOC0_fit);
123  m_outputTree->Branch("err_eLOC1_fit", &m_err_eLOC1_fit);
124  m_outputTree->Branch("err_ePHI_fit", &m_err_ePHI_fit);
125  m_outputTree->Branch("err_eTHETA_fit", &m_err_eTHETA_fit);
126  m_outputTree->Branch("err_eQOP_fit", &m_err_eQOP_fit);
127  m_outputTree->Branch("err_eT_fit", &m_err_eT_fit);
128  m_outputTree->Branch("res_eLOC0_fit", &m_res_eLOC0_fit);
129  m_outputTree->Branch("res_eLOC1_fit", &m_res_eLOC1_fit);
130  m_outputTree->Branch("res_ePHI_fit", &m_res_ePHI_fit);
131  m_outputTree->Branch("res_eTHETA_fit", &m_res_eTHETA_fit);
132  m_outputTree->Branch("res_eQOP_fit", &m_res_eQOP_fit);
133  m_outputTree->Branch("res_eT_fit", &m_res_eT_fit);
134  m_outputTree->Branch("pull_eLOC0_fit", &m_pull_eLOC0_fit);
135  m_outputTree->Branch("pull_eLOC1_fit", &m_pull_eLOC1_fit);
136  m_outputTree->Branch("pull_ePHI_fit", &m_pull_ePHI_fit);
137  m_outputTree->Branch("pull_eTHETA_fit", &m_pull_eTHETA_fit);
138  m_outputTree->Branch("pull_eQOP_fit", &m_pull_eQOP_fit);
139  m_outputTree->Branch("pull_eT_fit", &m_pull_eT_fit);
140  if (m_cfg.writeCovMat == true) {
141  // create one branch for every entry of covariance matrix
142  // one block for every row of the matrix, every entry gets own branch
143  m_outputTree->Branch("cov_eLOC0_eLOC0", &m_cov_eLOC0_eLOC0);
144  m_outputTree->Branch("cov_eLOC0_eLOC1", &m_cov_eLOC0_eLOC1);
145  m_outputTree->Branch("cov_eLOC0_ePHI", &m_cov_eLOC0_ePHI);
146  m_outputTree->Branch("cov_eLOC0_eTHETA", &m_cov_eLOC0_eTHETA);
147  m_outputTree->Branch("cov_eLOC0_eQOP", &m_cov_eLOC0_eQOP);
148  m_outputTree->Branch("cov_eLOC0_eT", &m_cov_eLOC0_eT);
149 
150  m_outputTree->Branch("cov_eLOC1_eLOC0", &m_cov_eLOC1_eLOC0);
151  m_outputTree->Branch("cov_eLOC1_eLOC1", &m_cov_eLOC1_eLOC1);
152  m_outputTree->Branch("cov_eLOC1_ePHI", &m_cov_eLOC1_ePHI);
153  m_outputTree->Branch("cov_eLOC1_eTHETA", &m_cov_eLOC1_eTHETA);
154  m_outputTree->Branch("cov_eLOC1_eQOP", &m_cov_eLOC1_eQOP);
155  m_outputTree->Branch("cov_eLOC1_eT", &m_cov_eLOC1_eT);
156 
157  m_outputTree->Branch("cov_ePHI_eLOC0", &m_cov_ePHI_eLOC0);
158  m_outputTree->Branch("cov_ePHI_eLOC1", &m_cov_ePHI_eLOC1);
159  m_outputTree->Branch("cov_ePHI_ePHI", &m_cov_ePHI_ePHI);
160  m_outputTree->Branch("cov_ePHI_eTHETA", &m_cov_ePHI_eTHETA);
161  m_outputTree->Branch("cov_ePHI_eQOP", &m_cov_ePHI_eQOP);
162  m_outputTree->Branch("cov_ePHI_eT", &m_cov_ePHI_eT);
163 
164  m_outputTree->Branch("cov_eTHETA_eLOC0", &m_cov_eTHETA_eLOC0);
165  m_outputTree->Branch("cov_eTHETA_eLOC1", &m_cov_eTHETA_eLOC1);
166  m_outputTree->Branch("cov_eTHETA_ePHI", &m_cov_eTHETA_ePHI);
167  m_outputTree->Branch("cov_eTHETA_eTHETA", &m_cov_eTHETA_eTHETA);
168  m_outputTree->Branch("cov_eTHETA_eQOP", &m_cov_eTHETA_eQOP);
169  m_outputTree->Branch("cov_eTHETA_eT", &m_cov_eTHETA_eT);
170 
171  m_outputTree->Branch("cov_eQOP_eLOC0", &m_cov_eQOP_eLOC0);
172  m_outputTree->Branch("cov_eQOP_eLOC1", &m_cov_eQOP_eLOC1);
173  m_outputTree->Branch("cov_eQOP_ePHI", &m_cov_eQOP_ePHI);
174  m_outputTree->Branch("cov_eQOP_eTHETA", &m_cov_eQOP_eTHETA);
175  m_outputTree->Branch("cov_eQOP_eQOP", &m_cov_eQOP_eQOP);
176  m_outputTree->Branch("cov_eQOP_eT", &m_cov_eQOP_eT);
177 
178  m_outputTree->Branch("cov_eT_eLOC0", &m_cov_eT_eLOC0);
179  m_outputTree->Branch("cov_eT_eLOC1", &m_cov_eT_eLOC1);
180  m_outputTree->Branch("cov_eT_ePHI", &m_cov_eT_ePHI);
181  m_outputTree->Branch("cov_eT_eTHETA", &m_cov_eT_eTHETA);
182  m_outputTree->Branch("cov_eT_eQOP", &m_cov_eT_eQOP);
183  m_outputTree->Branch("cov_eT_eT", &m_cov_eT_eT);
184  }
185  }
186 }
187 
189  m_outputFile->Close();
190 }
191 
194  m_outputFile->cd();
195  m_outputTree->Write();
196  m_outputFile->Close();
197 
198  if (m_cfg.writeCovMat) {
199  ACTS_INFO("Wrote full covariance matrix to tree");
200  }
201  ACTS_INFO("Wrote parameters of trajectories to tree '"
202  << m_cfg.treeName << "' in '" << m_cfg.filePath << "'");
203 
204  return ProcessCode::SUCCESS;
205 }
206 
208  const AlgorithmContext& ctx, const TrajectoriesContainer& trajectories) {
209  // Read additional input collections
210  const auto& particles = m_inputParticles(ctx);
211  const auto& hitParticlesMap = m_inputMeasurementParticlesMap(ctx);
212 
213  // For each particle within a track, how many hits did it contribute
214  std::vector<ParticleHitCount> particleHitCounts;
215 
216  // Exclusive access to the tree while writing
217  std::lock_guard<std::mutex> lock(m_writeMutex);
218 
219  // Get the event number
220  m_eventNr = ctx.eventNumber;
221 
222  // Loop over the trajectories
223  for (size_t itraj = 0; itraj < trajectories.size(); ++itraj) {
224  const auto& traj = trajectories[itraj];
225 
226  // The trajectory entry indices
227  const auto& trackTips = traj.tips();
228 
229  // Don't write empty MultiTrajectory
230  if (trackTips.empty()) {
231  continue;
232  }
233 
234  // Get the MultiTrajectory
235  const auto& mj = traj.multiTrajectory();
236 
237  // The trajectory index
238  m_multiTrajNr.push_back(itraj);
239 
240  // Loop over the entry indices for the subtrajectories
241  for (unsigned int isubtraj = 0; isubtraj < trackTips.size(); ++isubtraj) {
242  // The subtrajectory index
243  m_subTrajNr.push_back(isubtraj);
244  // The entry index for this subtrajectory
245  const auto& trackTip = trackTips[isubtraj];
246 
247  // Collect the trajectory summary info
248  auto trajState =
250  m_nStates.push_back(trajState.nStates);
251  m_nMeasurements.push_back(trajState.nMeasurements);
252  m_nOutliers.push_back(trajState.nOutliers);
253  m_nHoles.push_back(trajState.nHoles);
254  m_nSharedHits.push_back(trajState.nSharedHits);
255  m_chi2Sum.push_back(trajState.chi2Sum);
256  m_NDF.push_back(trajState.NDF);
257  m_measurementChi2.push_back(trajState.measurementChi2);
258  m_outlierChi2.push_back(trajState.outlierChi2);
259  // They are stored as double (as the vector of vector of int is not known
260  // to ROOT)
261  m_measurementVolume.emplace_back(trajState.measurementVolume.begin(),
262  trajState.measurementVolume.end());
263  m_measurementLayer.emplace_back(trajState.measurementLayer.begin(),
264  trajState.measurementLayer.end());
265  m_outlierVolume.emplace_back(trajState.outlierVolume.begin(),
266  trajState.outlierVolume.end());
267  m_outlierLayer.emplace_back(trajState.outlierLayer.begin(),
268  trajState.outlierLayer.end());
269 
270  // Initialize the truth particle info
271  ActsFatras::Barcode majorityParticleId(
272  std::numeric_limits<size_t>::max());
273  unsigned int nMajorityHits = std::numeric_limits<unsigned int>::max();
274  int t_charge = std::numeric_limits<int>::max();
275  float t_time = NaNfloat;
276  float t_vx = NaNfloat;
277  float t_vy = NaNfloat;
278  float t_vz = NaNfloat;
279  float t_px = NaNfloat;
280  float t_py = NaNfloat;
281  float t_pz = NaNfloat;
282  float t_theta = NaNfloat;
283  float t_phi = NaNfloat;
284  float t_eta = NaNfloat;
285  float t_p = NaNfloat;
286  float t_pT = NaNfloat;
287  float t_d0 = NaNfloat;
288  float t_z0 = NaNfloat;
289  float t_qop = NaNfloat;
290 
291  // Get the perigee surface
292  Acts::Surface* pSurface = nullptr;
293  if (traj.hasTrackParameters(trackTip)) {
294  const auto& boundParam = traj.trackParameters(trackTip);
295  pSurface = const_cast<Acts::Surface*>(&boundParam.referenceSurface());
296  }
297 
298  // Get the majority truth particle to this track
299  identifyContributingParticles(hitParticlesMap, traj, trackTip,
300  particleHitCounts);
301  bool foundMajorityParticle = false;
302  // Get the truth particle info
303  if (not particleHitCounts.empty()) {
304  // Get the barcode of the majority truth particle
305  majorityParticleId = particleHitCounts.front().particleId;
306  nMajorityHits = particleHitCounts.front().hitCount;
307 
308  // Find the truth particle via the barcode
309  auto ip = particles.find(majorityParticleId);
310  if (ip != particles.end()) {
311  foundMajorityParticle = true;
312 
313  const auto& particle = *ip;
314  ACTS_VERBOSE("Find the truth particle with barcode "
315  << majorityParticleId << "="
316  << majorityParticleId.value());
317  // Get the truth particle info at vertex
318  t_p = particle.absoluteMomentum();
319  t_charge = static_cast<int>(particle.charge());
320  t_time = particle.time();
321  t_vx = particle.position().x();
322  t_vy = particle.position().y();
323  t_vz = particle.position().z();
324  t_px = t_p * particle.direction().x();
325  t_py = t_p * particle.direction().y();
326  t_pz = t_p * particle.direction().z();
327  t_theta = theta(particle.direction());
328  t_phi = phi(particle.direction());
329  t_eta = eta(particle.direction());
330  t_pT = t_p * perp(particle.direction());
331  t_qop = particle.qOverP();
332 
333  if (pSurface != nullptr) {
334  auto intersection =
335  pSurface
336  ->intersect(ctx.geoContext, particle.position(),
337  particle.direction(), false)
338  .closest();
339  auto position = intersection.position();
340 
341  // get the truth perigee parameter
342  auto lpResult = pSurface->globalToLocal(ctx.geoContext, position,
343  particle.direction());
344  if (lpResult.ok()) {
345  t_d0 = lpResult.value()[Acts::BoundIndices::eBoundLoc0];
346  t_z0 = lpResult.value()[Acts::BoundIndices::eBoundLoc1];
347  } else {
348  ACTS_ERROR("Global to local transformation did not succeed.");
349  }
350  }
351  } else {
352  ACTS_DEBUG("Truth particle with barcode "
353  << majorityParticleId << "=" << majorityParticleId.value()
354  << " not found in the input collection!");
355  }
356  }
357  if (not foundMajorityParticle) {
358  ACTS_DEBUG("Truth particle for mj " << itraj << " subtraj " << isubtraj
359  << " not found!");
360  }
361 
362  // Push the corresponding truth particle info for the track.
363  // Always push back even if majority particle not found
364  m_majorityParticleId.push_back(majorityParticleId.value());
365  m_nMajorityHits.push_back(nMajorityHits);
366  m_t_charge.push_back(t_charge);
367  m_t_time.push_back(t_time);
368  m_t_vx.push_back(t_vx);
369  m_t_vy.push_back(t_vy);
370  m_t_vz.push_back(t_vz);
371  m_t_px.push_back(t_px);
372  m_t_py.push_back(t_py);
373  m_t_pz.push_back(t_pz);
374  m_t_theta.push_back(t_theta);
375  m_t_phi.push_back(t_phi);
376  m_t_eta.push_back(t_eta);
377  m_t_p.push_back(t_p);
378  m_t_pT.push_back(t_pT);
379  m_t_d0.push_back(t_d0);
380  m_t_z0.push_back(t_z0);
381 
382  // Initialize the fitted track parameters info
383  std::array<float, Acts::eBoundSize> param = {
384  NaNfloat, NaNfloat, NaNfloat, NaNfloat, NaNfloat, NaNfloat};
385  std::array<float, Acts::eBoundSize> error = {
386  NaNfloat, NaNfloat, NaNfloat, NaNfloat, NaNfloat, NaNfloat};
387 
388  // get entries of covariance matrix. If no entry, return NaN
389  auto getCov = [&](auto i, auto j) {
390  return traj.trackParameters(trackTip).covariance().has_value()
391  ? traj.trackParameters(trackTip).covariance().value()(i, j)
392  : NaNfloat;
393  };
394 
395  bool hasFittedParams = false;
396  bool hasFittedCov = false;
397  if (traj.hasTrackParameters(trackTip)) {
398  hasFittedParams = true;
399  const auto& boundParam = traj.trackParameters(trackTip);
400  const auto& parameter = boundParam.parameters();
401  for (unsigned int i = 0; i < Acts::eBoundSize; ++i) {
402  param[i] = parameter[i];
403  }
404 
405  if (boundParam.covariance().has_value()) {
406  hasFittedCov = true;
407  const auto& covariance = *boundParam.covariance();
408  for (unsigned int i = 0; i < Acts::eBoundSize; ++i) {
409  error[i] = std::sqrt(covariance(i, i));
410  }
411  }
412  }
413 
414  std::array<float, Acts::eBoundSize> res = {NaNfloat, NaNfloat, NaNfloat,
415  NaNfloat, NaNfloat, NaNfloat};
416  std::array<float, Acts::eBoundSize> pull = {NaNfloat, NaNfloat, NaNfloat,
417  NaNfloat, NaNfloat, NaNfloat};
418  if (foundMajorityParticle && hasFittedParams) {
419  res = {param[Acts::eBoundLoc0] - t_d0,
420  param[Acts::eBoundLoc1] - t_z0,
422  static_cast<float>(2 * M_PI)),
423  param[Acts::eBoundTheta] - t_theta,
424  param[Acts::eBoundQOverP] - t_qop,
425  param[Acts::eBoundTime] - t_time};
426 
427  if (hasFittedCov) {
428  for (unsigned int i = 0; i < Acts::eBoundSize; ++i) {
429  pull[i] = res[i] / error[i]; // MARK: fpeMask(FLTINV, 1, #2284)
430  }
431  }
432  }
433 
434  // Push the fitted track parameters.
435  // Always push back even if no fitted track parameters
436  m_eLOC0_fit.push_back(param[Acts::eBoundLoc0]);
437  m_eLOC1_fit.push_back(param[Acts::eBoundLoc1]);
438  m_ePHI_fit.push_back(param[Acts::eBoundPhi]);
439  m_eTHETA_fit.push_back(param[Acts::eBoundTheta]);
440  m_eQOP_fit.push_back(param[Acts::eBoundQOverP]);
441  m_eT_fit.push_back(param[Acts::eBoundTime]);
442 
443  m_res_eLOC0_fit.push_back(res[Acts::eBoundLoc0]);
444  m_res_eLOC1_fit.push_back(res[Acts::eBoundLoc1]);
445  m_res_ePHI_fit.push_back(res[Acts::eBoundPhi]);
446  m_res_eTHETA_fit.push_back(res[Acts::eBoundTheta]);
447  m_res_eQOP_fit.push_back(res[Acts::eBoundQOverP]);
448  m_res_eT_fit.push_back(res[Acts::eBoundTime]);
449 
450  m_err_eLOC0_fit.push_back(error[Acts::eBoundLoc0]);
451  m_err_eLOC1_fit.push_back(error[Acts::eBoundLoc1]);
452  m_err_ePHI_fit.push_back(error[Acts::eBoundPhi]);
453  m_err_eTHETA_fit.push_back(error[Acts::eBoundTheta]);
454  m_err_eQOP_fit.push_back(error[Acts::eBoundQOverP]);
455  m_err_eT_fit.push_back(error[Acts::eBoundTime]);
456 
457  m_pull_eLOC0_fit.push_back(pull[Acts::eBoundLoc0]);
458  m_pull_eLOC1_fit.push_back(pull[Acts::eBoundLoc1]);
459  m_pull_ePHI_fit.push_back(pull[Acts::eBoundPhi]);
460  m_pull_eTHETA_fit.push_back(pull[Acts::eBoundTheta]);
461  m_pull_eQOP_fit.push_back(pull[Acts::eBoundQOverP]);
462  m_pull_eT_fit.push_back(pull[Acts::eBoundTime]);
463 
464  m_hasFittedParams.push_back(hasFittedParams);
465  if (m_cfg.writeCovMat) {
466  // write all entries of covariance matrix to output file
467  // one branch for every entry of the matrix.
468  m_cov_eLOC0_eLOC0.push_back(getCov(0, 0));
469  m_cov_eLOC0_eLOC1.push_back(getCov(0, 1));
470  m_cov_eLOC0_ePHI.push_back(getCov(0, 2));
471  m_cov_eLOC0_eTHETA.push_back(getCov(0, 3));
472  m_cov_eLOC0_eQOP.push_back(getCov(0, 4));
473  m_cov_eLOC0_eT.push_back(getCov(0, 5));
474 
475  m_cov_eLOC1_eLOC0.push_back(getCov(1, 0));
476  m_cov_eLOC1_eLOC1.push_back(getCov(1, 1));
477  m_cov_eLOC1_ePHI.push_back(getCov(1, 2));
478  m_cov_eLOC1_eTHETA.push_back(getCov(1, 3));
479  m_cov_eLOC1_eQOP.push_back(getCov(1, 4));
480  m_cov_eLOC1_eT.push_back(getCov(1, 5));
481 
482  m_cov_ePHI_eLOC0.push_back(getCov(2, 0));
483  m_cov_ePHI_eLOC1.push_back(getCov(2, 1));
484  m_cov_ePHI_ePHI.push_back(getCov(2, 2));
485  m_cov_ePHI_eTHETA.push_back(getCov(2, 3));
486  m_cov_ePHI_eQOP.push_back(getCov(2, 4));
487  m_cov_ePHI_eT.push_back(getCov(2, 5));
488 
489  m_cov_eTHETA_eLOC0.push_back(getCov(3, 0));
490  m_cov_eTHETA_eLOC1.push_back(getCov(3, 1));
491  m_cov_eTHETA_ePHI.push_back(getCov(3, 2));
492  m_cov_eTHETA_eTHETA.push_back(getCov(3, 3));
493  m_cov_eTHETA_eQOP.push_back(getCov(3, 4));
494  m_cov_eTHETA_eT.push_back(getCov(3, 5));
495 
496  m_cov_eQOP_eLOC0.push_back(getCov(4, 0));
497  m_cov_eQOP_eLOC1.push_back(getCov(4, 1));
498  m_cov_eQOP_ePHI.push_back(getCov(4, 2));
499  m_cov_eQOP_eTHETA.push_back(getCov(4, 3));
500  m_cov_eQOP_eQOP.push_back(getCov(4, 4));
501  m_cov_eQOP_eT.push_back(getCov(4, 5));
502 
503  m_cov_eT_eLOC0.push_back(getCov(5, 0));
504  m_cov_eT_eLOC1.push_back(getCov(5, 1));
505  m_cov_eT_ePHI.push_back(getCov(5, 2));
506  m_cov_eT_eTHETA.push_back(getCov(5, 3));
507  m_cov_eT_eQOP.push_back(getCov(5, 4));
508  m_cov_eT_eT.push_back(getCov(5, 5));
509  }
510 
511  } // all subtrajectories
512  } // all trajectories
513 
514  // fill the variables
515  m_outputTree->Fill();
516 
517  m_multiTrajNr.clear();
518  m_subTrajNr.clear();
519  m_nStates.clear();
520  m_nMeasurements.clear();
521  m_nOutliers.clear();
522  m_nHoles.clear();
523  m_nSharedHits.clear();
524  m_chi2Sum.clear();
525  m_NDF.clear();
526  m_measurementChi2.clear();
527  m_outlierChi2.clear();
528  m_measurementVolume.clear();
529  m_measurementLayer.clear();
530  m_outlierVolume.clear();
531  m_outlierLayer.clear();
532 
533  m_nMajorityHits.clear();
534  m_majorityParticleId.clear();
535  m_t_charge.clear();
536  m_t_time.clear();
537  m_t_vx.clear();
538  m_t_vy.clear();
539  m_t_vz.clear();
540  m_t_px.clear();
541  m_t_py.clear();
542  m_t_pz.clear();
543  m_t_theta.clear();
544  m_t_phi.clear();
545  m_t_p.clear();
546  m_t_pT.clear();
547  m_t_eta.clear();
548  m_t_d0.clear();
549  m_t_z0.clear();
550 
551  m_hasFittedParams.clear();
552  m_eLOC0_fit.clear();
553  m_eLOC1_fit.clear();
554  m_ePHI_fit.clear();
555  m_eTHETA_fit.clear();
556  m_eQOP_fit.clear();
557  m_eT_fit.clear();
558  m_err_eLOC0_fit.clear();
559  m_err_eLOC1_fit.clear();
560  m_err_ePHI_fit.clear();
561  m_err_eTHETA_fit.clear();
562  m_err_eQOP_fit.clear();
563  m_err_eT_fit.clear();
564  m_res_eLOC0_fit.clear();
565  m_res_eLOC1_fit.clear();
566  m_res_ePHI_fit.clear();
567  m_res_eTHETA_fit.clear();
568  m_res_eQOP_fit.clear();
569  m_res_eT_fit.clear();
570  m_pull_eLOC0_fit.clear();
571  m_pull_eLOC1_fit.clear();
572  m_pull_ePHI_fit.clear();
573  m_pull_eTHETA_fit.clear();
574  m_pull_eQOP_fit.clear();
575  m_pull_eT_fit.clear();
576 
577  if (m_cfg.writeCovMat) {
578  m_cov_eLOC0_eLOC0.clear();
579  m_cov_eLOC0_eLOC1.clear();
580  m_cov_eLOC0_ePHI.clear();
581  m_cov_eLOC0_eTHETA.clear();
582  m_cov_eLOC0_eQOP.clear();
583  m_cov_eLOC0_eT.clear();
584 
585  m_cov_eLOC1_eLOC0.clear();
586  m_cov_eLOC1_eLOC1.clear();
587  m_cov_eLOC1_ePHI.clear();
588  m_cov_eLOC1_eTHETA.clear();
589  m_cov_eLOC1_eQOP.clear();
590  m_cov_eLOC1_eT.clear();
591 
592  m_cov_ePHI_eLOC0.clear();
593  m_cov_ePHI_eLOC1.clear();
594  m_cov_ePHI_ePHI.clear();
595  m_cov_ePHI_eTHETA.clear();
596  m_cov_ePHI_eQOP.clear();
597  m_cov_ePHI_eT.clear();
598 
599  m_cov_eTHETA_eLOC0.clear();
600  m_cov_eTHETA_eLOC1.clear();
601  m_cov_eTHETA_ePHI.clear();
602  m_cov_eTHETA_eTHETA.clear();
603  m_cov_eTHETA_eQOP.clear();
604  m_cov_eTHETA_eT.clear();
605 
606  m_cov_eQOP_eLOC0.clear();
607  m_cov_eQOP_eLOC1.clear();
608  m_cov_eQOP_ePHI.clear();
609  m_cov_eQOP_eTHETA.clear();
610  m_cov_eQOP_eQOP.clear();
611  m_cov_eQOP_eT.clear();
612 
613  m_cov_eT_eLOC0.clear();
614  m_cov_eT_eLOC1.clear();
615  m_cov_eT_ePHI.clear();
616  m_cov_eT_eTHETA.clear();
617  m_cov_eT_eQOP.clear();
618  m_cov_eT_eT.clear();
619  }
620 
621  return ProcessCode::SUCCESS;
622 }