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