29 #include <type_traits>
41 :
WriterT(config.collection,
"RootMaterialTrackWriter", level),
45 throw std::invalid_argument(
"Missing input collection");
47 throw std::invalid_argument(
"Missing tree name");
53 throw std::ios_base::failure(
"Could not open '" +
m_cfg.
filePath);
58 new TTree(
m_cfg.
treeName.c_str(),
"TTree from RootMaterialTrackWriter");
60 throw std::bad_alloc();
112 if (m_outputFile !=
nullptr) {
113 m_outputFile->Close();
122 m_outputTree->Write();
123 m_outputFile->Close();
130 const std::unordered_map<size_t, Acts::RecordedMaterialTrack>&
133 std::lock_guard<std::mutex> lock(m_writeMutex);
137 for (
auto& [idTrack, mtrack] : materialTracks) {
151 m_step_length.clear();
163 m_sur_pathCorrection.clear();
164 m_sur_range_min.clear();
165 m_sur_range_max.clear();
169 auto materialInteractions = mtrack.second.materialInteractions;
170 if (
m_cfg.collapseInteractions) {
171 std::vector<Acts::MaterialInteraction> collapsed;
174 double pathCorrectionSum = 0;
176 for (std::size_t
start = 0,
end = 0;
end < materialInteractions.size();
178 const auto& mintStart = materialInteractions[
start];
179 const auto& mintEnd = materialInteractions[
end];
181 positionSum += mintEnd.position;
182 pathCorrectionSum += mintEnd.pathCorrection;
184 const bool same = mintStart.materialSlab.material() ==
185 mintEnd.materialSlab.material();
186 const bool last =
end == materialInteractions.size() - 1;
189 auto mint = mintStart;
191 mint.pathCorrection = pathCorrectionSum;
193 collapsed.push_back(
mint);
196 positionSum = Acts::Vector3::Zero();
197 pathCorrectionSum = 0;
201 materialInteractions =
std::move(collapsed);
205 size_t mints = materialInteractions.size();
206 m_step_sx.reserve(mints);
207 m_step_sy.reserve(mints);
208 m_step_sz.reserve(mints);
209 m_step_x.reserve(mints);
210 m_step_y.reserve(mints);
211 m_step_z.reserve(mints);
212 m_step_ex.reserve(mints);
213 m_step_ey.reserve(mints);
214 m_step_ez.reserve(mints);
215 m_step_dx.reserve(mints);
216 m_step_dy.reserve(mints);
217 m_step_dz.reserve(mints);
218 m_step_length.reserve(mints);
219 m_step_X0.reserve(mints);
220 m_step_L0.reserve(mints);
221 m_step_A.reserve(mints);
222 m_step_Z.reserve(mints);
223 m_step_rho.reserve(mints);
225 m_sur_id.reserve(mints);
226 m_sur_type.reserve(mints);
227 m_sur_x.reserve(mints);
228 m_sur_y.reserve(mints);
229 m_sur_z.reserve(mints);
230 m_sur_pathCorrection.reserve(mints);
231 m_sur_range_min.reserve(mints);
232 m_sur_range_max.reserve(mints);
234 m_vol_id.reserve(mints);
237 if (
m_cfg.recalculateTotals) {
241 m_tX0 = mtrack.second.materialInX0;
242 m_tL0 = mtrack.second.materialInL0;
246 m_v_x = mtrack.first.first.x();
247 m_v_y = mtrack.first.first.y();
248 m_v_z = mtrack.first.first.z();
249 m_v_px = mtrack.first.second.x();
250 m_v_py = mtrack.first.second.y();
251 m_v_pz = mtrack.first.second.z();
252 m_v_phi =
phi(mtrack.first.second);
253 m_v_eta =
eta(mtrack.first.second);
256 for (
const auto&
mint : materialInteractions) {
257 auto direction =
mint.direction.normalized();
260 m_step_x.push_back(
mint.position.x());
261 m_step_y.push_back(
mint.position.y());
262 m_step_z.push_back(
mint.position.z());
263 m_step_dx.push_back(direction.x());
264 m_step_dy.push_back(direction.y());
265 m_step_dz.push_back(direction.z());
267 if (
m_cfg.prePostStep) {
269 mint.position - 0.5 *
mint.pathCorrection * direction;
271 mint.position + 0.5 *
mint.pathCorrection * direction;
273 m_step_sx.push_back(prePos.x());
274 m_step_sy.push_back(prePos.y());
275 m_step_sz.push_back(prePos.z());
276 m_step_ex.push_back(posPos.x());
277 m_step_ey.push_back(posPos.y());
278 m_step_ez.push_back(posPos.z());
282 if (
m_cfg.storeSurface) {
284 if (
mint.intersectionID.value() != 0) {
285 m_sur_id.push_back(
mint.intersectionID.value());
286 m_sur_pathCorrection.push_back(
mint.pathCorrection);
287 m_sur_x.push_back(
mint.intersection.x());
288 m_sur_y.push_back(
mint.intersection.y());
289 m_sur_z.push_back(
mint.intersection.z());
290 }
else if (surface !=
nullptr) {
291 auto sfIntersection = surface
293 mint.direction,
true)
296 m_sur_pathCorrection.push_back(1.0);
297 m_sur_x.push_back(sfIntersection.position().x());
298 m_sur_y.push_back(sfIntersection.position().y());
299 m_sur_z.push_back(sfIntersection.position().z());
302 m_sur_x.push_back(0);
303 m_sur_y.push_back(0);
304 m_sur_z.push_back(0);
305 m_sur_pathCorrection.push_back(1.0);
307 if (surface !=
nullptr) {
308 m_sur_type.push_back(surface->
type());
314 if (radialBounds !=
nullptr) {
315 m_sur_range_min.push_back(radialBounds->
rMin());
316 m_sur_range_max.push_back(radialBounds->
rMax());
317 }
else if (cylinderBounds !=
nullptr) {
318 m_sur_range_min.push_back(
320 m_sur_range_max.push_back(
323 m_sur_range_min.push_back(0);
324 m_sur_range_max.push_back(0);
327 m_sur_type.push_back(-1);
328 m_sur_range_min.push_back(0);
329 m_sur_range_max.push_back(0);
334 if (
m_cfg.storeVolume) {
336 if (not
mint.volume.empty()) {
337 vlayerID =
mint.volume.geometryId();
338 m_vol_id.push_back(vlayerID.
value());
345 m_vol_id.push_back(vlayerID.
value());
350 const auto& mprops =
mint.materialSlab;
351 m_step_length.push_back(mprops.thickness());
352 m_step_X0.push_back(mprops.material().X0());
353 m_step_L0.push_back(mprops.material().L0());
354 m_step_A.push_back(mprops.material().Ar());
355 m_step_Z.push_back(mprops.material().Z());
356 m_step_rho.push_back(mprops.material().massDensity());
358 if (
m_cfg.recalculateTotals) {
359 m_tX0 += mprops.thicknessInX0();
360 m_tL0 += mprops.thicknessInL0();
364 m_outputTree->Fill();