Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RootPropagationStepsWriter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RootPropagationStepsWriter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2022 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 
19 
20 #include <ios>
21 #include <memory>
22 #include <ostream>
23 #include <stdexcept>
24 
25 #include <TFile.h>
26 #include <TTree.h>
27 
31  : WriterT(cfg.collection, "RootPropagationStepsWriter", level),
32  m_cfg(cfg),
33  m_outputFile(cfg.rootFile) {
34  // An input collection name and tree name must be specified
35  if (m_cfg.collection.empty()) {
36  throw std::invalid_argument("Missing input collection");
37  } else if (m_cfg.treeName.empty()) {
38  throw std::invalid_argument("Missing tree name");
39  }
40 
41  // Setup ROOT I/O
42  if (m_outputFile == nullptr) {
43  m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
44  if (m_outputFile == nullptr) {
45  throw std::ios_base::failure("Could not open '" + m_cfg.filePath);
46  }
47  }
48  m_outputFile->cd();
49 
50  m_outputTree = new TTree(m_cfg.treeName.c_str(),
51  "TTree from RootPropagationStepsWriter");
52  if (m_outputTree == nullptr) {
53  throw std::bad_alloc();
54  }
55 
56  // Set the branches
57  m_outputTree->Branch("event_nr", &m_eventNr);
58  m_outputTree->Branch("volume_id", &m_volumeID);
59  m_outputTree->Branch("boundary_id", &m_boundaryID);
60  m_outputTree->Branch("layer_id", &m_layerID);
61  m_outputTree->Branch("approach_id", &m_approachID);
62  m_outputTree->Branch("sensitive_id", &m_sensitiveID);
63  m_outputTree->Branch("material", &m_material);
64  m_outputTree->Branch("g_x", &m_x);
65  m_outputTree->Branch("g_y", &m_y);
66  m_outputTree->Branch("g_z", &m_z);
67  m_outputTree->Branch("d_x", &m_dx);
68  m_outputTree->Branch("d_y", &m_dy);
69  m_outputTree->Branch("d_z", &m_dz);
70  m_outputTree->Branch("type", &m_step_type);
71  m_outputTree->Branch("step_acc", &m_step_acc);
72  m_outputTree->Branch("step_act", &m_step_act);
73  m_outputTree->Branch("step_abt", &m_step_abt);
74  m_outputTree->Branch("step_usr", &m_step_usr);
75  m_outputTree->Branch("nStepTrials", &m_nStepTrials);
76 }
77 
79  if (m_outputFile != nullptr) {
80  m_outputFile->Close();
81  }
82 }
83 
85  // Write the tree
86  m_outputFile->cd();
87  m_outputTree->Write();
89  if (m_cfg.rootFile == nullptr) {
90  m_outputFile->Close();
91  }
92 
93  ACTS_VERBOSE("Wrote particles to tree '" << m_cfg.treeName << "' in '"
94  << m_cfg.filePath << "'");
95 
96  return ProcessCode::SUCCESS;
97 }
98 
100  const AlgorithmContext& context,
101  const std::vector<PropagationSteps>& stepCollection) {
102  // Exclusive access to the tree while writing
103  std::lock_guard<std::mutex> lock(m_writeMutex);
104 
105  // Get the event number
106  m_eventNr = context.eventNumber;
107 
108  // Loop over the step vector of each test propagation in this
109  for (auto& steps : stepCollection) {
110  // Clear the vectors for each collection
111  m_volumeID.clear();
112  m_boundaryID.clear();
113  m_layerID.clear();
114  m_approachID.clear();
115  m_sensitiveID.clear();
116  m_material.clear();
117  m_x.clear();
118  m_y.clear();
119  m_z.clear();
120  m_dx.clear();
121  m_dy.clear();
122  m_dz.clear();
123  m_step_type.clear();
124  m_step_acc.clear();
125  m_step_act.clear();
126  m_step_abt.clear();
127  m_step_usr.clear();
128  m_nStepTrials.clear();
129 
130  // Loop over single steps
131  for (auto& step : steps) {
132  const auto& geoID = step.geoID;
133  m_sensitiveID.push_back(geoID.sensitive());
134  m_approachID.push_back(geoID.approach());
135  m_layerID.push_back(geoID.layer());
136  m_boundaryID.push_back(geoID.boundary());
137  m_volumeID.push_back(geoID.volume());
138 
139  int material = 0;
140  if (step.surface) {
141  if (step.surface->surfaceMaterial() != nullptr) {
142  material = 1;
143  }
144  }
145  m_material.push_back(material);
146 
147  // kinematic information
148  m_x.push_back(step.position.x());
149  m_y.push_back(step.position.y());
150  m_z.push_back(step.position.z());
151  auto direction = step.momentum.normalized();
152  m_dx.push_back(direction.x());
153  m_dy.push_back(direction.y());
154  m_dz.push_back(direction.z());
155 
156  double accuracy = step.stepSize.accuracy();
157  double actor = step.stepSize.value(Acts::ConstrainedStep::actor);
158  double aborter = step.stepSize.value(Acts::ConstrainedStep::aborter);
159  double user = step.stepSize.value(Acts::ConstrainedStep::user);
160  double actAbs = std::abs(actor);
161  double accAbs = std::abs(accuracy);
162  double aboAbs = std::abs(aborter);
163  double usrAbs = std::abs(user);
164 
165  // todo - fold with direction
166  if (actAbs < accAbs && actAbs < aboAbs && actAbs < usrAbs) {
167  m_step_type.push_back(0);
168  } else if (accAbs < aboAbs && accAbs < usrAbs) {
169  m_step_type.push_back(1);
170  } else if (aboAbs < usrAbs) {
171  m_step_type.push_back(2);
172  } else {
173  m_step_type.push_back(3);
174  }
175 
176  // Step size information
177  m_step_acc.push_back(Acts::clampValue<float>(accuracy));
178  m_step_act.push_back(Acts::clampValue<float>(actor));
179  m_step_abt.push_back(Acts::clampValue<float>(aborter));
180  m_step_usr.push_back(Acts::clampValue<float>(user));
181 
182  // Stepper efficiency
183  m_nStepTrials.push_back(step.stepSize.nStepTrials);
184  }
185  m_outputTree->Fill();
186  }
188 }