ECCE @ EIC 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 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 
15 #include <TFile.h>
16 #include <TTree.h>
17 #include <ios>
18 #include <stdexcept>
19 
22 
26  : WriterT(cfg.collection, "RootPropagationStepsWriter", level),
27  m_cfg(cfg),
28  m_outputFile(cfg.rootFile) {
29  // An input collection name and tree name must be specified
30  if (m_cfg.collection.empty()) {
31  throw std::invalid_argument("Missing input collection");
32  } else if (m_cfg.treeName.empty()) {
33  throw std::invalid_argument("Missing tree name");
34  }
35 
36  // Setup ROOT I/O
37  if (m_outputFile == nullptr) {
38  m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
39  if (m_outputFile == nullptr) {
40  throw std::ios_base::failure("Could not open '" + m_cfg.filePath);
41  }
42  }
43  m_outputFile->cd();
44 
45  m_outputTree = new TTree(m_cfg.treeName.c_str(),
46  "TTree from RootPropagationStepsWriter");
47  if (m_outputTree == nullptr)
48  throw std::bad_alloc();
49 
50  // Set the branches
51  m_outputTree->Branch("event_nr", &m_eventNr);
52  m_outputTree->Branch("volume_id", &m_volumeID);
53  m_outputTree->Branch("boundary_id", &m_boundaryID);
54  m_outputTree->Branch("layer_id", &m_layerID);
55  m_outputTree->Branch("approach_id", &m_approachID);
56  m_outputTree->Branch("sensitive_id", &m_sensitiveID);
57  m_outputTree->Branch("g_x", &m_x);
58  m_outputTree->Branch("g_y", &m_y);
59  m_outputTree->Branch("g_z", &m_z);
60  m_outputTree->Branch("d_x", &m_dx);
61  m_outputTree->Branch("d_y", &m_dy);
62  m_outputTree->Branch("d_z", &m_dz);
63  m_outputTree->Branch("type", &m_step_type);
64  m_outputTree->Branch("step_acc", &m_step_acc);
65  m_outputTree->Branch("step_act", &m_step_act);
66  m_outputTree->Branch("step_abt", &m_step_abt);
67  m_outputTree->Branch("step_usr", &m_step_usr);
68 }
69 
72  if (m_cfg.rootFile == nullptr) {
73  m_outputFile->Close();
74  }
75 }
76 
78  // Write the tree
79  m_outputFile->cd();
80  m_outputTree->Write();
81  ACTS_VERBOSE("Wrote particles to tree '" << m_cfg.treeName << "' in '"
82  << m_cfg.filePath << "'");
83  return ProcessCode::SUCCESS;
84 }
85 
88  const std::vector<PropagationSteps>& stepCollection) {
89  // Exclusive access to the tree while writing
90  std::lock_guard<std::mutex> lock(m_writeMutex);
91 
92  // we get the event number
93  m_eventNr = context.eventNumber;
94 
95  // loop over the step vector of each test propagation in this
96  for (auto& steps : stepCollection) {
97  // clear the vectors for each collection
98  m_volumeID.clear();
99  m_boundaryID.clear();
100  m_layerID.clear();
101  m_approachID.clear();
102  m_sensitiveID.clear();
103  m_x.clear();
104  m_y.clear();
105  m_z.clear();
106  m_dx.clear();
107  m_dy.clear();
108  m_dz.clear();
109  m_step_type.clear();
110  m_step_acc.clear();
111  m_step_act.clear();
112  m_step_abt.clear();
113  m_step_usr.clear();
114 
115  // loop over single steps
116  for (auto& step : steps) {
117  // the identification of the step
118  Acts::GeometryID::Value volumeID = 0;
119  Acts::GeometryID::Value boundaryID = 0;
120  Acts::GeometryID::Value layerID = 0;
121  Acts::GeometryID::Value approachID = 0;
122  Acts::GeometryID::Value sensitiveID = 0;
123  // get the identification from the surface first
124  if (step.surface) {
125  auto geoID = step.surface->geoID();
126  volumeID = geoID.volume();
127  boundaryID = geoID.boundary();
128  layerID = geoID.layer();
129  approachID = geoID.approach();
130  sensitiveID = geoID.sensitive();
131  }
132  // a current volume overwrites the surface tagged one
133  if (step.volume) {
134  volumeID = step.volume->geoID().volume();
135  }
136  // now fill
137  m_sensitiveID.push_back(sensitiveID);
138  m_approachID.push_back(approachID);
139  m_layerID.push_back(layerID);
140  m_boundaryID.push_back(boundaryID);
141  m_volumeID.push_back(volumeID);
142 
143  // kinematic information
144  m_x.push_back(step.position.x());
145  m_y.push_back(step.position.y());
146  m_z.push_back(step.position.z());
147  auto direction = step.momentum.normalized();
148  m_dx.push_back(direction.x());
149  m_dy.push_back(direction.y());
150  m_dz.push_back(direction.z());
151 
152  double accuracy = step.stepSize.value(Acts::ConstrainedStep::accuracy);
153  double actor = step.stepSize.value(Acts::ConstrainedStep::actor);
154  double aborter = step.stepSize.value(Acts::ConstrainedStep::aborter);
155  double user = step.stepSize.value(Acts::ConstrainedStep::user);
156  double act2 = actor * actor;
157  double acc2 = accuracy * accuracy;
158  double abo2 = aborter * aborter;
159  double usr2 = user * user;
160 
161  // todo - fold with direction
162  if (act2 < acc2 && act2 < abo2 && act2 < usr2) {
163  m_step_type.push_back(0);
164  } else if (acc2 < abo2 && acc2 < usr2) {
165  m_step_type.push_back(1);
166  } else if (abo2 < usr2) {
167  m_step_type.push_back(2);
168  } else {
169  m_step_type.push_back(3);
170  }
171 
172  // step size information
173  m_step_acc.push_back(accuracy);
174  m_step_act.push_back(actor);
175  m_step_abt.push_back(aborter);
176  m_step_usr.push_back(user);
177  }
178  m_outputTree->Fill();
179  }
181 }