9 #include "GaudiKernel/EventContext.h"
18 #include "GeoModelKernel/GeoTube.h"
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>
58 using namespace Acts::UnitLiterals;
63 m_detStore(
"StoreGateSvc/DetectorStore",
name),
75 return StatusCode::FAILURE;
82 m_autoRetrieveTools =
false;
83 m_checkToolDeps =
false;
86 << Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"."
87 << Acts::VersionPatch <<
" [" << Acts::CommitHash <<
"]");
92 ATH_MSG_INFO(
"Configured to build " << buildSubdet.size()
94 for (
const auto &
s : buildSubdet) {
99 if (buildSubdet.find(
"Pixel") != buildSubdet.end()) {
102 if (buildSubdet.find(
"SCT") != buildSubdet.end()) {
105 if (buildSubdet.find(
"TRT") != buildSubdet.end()) {
109 if (buildSubdet.find(
"ITkPixel") != buildSubdet.end()) {
112 if (buildSubdet.find(
"ITkStrip") != buildSubdet.end()) {
115 if (buildSubdet.find(
"HGTD") != buildSubdet.end()) {
127 Acts::LayerArrayCreator::Config lacCfg;
128 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
131 Acts::TrackingVolumeArrayCreator::Config tvcCfg;
132 auto trackingVolumeArrayCreator =
133 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
136 Acts::CylinderVolumeHelper::Config cvhConfig;
137 cvhConfig.layerArrayCreator = layerArrayCreator;
138 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
140 auto cylinderVolumeHelper =
141 std::make_shared<const Acts::CylinderVolumeHelper>(
144 Acts::TrackingGeometryBuilder::Config tgbConfig;
145 tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
148 std::shared_ptr<const Acts::IMaterialDecorator> matDeco =
nullptr;
151 if (matFileFullPath.empty()) {
153 return StatusCode::FAILURE;
155 ATH_MSG_INFO(
"Configured to use material input: " << matFileFullPath);
157 if (matFileFullPath.find(
".json") != std::string::npos) {
159 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
161 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
164 tgbConfig.materialDecorator = matDeco;
167 std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
172 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
176 Acts::CylinderVolumeBuilder::Config bpvConfig =
179 Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
182 return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
189 if (buildSubdet.count(
"Pixel") > 0) {
190 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
195 auto lb = std::make_shared<ActsLayerBuilder>(
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;
205 Acts::CylinderVolumeBuilder cvb(
208 return cvb.trackingVolume(gctx, inner);
213 if (buildSubdet.count(
"ITkPixel") > 0) {
214 tgbConfig.trackingVolumeBuilders.push_back(
215 [&](
const auto &gctx,
const auto &inner,
const auto &) {
219 cfg.doEndcapLayerMerging =
true;
220 auto lb = std::make_shared<ActsLayerBuilder>(
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;
231 Acts::CylinderVolumeBuilder cvb(
235 return cvb.trackingVolume(gctx, inner);
238 tgbConfig.trackingVolumeBuilders.push_back(
239 [&](
const auto &gctx,
const auto &inner,
const auto &) {
243 cfg.doEndcapLayerMerging =
false;
244 auto lb = std::make_shared<ActsLayerBuilder>(
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;
257 Acts::CylinderVolumeBuilder cvb(
261 return cvb.trackingVolume(gctx, inner);
266 if (buildSubdet.count(
"ITkStrip") > 0) {
267 tgbConfig.trackingVolumeBuilders.push_back(
268 [&](
const auto &gctx,
const auto &inner,
const auto &) {
272 auto lb = std::make_shared<ActsLayerBuilder>(
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 =
284 Acts::CylinderVolumeBuilder cvb(
288 return cvb.trackingVolume(gctx, inner);
292 bool buildSCT = buildSubdet.count(
"SCT") > 0;
293 bool buildTRT = buildSubdet.count(
"TRT") > 0;
295 if (buildSCT && buildTRT) {
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>(
308 *cylinderVolumeHelper, inner);
311 }
else if (buildSCT) {
312 tgbConfig.trackingVolumeBuilders.push_back(
313 [&](
const auto &gctx,
const auto &inner,
const auto &) {
316 lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
317 auto lb = std::make_shared<ActsLayerBuilder>(
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;
329 Acts::CylinderVolumeBuilder cvb(
333 return cvb.trackingVolume(gctx, inner);
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;
347 Acts::CylinderVolumeBuilder cvb(
351 return cvb.trackingVolume(gctx, inner);
356 if(buildSubdet.count(
"HGTD") > 0) {
357 tgbConfig.trackingVolumeBuilders.push_back(
358 [&](
const auto &gctx,
const auto &inner,
const auto &) {
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;
368 Acts::CylinderVolumeBuilder cvb(
372 return cvb.trackingVolume(gctx, inner);
377 if (buildSubdet.count(
"Calo") > 0) {
378 tgbConfig.trackingVolumeBuilders.push_back(
379 [&](
const auto &gctx,
const auto &inner,
const auto &) {
384 ATH_MSG_ERROR(
"Encountered error when building Acts tracking geometry");
386 return StatusCode::FAILURE;
389 auto trackingGeometryBuilder =
390 std::make_shared<const Acts::TrackingGeometryBuilder>(
399 ATH_MSG_ERROR(
"No ACTS tracking geometry was built. Cannot proceeed");
400 return StatusCode::FAILURE;
405 ATH_MSG_INFO(
"Running extra consistency check! (this is SLOW)");
407 ATH_MSG_ERROR(
"Consistency check has failed! Geometry is not consistent");
408 return StatusCode::FAILURE;
412 ATH_MSG_INFO(
"Acts TrackingGeometry construction completed");
414 return StatusCode::SUCCESS;
420 std::vector<Acts::Vector2> localPoints;
423 std::uniform_real_distribution<> dist(0.0, 1.0);
425 std::optional<std::ofstream>
os;
429 throw std::runtime_error{
"Failed to open consistency check output file"};
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;
437 localPoints.emplace_back(dist(
gen), dist(
gen));
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;
449 auto isApprox = [](
auto&
a,
auto&
b) ->
bool {
450 return ((
a -
b).array().abs() < 1
e-5).
all();
456 const auto* actsDetElem =
dynamic_cast<const ActsDetectorElement*
>(surface->associatedDetectorElement());
457 if(actsDetElem ==
nullptr) {
463 if(siDetElem ==
nullptr) {
467 const auto* regSurface =
dynamic_cast<const Acts::RegularSurface*
>(surface);
468 const auto& trkSurface = siDetElem->
surface();
469 if(regSurface ==
nullptr) {
475 Acts::Vector3 center{regSurface->center(gctx)};
477 if (
dynamic_cast<const Acts::AnnulusBounds *
>(&surface->bounds()))
482 center.head<2>() = trkCenter.head<2>();
485 if(!isApprox(trkCenter, center)) {
487 if (
auto idHelper = siDetElem->getIdHelper())
489 trkName = idHelper->show_to_string(siDetElem->identify());
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++;
500 const auto* lineSurface =
dynamic_cast<const Acts::LineSurface*
>(surface);
501 if(lineSurface ==
nullptr) {
502 Acts::Vector3
norm{regSurface->normal(gctx, regSurface->center(gctx))};
504 if(!isApprox(trkNorm,
norm)) {
506 if (
auto idHelper = siDetElem->getIdHelper())
508 trkName = idHelper->show_to_string(siDetElem->identify());
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++;
520 auto doPoints = [&](
unsigned int type,
const Acts::Vector2& loc) -> std::array<bool,3> {
526 bool locg2lOk =
false;
527 auto locTrkRes = trkSurface.globalToLocal(glb);
529 locTrk = locTrkRes.value();
530 glbTrk = trkSurface.localToGlobal(locTrk);
533 if (locg2lRes.ok()) {
535 locg2l = locg2lRes.value();
539 auto gId = surface->geometryId();
542 <<
"," << gId.volume()
543 <<
"," << gId.layer()
544 <<
"," << gId.sensitive()
548 <<
"," << surface->insideBounds(loc)
551 <<
"," << trkSurface.insideBounds(locTrk)
563 return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
564 locg2lOk ? isApprox(loc, locg2l) :
true,
565 locTrkRes ? isApprox(glb, glbTrk) :
true};
571 std::array<bool,3> allOk{
true,
true,
true};
572 if(
const auto* bounds =
dynamic_cast<const Acts::PlanarBounds*
>(&surface->bounds()); bounds) {
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;
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) {
592 else if(
const auto* bounds =
dynamic_cast<const Acts::AnnulusBounds*
>(&surface->bounds()); bounds) {
596 std::vector<Acts::Vector2> vertices = bounds->vertices(5);
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());
603 min.array() -= envelope;
604 max.array() += envelope;
605 Acts::Vector2 diag =
max -
min;
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);
611 auto pointOk = doPoints(1, locPC);
612 for (
size_t i=0;
i<pointOk.size(); ++
i) {
625 for (
size_t i=0;
i<allOk.size(); ++
i) {
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]);
643 std::shared_ptr<const Acts::TrackingGeometry>
650 std::shared_ptr<const Acts::ILayerBuilder>
654 std::string managerName =
manager->getName();
655 auto matcher = [](
const Acts::GeometryContext & ,
657 const Acts::Surface *
658 ) ->
bool {
return false; };
660 Acts::SurfaceArrayCreator::Config sacCfg;
661 sacCfg.surfaceMatcher = matcher;
662 sacCfg.doPhiBinningOptimization =
false;
664 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
667 Acts::LayerCreator::Config lcCfg;
668 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
669 auto layerCreator = std::make_shared<Acts::LayerCreator>(
675 cfg.layerCreator = layerCreator;
677 return std::make_shared<const ActsStrawLayerBuilder>(
681 std::shared_ptr<const Acts::ILayerBuilder>
685 std::string managerName =
manager->getName();
686 auto matcher = [](
const Acts::GeometryContext & ,
688 const Acts::Surface *
689 ) ->
bool {
return false; };
691 Acts::SurfaceArrayCreator::Config sacCfg;
692 sacCfg.surfaceMatcher = matcher;
693 sacCfg.doPhiBinningOptimization =
false;
695 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
698 Acts::LayerCreator::Config lcCfg;
699 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
700 auto layerCreator = std::make_shared<Acts::LayerCreator>(
706 cfg.layerCreator = layerCreator;
708 return std::make_shared<const ActsHGTDLayerBuilder>(
714 std::string managerName =
manager->getName();
716 std::shared_ptr<const Acts::ILayerBuilder> gmLayerBuilder;
717 auto matcher = [](
const Acts::GeometryContext & ,
719 const Acts::Surface *bS) ->
bool {
721 aS->associatedDetectorElement());
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");
735 if (idA.
bec() != idB.
bec())
757 Acts::SurfaceArrayCreator::Config sacCfg;
758 sacCfg.surfaceMatcher = matcher;
760 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
763 Acts::LayerCreator::Config lcCfg;
764 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
765 auto layerCreator = std::make_shared<Acts::LayerCreator>(
769 cfg.surfaceMatcher = matcher;
773 throw std::invalid_argument(
"Number of barrel material bin counts != 2");
776 cfg.barrelMaterialBins = {brlBins.at(0), brlBins.at(1)};
779 throw std::invalid_argument(
"Number of endcap material bin counts != 2");
782 cfg.endcapMaterialBins = {ecBins.at(0), ecBins.at(1)};
787 cfg.layerCreator = layerCreator;
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) {
804 Acts::CylinderVolumeBuilder::Config cvbCfg;
805 Acts::CylinderVolumeBuilder cvb(
809 Acts::VolumeConfig sctNegEC =
810 cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
812 Acts::VolumeConfig sctPosEC =
813 cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
815 Acts::VolumeConfig sctBrl =
816 cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
819 Acts::VolumeConfig trtNegEC =
820 cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
822 Acts::VolumeConfig trtPosEC =
823 cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
825 Acts::VolumeConfig trtBrl =
826 cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
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));
833 trtNegEC.zMin = -absZMaxEC;
834 trtNegEC.zMax = -absZMinEC;
835 trtPosEC.zMin = absZMinEC;
836 trtPosEC.zMax = absZMaxEC;
838 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
841 bool isSCTSmallerInZ =
false;
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));
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);
854 sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
855 sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
856 sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
858 isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
860 sctNegEC.zMin = sctNegECzMin;
861 sctPosEC.zMax = sctPosECzMax;
871 << sctNegEC.toString());
872 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
873 << sctBrl.toString());
876 << sctPosEC.toString());
881 << trtNegEC.toString());
882 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
883 << trtBrl.toString());
886 << trtPosEC.toString());
890 sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
891 sctBrl.zMin = -sctBrl.zMax;
895 trtBrl.zMin = sctBrl.zMin;
896 trtBrl.zMax = sctBrl.zMax;
899 trtNegEC.zMin = sctNegEC.zMin;
900 trtPosEC.zMax = sctPosEC.zMax;
903 trtNegEC.zMax = trtBrl.zMin;
904 sctNegEC.zMax = trtBrl.zMin;
905 trtPosEC.zMin = trtBrl.zMax;
906 sctPosEC.zMin = trtBrl.zMax;
909 sctBrl.rMax = trtBrl.rMin;
910 sctNegEC.rMax = trtNegEC.rMin;
911 sctPosEC.rMax = trtPosEC.rMin;
914 trtNegEC.rMax = trtBrl.rMax;
915 trtPosEC.rMax = trtBrl.rMax;
917 ATH_MSG_VERBOSE(
"Dimensions after synchronization between SCT and TRT");
921 << sctNegEC.toString());
922 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
923 << sctBrl.toString());
926 << sctPosEC.toString());
931 << trtNegEC.toString());
932 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
933 << trtBrl.toString());
936 << trtPosEC.toString());
938 auto makeTVol = [&](
const auto &vConf,
const auto &
name) {
939 return cvh.createTrackingVolume(gctx, vConf.layers, {},
941 vConf.rMin, vConf.rMax, vConf.zMin,
946 auto tvSctNegEC = makeTVol(sctNegEC,
"SCT::NegativeEndcap");
947 auto tvSctBrl = makeTVol(sctBrl,
"SCT::Barrel");
948 auto tvSctPosEC = makeTVol(sctPosEC,
"SCT::PositiveEndcap");
950 auto tvTrtNegEC = makeTVol(trtNegEC,
"TRT::NegativeEndcap");
951 auto tvTrtBrl = makeTVol(trtBrl,
"TRT::Barrel");
952 auto tvTrtPosEC = makeTVol(trtPosEC,
"TRT::PositiveEndcap");
956 cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
958 cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
959 auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
964 cvh.createContainerTrackingVolume(gctx, {negEC,
barrel, posEC});
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;
975 if(!isSCTSmallerInZ) {
977 auto posGap = cvh.createGapTrackingVolume(
980 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
981 pixelBounds->get(CVBBV::eHalfLengthZ),
982 containerBounds->get(CVBBV::eHalfLengthZ),
985 "Pixel::PositiveGap");
986 auto negGap = cvh.createGapTrackingVolume(
989 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
990 -containerBounds->get(CVBBV::eHalfLengthZ),
991 -pixelBounds->get(CVBBV::eHalfLengthZ),
994 "Pixel::NegativeGap");
997 cvh.createContainerTrackingVolume(gctx, {negGap,
pixel, posGap});
1000 cvh.createContainerTrackingVolume(gctx, {
pixelContainer, container});
1005 cvh.createContainerTrackingVolume(gctx, {
pixel, container});
1014 ATH_MSG_DEBUG(
"Populate the alignment store with all detector elements");
1015 unsigned int nElements = 0;
1017 const Acts::DetectorElementBase *detElem = srf->associatedDetectorElement();
1021 ATH_MSG_DEBUG(
"Populated with " << nElements <<
" elements");
1026 Acts::CylinderVolumeBuilder::Config
1028 std::shared_ptr<const Acts::CylinderVolumeHelper> cvh)
const {
1038 Acts::Transform3 beamPipeTransform;
1039 beamPipeTransform.setIdentity();
1041 beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1043 double beamPipeRadius = 20;
1045 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1046 const GeoTube* beamPipeTube =
nullptr;
1049 if (beamPipeLogVolume ==
nullptr) {
1051 throw std::runtime_error(
"Beam pip volume has no log volume");
1054 beamPipeTube =
dynamic_cast<const GeoTube*
>(beamPipeLogVolume->getShape());
1055 if (beamPipeTube ==
nullptr){
1057 throw std::runtime_error{
"BeamPipeLogVolume was not of type GeoTube"};
1060 for(
unsigned int i=0;
i<beamPipeTopVolume->getNChildVols();
i++) {
1062 if(beamPipeTopVolume->getNameOfChildVol(
i) ==
"SectionC03"){
1064 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(
i);
1065 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1066 const GeoTube* childTube =
nullptr;
1068 if (childLogVolume){
1069 childTube =
dynamic_cast<const GeoTube*
>(childLogVolume->getShape());
1071 beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1080 ATH_MSG_VERBOSE(
"BeamPipe constructed from Database: translation (yes) - radius "
1081 << ( beamPipeTube ?
"(yes)" :
"(no)") <<
" - r = " << beamPipeRadius );
1085 Acts::CylinderVolumeBuilder::Config
cfg;
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>(
1096 cfg.trackingVolumeHelper = cvh;
1097 cfg.volumeName =
"BeamPipe";
1098 cfg.layerBuilder = beamPipeBuilder;
1099 cfg.layerEnvelopeR = {1_mm, 1_mm};
1100 cfg.buildToRadiusZero =
true;