ATLAS Offline Software
Loading...
Searching...
No Matches
MaterialTrackReader.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <optional>
8
9#include "GaudiKernel/IInterface.h"
11#include "TFile.h"
12#include "TTree.h"
13
15
17
19
20 if (m_fileNames.empty()) {
21 ATH_MSG_ERROR("No input files given... Please check!!");
22 return StatusCode::FAILURE;
23 }
24
25 // set up the input chain
26 m_inputChain = std::make_unique<TChain>(m_treeName.value().c_str());
27
28 // loop over the input files
29 for (const auto& inputFile : m_fileNames) {
30 // add file to the input chain
31 ATH_MSG_DEBUG("Adding File " << inputFile << " to tree '" << m_treeName
32 << "'.");
33 if (!m_inputChain->Add(inputFile.c_str())) {
34 ATH_MSG_ERROR("Failed to load file " << inputFile);
35 return StatusCode::FAILURE;
36 }
37 }
38
39 // Connect the branches
40 m_accessor.connectForRead(*m_inputChain);
41 // get the number of events, which also loads the tree
42 m_nTreeEntries = m_inputChain->GetEntries();
43
44 if (m_skipEvents > 0ul) {
45 std::optional<std::uint32_t> evt{0ul};
46 std::size_t procEvts{0ul};
47 ATH_MSG_DEBUG("Skip " << m_skipEvents << " events. ");
49 m_inputChain->GetEntry(m_currEntry);
50 if (!evt) {
51 evt = m_accessor.eventId();
52 } else if ((*evt) != m_accessor.eventId()) {
53 ++procEvts;
54 evt = m_accessor.eventId();
55 }
56 if (procEvts == m_skipEvents) {
57 break;
58 }
59 }
60 ATH_MSG_INFO("Skipped " << procEvts << " events. Corresponding to "
61 << m_currEntry << " tree entries");
62 }
63 if (!m_nTreeEntries) {
64 ATH_MSG_ERROR("Input does not contain any recorded track");
65 return StatusCode::FAILURE;
66 }
67 ATH_MSG_INFO("Material files contain "
68 << m_nTreeEntries << " entries. Process " << m_batchSize.value()
69 << " material events per athena event. Until "
70 << m_maxEvents.value()
71 << " events are processed or the tree is finished");
72 return StatusCode::SUCCESS;
73}
74
76 if (m_inputChain) {
78 "Not all entries / events have been processed. Processed entries: "
79 << (m_currEntry + 1) << "/" << m_nTreeEntries << ", processed events: "
80 << m_procEvents << "/" << m_maxEvents.value());
81 }
82 return StatusCode::SUCCESS;
83}
84
85StatusCode ActsTrk::MaterialTrackReader::execute(const EventContext& ctx) {
86 // Write to the collection to the EventStore
88
89 // Record the collection once per event if not already there
90 if (!materialTracks.isPresent()) {
91 ATH_CHECK(materialTracks.record(
92 std::make_unique<ActsTrk::RecordedMaterialTrackCollection>()));
93 }
94
96 m_inputChain.reset();
97 return StatusCode::SUCCESS;
98 }
99
100 std::size_t nProcEvents{0ul};
101 std::size_t nCurrentEvt{m_accessor.eventId()};
102
103 // Each tree entry is a single material step, not a full track: many
104 // consecutive entries share the same event_id and together make up one
105 // physical track. Accumulate them into pendingTrack and only push the
106 // merged track once the event_id changes (or we run out of entries),
107 // otherwise the material mapper's per-track averaging normalizes by the
108 // number of steps instead of the number of tracks.
109 std::optional<Acts::RecordedMaterialTrack> pendingTrack{};
110 auto flushPending = [&]() {
111 if (pendingTrack) {
112 materialTracks->push_back(std::move(*pendingTrack));
113 pendingTrack.reset();
114 }
115 };
116
118 ATH_MSG_VERBOSE("Fetched entry " << m_currEntry
119 << ", eventId: " << m_accessor.eventId());
120 // get the correspoing entry and read it
121 m_inputChain->GetEntry(m_currEntry);
122 Acts::RecordedMaterialTrack rmTrack = m_accessor.read();
123 m_accessor.eventId();
124
125 ATH_MSG_VERBOSE("Track vertex: " << Amg::toString(rmTrack.first.first)
126 << ", momentum:"
127 << Amg::toString(rmTrack.first.second));
128
129 if (nCurrentEvt != m_accessor.eventId()) {
130 // previous event_id's steps are complete: flush the assembled track
131 flushPending();
132 ++nProcEvents;
133 ++m_procEvents;
134 nCurrentEvt = m_accessor.eventId();
135 }
136
137 if (m_procEvents >= m_maxEvents) {
138 flushPending();
139 ATH_MSG_INFO("All " << m_maxEvents << " events have been processed");
141 return StatusCode::SUCCESS;
142 }
143
144 if (nProcEvents >= m_batchSize) {
145 ATH_MSG_DEBUG("Batch processing " << nProcEvents << " completed. ");
146 break;
147 }
148
149 // merge this step into the track being assembled for the current event_id
150 if (!pendingTrack) {
151 pendingTrack = std::move(rmTrack);
152 } else {
153 auto& interactions = pendingTrack->second.materialInteractions;
154 interactions.insert(
155 interactions.end(),
156 std::make_move_iterator(rmTrack.second.materialInteractions.begin()),
157 std::make_move_iterator(rmTrack.second.materialInteractions.end()));
158 pendingTrack->second.materialInX0 += rmTrack.second.materialInX0;
159 pendingTrack->second.materialInL0 += rmTrack.second.materialInL0;
160 }
161 }
162 // end of tree reached while a track was still being assembled
163 flushPending();
164 return StatusCode::SUCCESS;
165}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
std::unique_ptr< TChain > m_inputChain
The input chain of entries.
Gaudi::Property< std::size_t > m_batchSize
The batch size (number of track per events).
ActsPlugins::RootMaterialTrackIo m_accessor
The read - write payload.
Gaudi::Property< std::size_t > m_skipEvents
The number of events in the file to skip.
virtual StatusCode initialize() override
Gaudi::Property< std::size_t > m_maxEvents
The number of events in the processed.
virtual StatusCode finalize() override
Gaudi::Property< std::vector< std::string > > m_fileNames
The list of input filenames.
Gaudi::Property< std::string > m_treeName
The name of the input tree.
std::size_t m_nTreeEntries
The number of entries in the tree to read.
SG::WriteHandleKey< RecordedMaterialTrackCollection > m_materialTrackCollectionKey
The RecordedMaterialTrackCollection to write.
std::size_t m_currEntry
The current processed tree entry.
std::size_t m_procEvents
The number of processed tree events.
bool isPresent() const
Is the referenced object present in SG?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.