87 return StatusCode::FAILURE;
95 m_autoRetrieveTools =
false;
96 m_checkToolDeps =
false;
99 << Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"."
100 << Acts::VersionPatch <<
" [" << Acts::CommitHash.value_or(
"unknown hash") <<
"]");
105 ATH_MSG_INFO(
"Configured to build " << buildSubdet.size()
106 <<
" subdetectors:");
107 for (
const auto &s : buildSubdet) {
112 if (buildSubdet.find(
"Pixel") != buildSubdet.end()) {
115 if (buildSubdet.find(
"SCT") != buildSubdet.end()) {
118 if (buildSubdet.find(
"TRT") != buildSubdet.end()) {
122 if (buildSubdet.find(
"ITkPixel") != buildSubdet.end()) {
125 if (buildSubdet.find(
"ITkStrip") != buildSubdet.end()) {
128 if (buildSubdet.find(
"HGTD") != buildSubdet.end()) {
140 ATH_MSG_FATAL(
"Consistency check for ITk inner pixel barrel passive layer construction failed. Please check your inputs! ");
141 return StatusCode::FAILURE;
146 ATH_MSG_FATAL(
"Consistency check for ITk outer pixel barrel passive layer construction failed. Please check your inputs! ");
147 return StatusCode::FAILURE;
152 ATH_MSG_FATAL(
"Consistency check for ITk strip barrel passive layer construction failed. Please check your inputs! ");
153 return StatusCode::FAILURE;
159 ATH_MSG_INFO(
"Using Blueprint API for geometry construction");
166 using enum Acts::AxisDirection;
168 std::vector<ActsTrk::IBlueprintNodeBuilder*> ptrBuilders;
170 std::back_inserter(ptrBuilders),
171 [](ToolHandle<ActsTrk::IBlueprintNodeBuilder>& b) { return b.get(); });
175 Acts::Experimental::Blueprint::Config cfg;
176 cfg.envelope[AxisZ] = {20_mm, 20_mm};
177 cfg.envelope[AxisR] = {0_mm, 20_mm};
179 auto blueprint = std::make_unique<Acts::Experimental::Blueprint>(cfg);
181 auto& root = blueprint->addCylinderContainer(
"Detector", AxisZ);
183 std::shared_ptr<Acts::Experimental::BlueprintNode> currentTop{
nullptr};
185 for (
auto& builder : ptrBuilders) {
186 currentTop = builder->buildBlueprintNode(
getNominalContext().context(), std::move(currentTop));
190 root.addChild(std::move(currentTop));
192 Acts::Experimental::BlueprintOptions blueprintOptions;
194 std::unique_ptr<Acts::TrackingGeometry>
trackingGeometry = blueprint->construct(
206 Acts::ObjVisualization3D vis;
208 {.visible =
false}, {.visible =
true});
209 vis.write(
"blueprint_sensitive.obj");
213 {.visible =
false}, {.visible =
false});
214 vis.write(
"blueprint_volume.obj");
218 {.visible =
true}, {.visible =
false});
219 vis.write(
"blueprint_portals.obj");
222 Acts::detail::TrackingGeometryPrintVisitor printer{
m_nominalContext.context()};
224 ATH_MSG_INFO(
"Built tracking geometry \n"<<printer.stream().str());
228 return StatusCode::FAILURE;
231 return StatusCode::SUCCESS;
236 Acts::LayerArrayCreator::Config lacCfg;
237 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
240 Acts::TrackingVolumeArrayCreator::Config tvcCfg;
241 auto trackingVolumeArrayCreator =
242 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
245 Acts::CylinderVolumeHelper::Config cvhConfig;
246 cvhConfig.layerArrayCreator = layerArrayCreator;
247 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
249 auto cylinderVolumeHelper =
250 std::make_shared<const Acts::CylinderVolumeHelper>(
253 Acts::TrackingGeometryBuilder::Config tgbConfig;
254 tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
257 std::shared_ptr<const Acts::IMaterialDecorator> matDeco =
nullptr;
260 if (matFileFullPath.empty()) {
262 return StatusCode::FAILURE;
264 ATH_MSG_INFO(
"Configured to use material input: " << matFileFullPath);
266 if (matFileFullPath.find(
".json") != std::string::npos) {
268 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
270 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
273 tgbConfig.materialDecorator = matDeco;
276 std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
281 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
285 Acts::CylinderVolumeBuilder::Config bpvConfig =
288 Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
291 return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
298 if (buildSubdet.count(
"Pixel") > 0) {
299 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
304 auto lb = std::make_shared<ActsLayerBuilder>(
306 Acts::CylinderVolumeBuilder::Config cvbConfig;
307 cvbConfig.layerEnvelopeR = {3_mm, 3_mm};
308 cvbConfig.layerEnvelopeZ = 1_mm;
309 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
310 cvbConfig.volumeName =
"Pixel";
311 cvbConfig.layerBuilder =
lb;
314 Acts::CylinderVolumeBuilder cvb(
317 return cvb.trackingVolume(gctx, inner);
322 if (buildSubdet.count(
"ITkPixel") > 0) {
323 tgbConfig.trackingVolumeBuilders.push_back(
324 [&](
const auto &gctx,
const auto &inner,
const auto &) {
328 cfg.doEndcapLayerMerging =
true;
332 auto lb = std::make_shared<ActsLayerBuilder>(
335 Acts::CylinderVolumeBuilder::Config cvbConfig;
336 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
337 cvbConfig.layerEnvelopeZ = 1_mm;
338 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
339 cvbConfig.volumeName =
"ITkPixelInner";
340 cvbConfig.layerBuilder =
lb;
343 Acts::CylinderVolumeBuilder cvb(
347 return cvb.trackingVolume(gctx, inner);
350 tgbConfig.trackingVolumeBuilders.push_back(
351 [&](
const auto &gctx,
const auto &inner,
const auto &) {
355 cfg.doEndcapLayerMerging =
false;
359 auto lb = std::make_shared<ActsLayerBuilder>(
362 Acts::CylinderVolumeBuilder::Config cvbConfig;
363 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
364 cvbConfig.layerEnvelopeZ = 1_mm;
365 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
366 cvbConfig.volumeName =
"ITkPixelOuter";
367 cvbConfig.layerBuilder =
lb;
368 cvbConfig.buildToRadiusZero =
false;
369 cvbConfig.checkRingLayout =
true;
370 cvbConfig.ringTolerance = 10_mm;
372 Acts::CylinderVolumeBuilder cvb(
376 return cvb.trackingVolume(gctx, inner);
381 if (buildSubdet.count(
"ITkStrip") > 0) {
382 tgbConfig.trackingVolumeBuilders.push_back(
383 [&](
const auto &gctx,
const auto &inner,
const auto &) {
390 auto lb = std::make_shared<ActsLayerBuilder>(
393 Acts::CylinderVolumeBuilder::Config cvbConfig;
394 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
395 cvbConfig.layerEnvelopeZ = 1_mm;
396 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
397 cvbConfig.volumeName =
"ITkStrip";
398 cvbConfig.layerBuilder =
lb;
399 cvbConfig.buildToRadiusZero =
402 Acts::CylinderVolumeBuilder cvb(
406 return cvb.trackingVolume(gctx, inner);
410 bool buildSCT = buildSubdet.count(
"SCT") > 0;
411 bool buildTRT = buildSubdet.count(
"TRT") > 0;
413 if (buildSCT && buildTRT) {
415 tgbConfig.trackingVolumeBuilders.push_back(
416 [&](
const auto &gctx,
const auto &inner,
const auto &) {
419 cfg.endcapEnvelopeZ = sctECEnvelopeZ;
420 auto sct_lb = std::make_shared<ActsLayerBuilder>(
426 *cylinderVolumeHelper, inner);
429 }
else if (buildSCT) {
430 tgbConfig.trackingVolumeBuilders.push_back(
431 [&](
const auto &gctx,
const auto &inner,
const auto &) {
434 lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
435 auto lb = std::make_shared<ActsLayerBuilder>(
439 Acts::CylinderVolumeBuilder::Config cvbConfig;
440 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
441 cvbConfig.layerEnvelopeZ = 2_mm;
442 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
443 cvbConfig.volumeName =
"SCT";
444 cvbConfig.layerBuilder =
lb;
445 cvbConfig.buildToRadiusZero =
false;
447 Acts::CylinderVolumeBuilder cvb(
451 return cvb.trackingVolume(gctx, inner);
453 }
else if (buildTRT) {
454 tgbConfig.trackingVolumeBuilders.push_back(
455 [&](
const auto &gctx,
const auto &inner,
const auto &) {
457 Acts::CylinderVolumeBuilder::Config cvbConfig;
458 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
459 cvbConfig.layerEnvelopeZ = 2_mm;
460 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
461 cvbConfig.volumeName =
"TRT";
462 cvbConfig.layerBuilder =
lb;
463 cvbConfig.buildToRadiusZero =
false;
465 Acts::CylinderVolumeBuilder cvb(
469 return cvb.trackingVolume(gctx, inner);
474 if(buildSubdet.count(
"HGTD") > 0) {
475 tgbConfig.trackingVolumeBuilders.push_back(
476 [&](
const auto &gctx,
const auto &inner,
const auto &) {
478 Acts::CylinderVolumeBuilder::Config cvbConfig;
479 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
480 cvbConfig.layerEnvelopeZ = 1_mm;
481 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
482 cvbConfig.volumeName =
"HGTD";
483 cvbConfig.layerBuilder =
lb;
484 cvbConfig.buildToRadiusZero =
false;
486 Acts::CylinderVolumeBuilder cvb(
490 return cvb.trackingVolume(gctx, inner);
496 tgbConfig.trackingVolumeBuilders.push_back(
497 [&](
const auto &gctx,
const auto &inner,
const auto &) {
502 }
catch (
const std::exception &e) {
503 ATH_MSG_ERROR(
"Encountered error when building Acts tracking geometry");
505 return StatusCode::FAILURE;
508 auto trackingGeometryBuilder =
509 std::make_shared<const Acts::TrackingGeometryBuilder>(
518 ATH_MSG_ERROR(
"No ACTS tracking geometry was built. Cannot proceeed");
519 return StatusCode::FAILURE;
524 ATH_MSG_INFO(
"Running extra consistency check! (this is SLOW)");
526 ATH_MSG_ERROR(
"Consistency check has failed! Geometry is not consistent");
527 return StatusCode::FAILURE;
533 return StatusCode::FAILURE;
537 ATH_MSG_INFO(
"Acts TrackingGeometry construction completed");
539 return StatusCode::SUCCESS;
547 std::vector<Acts::Vector2> localPoints;
550 std::uniform_real_distribution<> dist(0.0, 1.0);
552 std::optional<std::ofstream> os;
556 throw std::runtime_error{
"Failed to open consistency check output file"};
561 (*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;
564 localPoints.emplace_back(dist(gen), dist(gen));
569 size_t nTotalSensors = 0;
570 std::array<size_t,3> nInconsistent{0,0,0};
571 size_t nMismatchedCenters = 0;
572 size_t nMismatchedNormals = 0;
576 auto isApprox = [](
auto&
a,
auto& b) ->
bool {
577 return ((
a - b).
array().abs() < 1e-5).all();
583 if(actsDetElem ==
nullptr) {
589 if(siDetElem ==
nullptr) {
593 const auto* regSurface =
dynamic_cast<const Acts::RegularSurface*
>(surface);
594 const auto& trkSurface = siDetElem->
surface();
595 if(regSurface ==
nullptr) {
601 Acts::Vector3 center{regSurface->center(gctx)};
603 if (
dynamic_cast<const Acts::AnnulusBounds *
>(&surface->bounds()))
608 center.head<2>() = trkCenter.head<2>();
611 if(!isApprox(trkCenter, center)) {
613 if (
auto idHelper = siDetElem->getIdHelper())
615 trkName = idHelper->show_to_string(siDetElem->identify());
618 << surface->geometryId()
619 <<
" center (" << center[0] <<
',' << center[1] <<
',' << center[2]
620 <<
") does not match Trk surface " << trkName
621 <<
" center (" << trkCenter[0] <<
',' << trkCenter[1] <<
',' << trkCenter[2] <<
')');
622 nMismatchedCenters++;
626 const auto* lineSurface =
dynamic_cast<const Acts::LineSurface*
>(surface);
627 if(lineSurface ==
nullptr) {
628 Acts::Vector3 norm{regSurface->normal(gctx, regSurface->center(gctx))};
630 if(!isApprox(trkNorm, norm)) {
632 if (
auto idHelper = siDetElem->getIdHelper())
634 trkName = idHelper->show_to_string(siDetElem->identify());
637 << surface->geometryId()
638 <<
" normal (" << norm[0] <<
',' << norm[1] <<
',' << norm[2]
639 <<
") does not match Trk surface " << trkName
640 <<
" normal (" << trkNorm[0] <<
',' << trkNorm[1] <<
',' << trkNorm[2] <<
')');
641 nMismatchedNormals++;
646 auto doPoints = [&](
unsigned int type,
const Acts::Vector2& loc) -> std::array<bool,3> {
647 Acts::Vector3 glb = surface->localToGlobal(gctx, loc, Acts::Vector3::Zero());
651 Acts::Vector2 locg2l = Acts::Vector2::Zero();
652 bool locg2lOk =
false;
653 auto locTrkRes = trkSurface.globalToLocal(glb);
655 locTrk = locTrkRes.value();
656 glbTrk = trkSurface.localToGlobal(locTrk);
658 auto locg2lRes = surface->globalToLocal(gctx, glbTrk, Acts::Vector3::Zero());
659 if (locg2lRes.ok()) {
661 locg2l = locg2lRes.value();
665 auto gId = surface->geometryId();
668 <<
"," << gId.volume()
669 <<
"," << gId.layer()
670 <<
"," << gId.sensitive()
674 <<
"," << surface->insideBounds(loc)
677 <<
"," << trkSurface.insideBounds(locTrk)
689 return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
690 locg2lOk ? isApprox(loc, locg2l) :
true,
691 locTrkRes ? isApprox(glb, glbTrk) :
true};
695 constexpr double envelope = 10.0 * Acts::UnitConstants::mm;
697 std::array<bool,3> allOk{
true,
true,
true};
698 if(
const auto* bounds =
dynamic_cast<const Acts::PlanarBounds*
>(&surface->bounds()); bounds) {
701 const Acts::RectangleBounds& boundingBox = bounds->boundingBox();
702 Acts::Vector2
min = boundingBox.min().array() - envelope;
703 Acts::Vector2
max = boundingBox.max().array() + envelope;
704 Acts::Vector2 diag =
max -
min;
706 for(
const auto& testPoint : localPoints) {
707 Acts::Vector2 loc =
min.array() + (testPoint.array() * diag.array());
708 auto pointOk = doPoints(0, loc);
709 for (
size_t i=0; i<pointOk.size(); ++i) {
718 else if(
const auto* bounds =
dynamic_cast<const Acts::AnnulusBounds*
>(&surface->bounds()); bounds) {
722 std::vector<Acts::Vector2> vertices = bounds->vertices(5);
723 Acts::Vector2
min{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()};
724 Acts::Vector2
max{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()};
725 for (
const auto& vtx : vertices) {
726 min =
min.array().min(vtx.array());
727 max =
max.array().max(vtx.array());
729 min.array() -= envelope;
730 max.array() += envelope;
731 Acts::Vector2 diag =
max -
min;
733 for(
const auto& testPoint : localPoints) {
734 Acts::Vector2 locXY =
min.array() + (testPoint.array() * diag.array());
735 Acts::Vector2 locPC =
dynamic_cast<const Acts::DiscSurface&
>(*surface).localCartesianToPolar(locXY);
737 auto pointOk = doPoints(1, locPC);
738 for (
size_t i=0; i<pointOk.size(); ++i) {
751 for (
size_t i=0; i<allOk.size(); ++i) {
759 ATH_MSG_INFO(
"Total number of sensors : " << nTotalSensors);
760 ATH_MSG_INFO(
"Number of sensors with mismatched centers : " << nMismatchedCenters);
761 ATH_MSG_INFO(
"Number of sensors with mismatched normals : " << nMismatchedNormals);
762 ATH_MSG_INFO(
"Number of sensors with inconsistent inside: " << nInconsistent[0]);
763 ATH_MSG_INFO(
"Number of sensors with inconsistent g2l : " << nInconsistent[1]);
764 ATH_MSG_INFO(
"Number of sensors with inconsistent l2g : " << nInconsistent[2]);
930 const Acts::GeometryContext &gctx,
const Acts::ILayerBuilder &sct_lb,
931 const Acts::ILayerBuilder &trt_lb,
const Acts::CylinderVolumeHelper &cvh,
932 const std::shared_ptr<const Acts::TrackingVolume> &
pixel) {
935 Acts::CylinderVolumeBuilder::Config cvbCfg;
936 Acts::CylinderVolumeBuilder cvb(
940 Acts::VolumeConfig sctNegEC =
941 cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
943 Acts::VolumeConfig sctPosEC =
944 cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
946 Acts::VolumeConfig sctBrl =
947 cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
950 Acts::VolumeConfig trtNegEC =
951 cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
953 Acts::VolumeConfig trtPosEC =
954 cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
956 Acts::VolumeConfig trtBrl =
957 cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
961 double absZMinEC = std::min(std::abs(trtNegEC.zMax), std::abs(trtPosEC.zMin));
962 double absZMaxEC = std::max(std::abs(trtNegEC.zMin), std::abs(trtPosEC.zMax));
964 trtNegEC.zMin = -absZMaxEC;
965 trtNegEC.zMax = -absZMinEC;
966 trtPosEC.zMin = absZMinEC;
967 trtPosEC.zMax = absZMaxEC;
969 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
972 bool isSCTSmallerInZ =
false;
974 ATH_MSG_VERBOSE(
"Shrinking SCT in R (and maybe in increase size in Z) to fit around Pixel");
975 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
976 &
pixel->volumeBounds());
977 double sctNegECzMin = std::min(sctNegEC.zMin, -pixelBounds->get(CVBBV::eHalfLengthZ));
978 double sctPosECzMax = std::max(sctPosEC.zMax, pixelBounds->get(CVBBV::eHalfLengthZ));
980 ATH_MSG_VERBOSE(
"- SCT +-EC.rMin: " << sctNegEC.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
981 ATH_MSG_VERBOSE(
"- SCT BRL.rMin: " << sctBrl.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
982 ATH_MSG_VERBOSE(
"- SCT EC.zMin: " << sctNegEC.zMin <<
" -> " << sctNegECzMin);
983 ATH_MSG_VERBOSE(
"- SCT EC.zMax: " << sctPosEC.zMax <<
" -> " << sctPosECzMax);
985 sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
986 sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
987 sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
989 isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
991 sctNegEC.zMin = sctNegECzMin;
992 sctPosEC.zMax = sctPosECzMax;
1002 << sctNegEC.toString());
1003 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
1004 << sctBrl.toString());
1007 << sctPosEC.toString());
1012 << trtNegEC.toString());
1013 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
1014 << trtBrl.toString());
1017 << trtPosEC.toString());
1021 sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
1022 sctBrl.zMin = -sctBrl.zMax;
1026 trtBrl.zMin = sctBrl.zMin;
1027 trtBrl.zMax = sctBrl.zMax;
1030 trtNegEC.zMin = sctNegEC.zMin;
1031 trtPosEC.zMax = sctPosEC.zMax;
1034 trtNegEC.zMax = trtBrl.zMin;
1035 sctNegEC.zMax = trtBrl.zMin;
1036 trtPosEC.zMin = trtBrl.zMax;
1037 sctPosEC.zMin = trtBrl.zMax;
1040 sctBrl.rMax = trtBrl.rMin;
1041 sctNegEC.rMax = trtNegEC.rMin;
1042 sctPosEC.rMax = trtPosEC.rMin;
1045 trtNegEC.rMax = trtBrl.rMax;
1046 trtPosEC.rMax = trtBrl.rMax;
1048 ATH_MSG_VERBOSE(
"Dimensions after synchronization between SCT and TRT");
1052 << sctNegEC.toString());
1053 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
1054 << sctBrl.toString());
1057 << sctPosEC.toString());
1062 << trtNegEC.toString());
1063 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
1064 << trtBrl.toString());
1067 << trtPosEC.toString());
1069 auto makeTVol = [&](
const auto &vConf,
const auto &name) {
1070 return cvh.createTrackingVolume(gctx, vConf.layers, {},
1072 vConf.rMin, vConf.rMax, vConf.zMin,
1077 auto tvSctNegEC = makeTVol(sctNegEC,
"SCT::NegativeEndcap");
1078 auto tvSctBrl = makeTVol(sctBrl,
"SCT::Barrel");
1079 auto tvSctPosEC = makeTVol(sctPosEC,
"SCT::PositiveEndcap");
1081 auto tvTrtNegEC = makeTVol(trtNegEC,
"TRT::NegativeEndcap");
1082 auto tvTrtBrl = makeTVol(trtBrl,
"TRT::Barrel");
1083 auto tvTrtPosEC = makeTVol(trtPosEC,
"TRT::PositiveEndcap");
1087 cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
1089 cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
1090 auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
1095 cvh.createContainerTrackingVolume(gctx, {negEC,
barrel, posEC});
1100 auto containerBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1101 &container->volumeBounds());
1102 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1103 &
pixel->volumeBounds());
1104 std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
1106 if(!isSCTSmallerInZ) {
1108 auto posGap = cvh.createGapTrackingVolume(
1111 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1112 pixelBounds->get(CVBBV::eHalfLengthZ),
1113 containerBounds->get(CVBBV::eHalfLengthZ),
1116 "Pixel::PositiveGap");
1117 auto negGap = cvh.createGapTrackingVolume(
1120 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1121 -containerBounds->get(CVBBV::eHalfLengthZ),
1122 -pixelBounds->get(CVBBV::eHalfLengthZ),
1125 "Pixel::NegativeGap");
1127 auto pixelContainer =
1128 cvh.createContainerTrackingVolume(gctx, {negGap,
pixel, posGap});
1131 cvh.createContainerTrackingVolume(gctx, {pixelContainer, container});
1136 cvh.createContainerTrackingVolume(gctx, {
pixel, container});
1155 std::shared_ptr<const Acts::CylinderVolumeHelper> cvh)
const {
1159 PVConstLink beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0);
1162 beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0)->getChildVol(0)->getChildVol(0);
1165 Acts::Transform3 beamPipeTransform;
1166 beamPipeTransform.setIdentity();
1168 beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1170 double beamPipeRadius = 20;
1172 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1173 const GeoTube* beamPipeTube =
nullptr;
1176 if (beamPipeLogVolume ==
nullptr) {
1178 throw std::runtime_error(
"Beam pip volume has no log volume");
1181 beamPipeTube =
dynamic_cast<const GeoTube*
>(beamPipeLogVolume->getShape());
1182 if (beamPipeTube ==
nullptr){
1184 throw std::runtime_error{
"BeamPipeLogVolume was not of type GeoTube"};
1187 for(
unsigned int i=0;i<beamPipeTopVolume->getNChildVols();i++) {
1189 if(beamPipeTopVolume->getNameOfChildVol(i) ==
"SectionC03"){
1191 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(i);
1192 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1193 const GeoTube* childTube =
nullptr;
1195 if (childLogVolume){
1196 childTube =
dynamic_cast<const GeoTube*
>(childLogVolume->getShape());
1198 beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1207 ATH_MSG_VERBOSE(
"BeamPipe constructed from Database: translation (yes) - radius "
1208 << ( beamPipeTube ?
"(yes)" :
"(no)") <<
" - r = " << beamPipeRadius );
1212 Acts::CylinderVolumeBuilder::Config cfg;
1214 Acts::PassiveLayerBuilder::Config bplConfig;
1215 bplConfig.layerIdentification =
"BeamPipe";
1216 bplConfig.centralLayerRadii = {beamPipeRadius * 1_mm};
1217 bplConfig.centralLayerHalflengthZ = {3000_mm};
1218 bplConfig.centralLayerThickness = {1_mm};
1219 auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
1223 cfg.trackingVolumeHelper = cvh;
1224 cfg.volumeName =
"BeamPipe";
1225 cfg.layerBuilder = beamPipeBuilder;
1226 cfg.layerEnvelopeR = {1_mm, 1_mm};
1227 cfg.buildToRadiusZero =
true;