ATLAS Offline Software
ActsTrackingGeometrySvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
8 // ATHENA
9 #include "GaudiKernel/EventContext.h"
12 #include "InDetIdentifier/TRT_ID.h"
15 #include "StoreGate/StoreGateSvc.h"
18 #include "GeoModelKernel/GeoTube.h"
19 
20 // ACTS
21 #include "Acts/ActsVersion.hpp"
22 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
23 #include "Acts/Geometry/CylinderVolumeBuilder.hpp"
24 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
25 #include "Acts/Geometry/ITrackingVolumeBuilder.hpp"
26 #include "Acts/Geometry/LayerArrayCreator.hpp"
27 #include "Acts/Geometry/LayerCreator.hpp"
28 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
29 #include "Acts/Geometry/TrackingGeometry.hpp"
30 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
31 #include "Acts/Geometry/TrackingVolume.hpp"
32 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
33 #include "Acts/Utilities/Logger.hpp"
34 #include "Acts/Definitions/Units.hpp"
35 #include "Acts/Geometry/PassiveLayerBuilder.hpp"
36 #include <Acts/Plugins/Json/JsonMaterialDecorator.hpp>
37 #include <Acts/Plugins/Json/MaterialMapJsonConverter.hpp>
38 #include <Acts/Surfaces/PlanarBounds.hpp>
39 #include <Acts/Surfaces/AnnulusBounds.hpp>
40 #include <Acts/Surfaces/DiscSurface.hpp>
41 #include <Acts/Surfaces/LineSurface.hpp>
42 #include <Acts/Surfaces/RectangleBounds.hpp>
43 
44 // PACKAGE
51 #include "ActsInterop/Logger.h"
53 
54 #include <limits>
55 #include <random>
56 #include <stdexcept>
57 
58 using namespace Acts::UnitLiterals;
59 using namespace ActsTrk;
61  ISvcLocator *svc)
62  : base_class(name, svc),
63  m_detStore("StoreGateSvc/DetectorStore", name),
64  m_elementStore (std::make_shared<ActsElementVector>())
65 {
66 }
67 
69  ATH_MSG_INFO(name() << " is initializing");
70  for (unsigned int skipAlign : m_subDetNoAlignProp) {
71  try {
72  m_subDetNoAlign.insert(static_cast<DetectorType>(skipAlign));
73  } catch (...) {
74  ATH_MSG_FATAL("Failed to interpret " << m_subDetNoAlignProp << " as ActsDetectorElements");
75  return StatusCode::FAILURE;
76  }
77 }
78 
79  // FIXME: ActsCaloTrackingVolumeBuilder holds ReadHandle to
80  // CaloDetDescrManager. Hopefully this service is never called before that
81  // object is available.
82  m_autoRetrieveTools = false;
83  m_checkToolDeps = false;
84 
85  ATH_MSG_INFO("ACTS version is: v"
86  << Acts::VersionMajor << "." << Acts::VersionMinor << "."
87  << Acts::VersionPatch << " [" << Acts::CommitHash << "]");
88 
89  // load which subdetectors to build from property
90  std::set<std::string> buildSubdet(m_buildSubdetectors.begin(),
91  m_buildSubdetectors.end());
92  ATH_MSG_INFO("Configured to build " << buildSubdet.size()
93  << " subdetectors:");
94  for (const auto &s : buildSubdet) {
95  ATH_MSG_INFO(" - " << s);
96  }
97 
98  ATH_MSG_DEBUG("Loading detector manager(s)");
99  if (buildSubdet.find("Pixel") != buildSubdet.end()) {
100  ATH_CHECK(m_detStore->retrieve(p_pixelManager, "Pixel"));
101  }
102  if (buildSubdet.find("SCT") != buildSubdet.end()) {
103  ATH_CHECK(m_detStore->retrieve(p_SCTManager, "SCT"));
104  }
105  if (buildSubdet.find("TRT") != buildSubdet.end()) {
106  ATH_CHECK(m_detStore->retrieve(p_TRTManager, "TRT"));
107  ATH_CHECK(m_detStore->retrieve(m_TRT_idHelper, "TRT_ID"));
108  }
109  if (buildSubdet.find("ITkPixel") != buildSubdet.end()) {
110  ATH_CHECK(m_detStore->retrieve(p_ITkPixelManager, "ITkPixel"));
111  }
112  if (buildSubdet.find("ITkStrip") != buildSubdet.end()) {
113  ATH_CHECK(m_detStore->retrieve(p_ITkStripManager, "ITkStrip"));
114  }
115  if (buildSubdet.find("HGTD") != buildSubdet.end()) {
116  ATH_CHECK(m_detStore->retrieve(p_HGTDManager, "HGTD"));
117  ATH_CHECK(m_detStore->retrieve(m_HGTD_idHelper, "HGTD_ID"));
118  }
119 
120  if(m_buildBeamPipe) {
121  ATH_CHECK(m_detStore->retrieve(p_beamPipeMgr, "BeamPipe"));
122  }
123 
124 
125  ATH_MSG_DEBUG("Setting up ACTS geometry helpers");
126 
127  Acts::LayerArrayCreator::Config lacCfg;
128  auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
129  lacCfg, makeActsAthenaLogger(this, std::string("LayArrCrtr"), std::string("ActsTGSvc")));
130 
131  Acts::TrackingVolumeArrayCreator::Config tvcCfg;
132  auto trackingVolumeArrayCreator =
133  std::make_shared<const Acts::TrackingVolumeArrayCreator>(
134  tvcCfg, makeActsAthenaLogger(this, std::string("TrkVolArrCrtr"), std::string("ActsTGSvc")));
135 
136  Acts::CylinderVolumeHelper::Config cvhConfig;
137  cvhConfig.layerArrayCreator = layerArrayCreator;
138  cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
139 
140  auto cylinderVolumeHelper =
141  std::make_shared<const Acts::CylinderVolumeHelper>(
142  cvhConfig, makeActsAthenaLogger(this, std::string("CylVolHlpr"), std::string("ActsTGSvc")));
143 
144  Acts::TrackingGeometryBuilder::Config tgbConfig;
145  tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
146 
147  if (m_useMaterialMap) {
148  std::shared_ptr<const Acts::IMaterialDecorator> matDeco = nullptr;
149 
150  std::string matFileFullPath = PathResolverFindCalibFile(m_materialMapCalibFolder.value()+"/"+m_materialMapInputFileBase.value());
151  if (matFileFullPath.empty()) {
152  ATH_MSG_ERROR( "Material Map Input File " << m_materialMapCalibFolder.value() << "/" << m_materialMapInputFileBase.value() << " not found.");
153  return StatusCode::FAILURE;
154  }
155  ATH_MSG_INFO("Configured to use material input: " << matFileFullPath);
156 
157  if (matFileFullPath.find(".json") != std::string::npos) {
158  // Set up the converter first
159  Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
160  // Set up the json-based decorator
161  matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
162  jsonGeoConvConfig, matFileFullPath, ActsTrk::actsLevelVector(msg().level()));
163  }
164  tgbConfig.materialDecorator = matDeco;
165  }
166 
167  std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
168 
169  try {
170  // BeamPipe
171  if(m_buildBeamPipe) {
172  tgbConfig.trackingVolumeBuilders.push_back([&](const auto &gctx,
173  const auto &inner,
174  const auto &) {
175 
176  Acts::CylinderVolumeBuilder::Config bpvConfig =
177  makeBeamPipeConfig(cylinderVolumeHelper);
178 
179  Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
180  bpvConfig, makeActsAthenaLogger(this, std::string("BPVolBldr"), std::string("ActsTGSvc"))};
181 
182  return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
183  });
184  }
185 
186 
187 
188  // PIXEL
189  if (buildSubdet.count("Pixel") > 0) {
190  tgbConfig.trackingVolumeBuilders.push_back([&](const auto &gctx,
191  const auto &inner,
192  const auto &) {
195  auto lb = std::make_shared<ActsLayerBuilder>(
196  cfg, makeActsAthenaLogger(this, std::string("PixelGMSLayBldr"), std::string("ActsTGSvc")));
197  Acts::CylinderVolumeBuilder::Config cvbConfig;
198  cvbConfig.layerEnvelopeR = {3_mm, 3_mm};
199  cvbConfig.layerEnvelopeZ = 1_mm;
200  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
201  cvbConfig.volumeName = "Pixel";
202  cvbConfig.layerBuilder = lb;
203  cvbConfig.buildToRadiusZero = !m_buildBeamPipe;
204 
205  Acts::CylinderVolumeBuilder cvb(
206  cvbConfig, makeActsAthenaLogger(this, std::string("CylVolBldr"), std::string("ActsTGSvc")));
207 
208  return cvb.trackingVolume(gctx, inner);
209  });
210  }
211 
212  // ITK PIXEL
213  if (buildSubdet.count("ITkPixel") > 0) {
214  tgbConfig.trackingVolumeBuilders.push_back(
215  [&](const auto &gctx, const auto &inner, const auto &) {
218  cfg.objDebugOutput = m_objDebugOutput;
219  cfg.doEndcapLayerMerging = true;
220  auto lb = std::make_shared<ActsLayerBuilder>(
221  cfg, makeActsAthenaLogger(this, std::string("ITkPxInLb"), std::string("ActsTGSvc")));
222 
223  Acts::CylinderVolumeBuilder::Config cvbConfig;
224  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
225  cvbConfig.layerEnvelopeZ = 1_mm;
226  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
227  cvbConfig.volumeName = "ITkPixelInner";
228  cvbConfig.layerBuilder = lb;
229  cvbConfig.buildToRadiusZero = !m_buildBeamPipe;
230 
231  Acts::CylinderVolumeBuilder cvb(
232  cvbConfig,
233  makeActsAthenaLogger(this, std::string("CylVolBldr"), std::string("ActsTGSvc")));
234 
235  return cvb.trackingVolume(gctx, inner);
236  });
237 
238  tgbConfig.trackingVolumeBuilders.push_back(
239  [&](const auto &gctx, const auto &inner, const auto &) {
242  cfg.objDebugOutput = m_objDebugOutput;
243  cfg.doEndcapLayerMerging = false;
244  auto lb = std::make_shared<ActsLayerBuilder>(
245  cfg, makeActsAthenaLogger(this, std::string("ITkPxOtLb"), std::string("ActsTGSvc")));
246 
247  Acts::CylinderVolumeBuilder::Config cvbConfig;
248  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
249  cvbConfig.layerEnvelopeZ = 1_mm;
250  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
251  cvbConfig.volumeName = "ITkPixelOuter";
252  cvbConfig.layerBuilder = lb;
253  cvbConfig.buildToRadiusZero = false;
254  cvbConfig.checkRingLayout = true;
255  cvbConfig.ringTolerance = 10_mm;
256 
257  Acts::CylinderVolumeBuilder cvb(
258  cvbConfig,
259  makeActsAthenaLogger(this, std::string("CylVolBldr"), std::string("ActsTGSvc")));
260 
261  return cvb.trackingVolume(gctx, inner);
262  });
263  }
264 
265  // ITK STRIP
266  if (buildSubdet.count("ITkStrip") > 0) {
267  tgbConfig.trackingVolumeBuilders.push_back(
268  [&](const auto &gctx, const auto &inner, const auto &) {
271  cfg.objDebugOutput = m_objDebugOutput;
272  auto lb = std::make_shared<ActsLayerBuilder>(
273  cfg, makeActsAthenaLogger(this, std::string("ITkStripLB"), std::string("ActsTGSvc")));
274 
275  Acts::CylinderVolumeBuilder::Config cvbConfig;
276  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
277  cvbConfig.layerEnvelopeZ = 1_mm;
278  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
279  cvbConfig.volumeName = "ITkStrip";
280  cvbConfig.layerBuilder = lb;
281  cvbConfig.buildToRadiusZero =
282  buildSubdet.count("ITkPixel") == 0 && !m_buildBeamPipe;
283 
284  Acts::CylinderVolumeBuilder cvb(
285  cvbConfig,
286  makeActsAthenaLogger(this, std::string("CylVolBldr"), std::string("ActsTGSvc")));
287 
288  return cvb.trackingVolume(gctx, inner);
289  });
290  }
291 
292  bool buildSCT = buildSubdet.count("SCT") > 0;
293  bool buildTRT = buildSubdet.count("TRT") > 0;
294 
295  if (buildSCT && buildTRT) {
296  // building both we need to take care
297  tgbConfig.trackingVolumeBuilders.push_back(
298  [&](const auto &gctx, const auto &inner, const auto &) {
301  cfg.endcapEnvelopeZ = sctECEnvelopeZ;
302  auto sct_lb = std::make_shared<ActsLayerBuilder>(
303  cfg, makeActsAthenaLogger(this, std::string("SCTGMSLayBldr"), std::string("ActsTGSvc")));
304 
305  auto trt_lb = makeStrawLayerBuilder(p_TRTManager);
306 
307  return makeSCTTRTAssembly(gctx, *sct_lb, *trt_lb,
308  *cylinderVolumeHelper, inner);
309  });
310 
311  } else if (buildSCT) {
312  tgbConfig.trackingVolumeBuilders.push_back(
313  [&](const auto &gctx, const auto &inner, const auto &) {
314  auto lbCfg = makeLayerBuilderConfig(p_SCTManager);
315  lbCfg.mode = ActsLayerBuilder::Mode::SCT;
316  lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
317  auto lb = std::make_shared<ActsLayerBuilder>(
318  lbCfg,
319  makeActsAthenaLogger(this, std::string("SCTGMSLayBldr"), std::string("ActsTGSvc")));
320 
321  Acts::CylinderVolumeBuilder::Config cvbConfig;
322  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
323  cvbConfig.layerEnvelopeZ = 2_mm;
324  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
325  cvbConfig.volumeName = "SCT";
326  cvbConfig.layerBuilder = lb;
327  cvbConfig.buildToRadiusZero = false;
328 
329  Acts::CylinderVolumeBuilder cvb(
330  cvbConfig,
331  makeActsAthenaLogger(this, std::string("SCTCylVolBldr"), std::string("ActsTGSvc")));
332 
333  return cvb.trackingVolume(gctx, inner);
334  });
335  } else if (buildTRT) {
336  tgbConfig.trackingVolumeBuilders.push_back(
337  [&](const auto &gctx, const auto &inner, const auto &) {
339  Acts::CylinderVolumeBuilder::Config cvbConfig;
340  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
341  cvbConfig.layerEnvelopeZ = 2_mm;
342  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
343  cvbConfig.volumeName = "TRT";
344  cvbConfig.layerBuilder = lb;
345  cvbConfig.buildToRadiusZero = false;
346 
347  Acts::CylinderVolumeBuilder cvb(
348  cvbConfig,
349  makeActsAthenaLogger(this, std::string("TRTCylVolBldr"), std::string("ActsTGSvc")));
350 
351  return cvb.trackingVolume(gctx, inner);
352  });
353  }
354 
355  //HGTD
356  if(buildSubdet.count("HGTD") > 0) {
357  tgbConfig.trackingVolumeBuilders.push_back(
358  [&](const auto &gctx, const auto &inner, const auto &) {
359  auto lb = makeHGTDLayerBuilder(p_HGTDManager); //using ActsHGTDLayerBuilder
360  Acts::CylinderVolumeBuilder::Config cvbConfig;
361  cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
362  cvbConfig.layerEnvelopeZ = 1_mm;
363  cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
364  cvbConfig.volumeName = "HGTD";
365  cvbConfig.layerBuilder = lb;
366  cvbConfig.buildToRadiusZero = false;
367 
368  Acts::CylinderVolumeBuilder cvb(
369  cvbConfig,
370  makeActsAthenaLogger(this, std::string("HGTDCylVolBldr"), std::string("ActsTGSvc")));
371 
372  return cvb.trackingVolume(gctx, inner);
373  });
374  }
375 
376  // Calo
377  if (buildSubdet.count("Calo") > 0) {
378  tgbConfig.trackingVolumeBuilders.push_back(
379  [&](const auto &gctx, const auto &inner, const auto &) {
380  return m_caloVolumeBuilder->trackingVolume(gctx, inner, nullptr);
381  });
382  }
383  } catch (const std::exception &e) {
384  ATH_MSG_ERROR("Encountered error when building Acts tracking geometry");
385  ATH_MSG_ERROR(e.what());
386  return StatusCode::FAILURE;
387  }
388 
389  auto trackingGeometryBuilder =
390  std::make_shared<const Acts::TrackingGeometryBuilder>(
391  tgbConfig, makeActsAthenaLogger(this, std::string("TrkGeomBldr"), std::string("ActsTGSvc")));
392 
393  ATH_MSG_VERBOSE("Begin building process");
395  trackingGeometryBuilder->trackingGeometry(getNominalContext().context());
396  ATH_MSG_VERBOSE("Building process completed");
397 
398  if (!m_trackingGeometry) {
399  ATH_MSG_ERROR("No ACTS tracking geometry was built. Cannot proceeed");
400  return StatusCode::FAILURE;
401  }
402 
403 
405  ATH_MSG_INFO("Running extra consistency check! (this is SLOW)");
406  if(!runConsistencyChecks()) {
407  ATH_MSG_ERROR("Consistency check has failed! Geometry is not consistent");
408  return StatusCode::FAILURE;
409  }
410  }
411 
412  ATH_MSG_INFO("Acts TrackingGeometry construction completed");
413 
414  return StatusCode::SUCCESS;
415 }
416 
418  bool result = true;
419 
420  std::vector<Acts::Vector2> localPoints;
421  localPoints.reserve(m_consistencyCheckPoints);
422  std::mt19937 gen;
423  std::uniform_real_distribution<> dist(0.0, 1.0);
424 
425  std::optional<std::ofstream> os;
426  if(!m_consistencyCheckOutput.empty()){
427  os = std::ofstream{m_consistencyCheckOutput};
428  if(!os->good()) {
429  throw std::runtime_error{"Failed to open consistency check output file"};
430  }
431  }
432 
433  if(os) {
434  (*os) << "geo_id,vol_id,lay_id,sen_id,type,acts_loc0,acts_loc1,acts_inside,trk_loc0,trk_loc1,trk_inside,x,y,z,g2l_loc0,g2l_loc1,trk_x,trk_y,trk_z" << std::endl;
435  }
436  for(size_t i=0;i<m_consistencyCheckPoints;i++) {
437  localPoints.emplace_back(dist(gen), dist(gen));
438  }
439 
440  Acts::GeometryContext gctx = getNominalContext().context();
441 
442  size_t nTotalSensors = 0;
443  std::array<size_t,3> nInconsistent{0,0,0};
444  size_t nMismatchedCenters = 0;
445  size_t nMismatchedNormals = 0;
446 
447  // Comparison of Eigen vectors, similar to a.isApprox(b), but use absolute comparison to also work with zero vectors.
448  // All values will be mm or radians, so 1e-5 is a reasonable precision.
449  auto isApprox = [](auto& a, auto& b) -> bool {
450  return ((a - b).array().abs() < 1e-5).all();
451  };
452 
453  m_trackingGeometry->visitSurfaces([&](const Acts::Surface *surface) {
454  nTotalSensors++;
455 
456  const auto* actsDetElem = dynamic_cast<const ActsDetectorElement*>(surface->associatedDetectorElement());
457  if(actsDetElem == nullptr) {
458  ATH_MSG_ERROR("Invalid detector element found");
459  result = false;
460  return;
461  }
462  const auto* siDetElem = dynamic_cast<const InDetDD::SiDetectorElement*>(actsDetElem->upstreamDetectorElement());
463  if(siDetElem == nullptr) {
464  return;
465  }
466 
467  const auto* regSurface = dynamic_cast<const Acts::RegularSurface*>(surface);
468  const auto& trkSurface = siDetElem->surface();
469  if(regSurface == nullptr) {
470  ATH_MSG_ERROR("Invalid surface found");
471  result = false;
472  return;
473  }
474 
475  Acts::Vector3 center{regSurface->center(gctx)};
476  Amg::Vector3D trkCenter{trkSurface.center()};
477  if (/* auto *b = */ dynamic_cast<const Acts::AnnulusBounds *>(&surface->bounds()))
478  {
479  // // Acts::AnnulusBounds defines center() as center of whole disc, so get it from the bounds
480  // Acts::Vector2 locCenter{0.5 * (b->rMin() + b->rMax()), 0.5 * (b->phiMin() + b->phiMax())};
481  // center = surface->localToGlobal(gctx, locCenter, Acts::Vector3::Zero());
482  center.head<2>() = trkCenter.head<2>(); // that doesn't (quite) work for xy, so just pass that check
483  }
484 
485  if(!isApprox(trkCenter, center)) {
486  std::string trkName;
487  if (auto idHelper = siDetElem->getIdHelper())
488  {
489  trkName = idHelper->show_to_string(siDetElem->identify());
490  }
491  ATH_MSG_WARNING("Acts surface "
492  << surface->geometryId()
493  << " center (" << center[0] << ',' << center[1] << ',' << center[2]
494  << ") does not match Trk surface " << trkName
495  << " center (" << trkCenter[0] << ',' << trkCenter[1] << ',' << trkCenter[2] << ')');
496  nMismatchedCenters++;
497  result = false;
498  }
499 
500  const auto* lineSurface = dynamic_cast<const Acts::LineSurface*>(surface);
501  if(lineSurface == nullptr) {
502  Acts::Vector3 norm{regSurface->normal(gctx, regSurface->center(gctx))};
503  Amg::Vector3D trkNorm{trkSurface.normal()};
504  if(!isApprox(trkNorm, norm)) {
505  std::string trkName;
506  if (auto idHelper = siDetElem->getIdHelper())
507  {
508  trkName = idHelper->show_to_string(siDetElem->identify());
509  }
510  ATH_MSG_WARNING("Acts surface "
511  << surface->geometryId()
512  << " normal (" << norm[0] << ',' << norm[1] << ',' << norm[2]
513  << ") does not match Trk surface " << trkName
514  << " normal (" << trkNorm[0] << ',' << trkNorm[1] << ',' << trkNorm[2] << ')');
515  nMismatchedNormals++;
516  result = false;
517  }
518  }
519 
520  auto doPoints = [&](unsigned int type, const Acts::Vector2& loc) -> std::array<bool,3> {
521  Acts::Vector3 glb = surface->localToGlobal(gctx, loc, Acts::Vector3::Zero());
522 
525  Acts::Vector2 locg2l = Acts::Vector2::Zero();
526  bool locg2lOk = false;
527  auto locTrkRes = trkSurface.globalToLocal(glb);
528  if (locTrkRes) {
529  locTrk = locTrkRes.value();
530  glbTrk = trkSurface.localToGlobal(locTrk);
531 
532  auto locg2lRes = surface->globalToLocal(gctx, glbTrk, Acts::Vector3::Zero());
533  if (locg2lRes.ok()) {
534  locg2lOk = true;
535  locg2l = locg2lRes.value();
536  }
537  }
538 
539  auto gId = surface->geometryId();
540  if(os) {
541  (*os) << gId.value()
542  << "," << gId.volume()
543  << "," << gId.layer()
544  << "," << gId.sensitive()
545  << "," << type
546  << "," << loc[0]
547  << "," << loc[1]
548  << "," << surface->insideBounds(loc)
549  << "," << locTrk[0]
550  << "," << locTrk[1]
551  << "," << trkSurface.insideBounds(locTrk)
552  << "," << glb[0]
553  << "," << glb[1]
554  << "," << glb[2]
555  << "," << locg2l[0]
556  << "," << locg2l[1]
557  << "," << glbTrk[0]
558  << "," << glbTrk[1]
559  << "," << glbTrk[2]
560  << std::endl;
561  }
562 
563  return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
564  locg2lOk ? isApprox(loc, locg2l) : true,
565  locTrkRes ? isApprox(glb, glbTrk) : true};
566  };
567 
568 
569  constexpr double envelope = 10.0 * Acts::UnitConstants::mm;
570 
571  std::array<bool,3> allOk{true,true,true};
572  if(const auto* bounds = dynamic_cast<const Acts::PlanarBounds*>(&surface->bounds()); bounds) {
573  ATH_MSG_VERBOSE("Planar bounds");
574 
575  const Acts::RectangleBounds& boundingBox = bounds->boundingBox();
576  Acts::Vector2 min = boundingBox.min().array() - envelope;
577  Acts::Vector2 max = boundingBox.max().array() + envelope;
578  Acts::Vector2 diag = max - min;
579 
580  for(const auto& testPoint : localPoints) {
581  Acts::Vector2 loc = min.array() + (testPoint.array() * diag.array());
582  auto pointOk = doPoints(0, loc);
583  for (size_t i=0; i<pointOk.size(); ++i) {
584  if (!pointOk[i]) {
585  result = false;
586  allOk[i] = false;
587  }
588  }
589  }
590 
591  }
592  else if(const auto* bounds = dynamic_cast<const Acts::AnnulusBounds*>(&surface->bounds()); bounds) {
593  ATH_MSG_VERBOSE("Annulus bounds");
594 
595  // custom bounding box algo
596  std::vector<Acts::Vector2> vertices = bounds->vertices(5); // 5 segments on the radial edges
598  Acts::Vector2 max{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()};
599  for (const auto& vtx : vertices) {
600  min = min.array().min(vtx.array());
601  max = max.array().max(vtx.array());
602  }
603  min.array() -= envelope;
604  max.array() += envelope;
605  Acts::Vector2 diag = max - min;
606 
607  for(const auto& testPoint : localPoints) {
608  Acts::Vector2 locXY = min.array() + (testPoint.array() * diag.array());
609  Acts::Vector2 locPC = dynamic_cast<const Acts::DiscSurface&>(*surface).localCartesianToPolar(locXY);
610 
611  auto pointOk = doPoints(1, locPC);
612  for (size_t i=0; i<pointOk.size(); ++i) {
613  if (!pointOk[i]) {
614  result = false;
615  allOk[i] = false;
616  }
617  }
618  }
619 
620  }
621  else {
622  result = false;
623  }
624 
625  for (size_t i=0; i<allOk.size(); ++i) {
626  if (!allOk[i]) {
627  ++nInconsistent[i];
628  }
629  }
630 
631  });
632 
633  ATH_MSG_INFO("Total number of sensors : " << nTotalSensors);
634  ATH_MSG_INFO("Number of sensors with mismatched centers : " << nMismatchedCenters);
635  ATH_MSG_INFO("Number of sensors with mismatched normals : " << nMismatchedNormals);
636  ATH_MSG_INFO("Number of sensors with inconsistent inside: " << nInconsistent[0]);
637  ATH_MSG_INFO("Number of sensors with inconsistent g2l : " << nInconsistent[1]);
638  ATH_MSG_INFO("Number of sensors with inconsistent l2g : " << nInconsistent[2]);
639 
640  return result;
641 }
642 
643 std::shared_ptr<const Acts::TrackingGeometry>
645 
646  ATH_MSG_VERBOSE("Retrieving tracking geometry");
647  return m_trackingGeometry;
648 }
649 
650 std::shared_ptr<const Acts::ILayerBuilder>
653 
654  std::string managerName = manager->getName();
655  auto matcher = [](const Acts::GeometryContext & /*gctx*/,
656  Acts::BinningValue /*bValue*/, const Acts::Surface * /*aS*/,
657  const Acts::Surface *
658  /*bS*/) -> bool { return false; };
659 
660  Acts::SurfaceArrayCreator::Config sacCfg;
661  sacCfg.surfaceMatcher = matcher;
662  sacCfg.doPhiBinningOptimization = false;
663 
664  auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
665  sacCfg,
666  makeActsAthenaLogger(this, managerName + "SrfArrCrtr", std::string("ActsTGSvc")));
667  Acts::LayerCreator::Config lcCfg;
668  lcCfg.surfaceArrayCreator = surfaceArrayCreator;
669  auto layerCreator = std::make_shared<Acts::LayerCreator>(
670  lcCfg, makeActsAthenaLogger(this, managerName + "LayCrtr", std::string("ActsTGSvc")));
671 
673  cfg.mng = static_cast<const InDetDD::TRT_DetectorManager *>(manager);
674  cfg.elementStore = m_elementStore;
675  cfg.layerCreator = layerCreator;
676  cfg.idHelper = m_TRT_idHelper;
677  return std::make_shared<const ActsStrawLayerBuilder>(
678  cfg, makeActsAthenaLogger(this, managerName + "GMSLayBldr", std::string("ActsTGSvc")));
679 }
680 
681 std::shared_ptr<const Acts::ILayerBuilder>
683  const HGTD_DetectorManager *manager) {
684 
685  std::string managerName = manager->getName();
686  auto matcher = [](const Acts::GeometryContext & /*gctx*/,
687  Acts::BinningValue /*bValue*/, const Acts::Surface * /*aS*/,
688  const Acts::Surface *
689  /*bS*/) -> bool { return false; };
690 
691  Acts::SurfaceArrayCreator::Config sacCfg;
692  sacCfg.surfaceMatcher = matcher;
693  sacCfg.doPhiBinningOptimization = false;
694 
695  auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
696  sacCfg,
697  makeActsAthenaLogger(this, managerName + "SrfArrCrtr", std::string("ActsTGSvc")));
698  Acts::LayerCreator::Config lcCfg;
699  lcCfg.surfaceArrayCreator = surfaceArrayCreator;
700  auto layerCreator = std::make_shared<Acts::LayerCreator>(
701  lcCfg, makeActsAthenaLogger(this, managerName + "LayCrtr", std::string("ActsTGSvc")));
702 
704  cfg.mng = static_cast<const HGTD_DetectorManager *>(manager);
705  cfg.elementStore = m_elementStore;
706  cfg.layerCreator = layerCreator;
707  cfg.idHelper = m_HGTD_idHelper;
708  return std::make_shared<const ActsHGTDLayerBuilder>(
709  cfg, makeActsAthenaLogger(this, managerName + "GMSLayBldr", std::string("ActsTGSvc")));
710 }
711 
714  std::string managerName = manager->getName();
715 
716  std::shared_ptr<const Acts::ILayerBuilder> gmLayerBuilder;
717  auto matcher = [](const Acts::GeometryContext & /*gctx*/,
718  Acts::BinningValue bValue, const Acts::Surface *aS,
719  const Acts::Surface *bS) -> bool {
720  auto a = dynamic_cast<const ActsDetectorElement *>(
721  aS->associatedDetectorElement());
722  auto b = dynamic_cast<const ActsDetectorElement *>(
723  bS->associatedDetectorElement());
724  if ((not a) or (not b)) {
725  throw std::runtime_error(
726  "Cast of surface associated element to ActsDetectorElement failed "
727  "in ActsTrackingGeometrySvc::makeVolumeBuilder");
728  }
729 
730  IdentityHelper idA = a->identityHelper();
731  IdentityHelper idB = b->identityHelper();
732 
733  // check if same bec
734  // can't be same if not
735  if (idA.bec() != idB.bec())
736  return false;
737 
738  if (bValue == Acts::BinningValue::binPhi) {
739  // std::cout << idA.phi_module() << " <-> " << idB.phi_module() <<
740  // std::endl;
741  return idA.phi_module() == idB.phi_module();
742  }
743 
744  if (bValue == Acts::BinningValue::binZ) {
745  return (idA.eta_module() == idB.eta_module()) &&
746  (idA.layer_disk() == idB.layer_disk()) && (idA.bec() == idB.bec());
747  }
748 
749  if (bValue == Acts::BinningValue::binR) {
750  return (idA.eta_module() == idB.eta_module()) &&
751  (idA.layer_disk() == idB.layer_disk()) && (idB.bec() == idA.bec());
752  }
753 
754  return false;
755  };
756 
757  Acts::SurfaceArrayCreator::Config sacCfg;
758  sacCfg.surfaceMatcher = matcher;
759 
760  auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
761  sacCfg,
762  makeActsAthenaLogger(this, managerName + "SrfArrCrtr", std::string("ActsTGSvc")));
763  Acts::LayerCreator::Config lcCfg;
764  lcCfg.surfaceArrayCreator = surfaceArrayCreator;
765  auto layerCreator = std::make_shared<Acts::LayerCreator>(
766  lcCfg, makeActsAthenaLogger(this, managerName + "LayCrtr", std::string("ActsTGSvc")));
767 
769  cfg.surfaceMatcher = matcher;
770 
771  // set bins from configuration
772  if (m_barrelMaterialBins.size() != 2) {
773  throw std::invalid_argument("Number of barrel material bin counts != 2");
774  }
775  std::vector<size_t> brlBins(m_barrelMaterialBins);
776  cfg.barrelMaterialBins = {brlBins.at(0), brlBins.at(1)};
777 
778  if (m_endcapMaterialBins.size() != 2) {
779  throw std::invalid_argument("Number of endcap material bin counts != 2");
780  }
781  std::vector<size_t> ecBins(m_endcapMaterialBins);
782  cfg.endcapMaterialBins = {ecBins.at(0), ecBins.at(1)};
783 
784  cfg.mng = static_cast<const InDetDD::SiDetectorManager *>(manager);
785  // use class member element store
786  cfg.elementStore = m_elementStore;
787  cfg.layerCreator = layerCreator;
788 
789  // gmLayerBuilder = std::make_shared<const ActsLayerBuilder>(
790  // cfg, makeActsAthenaLogger(this, managerName + "GMLayBldr",
791  // "ActsTGSvc"));
792 
793  // return gmLayerBuilder;
794  return cfg;
795 }
796 
797 std::shared_ptr<Acts::TrackingVolume>
799  const Acts::GeometryContext &gctx, const Acts::ILayerBuilder &sct_lb,
800  const Acts::ILayerBuilder &trt_lb, const Acts::CylinderVolumeHelper &cvh,
801  const std::shared_ptr<const Acts::TrackingVolume> &pixel) {
802  ATH_MSG_VERBOSE("Building SCT+TRT assembly");
803 
804  Acts::CylinderVolumeBuilder::Config cvbCfg;
805  Acts::CylinderVolumeBuilder cvb(
806  cvbCfg, makeActsAthenaLogger(this, std::string("SCTTRTCVB"), std::string("ActsTGSvc")));
807 
808  ATH_MSG_VERBOSE("Making SCT negative layers: ");
809  Acts::VolumeConfig sctNegEC =
810  cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
811  ATH_MSG_VERBOSE("Making SCT positive layers: ");
812  Acts::VolumeConfig sctPosEC =
813  cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
814  ATH_MSG_VERBOSE("Making SCT central layers: ");
815  Acts::VolumeConfig sctBrl =
816  cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
817 
818  ATH_MSG_VERBOSE("Making TRT negative layers: ");
819  Acts::VolumeConfig trtNegEC =
820  cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
821  ATH_MSG_VERBOSE("Making TRT positive layers: ");
822  Acts::VolumeConfig trtPosEC =
823  cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
824  ATH_MSG_VERBOSE("Making TRT central layers: ");
825  Acts::VolumeConfig trtBrl =
826  cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
827 
828  // synchronize trt
829 
830  double absZMinEC = std::min(std::abs(trtNegEC.zMax), std::abs(trtPosEC.zMin));
831  double absZMaxEC = std::max(std::abs(trtNegEC.zMin), std::abs(trtPosEC.zMax));
832 
833  trtNegEC.zMin = -absZMaxEC;
834  trtNegEC.zMax = -absZMinEC;
835  trtPosEC.zMin = absZMinEC;
836  trtPosEC.zMax = absZMaxEC;
837 
838  using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
839 
840  // if pixel is present, shrink SCT volumes in R
841  bool isSCTSmallerInZ = false;
842  if (pixel) {
843  ATH_MSG_VERBOSE("Shrinking SCT in R (and maybe in increase size in Z) to fit around Pixel");
844  auto pixelBounds = dynamic_cast<const Acts::CylinderVolumeBounds *>(
845  &pixel->volumeBounds());
846  double sctNegECzMin = std::min(sctNegEC.zMin, -pixelBounds->get(CVBBV::eHalfLengthZ));
847  double sctPosECzMax = std::max(sctPosEC.zMax, pixelBounds->get(CVBBV::eHalfLengthZ));
848 
849  ATH_MSG_VERBOSE("- SCT +-EC.rMin: " << sctNegEC.rMin << " -> " << pixelBounds->get(CVBBV::eMaxR));
850  ATH_MSG_VERBOSE("- SCT BRL.rMin: " << sctBrl.rMin << " -> " << pixelBounds->get(CVBBV::eMaxR));
851  ATH_MSG_VERBOSE("- SCT EC.zMin: " << sctNegEC.zMin << " -> " << sctNegECzMin);
852  ATH_MSG_VERBOSE("- SCT EC.zMax: " << sctPosEC.zMax << " -> " << sctPosECzMax);
853 
854  sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
855  sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
856  sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
857 
858  isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
859 
860  sctNegEC.zMin = sctNegECzMin;
861  sctPosEC.zMax = sctPosECzMax;
862 
863 
864  } else {
865  ATH_MSG_VERBOSE("Pixel is not configured, not wrapping");
866  }
867 
868  ATH_MSG_VERBOSE("SCT Volume Configuration:");
869  ATH_MSG_VERBOSE("- SCT::NegativeEndcap: " << sctNegEC.layers.size()
870  << " layers, "
871  << sctNegEC.toString());
872  ATH_MSG_VERBOSE("- SCT::Barrel: " << sctBrl.layers.size() << " layers, "
873  << sctBrl.toString());
874  ATH_MSG_VERBOSE("- SCT::PositiveEncap: " << sctPosEC.layers.size()
875  << " layers, "
876  << sctPosEC.toString());
877 
878  ATH_MSG_VERBOSE("TRT Volume Configuration:");
879  ATH_MSG_VERBOSE("- TRT::NegativeEndcap: " << trtNegEC.layers.size()
880  << " layers, "
881  << trtNegEC.toString());
882  ATH_MSG_VERBOSE("- TRT::Barrel: " << trtBrl.layers.size() << " layers, "
883  << trtBrl.toString());
884  ATH_MSG_VERBOSE("- TRT::PositiveEncap: " << trtPosEC.layers.size()
885  << " layers, "
886  << trtPosEC.toString());
887 
888  // harmonize SCT BRL <-> EC, normally the CVB does this, but we're skipping
889  // that
890  sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
891  sctBrl.zMin = -sctBrl.zMax;
892 
893  // and now harmonize everything
894  // inflate TRT Barrel to match SCT
895  trtBrl.zMin = sctBrl.zMin;
896  trtBrl.zMax = sctBrl.zMax;
897 
898  // extend TRT endcaps outwards z so they match SCT
899  trtNegEC.zMin = sctNegEC.zMin;
900  trtPosEC.zMax = sctPosEC.zMax;
901 
902  // extend endcap in z so it touches barrel
903  trtNegEC.zMax = trtBrl.zMin;
904  sctNegEC.zMax = trtBrl.zMin;
905  trtPosEC.zMin = trtBrl.zMax;
906  sctPosEC.zMin = trtBrl.zMax;
907 
908  // extend SCT in R so they touch TRT barel
909  sctBrl.rMax = trtBrl.rMin;
910  sctNegEC.rMax = trtNegEC.rMin;
911  sctPosEC.rMax = trtPosEC.rMin;
912 
913  // extend TRT endcaps in r to that of Barrel
914  trtNegEC.rMax = trtBrl.rMax;
915  trtPosEC.rMax = trtBrl.rMax;
916 
917  ATH_MSG_VERBOSE("Dimensions after synchronization between SCT and TRT");
918  ATH_MSG_VERBOSE("SCT Volume Configuration:");
919  ATH_MSG_VERBOSE("- SCT::NegativeEndcap: " << sctNegEC.layers.size()
920  << " layers, "
921  << sctNegEC.toString());
922  ATH_MSG_VERBOSE("- SCT::Barrel: " << sctBrl.layers.size() << " layers, "
923  << sctBrl.toString());
924  ATH_MSG_VERBOSE("- SCT::PositiveEncap: " << sctPosEC.layers.size()
925  << " layers, "
926  << sctPosEC.toString());
927 
928  ATH_MSG_VERBOSE("TRT Volume Configuration:");
929  ATH_MSG_VERBOSE("- TRT::NegativeEndcap: " << trtNegEC.layers.size()
930  << " layers, "
931  << trtNegEC.toString());
932  ATH_MSG_VERBOSE("- TRT::Barrel: " << trtBrl.layers.size() << " layers, "
933  << trtBrl.toString());
934  ATH_MSG_VERBOSE("- TRT::PositiveEncap: " << trtPosEC.layers.size()
935  << " layers, "
936  << trtPosEC.toString());
937 
938  auto makeTVol = [&](const auto &vConf, const auto &name) {
939  return cvh.createTrackingVolume(gctx, vConf.layers, {},
940  nullptr, // no material
941  vConf.rMin, vConf.rMax, vConf.zMin,
942  vConf.zMax, name);
943  };
944 
945  // now turn them into actual TrackingVolumes
946  auto tvSctNegEC = makeTVol(sctNegEC, "SCT::NegativeEndcap");
947  auto tvSctBrl = makeTVol(sctBrl, "SCT::Barrel");
948  auto tvSctPosEC = makeTVol(sctPosEC, "SCT::PositiveEndcap");
949 
950  auto tvTrtNegEC = makeTVol(trtNegEC, "TRT::NegativeEndcap");
951  auto tvTrtBrl = makeTVol(trtBrl, "TRT::Barrel");
952  auto tvTrtPosEC = makeTVol(trtPosEC, "TRT::PositiveEndcap");
953 
954  // combine the endcaps and the barrels, respetively
955  auto negEC =
956  cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
957  auto posEC =
958  cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
959  auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
960 
961  // and now combine all of those into one container for the assembly
962 
963  auto container =
964  cvh.createContainerTrackingVolume(gctx, {negEC, barrel, posEC});
965 
966  // if pixel is present, add positive and negative gap volumes so we can wrap
967  // it all
968  if (pixel) {
969  auto containerBounds = dynamic_cast<const Acts::CylinderVolumeBounds *>(
970  &container->volumeBounds());
971  auto pixelBounds = dynamic_cast<const Acts::CylinderVolumeBounds *>(
972  &pixel->volumeBounds());
973  std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
974 
975  if(!isSCTSmallerInZ) {
976  // pixel is smaller in z, need gap volumes
977  auto posGap = cvh.createGapTrackingVolume(
978  gctx, noVolumes,
979  nullptr, // no material,
980  pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
981  pixelBounds->get(CVBBV::eHalfLengthZ),
982  containerBounds->get(CVBBV::eHalfLengthZ),
983  0, // material layers,
984  true, // cylinder
985  "Pixel::PositiveGap");
986  auto negGap = cvh.createGapTrackingVolume(
987  gctx, noVolumes,
988  nullptr, // no material,
989  pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
990  -containerBounds->get(CVBBV::eHalfLengthZ),
991  -pixelBounds->get(CVBBV::eHalfLengthZ),
992  0, // material layers,
993  true, // cylinder
994  "Pixel::NegativeGap");
995 
996  auto pixelContainer =
997  cvh.createContainerTrackingVolume(gctx, {negGap, pixel, posGap});
998  // and now create one container that contains Pixel+SCT+TRT
999  container =
1000  cvh.createContainerTrackingVolume(gctx, {pixelContainer, container});
1001  }
1002  else {
1003  // wrap the pixel directly
1004  container =
1005  cvh.createContainerTrackingVolume(gctx, {pixel, container});
1006  }
1007 
1008  }
1009 
1010  return container;
1011 }
1012 
1014  ATH_MSG_DEBUG("Populate the alignment store with all detector elements");
1015  unsigned int nElements = 0;
1016  m_trackingGeometry->visitSurfaces([&store, &nElements](const Acts::Surface *srf) {
1017  const Acts::DetectorElementBase *detElem = srf->associatedDetectorElement();
1018  const IDetectorElement *gmde = dynamic_cast<const IDetectorElement *>(detElem);
1019  nElements += gmde->storeAlignedTransforms(store);
1020  });
1021  ATH_MSG_DEBUG("Populated with " << nElements << " elements");
1022  return nElements;
1023 }
1025 
1026 Acts::CylinderVolumeBuilder::Config
1028  std::shared_ptr<const Acts::CylinderVolumeHelper> cvh) const {
1029 
1030  // adapted from InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilder.cxx
1031 
1032  PVConstLink beamPipeTopVolume = p_beamPipeMgr->getTreeTop(0);
1033 
1034  if (p_beamPipeMgr->getNumTreeTops() == 1){
1035  beamPipeTopVolume = p_beamPipeMgr->getTreeTop(0)->getChildVol(0)->getChildVol(0);
1036  }
1037 
1038  Acts::Transform3 beamPipeTransform;
1039  beamPipeTransform.setIdentity();
1040 
1041  beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1042 
1043  double beamPipeRadius = 20;
1044 
1045  const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1046  const GeoTube* beamPipeTube = nullptr;
1047 
1048 
1049  if (beamPipeLogVolume == nullptr) {
1050  ATH_MSG_ERROR("Beam pip volume has no log volume");
1051  throw std::runtime_error("Beam pip volume has no log volume");
1052  }
1053  // get the geoShape and translate
1054  beamPipeTube = dynamic_cast<const GeoTube*>(beamPipeLogVolume->getShape());
1055  if (beamPipeTube == nullptr){
1056  ATH_MSG_ERROR("BeamPipeLogVolume was not of type GeoTube");
1057  throw std::runtime_error{"BeamPipeLogVolume was not of type GeoTube"};
1058  }
1059 
1060  for(unsigned int i=0;i<beamPipeTopVolume->getNChildVols();i++) {
1061 
1062  if(beamPipeTopVolume->getNameOfChildVol(i) == "SectionC03"){
1063 
1064  PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(i);
1065  const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1066  const GeoTube* childTube = nullptr;
1067 
1068  if (childLogVolume){
1069  childTube = dynamic_cast<const GeoTube*>(childLogVolume->getShape());
1070  if (childTube){
1071  beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1072  }
1073  }
1074 
1075  break; // Exit loop after SectionC03 is found
1076  }
1077 
1078  } // Loop over child volumes
1079 
1080  ATH_MSG_VERBOSE("BeamPipe constructed from Database: translation (yes) - radius "
1081  << ( beamPipeTube ? "(yes)" : "(no)") << " - r = " << beamPipeRadius );
1082 
1083  ATH_MSG_VERBOSE("BeamPipe shift estimated as : " << Amg::toString(beamPipeTransform.translation()));
1084 
1085  Acts::CylinderVolumeBuilder::Config cfg;
1086 
1087  Acts::PassiveLayerBuilder::Config bplConfig;
1088  bplConfig.layerIdentification = "BeamPipe";
1089  bplConfig.centralLayerRadii = {beamPipeRadius * 1_mm};
1090  bplConfig.centralLayerHalflengthZ = {3000_mm};
1091  bplConfig.centralLayerThickness = {1_mm};
1092  auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
1093  bplConfig, makeActsAthenaLogger(this, std::string("BPLayBldr"), std::string("ActsTGSvc")));
1094 
1095  // create the volume for the beam pipe
1096  cfg.trackingVolumeHelper = cvh;
1097  cfg.volumeName = "BeamPipe";
1098  cfg.layerBuilder = beamPipeBuilder;
1099  cfg.layerEnvelopeR = {1_mm, 1_mm};
1100  cfg.buildToRadiusZero = true;
1101 
1102  return cfg;
1103 }
ActsTrackingGeometrySvc::makeBeamPipeConfig
Acts::CylinderVolumeBuilder::Config makeBeamPipeConfig(std::shared_ptr< const Acts::CylinderVolumeHelper > cvh) const
Definition: ActsTrackingGeometrySvc.cxx:1027
IdentityHelper::phi_module
int phi_module() const
Definition: IdentityHelper.cxx:61
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
SGTest::store
TestStore store
Definition: TestStore.cxx:23
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
ActsTrackingGeometrySvc::m_runConsistencyChecks
BooleanProperty m_runConsistencyChecks
Definition: ActsTrackingGeometrySvc.h:112
get_generator_info.result
result
Definition: get_generator_info.py:21
ActsLayerBuilder::Mode::ITkPixelOuter
@ ITkPixelOuter
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ActsTrackingGeometrySvc::m_consistencyCheckOutput
StringProperty m_consistencyCheckOutput
Definition: ActsTrackingGeometrySvc.h:115
TRT_DetectorManager.h
ActsLayerBuilder::Mode::ITkPixelInner
@ ITkPixelInner
ActsTrk::DetectorType
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
Definition: GeometryDefs.h:17
ActsGeometryContext.h
Trk::binZ
@ binZ
Definition: BinningType.h:49
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
ActsTrk::DetectorAlignStore
Definition: DetectorAlignStore.h:20
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
IdentityHelper.h
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
ActsTrackingGeometrySvc::m_barrelMaterialBins
Gaudi::Property< std::vector< size_t > > m_barrelMaterialBins
Definition: ActsTrackingGeometrySvc.h:108
ActsTrackingGeometrySvc::populateAlignmentStore
unsigned int populateAlignmentStore(ActsTrk::DetectorAlignStore &store) const override
Definition: ActsTrackingGeometrySvc.cxx:1013
ActsHGTDLayerBuilder::Config
Definition: ActsHGTDLayerBuilder.h:45
IdentityHelper::layer_disk
int layer_disk() const
Definition: IdentityHelper.cxx:49
ActsStrawLayerBuilder.h
BeamPipeDetectorManager::getNumTreeTops
virtual unsigned int getNumTreeTops() const
Definition: BeamPipeDetectorManager.cxx:15
TRT_ID.h
This is an Identifier helper class for the TRT subdetector. This class is a factory for creating comp...
InDetDD::SolidStateDetectorElementBase::surface
Trk::Surface & surface()
Element Surface.
ActsTrackingGeometrySvc::runConsistencyChecks
bool runConsistencyChecks() const
Definition: ActsTrackingGeometrySvc.cxx:417
ReadBchFromCool.barrel
barrel
Definition: ReadBchFromCool.py:405
ActsTrk::actsLevelVector
Acts::Logging::Level actsLevelVector(MSG::Level lvl)
Definition: LoggerUtils.cxx:9
ActsStrawLayerBuilder::Config
Definition: ActsStrawLayerBuilder.h:35
ActsTrackingGeometrySvc::m_consistencyCheckPoints
Gaudi::Property< size_t > m_consistencyCheckPoints
Definition: ActsTrackingGeometrySvc.h:118
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ActsTrackingGeometrySvc::m_detStore
ServiceHandle< StoreGateSvc > m_detStore
Definition: ActsTrackingGeometrySvc.h:85
ActsTrackingGeometrySvc::p_ITkPixelManager
const InDetDD::SiDetectorManager * p_ITkPixelManager
Definition: ActsTrackingGeometrySvc.h:89
BeamPipeDetectorManager::getTreeTop
virtual PVConstLink getTreeTop(unsigned int i) const
Definition: BeamPipeDetectorManager.cxx:20
ActsLayerBuilder::Config
Definition: ActsLayerBuilder.h:50
HGTD_DetectorManager.h
ActsTrackingGeometrySvc::p_beamPipeMgr
const BeamPipeDetectorManager * p_beamPipeMgr
Definition: ActsTrackingGeometrySvc.h:91
ActsTrackingGeometrySvc::m_caloVolumeBuilder
ToolHandle< IActsTrackingVolumeBuilder > m_caloVolumeBuilder
Definition: ActsTrackingGeometrySvc.h:121
ActsLayerBuilder::Mode::Pixel
@ Pixel
master.gen
gen
Definition: master.py:32
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
ActsTrackingGeometrySvc::getNominalContext
const ActsGeometryContext & getNominalContext() const override
Definition: ActsTrackingGeometrySvc.cxx:1024
ActsTrackingGeometrySvc::p_TRTManager
const InDetDD::TRT_DetectorManager * p_TRTManager
Definition: ActsTrackingGeometrySvc.h:88
makeActsAthenaLogger
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition: Tracking/Acts/ActsInterop/src/Logger.cxx:64
ActsGeometryContext::context
Acts::GeometryContext context() const
Definition: ActsGeometryContext.h:45
BeamPipeDetectorManager.h
GeoPrimitives.h
ActsTrackingGeometrySvc::p_HGTDManager
const HGTD_DetectorManager * p_HGTDManager
Definition: ActsTrackingGeometrySvc.h:92
ActsLayerBuilder::Mode::ITkStrip
@ ITkStrip
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::BinningValue
BinningValue
how to take the global / local position
Definition: BinningType.h:46
python.BunchSpacingUtils.lb
lb
Definition: BunchSpacingUtils.py:88
ActsLayerBuilder.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
ActsTrackingGeometrySvc::m_elementStore
std::shared_ptr< ActsElementVector > m_elementStore
Definition: ActsTrackingGeometrySvc.h:94
ActsTrackingGeometrySvc::m_materialMapInputFileBase
Gaudi::Property< std::string > m_materialMapInputFileBase
Definition: ActsTrackingGeometrySvc.h:104
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ActsTrackingGeometrySvc::p_pixelManager
const InDetDD::SiDetectorManager * p_pixelManager
Definition: ActsTrackingGeometrySvc.h:86
calibdata.exception
exception
Definition: calibdata.py:496
ActsTrackingGeometrySvc::p_SCTManager
const InDetDD::SiDetectorManager * p_SCTManager
Definition: ActsTrackingGeometrySvc.h:87
ActsTrackingGeometrySvc::m_buildBeamPipe
Gaudi::Property< bool > m_buildBeamPipe
Definition: ActsTrackingGeometrySvc.h:106
InDetDD::InDetDetectorManager
Definition: InDetDetectorManager.h:60
ActsTrackingGeometrySvc::makeLayerBuilderConfig
ActsLayerBuilder::Config makeLayerBuilderConfig(const InDetDD::InDetDetectorManager *manager)
Definition: ActsTrackingGeometrySvc.cxx:712
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrackingGeometrySvc::trackingGeometry
std::shared_ptr< const Acts::TrackingGeometry > trackingGeometry() override
Definition: ActsTrackingGeometrySvc.cxx:644
ActsDetectorElement
Definition: ActsDetectorElement.h:42
ActsHGTDLayerBuilder.h
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
ActsTrk::IDetectorElement
Base class interface for the actual readout elements.
Definition: IDetectorElement.h:43
ActsTrk::IDetectorElement::storeAlignedTransforms
virtual unsigned int storeAlignedTransforms(const ActsTrk::DetectorAlignStore &store) const =0
Caches the aligned transformation in the provided store. Returns the number of cached elements.
ActsTrackingGeometrySvc::m_endcapMaterialBins
Gaudi::Property< std::vector< size_t > > m_endcapMaterialBins
Definition: ActsTrackingGeometrySvc.h:109
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
ActsTrackingGeometrySvc::m_materialMapCalibFolder
Gaudi::Property< std::string > m_materialMapCalibFolder
Definition: ActsTrackingGeometrySvc.h:105
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
PathResolver.h
IdentityHelper::eta_module
int eta_module() const
Definition: IdentityHelper.cxx:73
ActsElementVector
Helper to hold elements for deletion.
Definition: ActsElementVector.h:30
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ActsTrackingGeometrySvc::makeSCTTRTAssembly
std::shared_ptr< Acts::TrackingVolume > makeSCTTRTAssembly(const Acts::GeometryContext &gctx, const Acts::ILayerBuilder &sct_lb, const Acts::ILayerBuilder &trt_lb, const Acts::CylinderVolumeHelper &cvh, const std::shared_ptr< const Acts::TrackingVolume > &pixel)
Definition: ActsTrackingGeometrySvc.cxx:798
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Cut::all
@ all
Definition: SUSYToolsAlg.cxx:67
ActsTrackingGeometrySvc::p_ITkStripManager
const InDetDD::SiDetectorManager * p_ITkStripManager
Definition: ActsTrackingGeometrySvc.h:90
CVBBV
Acts::CylinderVolumeBounds::BoundValues CVBBV
Definition: ActsCaloTrackingVolumeBuilder.cxx:31
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
IdentityHelper::bec
int bec() const
Definition: IdentityHelper.cxx:37
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
Trk::binR
@ binR
Definition: BinningType.h:50
InDetDD::TRT_DetectorManager
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Definition: TRT_DetectorManager.h:69
a
TList * a
Definition: liststreamerinfos.cxx:10
ActsTrackingGeometrySvc::m_subDetNoAlign
std::set< ActsTrk::DetectorType > m_subDetNoAlign
Definition: ActsTrackingGeometrySvc.h:125
ActsTrackingGeometrySvc::initialize
StatusCode initialize() override
Definition: ActsTrackingGeometrySvc.cxx:68
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
GeoPrimitivesToStringConverter.h
InDetDD::SiDetectorManager
Definition: SiDetectorManager.h:60
HGTD_DetectorManager
Definition: HGTD_DetectorManager.h:33
ActsTrackingGeometrySvc::ActsTrackingGeometrySvc
ActsTrackingGeometrySvc(const std::string &name, ISvcLocator *pSvcLocator)
Definition: ActsTrackingGeometrySvc.cxx:60
ActsTrackingGeometrySvc::makeStrawLayerBuilder
std::shared_ptr< const Acts::ILayerBuilder > makeStrawLayerBuilder(const InDetDD::InDetDetectorManager *manager)
Definition: ActsTrackingGeometrySvc.cxx:651
IDetectorElement.h
LoggerUtils.h
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:54
python.Logging.manager
manager
Definition: PhysicsAnalysis/D3PDTools/AnaAlgorithm/python/Logging.py:92
SiDetectorManager.h
ActsTrackingGeometrySvc::m_useMaterialMap
Gaudi::Property< bool > m_useMaterialMap
Definition: ActsTrackingGeometrySvc.h:102
ActsTrackingGeometrySvc::m_trackingGeometry
std::shared_ptr< const Acts::TrackingGeometry > m_trackingGeometry
Definition: ActsTrackingGeometrySvc.h:95
Logger.h
DataPrepToActsConfig.pixelContainer
pixelContainer
Definition: DataPrepToActsConfig.py:9
ActsTrackingGeometrySvc::makeHGTDLayerBuilder
std::shared_ptr< const Acts::ILayerBuilder > makeHGTDLayerBuilder(const HGTD_DetectorManager *manager)
Definition: ActsTrackingGeometrySvc.cxx:682
ActsTrackingGeometrySvc::m_buildSubdetectors
Gaudi::Property< std::vector< std::string > > m_buildSubdetectors
Definition: ActsTrackingGeometrySvc.h:110
IdentityHelper
Definition: IdentityHelper.h:14
ActsTrackingGeometrySvc::m_nominalContext
ActsGeometryContext m_nominalContext
Definition: ActsTrackingGeometrySvc.h:100
ActsTrackingGeometrySvc::m_TRT_idHelper
const TRT_ID * m_TRT_idHelper
Definition: ActsTrackingGeometrySvc.h:97
ActsTrackingGeometrySvc::m_HGTD_idHelper
const HGTD_ID * m_HGTD_idHelper
Definition: ActsTrackingGeometrySvc.h:98
StoreGateSvc.h
ActsTrackingGeometrySvc.h
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
ActsTrackingGeometrySvc::m_subDetNoAlignProp
Gaudi::Property< std::vector< unsigned int > > m_subDetNoAlignProp
Define the subdetectors for which the tracking geometry does not expect a valid alignment store.
Definition: ActsTrackingGeometrySvc.h:124
ActsTrackingGeometrySvc::m_objDebugOutput
Gaudi::Property< bool > m_objDebugOutput
Definition: ActsTrackingGeometrySvc.h:103
SiliconTech::pixel
@ pixel
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
ActsLayerBuilder::Mode::SCT
@ SCT
Trk::binPhi
@ binPhi
Definition: BinningType.h:51