LDMX Software
PropagatorStepWriter.cxx
1#include "Tracking/Sim/PropagatorStepWriter.h"
2
3//--- ACTS --- //
4#include <Acts/Geometry/GeometryIdentifier.hpp>
5#include <Acts/Geometry/TrackingVolume.hpp>
6#include <Acts/Propagator/ConstrainedStep.hpp>
7#include <Acts/Surfaces/Surface.hpp>
8
9#include "Acts/Geometry/DetectorElementBase.hpp"
10#include "Framework/Exception/Exception.h"
11// mg ... I don't think these are used, and they are not defined in acts v36
12// #include "Acts/Plugins/Identification/IdentifiedDetectorElement.hpp"
13// #include "Acts/Plugins/Identification/Identifier.hpp"
14
15namespace tracking {
16namespace sim {
17
20 : m_cfg_(cfg), m_output_file_(cfg.root_file_) {
21 if (m_cfg_.tree_name_.empty()) {
22 EXCEPTION_RAISE("InvalidArgument", "Missing tree name");
23 }
24
25 // Setup ROOT I/O
26 if (m_output_file_ == nullptr) {
28 TFile::Open(m_cfg_.file_path_.c_str(), m_cfg_.file_mode_.c_str());
29 if (m_output_file_ == nullptr) {
30 throw std::ios_base::failure("Could not open '" + m_cfg_.file_path_);
31 }
32 }
33 m_output_file_->cd();
34
35 m_output_tree_ = new TTree(m_cfg_.tree_name_.c_str(),
36 "TTree from RootPropagationStepsWriter");
37 if (m_output_tree_ == nullptr) throw std::bad_alloc();
38
39 // Set the branches
40 m_output_tree_->Branch("event_nr", &m_event_nr_);
41 // m_outputTree->Branch("volume_id", &m_volumeID);
42 m_output_tree_->Branch("boundary_id", &m_boundary_id_);
43 m_output_tree_->Branch("layer_id", &m_layer_id_);
44 m_output_tree_->Branch("approach_id", &m_approach_id_);
45 m_output_tree_->Branch("sensitive_id", &m_sensitive_id_);
46 m_output_tree_->Branch("g_x", &m_x_);
47 m_output_tree_->Branch("g_y", &m_y_);
48 m_output_tree_->Branch("g_z", &m_z_);
49 m_output_tree_->Branch("d_x", &m_dx_);
50 m_output_tree_->Branch("d_y", &m_dy_);
51 m_output_tree_->Branch("d_z", &m_dz_);
52 m_output_tree_->Branch("type", &m_step_type_);
53 m_output_tree_->Branch("step_acc", &m_step_acc_);
54 m_output_tree_->Branch("step_act", &m_step_act_);
55 m_output_tree_->Branch("step_abt", &m_step_abt_);
56 m_output_tree_->Branch("step_usr", &m_step_usr_);
57 m_output_tree_->Branch("hit_x", &m_hit_x_);
58 m_output_tree_->Branch("hit_y", &m_hit_y_);
59 m_output_tree_->Branch("hit_z", &m_hit_z_);
60 m_output_tree_->Branch("start_pos", &m_start_pos_);
61 m_output_tree_->Branch("start_mom", &m_start_mom_);
62
63} // constructor
64
67 if (m_cfg_.root_file_ == nullptr) {
68 m_output_file_->cd();
69 m_output_tree_->Write();
70 m_output_file_->Close();
71 }
72} // destructor
73
74bool PropagatorStepWriter::writeSteps(
75 framework::Event& event,
76 const std::vector<PropagationSteps>& stepCollection,
77 const std::vector<ldmx::Measurement>& measurements,
78 const Acts::Vector3& start_pos, const Acts::Vector3& start_mom) {
79 // Exclusive access to the tree while writing
80 std::lock_guard<std::mutex> lock(m_write_mutex_);
81
82 m_output_file_->cd();
83
84 // we get the event number
85 m_event_nr_ = event.getEventNumber();
86
87 // fill the hits_
88 m_hit_x_.clear();
89 m_hit_y_.clear();
90 m_hit_z_.clear();
91 // m_hit_erru.clear();
92 // m_hit_errv.clear();
93
94 m_start_pos_.clear();
95 m_start_mom_.clear();
96
97 for (auto& meas : measurements) {
98 m_hit_x_.push_back(meas.getGlobalPosition()[0]);
99 m_hit_y_.push_back(meas.getGlobalPosition()[1]);
100 m_hit_z_.push_back(meas.getGlobalPosition()[2]);
101 }
102
103 for (unsigned int i = 0; i < 3; i++) {
104 m_start_pos_.push_back(start_pos(i));
105 m_start_mom_.push_back(start_mom(i));
106 }
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_boundary_id_.clear();
113 m_layer_id_.clear();
114 m_approach_id_.clear();
115 m_sensitive_id_.clear();
116 m_x_.clear();
117 m_y_.clear();
118 m_z_.clear();
119 m_dx_.clear();
120 m_dy_.clear();
121 m_dz_.clear();
122 m_step_type_.clear();
123 m_step_acc_.clear();
124 m_step_act_.clear();
125 m_step_abt_.clear();
126 m_step_usr_.clear();
127
128 // loop over single steps
129 for (auto& step : steps) {
130 // the identification of the step
131 // Acts::GeometryIdentifier::Value volumeID = 0;
132 Acts::GeometryIdentifier::Value boundary_id = 0;
133 Acts::GeometryIdentifier::Value layer_id = 0;
134 Acts::GeometryIdentifier::Value approach_id = 0;
135 Acts::GeometryIdentifier::Value sensitive_id = 0;
136 // get the identification from the surface first
137 if (step.surface) {
138 auto geo_id = step.surface->geometryId();
139 // volumeID = geoID.volume();
140 boundary_id = geo_id.boundary();
141 layer_id = geo_id.layer();
142 approach_id = geo_id.approach();
143 sensitive_id = geo_id.sensitive();
144 }
145 // a current volume overwrites the surface tagged one
146 // mg ... v36 Step does not include volume
147 // if (step.volume) {
148 // volumeID = step.volume->geometryId().volume();
149 // }
150 // now fill
151 m_sensitive_id_.push_back(sensitive_id);
152 m_approach_id_.push_back(approach_id);
153 m_layer_id_.push_back(layer_id);
154 m_boundary_id_.push_back(boundary_id);
155 // m_volumeID.push_back(volumeID);
156
157 // kinematic information
158 m_x_.push_back(step.position.x());
159 m_y_.push_back(step.position.y());
160 m_z_.push_back(step.position.z());
161 auto direction = step.momentum.normalized();
162 m_dx_.push_back(direction.x());
163 m_dy_.push_back(direction.y());
164 m_dz_.push_back(direction.z());
165
166 // double accuracy =
167 // step.stepSize.value(Acts::ConstrainedStep::accuracy());
168 double accuracy = step.stepSize.accuracy();
169 double actor = step.stepSize.value(Acts::ConstrainedStep::actor);
170 double aborter = step.stepSize.value(Acts::ConstrainedStep::aborter);
171 double user = step.stepSize.value(Acts::ConstrainedStep::user);
172 double act2 = actor * actor;
173 double acc2 = accuracy * accuracy;
174 double abo2 = aborter * aborter;
175 double usr2 = user * user;
176
177 // todo - fold with direction
178 if (act2 < acc2 && act2 < abo2 && act2 < usr2) {
179 m_step_type_.push_back(0);
180 } else if (acc2 < abo2 && acc2 < usr2) {
181 m_step_type_.push_back(1);
182 } else if (abo2 < usr2) {
183 m_step_type_.push_back(2);
184 } else {
185 m_step_type_.push_back(3);
186 }
187
188 // step size information
189 m_step_acc_.push_back(accuracy);
190 m_step_act_.push_back(actor);
191 m_step_abt_.push_back(aborter);
192 m_step_usr_.push_back(user);
193 }
194 m_output_tree_->Fill();
195 }
196 return true;
197}
198} // namespace sim
199} // namespace tracking
Implements an event buffer system for storing event data.
Definition Event.h:42
std::vector< float > m_dx_
global direction x_
PropagatorStepWriter(const Config &cfg)
Constructor with.
std::vector< float > m_x_
global x_
std::vector< float > m_start_mom_
start momentum of the particle propagated
std::vector< float > m_start_pos_
start position of the particle propagated
TFile * m_output_file_
the output file name
std::vector< float > m_hit_x_
hit location X
std::vector< float > m_z_
global z_
std::vector< float > m_y_
global y_
std::mutex m_write_mutex_
protect multi-threaded writes
std::vector< float > m_step_abt_
aborter
std::vector< float > m_hit_y_
hit location Y
std::vector< float > m_hit_z_
hit location Z
std::vector< int > m_approach_id_
surface identifier
Config m_cfg_
the configuration object
std::vector< int > m_sensitive_id_
surface identifier
std::vector< float > m_dz_
global direction z_
std::vector< float > m_dy_
global direction y_
std::vector< float > m_step_act_
actor check
std::vector< int > m_boundary_id_
boundary identifier
std::vector< int > m_layer_id_
layer identifier if
std::vector< float > m_step_acc_
accuracy
std::vector< int > m_step_type_
step type
The measurement calibrator can be a function or a class/struct able to retrieve the sim hits containe...
std::string tree_name_
name of the output tree
std::string file_path_
path of the output file