107 return StatusCode::FAILURE;
115 m_autoRetrieveTools =
false;
116 m_checkToolDeps =
false;
119 << Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"."
120 << Acts::VersionPatch <<
" [" << Acts::CommitHash.value_or(
"unknown hash") <<
"]");
125 ATH_MSG_INFO(
"Configured to build " << buildSubdet.size()
126 <<
" subdetectors:");
127 for (
const auto &s : buildSubdet) {
132 if (buildSubdet.contains(
"Pixel") ) {
135 if (buildSubdet.contains(
"SCT") ) {
138 if (buildSubdet.contains(
"TRT") ) {
142 if (buildSubdet.contains(
"ITkPixel") ) {
145 if (buildSubdet.contains(
"ITkStrip") ) {
148 if (buildSubdet.contains(
"HGTD") ) {
160 ATH_MSG_FATAL(
"Consistency check for ITk inner pixel barrel passive layer construction failed. Please check your inputs! ");
161 return StatusCode::FAILURE;
166 ATH_MSG_FATAL(
"Consistency check for ITk outer pixel barrel passive layer construction failed. Please check your inputs! ");
167 return StatusCode::FAILURE;
172 ATH_MSG_FATAL(
"Consistency check for ITk strip barrel passive layer construction failed. Please check your inputs! ");
173 return StatusCode::FAILURE;
179 ATH_MSG_INFO(
"Using Blueprint API for geometry construction");
186 using enum Acts::AxisDirection;
188 std::vector<ActsTrk::IBlueprintNodeBuilder*> ptrBuilders;
190 std::back_inserter(ptrBuilders),
191 [](ToolHandle<ActsTrk::IBlueprintNodeBuilder>& b) { return b.get(); });
195 Acts::Blueprint::Config cfg;
196 cfg.envelope[AxisZ] = {20_mm, 20_mm};
197 cfg.envelope[AxisR] = {0_mm, 20_mm};
199 auto blueprint = std::make_unique<Acts::Blueprint>(cfg);
201 auto& root = blueprint->addCylinderContainer(
"Detector", AxisZ);
203 std::shared_ptr<Acts::BlueprintNode> currentTop{
nullptr};
205 for (
auto& builder : ptrBuilders) {
206 currentTop = builder->buildBlueprintNode(
getNominalContext().context(), std::move(currentTop));
210 root.addChild(std::move(currentTop));
212 Acts::BlueprintOptions blueprintOptions;
214 std::unique_ptr<Acts::TrackingGeometry>
trackingGeometry = blueprint->construct(
226 Acts::ObjVisualization3D vis;
228 viewConfigFunc({.visible =
false}, {.visible =
false}, {.visible =
true}));
229 vis.write(
"blueprint_sensitive.obj");
233 viewConfigFunc({.visible =
true}, {.visible =
false}, {.visible =
false}));
234 vis.write(
"blueprint_volume.obj");
238 viewConfigFunc({.visible =
false}, {.visible =
true}, {.visible =
false}));
239 vis.write(
"blueprint_portals.obj");
242 Acts::detail::TrackingGeometryPrintVisitor printer{
m_nominalContext.context()};
244 ATH_MSG_INFO(
"Built tracking geometry \n"<<printer.stream().str());
248 return StatusCode::FAILURE;
251 return StatusCode::SUCCESS;
256 Acts::LayerArrayCreator::Config lacCfg;
257 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
260 Acts::TrackingVolumeArrayCreator::Config tvcCfg;
261 auto trackingVolumeArrayCreator =
262 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
265 Acts::CylinderVolumeHelper::Config cvhConfig;
266 cvhConfig.layerArrayCreator = layerArrayCreator;
267 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
269 auto cylinderVolumeHelper =
270 std::make_shared<const Acts::CylinderVolumeHelper>(
273 Acts::TrackingGeometryBuilder::Config tgbConfig;
274 tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
277 std::shared_ptr<const Acts::IMaterialDecorator> matDeco =
nullptr;
280 if (matFileFullPath.empty()) {
282 return StatusCode::FAILURE;
284 ATH_MSG_INFO(
"Configured to use material input: " << matFileFullPath);
286 if (matFileFullPath.find(
".json") != std::string::npos) {
288 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
290 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
293 tgbConfig.materialDecorator = std::move(matDeco);
296 std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
301 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
305 Acts::CylinderVolumeBuilder::Config bpvConfig =
308 Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
311 return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
318 if (buildSubdet.contains(
"Pixel")) {
319 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
324 auto lb = std::make_shared<ActsLayerBuilder>(
326 Acts::CylinderVolumeBuilder::Config cvbConfig;
327 cvbConfig.layerEnvelopeR = {3_mm, 3_mm};
328 cvbConfig.layerEnvelopeZ = 1_mm;
329 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
330 cvbConfig.volumeName =
"Pixel";
331 cvbConfig.layerBuilder =
lb;
334 Acts::CylinderVolumeBuilder cvb(
337 return cvb.trackingVolume(gctx, inner);
342 if (buildSubdet.contains(
"ITkPixel") ) {
343 tgbConfig.trackingVolumeBuilders.push_back(
344 [&](
const auto &gctx,
const auto &inner,
const auto &) {
348 cfg.doEndcapLayerMerging =
true;
352 auto lb = std::make_shared<ActsLayerBuilder>(
355 Acts::CylinderVolumeBuilder::Config cvbConfig;
356 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
357 cvbConfig.layerEnvelopeZ = 1_mm;
358 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
359 cvbConfig.volumeName =
"ITkPixelInner";
360 cvbConfig.layerBuilder =
lb;
363 Acts::CylinderVolumeBuilder cvb(
367 return cvb.trackingVolume(gctx, inner);
370 tgbConfig.trackingVolumeBuilders.push_back(
371 [&](
const auto &gctx,
const auto &inner,
const auto &) {
375 cfg.doEndcapLayerMerging =
false;
379 auto lb = std::make_shared<ActsLayerBuilder>(
382 Acts::CylinderVolumeBuilder::Config cvbConfig;
383 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
384 cvbConfig.layerEnvelopeZ = 1_mm;
385 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
386 cvbConfig.volumeName =
"ITkPixelOuter";
387 cvbConfig.layerBuilder =
lb;
388 cvbConfig.buildToRadiusZero =
false;
389 cvbConfig.checkRingLayout =
true;
390 cvbConfig.ringTolerance = 10_mm;
392 Acts::CylinderVolumeBuilder cvb(
396 return cvb.trackingVolume(gctx, inner);
401 if (buildSubdet.contains(
"ITkStrip")) {
402 tgbConfig.trackingVolumeBuilders.push_back(
403 [&](
const auto &gctx,
const auto &inner,
const auto &) {
410 auto lb = std::make_shared<ActsLayerBuilder>(
413 Acts::CylinderVolumeBuilder::Config cvbConfig;
414 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
415 cvbConfig.layerEnvelopeZ = 1_mm;
416 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
417 cvbConfig.volumeName =
"ITkStrip";
418 cvbConfig.layerBuilder =
lb;
419 cvbConfig.buildToRadiusZero =
422 Acts::CylinderVolumeBuilder cvb(
426 return cvb.trackingVolume(gctx, inner);
430 bool buildSCT = buildSubdet.contains(
"SCT") ;
431 bool buildTRT = buildSubdet.contains(
"TRT");
433 if (buildSCT && buildTRT) {
435 tgbConfig.trackingVolumeBuilders.push_back(
436 [&](
const auto &gctx,
const auto &inner,
const auto &) {
439 cfg.endcapEnvelopeZ = sctECEnvelopeZ;
440 auto sct_lb = std::make_shared<ActsLayerBuilder>(
446 *cylinderVolumeHelper, inner);
449 }
else if (buildSCT) {
450 tgbConfig.trackingVolumeBuilders.push_back(
451 [&](
const auto &gctx,
const auto &inner,
const auto &) {
454 lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
455 auto lb = std::make_shared<ActsLayerBuilder>(
459 Acts::CylinderVolumeBuilder::Config cvbConfig;
460 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
461 cvbConfig.layerEnvelopeZ = 2_mm;
462 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
463 cvbConfig.volumeName =
"SCT";
464 cvbConfig.layerBuilder =
lb;
465 cvbConfig.buildToRadiusZero =
false;
467 Acts::CylinderVolumeBuilder cvb(
471 return cvb.trackingVolume(gctx, inner);
473 }
else if (buildTRT) {
474 tgbConfig.trackingVolumeBuilders.push_back(
475 [&](
const auto &gctx,
const auto &inner,
const auto &) {
477 Acts::CylinderVolumeBuilder::Config cvbConfig;
478 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
479 cvbConfig.layerEnvelopeZ = 2_mm;
480 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
481 cvbConfig.volumeName =
"TRT";
482 cvbConfig.layerBuilder = std::move(
lb);
483 cvbConfig.buildToRadiusZero =
false;
485 Acts::CylinderVolumeBuilder cvb(
489 return cvb.trackingVolume(gctx, inner);
494 if(buildSubdet.contains(
"HGTD") ) {
495 tgbConfig.trackingVolumeBuilders.push_back(
496 [&](
const auto &gctx,
const auto &inner,
const auto &) {
498 Acts::CylinderVolumeBuilder::Config cvbConfig;
499 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
500 cvbConfig.layerEnvelopeZ = 1_mm;
501 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
502 cvbConfig.volumeName =
"HGTD";
503 cvbConfig.layerBuilder = std::move(
lb);
504 cvbConfig.buildToRadiusZero =
false;
506 Acts::CylinderVolumeBuilder cvb(
510 return cvb.trackingVolume(gctx, inner);
516 tgbConfig.trackingVolumeBuilders.push_back(
517 [&](
const auto &gctx,
const auto &inner,
const auto &) {
522 }
catch (
const std::exception &e) {
523 ATH_MSG_ERROR(
"Encountered error when building Acts tracking geometry");
525 return StatusCode::FAILURE;
528 auto trackingGeometryBuilder =
529 std::make_shared<const Acts::TrackingGeometryBuilder>(
538 ATH_MSG_ERROR(
"No ACTS tracking geometry was built. Cannot proceeed");
539 return StatusCode::FAILURE;
544 ATH_MSG_INFO(
"Running extra consistency check! (this is SLOW)");
546 ATH_MSG_ERROR(
"Consistency check has failed! Geometry is not consistent");
547 return StatusCode::FAILURE;
553 return StatusCode::FAILURE;
557 ATH_MSG_INFO(
"Acts TrackingGeometry construction completed");
559 return StatusCode::SUCCESS;
567 std::vector<Acts::Vector2> localPoints;
570 std::uniform_real_distribution<> dist(0.0, 1.0);
572 std::optional<std::ofstream> os;
576 throw std::runtime_error{
"Failed to open consistency check output file"};
581 (*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;
584 localPoints.emplace_back(dist(gen), dist(gen));
589 size_t nTotalSensors = 0;
590 std::array<size_t,3> nInconsistent{0,0,0};
591 size_t nMismatchedCenters = 0;
592 size_t nMismatchedNormals = 0;
596 auto isApprox = [](
auto&
a,
auto& b) ->
bool {
597 return ((
a - b).array().abs() < 1e-5).all();
603 if(actsDetElem ==
nullptr) {
609 if(siDetElem ==
nullptr) {
613 const auto* regSurface =
dynamic_cast<const Acts::RegularSurface*
>(surface);
614 const auto& trkSurface = siDetElem->
surface();
615 if(regSurface ==
nullptr) {
621 Acts::Vector3 center{regSurface->center(gctx)};
623 if (
dynamic_cast<const Acts::AnnulusBounds *
>(&surface->bounds()))
628 center.head<2>() = trkCenter.head<2>();
631 if(!isApprox(trkCenter, center)) {
633 if (
auto idHelper = siDetElem->getIdHelper())
635 trkName = idHelper->show_to_string(siDetElem->identify());
638 << surface->geometryId()
639 <<
" center (" << center[0] <<
',' << center[1] <<
',' << center[2]
640 <<
") does not match Trk surface " << trkName
641 <<
" center (" << trkCenter[0] <<
',' << trkCenter[1] <<
',' << trkCenter[2] <<
')');
642 nMismatchedCenters++;
646 const auto* lineSurface =
dynamic_cast<const Acts::LineSurface*
>(surface);
647 if(lineSurface ==
nullptr) {
648 Acts::Vector3 norm{regSurface->normal(gctx, regSurface->center(gctx))};
650 if(!isApprox(trkNorm, norm)) {
652 if (
auto idHelper = siDetElem->getIdHelper())
654 trkName = idHelper->show_to_string(siDetElem->identify());
657 << surface->geometryId()
658 <<
" normal (" << norm[0] <<
',' << norm[1] <<
',' << norm[2]
659 <<
") does not match Trk surface " << trkName
660 <<
" normal (" << trkNorm[0] <<
',' << trkNorm[1] <<
',' << trkNorm[2] <<
')');
661 nMismatchedNormals++;
666 auto doPoints = [&](
unsigned int type,
const Acts::Vector2& loc) -> std::array<bool,3> {
667 Acts::Vector3 glb = surface->localToGlobal(gctx, loc, Acts::Vector3::Zero());
671 Acts::Vector2 locg2l = Acts::Vector2::Zero();
672 bool locg2lOk =
false;
673 auto locTrkRes = trkSurface.globalToLocal(glb);
675 locTrk = locTrkRes.value();
676 glbTrk = trkSurface.localToGlobal(locTrk);
678 auto locg2lRes = surface->globalToLocal(gctx, glbTrk, Acts::Vector3::Zero());
679 if (locg2lRes.ok()) {
681 locg2l = locg2lRes.value();
685 auto gId = surface->geometryId();
688 <<
"," << gId.volume()
689 <<
"," << gId.layer()
690 <<
"," << gId.sensitive()
694 <<
"," << surface->insideBounds(loc)
697 <<
"," << trkSurface.insideBounds(locTrk)
709 return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
710 locg2lOk ? isApprox(loc, locg2l) :
true,
711 locTrkRes ? isApprox(glb, glbTrk) :
true};
715 constexpr double envelope = 10.0 * Acts::UnitConstants::mm;
717 std::array<bool,3> allOk{
true,
true,
true};
718 if(
const auto* bounds =
dynamic_cast<const Acts::PlanarBounds*
>(&surface->bounds()); bounds) {
721 const Acts::RectangleBounds& boundingBox = bounds->boundingBox();
722 Acts::Vector2
min = boundingBox.min().array() - envelope;
723 Acts::Vector2
max = boundingBox.max().array() + envelope;
724 Acts::Vector2 diag =
max -
min;
726 for(
const auto& testPoint : localPoints) {
727 Acts::Vector2 loc =
min.array() + (testPoint.array() * diag.array());
728 auto pointOk = doPoints(0, loc);
729 for (
size_t i=0; i<pointOk.size(); ++i) {
738 else if(
const auto* bounds =
dynamic_cast<const Acts::AnnulusBounds*
>(&surface->bounds()); bounds) {
742 std::vector<Acts::Vector2> vertices = bounds->vertices(5);
743 Acts::Vector2
min{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()};
744 Acts::Vector2
max{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()};
745 for (
const auto& vtx : vertices) {
746 min =
min.array().min(vtx.array());
747 max =
max.array().max(vtx.array());
749 min.array() -= envelope;
750 max.array() += envelope;
751 Acts::Vector2 diag =
max -
min;
753 for(
const auto& testPoint : localPoints) {
754 Acts::Vector2 locXY =
min.array() + (testPoint.array() * diag.array());
755 Acts::Vector2 locPC =
dynamic_cast<const Acts::DiscSurface&
>(*surface).localCartesianToPolar(locXY);
757 auto pointOk = doPoints(1, locPC);
758 for (
size_t i=0; i<pointOk.size(); ++i) {
771 for (
size_t i=0; i<allOk.size(); ++i) {
779 ATH_MSG_INFO(
"Total number of sensors : " << nTotalSensors);
780 ATH_MSG_INFO(
"Number of sensors with mismatched centers : " << nMismatchedCenters);
781 ATH_MSG_INFO(
"Number of sensors with mismatched normals : " << nMismatchedNormals);
782 ATH_MSG_INFO(
"Number of sensors with inconsistent inside: " << nInconsistent[0]);
783 ATH_MSG_INFO(
"Number of sensors with inconsistent g2l : " << nInconsistent[1]);
784 ATH_MSG_INFO(
"Number of sensors with inconsistent l2g : " << nInconsistent[2]);
950 const Acts::GeometryContext &gctx,
const Acts::ILayerBuilder &sct_lb,
951 const Acts::ILayerBuilder &trt_lb,
const Acts::CylinderVolumeHelper &cvh,
952 const std::shared_ptr<const Acts::TrackingVolume> &
pixel) {
955 Acts::CylinderVolumeBuilder::Config cvbCfg;
956 Acts::CylinderVolumeBuilder cvb(
960 Acts::VolumeConfig sctNegEC =
961 cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
963 Acts::VolumeConfig sctPosEC =
964 cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
966 Acts::VolumeConfig sctBrl =
967 cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
970 Acts::VolumeConfig trtNegEC =
971 cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
973 Acts::VolumeConfig trtPosEC =
974 cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
976 Acts::VolumeConfig trtBrl =
977 cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
981 double absZMinEC = std::min(std::abs(trtNegEC.zMax), std::abs(trtPosEC.zMin));
982 double absZMaxEC = std::max(std::abs(trtNegEC.zMin), std::abs(trtPosEC.zMax));
984 trtNegEC.zMin = -absZMaxEC;
985 trtNegEC.zMax = -absZMinEC;
986 trtPosEC.zMin = absZMinEC;
987 trtPosEC.zMax = absZMaxEC;
989 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
992 bool isSCTSmallerInZ =
false;
994 ATH_MSG_VERBOSE(
"Shrinking SCT in R (and maybe in increase size in Z) to fit around Pixel");
995 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
996 &
pixel->volumeBounds());
997 double sctNegECzMin = std::min(sctNegEC.zMin, -pixelBounds->get(CVBBV::eHalfLengthZ));
998 double sctPosECzMax = std::max(sctPosEC.zMax, pixelBounds->get(CVBBV::eHalfLengthZ));
1000 ATH_MSG_VERBOSE(
"- SCT +-EC.rMin: " << sctNegEC.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
1001 ATH_MSG_VERBOSE(
"- SCT BRL.rMin: " << sctBrl.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
1002 ATH_MSG_VERBOSE(
"- SCT EC.zMin: " << sctNegEC.zMin <<
" -> " << sctNegECzMin);
1003 ATH_MSG_VERBOSE(
"- SCT EC.zMax: " << sctPosEC.zMax <<
" -> " << sctPosECzMax);
1005 sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
1006 sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
1007 sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
1009 isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
1011 sctNegEC.zMin = sctNegECzMin;
1012 sctPosEC.zMax = sctPosECzMax;
1022 << sctNegEC.toString());
1023 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
1024 << sctBrl.toString());
1027 << sctPosEC.toString());
1032 << trtNegEC.toString());
1033 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
1034 << trtBrl.toString());
1037 << trtPosEC.toString());
1041 sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
1042 sctBrl.zMin = -sctBrl.zMax;
1046 trtBrl.zMin = sctBrl.zMin;
1047 trtBrl.zMax = sctBrl.zMax;
1050 trtNegEC.zMin = sctNegEC.zMin;
1051 trtPosEC.zMax = sctPosEC.zMax;
1054 trtNegEC.zMax = trtBrl.zMin;
1055 sctNegEC.zMax = trtBrl.zMin;
1056 trtPosEC.zMin = trtBrl.zMax;
1057 sctPosEC.zMin = trtBrl.zMax;
1060 sctBrl.rMax = trtBrl.rMin;
1061 sctNegEC.rMax = trtNegEC.rMin;
1062 sctPosEC.rMax = trtPosEC.rMin;
1065 trtNegEC.rMax = trtBrl.rMax;
1066 trtPosEC.rMax = trtBrl.rMax;
1068 ATH_MSG_VERBOSE(
"Dimensions after synchronization between SCT and TRT");
1072 << sctNegEC.toString());
1073 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
1074 << sctBrl.toString());
1077 << sctPosEC.toString());
1082 << trtNegEC.toString());
1083 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
1084 << trtBrl.toString());
1087 << trtPosEC.toString());
1089 auto makeTVol = [&](
const auto &vConf,
const auto &name) {
1090 return cvh.createTrackingVolume(gctx, vConf.layers, {},
1092 vConf.rMin, vConf.rMax, vConf.zMin,
1097 auto tvSctNegEC = makeTVol(sctNegEC,
"SCT::NegativeEndcap");
1098 auto tvSctBrl = makeTVol(sctBrl,
"SCT::Barrel");
1099 auto tvSctPosEC = makeTVol(sctPosEC,
"SCT::PositiveEndcap");
1101 auto tvTrtNegEC = makeTVol(trtNegEC,
"TRT::NegativeEndcap");
1102 auto tvTrtBrl = makeTVol(trtBrl,
"TRT::Barrel");
1103 auto tvTrtPosEC = makeTVol(trtPosEC,
"TRT::PositiveEndcap");
1107 cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
1109 cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
1110 auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
1115 cvh.createContainerTrackingVolume(gctx, {negEC,
barrel, posEC});
1120 auto containerBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1121 &container->volumeBounds());
1122 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1123 &
pixel->volumeBounds());
1124 std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
1126 if(!isSCTSmallerInZ) {
1128 auto posGap = cvh.createGapTrackingVolume(
1131 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1132 pixelBounds->get(CVBBV::eHalfLengthZ),
1133 containerBounds->get(CVBBV::eHalfLengthZ),
1136 "Pixel::PositiveGap");
1137 auto negGap = cvh.createGapTrackingVolume(
1140 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1141 -containerBounds->get(CVBBV::eHalfLengthZ),
1142 -pixelBounds->get(CVBBV::eHalfLengthZ),
1145 "Pixel::NegativeGap");
1147 auto pixelContainer =
1148 cvh.createContainerTrackingVolume(gctx, {negGap,
pixel, posGap});
1151 cvh.createContainerTrackingVolume(gctx, {pixelContainer, container});
1156 cvh.createContainerTrackingVolume(gctx, {
pixel, container});
1175 std::shared_ptr<const Acts::CylinderVolumeHelper> cvh)
const {
1179 PVConstLink beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0);
1182 beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0)->getChildVol(0)->getChildVol(0);
1185 Acts::Transform3 beamPipeTransform;
1186 beamPipeTransform.setIdentity();
1188 beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1190 double beamPipeRadius = 20;
1192 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1193 const GeoTube* beamPipeTube =
nullptr;
1196 if (beamPipeLogVolume ==
nullptr) {
1198 throw std::runtime_error(
"Beam pip volume has no log volume");
1201 beamPipeTube =
dynamic_cast<const GeoTube*
>(beamPipeLogVolume->getShape());
1202 if (beamPipeTube ==
nullptr){
1204 throw std::runtime_error{
"BeamPipeLogVolume was not of type GeoTube"};
1207 for(
unsigned int i=0;i<beamPipeTopVolume->getNChildVols();i++) {
1209 if(beamPipeTopVolume->getNameOfChildVol(i) ==
"SectionC03"){
1211 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(i);
1212 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1213 const GeoTube* childTube =
nullptr;
1215 if (childLogVolume){
1216 childTube =
dynamic_cast<const GeoTube*
>(childLogVolume->getShape());
1218 beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1227 ATH_MSG_VERBOSE(
"BeamPipe constructed from Database: translation (yes) - radius "
1228 << ( beamPipeTube ?
"(yes)" :
"(no)") <<
" - r = " << beamPipeRadius );
1232 Acts::CylinderVolumeBuilder::Config cfg;
1234 Acts::PassiveLayerBuilder::Config bplConfig;
1235 bplConfig.layerIdentification =
"BeamPipe";
1236 bplConfig.centralLayerRadii = {beamPipeRadius * 1_mm};
1237 bplConfig.centralLayerHalflengthZ = {3000_mm};
1238 bplConfig.centralLayerThickness = {1_mm};
1239 auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
1243 cfg.trackingVolumeHelper = cvh;
1244 cfg.volumeName =
"BeamPipe";
1245 cfg.layerBuilder = beamPipeBuilder;
1246 cfg.layerEnvelopeR = {1_mm, 1_mm};
1247 cfg.buildToRadiusZero =
true;