Function initializing and executing the geometry conversion.
25{
26 ATH_MSG_DEBUG(
"Initializing device detector description provider service ");
27
31
36
37 std::map<Acts::GeometryIdentifier, Identifier> actsToAthena;
38 std::unordered_map<uint64_t, Identifier> detrayToAthenaMap;
39 std::unordered_map<Identifier, uint64_t> athenaToDetrayMap;
40
41 int nPix = 0,
nStrip = 0, nEC = 0, nBar = 0;
42 std::vector<Acts::GeometryIdentifier> actsHGTD;
44
45
46
47
50
52 if (!surface) return;
54 if (!actsElement){
55 ATH_MSG_DEBUG(
"Could not find matching Acts detector element for surface with geometryId " << surface->geometryId());
56 return;
57 }
58
61
62
63 ATH_MSG_VERBOSE(
"Found HGTD surface with geometryId " << surface->geometryId());
64 actsHGTD.push_back(surface->geometryId());
65 return;
66 }
68 ATH_MSG_DEBUG(
"Found non-pixel, non-strip detector element with geometryId " << surface->geometryId());
69 return;
70 }
71 const auto *detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(actsElement->upstreamDetectorElement());
72 if (!detElem) {
73 ATH_MSG_DEBUG(
"Could not find matching Athena silicon detector element for surface with geometryId " << surface->geometryId());
74 return;
75 }
76
77 Identifier athenaID;
78 moduleInfo thismod;
79
80
81
82
83
85 thismod.
pixel =
false;
87
88 switch (detType) {
90 ++nPix;
91 athenaID = detElem->identify();
92 const auto* p_design = static_cast<const InDetDD::PixelModuleDesign*>(&detElem->design());
93
96
97 std::vector<traccc::scalar> row_centres;
98 std::vector<traccc::scalar> column_centres;
99
100
101
104
106
107 for(
int row = 0;
row < p_design->rows();
row++){
108
109 std::array<InDetDD::PixelDiodeTree::CellIndexType, 2>
111 row, 0);
112 InDetDD::PixelDiodeTree::DiodeProxyWithPosition si_param(
113 p_design->diodeProxyFromIdxCachePosition(diode_idx));
114
115 (row_centres).
push_back(si_param.position()[0]-0.5*si_param.width()[0]);
116 if(row == p_design->rows()-1){
117 (row_centres).
push_back(si_param.position()[0]+0.5*si_param.width()[0]);
118 }
119
120 float leading_edge = si_param.position()[0] - 0.5f*si_param.width()[0];
121 float trailing_edge = si_param.position()[0] + 0.5f*si_param.width()[0];
122 float midpoint = (leading_edge + trailing_edge) / 2.f;
123 if(std::abs(midpoint - si_param.position()[0]) > 1e-6f){
125 << " != geometry centre " << si_param.position()[0]
126 << " (diff=" << midpoint - si_param.position()[0] << ")");
127 }
128
129 }
130 for(int col = 0; col < p_design->columns(); col++){
131
132 std::array<InDetDD::PixelDiodeTree::CellIndexType, 2>
134 0, col);
135 InDetDD::PixelDiodeTree::DiodeProxyWithPosition si_param(
136 p_design->diodeProxyFromIdxCachePosition(diode_idx));
137
138 (column_centres).
push_back(si_param.position()[1]-0.5*si_param.width()[1]);
139 if(col == p_design->columns()-1){
140 (column_centres).
push_back(si_param.position()[1]+0.5*si_param.width()[1]);
141 }
142
143 float leading_edge = si_param.position()[1] - 0.5f*si_param.width()[1];
144 float trailing_edge = si_param.position()[1] + 0.5f*si_param.width()[1];
145 float midpoint = (leading_edge + trailing_edge) / 2.f;
146 if(std::abs(midpoint - si_param.position()[1]) > 1e-6f){
147 ATH_MSG_ERROR(
"Column " << col <<
" edge midpoint " << midpoint
148 << " != geometry centre " << si_param.position()[1]
149 << " (diff=" << midpoint - si_param.position()[1] << ")");
150 }
151
152 }
153
154 }
155
158
161 thismod.
rows = p_design->rows();
162 thismod.
columns = p_design->columns();
163 break;
164 }
167 const Identifier moduleID =
m_stripID->module_id(detElem->identify());
168 const IdentifierHash moduleHash =
m_stripID->wafer_hash(moduleID);
170 athenaID =
m_stripID->wafer_id(moduleHash + side);
171
172 thismod.
pixel =
false;
175
176 if (
m_stripID->barrel_ec(athenaID) == 0) {
177 ++nBar;
178 const auto* s_design = static_cast<const InDetDD::SCT_BarrelModuleSideDesign*>(&detElem->design());
179
182 thismod.
rows = s_design->cells();
183 } else {
184 ++nEC;
185 const auto* annulus_design = static_cast<const InDetDD::StripStereoAnnulusDesign*>(&detElem->design());
186 const InDetDD::SiCellId annulus_cell = detElem->cellIdFromIdentifier(athenaID);
187 const double pitch_row = annulus_design->phiPitchPhi(annulus_cell);
188 const int nDiodes = annulus_design->diodesInRow(0.);
189 const double max_phi = nDiodes * pitch_row;
191
192
194 thismod.
rows = nDiodes;
196 }
197 break;
198 }
199 default:
200
201 return;
202 }
203
205 const auto geo_id = surface->geometryId();
206 actsToAthena[geo_id] = athenaID;
207
208 });
209
211 ATH_MSG_DEBUG(nStrip <<
" Atlas Strip modules found, " << nBar <<
" in barrel and " << nEC <<
" in the endcap");
213
214
216
217 int found_detray = 0;
218 int missing_detray = 0;
219 int missing_detray_passives = 0;
220
222 const auto& itkDetector = hostDetector->as<traccc::itk_detector>();
223 for (const auto& surface : itkDetector.surfaces()) {
224 const auto geo_id = surface.source;
225 const Acts::GeometryIdentifier acts_geom_id{geo_id};
226 auto sf = detray::tracking_surface{itkDetector, surface};
227 const auto detray_id =
sf.identifier().value();
228
229 if (auto pIdPair = actsToAthena.find(acts_geom_id); pIdPair != actsToAthena.end()) {
230 auto athena_id = pIdPair->second;
231 detrayToAthenaMap[detray_id] = athena_id;
232 athenaToDetrayMap[athena_id] = detray_id;
233 found_detray++;
234 } else {
235 if (std::find(actsHGTD.begin(), actsHGTD.end(), acts_geom_id) != actsHGTD.end()) {
236 ATH_MSG_VERBOSE(
"ACTS surface with key " << acts_geom_id <<
" is HGTD, detray id: " << detray_id);
237 continue;
238 }
239 ATH_MSG_VERBOSE(
"ACTS surface with key " << acts_geom_id <<
" was not translated to detray geometry.");
240 missing_detray++;
241 if (surface.is_sensitive()) continue;
242 ATH_MSG_VERBOSE(
"found this passive surface in detray: " << acts_geom_id);
243 missing_detray_passives++;
244 }
245 }
246
247 ATH_MSG_DEBUG(
"Traccc detector has " << found_detray <<
" surfaces matching ACTS and " << missing_detray <<
" additional surfaces, out of which " << missing_detray_passives <<
" are not sensitive.");
248
249
250
251
252 std::map<designKey, unsigned int> designLookup;
253 unsigned int nextDesignId = 0;
254
255 const std::size_t nSurfaces = itkDetector.surfaces().size();
257
258 auto idMapping = std::make_unique<ActsTrk::GeometryIdMapping>();
259 idMapping->reserve(nSurfaces);
260
261 for (std::size_t condIndex = 0; condIndex < nSurfaces; ++condIndex) {
262 const auto& surface = itkDetector.surfaces()[condIndex];
263 if (!surface.is_sensitive()) {
264 ATH_MSG_VERBOSE(
"Skipping passive surface with geometryId " << surface.source);
265 continue;
266 }
267 const auto geo_id = surface.source;
268 const Acts::GeometryIdentifier acts_geom_id{geo_id};
269 auto sf = detray::tracking_surface{itkDetector, surface};
270 const auto detray_id =
sf.identifier().value();
271
272 StaticCondEntry
entry;
273 entry.detrayGeometryId = detray::geometry::identifier{detray_id};
274 entry.actsGeometryId = acts_geom_id.value();
275
276 auto detrayIt = detrayToAthenaMap.find(detray_id);
277 std::optional<Identifier> athenaId;
278 if (detrayIt != detrayToAthenaMap.end()) {
279 athenaId = detrayIt->second;
282 const moduleInfo& thismod = modIt->second;
283
284 const int nBinsX = thismod.
rows;
286
289
293 }
294
297
298 const auto [
it, inserted] = designLookup.try_emplace(key, nextDesignId);
300 if (inserted) ++nextDesignId;
301
302 entry.athenaId = *athenaId;
303 entry.hasAthenaModule =
true;
305 }
306 }else{
307 if (std::find(actsHGTD.begin(), actsHGTD.end(), acts_geom_id) != actsHGTD.end()) {
308 ATH_MSG_VERBOSE(
"ACTS surface with key " << acts_geom_id <<
" is HGTD, detray id: " << detray_id);
309 continue;
310 }
311 ATH_MSG_ERROR(
"Could not find matching Athena module for detray surface with geometryId " << detray_id);
312 return StatusCode::FAILURE;
313 }
314
315 idMapping->addEntry(detray_id, acts_geom_id.value(), athenaId);
316
317 idMapping->addDetDescIndex(detray_id, static_cast<unsigned int>(condIndex));
319 }
320
321
322
323 auto hostDesign = std::make_unique<traccc::detector_design_description::host>(*
m_MRs->hostMR());
324 hostDesign->resize(designLookup.size());
325 for (const auto& [key, id] : designLookup) {
326 hostDesign->design_id()[
id] =
static_cast<int>(
id);
327
328 hostDesign->dimensions()[
id] =
key.pixel ? 2 : 1;
329
331 hostDesign->bin_edges_x()[
id].assign(
key.edgesX.begin(),
key.edgesX.end());
332 hostDesign->bin_edges_y()[
id].assign(
key.edgesY.begin(),
key.edgesY.end());
333 hostDesign->subspace()[
id] = std::array<detray::dindex_type<traccc::default_algebra>, 2u>{0
u, 1u};
334 }else{
335 hostDesign->bin_edges_y()[
id].assign(
key.edgesX.begin(),
key.edgesX.end());
336 hostDesign->bin_edges_x()[
id].assign(
key.edgesY.begin(),
key.edgesY.end());
337 hostDesign->subspace()[
id] = std::array<detray::dindex_type<traccc::default_algebra>, 2u>{1u, 0
u};
338 }
339
340 }
341
342 std::vector<unsigned int> designSizes(hostDesign->size());
343 for (std::size_t i = 0;
i < hostDesign->size(); ++
i) {
344 auto thisDesign = hostDesign->at(i);
345 designSizes[
i] = std::max(
346 static_cast<unsigned int>(thisDesign.bin_edges_x().size()),
347 static_cast<unsigned int>(thisDesign.bin_edges_y().size()));
348 }
349
350 auto initCopy =
m_copy->copy(EventContext{});
351 auto deviceDesign = std::make_unique<traccc::detector_design_description::buffer>(
352 designSizes,
m_MRs->mainMR(),
m_MRs->hostMR(),
353 vecmem::data::buffer_type::resizable);
354 (*initCopy).setup(*deviceDesign)->wait();
355 (*initCopy)(vecmem::get_data(*hostDesign), *deviceDesign)->wait();
356
357 constexpr bool allowMods = false;
361
362 auto deviceDetector = std::make_unique<traccc::detector_buffer>();
363 deviceDetector->set<traccc::itk_detector>(
364 detray::get_buffer(itkDetector,
m_MRs->mainMR(),
const_cast<vecmem::copy&
>(*initCopy)));
366
368
369 } else {
371 return StatusCode::FAILURE;
372 }
373
374
375 return StatusCode::SUCCESS;
376}
const ActsDetectorElement * getActsDetectorElement(const Acts::Surface &surf)
Attempts to retrieve the ActsDetectorElement associated to the passed ActsSurface.
#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,...)
#define ATH_MSG_FATAL(x,...)
ServiceHandle< StoreGateSvc > m_detStore
const PixelID * m_pixelID
Conversion helpers (to retrieve module design, hash, etc.) {.
Gaudi::Property< std::string > m_pixelIdHelperName
const InDetDD::SCT_DetectorManager * m_stripManager
ToolHandle< AthDevice::ICopyTool > m_copy
The copy tool used for copying data to device.
ToolHandle< AthDevice::IMemoryResourcesTool > m_MRs
Gaudi::Property< std::string > m_geoIdMappingObjectName
Gaudi::Property< std::string > m_deviceDesignObjectName
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
const InDetDD::PixelDetectorManager * m_pixelManager
std::shared_ptr< const Acts::TrackingGeometry > m_trackingGeometry
std::map< Identifier, moduleInfo > m_atlasModuleInfo
Gaudi::Property< std::string > m_hostDesignObjectName
std::vector< StaticCondEntry > m_staticCondEntries
Gaudi::Property< std::string > m_deviceDetectorName
Gaudi::Property< std::string > m_stripIdHelperName
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
@ Pixel
Inner detector legacy.
std::vector< traccc::scalar > makeEquidistantEdges(float halfWidth, int nBins)
row
Appending html table to final .html summary file.
@ u
Enums for curvilinear frames.
@ nStrip
Get number of strips.
std::vector< traccc::scalar > row_centres
std::vector< traccc::scalar > column_centres