ATLAS Offline Software
Loading...
Searching...
No Matches
GbtsTrainingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "GbtsTrainingAlg.h"
5
6#include <fstream>
7
9
10namespace ActsTrk {
11
12namespace {
13
14// string parser for detector layer information
15std::vector<Acts::Experimental::GbtsLayerConnectionTool::LayerDescription>
16geometryParser(const std::string& geometryInformation) {
17
18 std::ifstream inStream(geometryInformation);
19
20 if (!inStream) {
21 throw std::runtime_error("File does not exist or could not be opened: " +
22 geometryInformation);
23 }
24
25 std::vector<Acts::Experimental::GbtsLayerConnectionTool::LayerDescription>
26 detectorGeometry{};
27 // create geometry objects
28 float minR{};
29 float maxR{};
30
31 float minZ{};
32 float maxZ{};
33
34 std::int32_t gbtsId{};
35
36 while (inStream >> minR >> maxR >> minZ >> maxZ >> gbtsId) {
37 detectorGeometry.emplace_back(minR, maxR, minZ, maxZ, gbtsId);
38 }
39
40 // the loop above stops on the first extraction that fails, so check why:
41 // reaching the end of the file is the only acceptable reason
42 if (inStream.bad()) {
43 throw std::runtime_error("I/O error while reading geometry file: " +
44 geometryInformation);
45 }
46
47 if (!inStream.eof()) {
48 throw std::runtime_error("Malformed record in geometry file: " +
49 geometryInformation);
50 }
51
52 return detectorGeometry;
53}
54
55// function for obtaining old formatting of connection table (will be retired at
56// some point soon) but good to keep for comparison for now
57bool writeOldConnectionTable(
58 const std::string& outputFileLocation,
59 const Acts::Experimental::GbtsLayerConnectionTool::LayerIdPairs&
60 tempTable) {
61
62 std::ofstream outputFile(outputFileLocation);
63
64 if (!outputFile) {
65 return false;
66 }
67
68 outputFile << tempTable.size() << " " << 0.2 << "\n";
69 for (const auto& layerPair : tempTable) {
70 outputFile << 0 << " " << 1 << " " << layerPair.second << " "
71 << layerPair.first << " " << 1 << " " << 1 << " " << 100 << "\n"
72 << 100 << "\n";
73 }
74
75 // close explicitly so that any failure to flush is reported here
76 outputFile.close();
77
78 return outputFile.good();
79}
80
81// writes the layer transitions out, in either the current or the old format
82bool writeConnectionTable(
83 const std::string& outputFileLocation,
84 const Acts::Experimental::GbtsLayerConnectionTool::LayerIdPairs& layerTable,
85 const bool useOldFormatting) {
86
87 if (useOldFormatting) {
88 return writeOldConnectionTable(outputFileLocation, layerTable);
89 }
90
91 // define output text file
92 std::ofstream outputFile(outputFileLocation);
93
94 if (!outputFile) {
95 return false;
96 }
97
98 outputFile << layerTable.size() << "\n";
99 for (const auto& layerPair : layerTable) {
100
101 // swap order as we want outward -> inward ordering
102 outputFile << layerPair.second << " " << layerPair.first << "\n";
103 }
104
105 // close explicitly so that any failure to flush is reported here
106 outputFile.close();
107
108 return outputFile.good();
109}
110} // namespace
111
113
114 // retireive truth track builder tool
116 // Make the logger And Propagate to ACTS routines
117 m_logger = makeActsAthenaLogger(this, "Acts");
118
119 m_config.detectorGeometry = geometryParser(m_geometryFile);
121
122 m_layerConnectionTool.emplace(m_config,
123 logger().cloneWithSuffix("gbtsLayerTool"));
124
125 return StatusCode::SUCCESS;
126}
127
128// outline:
129// get the truth particle to reco cluster map,
130// "invert" such that we have a map of truth particles with a vector of clusters
131// time or distance order (time prefereable) to "recontruct" a truth matched
132// track do for both pixel and strip clusters
133StatusCode GbtsTrainingAlg::execute(const EventContext& ctx) const {
134
136
137 ATH_CHECK(m_truthTrackBuilderTool->buildTruthTracks(ctx, truthTracks));
138
139 for (auto& [truthParticle, truthClusters] : truthTracks) {
140 // find the GBTS layer of each cluster; a cluster without a layer splits
141 // the track, so that no transition skips over it
142 std::vector<std::vector<Acts::Experimental::GbtsExperimentLayerId>>
143 segments(1);
144 for (const auto& cluster : truthClusters) {
145
146 const float r =
147 std::hypot(cluster.globalPosition.x(), cluster.globalPosition.y());
148 const float z = cluster.globalPosition.z();
149
150 const auto gbtsId = findGbtsIdByCoord(r, z);
151 if (!gbtsId) {
152 ATH_MSG_WARNING("No Gbts Layer for coordinates with r: "
153 << r << " and z: " << z);
154 if (!segments.back().empty()) {
155 segments.emplace_back();
156 }
157 continue;
158 }
159
160 segments.back().push_back(*gbtsId);
161 }
162
163 // add track segments to training algorithm
164 {
165 std::lock_guard<std::mutex> lock(m_gbtsTrainingToolMutex);
166 for (const auto& segment : segments) {
167 if (segment.size() < 2) {
168 continue;
169 }
170 m_layerConnectionTool->addTrack(segment);
171 }
172 }
173 }
174
175 return StatusCode::SUCCESS;
176}
177
179
180 const auto layerTable = m_layerConnectionTool->createConnectionTable();
181
182 // finally, add transitions to output file (old or new format)
183 if (!writeConnectionTable(m_outputConnectionTable, layerTable,
185
186 ATH_MSG_ERROR("Could not write connection table to "
187 << m_outputConnectionTable.value());
188 return StatusCode::FAILURE;
189 }
190
191 return StatusCode::SUCCESS;
192}
193
195
196 m_config.doSymmetrization = m_doSymmetrization;
197 m_config.probThreshold = m_probThreshold;
198}
199
200std::optional<Acts::Experimental::GbtsExperimentLayerId>
201GbtsTrainingAlg::findGbtsIdByCoord(const float r, const float z) const {
202 for (const auto& layer : m_config.detectorGeometry) {
203 const float zMin = layer.minZ - m_zMinTol;
204 const float zMax = layer.maxZ + m_zMaxTol;
205 const float rMin = layer.minR - m_rMinTol;
206 const float rMax = layer.maxR + m_rMaxTol;
207
208 if (zMin <= z && z <= zMax && rMin <= r && r <= rMax) {
209 return layer.gbtsId;
210 }
211 }
212
213 return std::nullopt;
214}
215} // namespace ActsTrk
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition Logger.cxx:64
#define z
Acts::Experimental::GbtsLayerConnectionTool::Config m_config
std::unique_ptr< const Acts::Logger > m_logger
StatusCode initialize() override
Gaudi::Property< float > m_zMinTol
Gaudi::Property< float > m_zMaxTol
Gaudi::Property< std::string > m_outputConnectionTable
Gaudi::Property< float > m_rMinTol
ToolHandle< TruthTrackBuilderTool > m_truthTrackBuilderTool
Gaudi::Property< std::string > m_geometryFile
std::optional< Acts::Experimental::GbtsExperimentLayerId > findGbtsIdByCoord(float r, float z) const
Gaudi::Property< float > m_rMaxTol
StatusCode execute(const EventContext &ctx) const override
StatusCode finalize() override
Gaudi::Property< bool > m_useOldFormatting
const Acts::Logger & logger() const
private member functions
Gaudi::Property< bool > m_doSymmetrization
Gaudi::Property< float > m_probThreshold
std::unordered_map< const xAOD::TruthParticle *, TruthHits > TruthTracks
int r
Definition globals.cxx:22
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...