85 return StatusCode::FAILURE;
93 m_autoRetrieveTools =
false;
94 m_checkToolDeps =
false;
97 << Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"."
98 << Acts::VersionPatch <<
" [" << Acts::CommitHash.value_or(
"unknown hash") <<
"]");
103 ATH_MSG_INFO(
"Configured to build " << buildSubdet.size()
104 <<
" subdetectors:");
105 for (
const auto &s : buildSubdet) {
110 if (buildSubdet.find(
"Pixel") != buildSubdet.end()) {
113 if (buildSubdet.find(
"SCT") != buildSubdet.end()) {
116 if (buildSubdet.find(
"TRT") != buildSubdet.end()) {
120 if (buildSubdet.find(
"ITkPixel") != buildSubdet.end()) {
123 if (buildSubdet.find(
"ITkStrip") != buildSubdet.end()) {
126 if (buildSubdet.find(
"HGTD") != buildSubdet.end()) {
138 ATH_MSG_FATAL(
"Consistency check for ITk inner pixel barrel passive layer construction failed. Please check your inputs! ");
139 return StatusCode::FAILURE;
144 ATH_MSG_FATAL(
"Consistency check for ITk outer pixel barrel passive layer construction failed. Please check your inputs! ");
145 return StatusCode::FAILURE;
150 ATH_MSG_FATAL(
"Consistency check for ITk strip barrel passive layer construction failed. Please check your inputs! ");
151 return StatusCode::FAILURE;
157 ATH_MSG_INFO(
"Using Blueprint API for geometry construction");
163 using enum Acts::AxisDirection;
165 std::vector<ActsTrk::IBlueprintNodeBuilder*> ptrBuilders;
167 std::back_inserter(ptrBuilders),
168 [](ToolHandle<ActsTrk::IBlueprintNodeBuilder>& b) { return b.get(); });
172 Acts::Experimental::Blueprint::Config cfg;
173 cfg.envelope[AxisZ] = {20_mm, 20_mm};
174 cfg.envelope[AxisR] = {0_mm, 20_mm};
176 auto blueprint = std::make_unique<Acts::Experimental::Blueprint>(cfg);
178 auto& root = blueprint->addCylinderContainer(
"Detector", AxisZ);
180 std::shared_ptr<Acts::Experimental::BlueprintNode> currentTop{
nullptr};
182 for (
auto& builder : ptrBuilders) {
183 currentTop = builder->buildBlueprintNode(
getNominalContext().context(), std::move(currentTop));
187 root.addChild(std::move(currentTop));
193 Acts::ObjVisualization3D vis;
195 {.visible =
false}, {.visible =
true});
196 vis.write(
"blueprint_sensitive.obj");
200 {.visible =
false}, {.visible =
false});
201 vis.write(
"blueprint_volume.obj");
205 {.visible =
true}, {.visible =
false});
206 vis.write(
"blueprint_portals.obj");
211 Acts::detail::TrackingGeometryPrintVisitor printer{
m_nominalContext.context()};
213 ATH_MSG_INFO(
"Built tracking geometry \n"<<printer.stream().str());
216 return StatusCode::SUCCESS;
221 Acts::LayerArrayCreator::Config lacCfg;
222 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
225 Acts::TrackingVolumeArrayCreator::Config tvcCfg;
226 auto trackingVolumeArrayCreator =
227 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
230 Acts::CylinderVolumeHelper::Config cvhConfig;
231 cvhConfig.layerArrayCreator = layerArrayCreator;
232 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
234 auto cylinderVolumeHelper =
235 std::make_shared<const Acts::CylinderVolumeHelper>(
238 Acts::TrackingGeometryBuilder::Config tgbConfig;
239 tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
242 std::shared_ptr<const Acts::IMaterialDecorator> matDeco =
nullptr;
245 if (matFileFullPath.empty()) {
247 return StatusCode::FAILURE;
249 ATH_MSG_INFO(
"Configured to use material input: " << matFileFullPath);
251 if (matFileFullPath.find(
".json") != std::string::npos) {
253 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
255 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
258 tgbConfig.materialDecorator = matDeco;
261 std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
266 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
270 Acts::CylinderVolumeBuilder::Config bpvConfig =
273 Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
276 return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
283 if (buildSubdet.count(
"Pixel") > 0) {
284 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
289 auto lb = std::make_shared<ActsLayerBuilder>(
291 Acts::CylinderVolumeBuilder::Config cvbConfig;
292 cvbConfig.layerEnvelopeR = {3_mm, 3_mm};
293 cvbConfig.layerEnvelopeZ = 1_mm;
294 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
295 cvbConfig.volumeName =
"Pixel";
296 cvbConfig.layerBuilder =
lb;
299 Acts::CylinderVolumeBuilder cvb(
302 return cvb.trackingVolume(gctx, inner);
307 if (buildSubdet.count(
"ITkPixel") > 0) {
308 tgbConfig.trackingVolumeBuilders.push_back(
309 [&](
const auto &gctx,
const auto &inner,
const auto &) {
313 cfg.doEndcapLayerMerging =
true;
317 auto lb = std::make_shared<ActsLayerBuilder>(
320 Acts::CylinderVolumeBuilder::Config cvbConfig;
321 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
322 cvbConfig.layerEnvelopeZ = 1_mm;
323 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
324 cvbConfig.volumeName =
"ITkPixelInner";
325 cvbConfig.layerBuilder =
lb;
328 Acts::CylinderVolumeBuilder cvb(
332 return cvb.trackingVolume(gctx, inner);
335 tgbConfig.trackingVolumeBuilders.push_back(
336 [&](
const auto &gctx,
const auto &inner,
const auto &) {
340 cfg.doEndcapLayerMerging =
false;
344 auto lb = std::make_shared<ActsLayerBuilder>(
347 Acts::CylinderVolumeBuilder::Config cvbConfig;
348 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
349 cvbConfig.layerEnvelopeZ = 1_mm;
350 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
351 cvbConfig.volumeName =
"ITkPixelOuter";
352 cvbConfig.layerBuilder =
lb;
353 cvbConfig.buildToRadiusZero =
false;
354 cvbConfig.checkRingLayout =
true;
355 cvbConfig.ringTolerance = 10_mm;
357 Acts::CylinderVolumeBuilder cvb(
361 return cvb.trackingVolume(gctx, inner);
366 if (buildSubdet.count(
"ITkStrip") > 0) {
367 tgbConfig.trackingVolumeBuilders.push_back(
368 [&](
const auto &gctx,
const auto &inner,
const auto &) {
375 auto lb = std::make_shared<ActsLayerBuilder>(
378 Acts::CylinderVolumeBuilder::Config cvbConfig;
379 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
380 cvbConfig.layerEnvelopeZ = 1_mm;
381 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
382 cvbConfig.volumeName =
"ITkStrip";
383 cvbConfig.layerBuilder =
lb;
384 cvbConfig.buildToRadiusZero =
387 Acts::CylinderVolumeBuilder cvb(
391 return cvb.trackingVolume(gctx, inner);
395 bool buildSCT = buildSubdet.count(
"SCT") > 0;
396 bool buildTRT = buildSubdet.count(
"TRT") > 0;
398 if (buildSCT && buildTRT) {
400 tgbConfig.trackingVolumeBuilders.push_back(
401 [&](
const auto &gctx,
const auto &inner,
const auto &) {
404 cfg.endcapEnvelopeZ = sctECEnvelopeZ;
405 auto sct_lb = std::make_shared<ActsLayerBuilder>(
411 *cylinderVolumeHelper, inner);
414 }
else if (buildSCT) {
415 tgbConfig.trackingVolumeBuilders.push_back(
416 [&](
const auto &gctx,
const auto &inner,
const auto &) {
419 lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
420 auto lb = std::make_shared<ActsLayerBuilder>(
424 Acts::CylinderVolumeBuilder::Config cvbConfig;
425 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
426 cvbConfig.layerEnvelopeZ = 2_mm;
427 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
428 cvbConfig.volumeName =
"SCT";
429 cvbConfig.layerBuilder =
lb;
430 cvbConfig.buildToRadiusZero =
false;
432 Acts::CylinderVolumeBuilder cvb(
436 return cvb.trackingVolume(gctx, inner);
438 }
else if (buildTRT) {
439 tgbConfig.trackingVolumeBuilders.push_back(
440 [&](
const auto &gctx,
const auto &inner,
const auto &) {
442 Acts::CylinderVolumeBuilder::Config cvbConfig;
443 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
444 cvbConfig.layerEnvelopeZ = 2_mm;
445 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
446 cvbConfig.volumeName =
"TRT";
447 cvbConfig.layerBuilder =
lb;
448 cvbConfig.buildToRadiusZero =
false;
450 Acts::CylinderVolumeBuilder cvb(
454 return cvb.trackingVolume(gctx, inner);
459 if(buildSubdet.count(
"HGTD") > 0) {
460 tgbConfig.trackingVolumeBuilders.push_back(
461 [&](
const auto &gctx,
const auto &inner,
const auto &) {
463 Acts::CylinderVolumeBuilder::Config cvbConfig;
464 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
465 cvbConfig.layerEnvelopeZ = 1_mm;
466 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
467 cvbConfig.volumeName =
"HGTD";
468 cvbConfig.layerBuilder =
lb;
469 cvbConfig.buildToRadiusZero =
false;
471 Acts::CylinderVolumeBuilder cvb(
475 return cvb.trackingVolume(gctx, inner);
481 tgbConfig.trackingVolumeBuilders.push_back(
482 [&](
const auto &gctx,
const auto &inner,
const auto &) {
487 }
catch (
const std::exception &e) {
488 ATH_MSG_ERROR(
"Encountered error when building Acts tracking geometry");
490 return StatusCode::FAILURE;
493 auto trackingGeometryBuilder =
494 std::make_shared<const Acts::TrackingGeometryBuilder>(
503 ATH_MSG_ERROR(
"No ACTS tracking geometry was built. Cannot proceeed");
504 return StatusCode::FAILURE;
509 ATH_MSG_INFO(
"Running extra consistency check! (this is SLOW)");
511 ATH_MSG_ERROR(
"Consistency check has failed! Geometry is not consistent");
512 return StatusCode::FAILURE;
516 ATH_MSG_INFO(
"Acts TrackingGeometry construction completed");
518 return StatusCode::SUCCESS;
524 std::vector<Acts::Vector2> localPoints;
527 std::uniform_real_distribution<> dist(0.0, 1.0);
529 std::optional<std::ofstream> os;
533 throw std::runtime_error{
"Failed to open consistency check output file"};
538 (*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;
541 localPoints.emplace_back(dist(gen), dist(gen));
546 size_t nTotalSensors = 0;
547 std::array<size_t,3> nInconsistent{0,0,0};
548 size_t nMismatchedCenters = 0;
549 size_t nMismatchedNormals = 0;
553 auto isApprox = [](
auto&
a,
auto& b) ->
bool {
554 return ((
a - b).
array().abs() < 1e-5).all();
560 const auto* actsDetElem =
dynamic_cast<const ActsDetectorElement*
>(surface->associatedDetectorElement());
561 if(actsDetElem ==
nullptr) {
567 if(siDetElem ==
nullptr) {
571 const auto* regSurface =
dynamic_cast<const Acts::RegularSurface*
>(surface);
572 const auto& trkSurface = siDetElem->
surface();
573 if(regSurface ==
nullptr) {
579 Acts::Vector3 center{regSurface->center(gctx)};
581 if (
dynamic_cast<const Acts::AnnulusBounds *
>(&surface->bounds()))
586 center.head<2>() = trkCenter.head<2>();
589 if(!isApprox(trkCenter, center)) {
591 if (
auto idHelper = siDetElem->getIdHelper())
593 trkName = idHelper->show_to_string(siDetElem->identify());
596 << surface->geometryId()
597 <<
" center (" << center[0] <<
',' << center[1] <<
',' << center[2]
598 <<
") does not match Trk surface " << trkName
599 <<
" center (" << trkCenter[0] <<
',' << trkCenter[1] <<
',' << trkCenter[2] <<
')');
600 nMismatchedCenters++;
604 const auto* lineSurface =
dynamic_cast<const Acts::LineSurface*
>(surface);
605 if(lineSurface ==
nullptr) {
606 Acts::Vector3 norm{regSurface->normal(gctx, regSurface->center(gctx))};
608 if(!isApprox(trkNorm, norm)) {
610 if (
auto idHelper = siDetElem->getIdHelper())
612 trkName = idHelper->show_to_string(siDetElem->identify());
615 << surface->geometryId()
616 <<
" normal (" << norm[0] <<
',' << norm[1] <<
',' << norm[2]
617 <<
") does not match Trk surface " << trkName
618 <<
" normal (" << trkNorm[0] <<
',' << trkNorm[1] <<
',' << trkNorm[2] <<
')');
619 nMismatchedNormals++;
624 auto doPoints = [&](
unsigned int type,
const Acts::Vector2& loc) -> std::array<bool,3> {
625 Acts::Vector3 glb = surface->localToGlobal(gctx, loc, Acts::Vector3::Zero());
629 Acts::Vector2 locg2l = Acts::Vector2::Zero();
630 bool locg2lOk =
false;
631 auto locTrkRes = trkSurface.globalToLocal(glb);
633 locTrk = locTrkRes.value();
634 glbTrk = trkSurface.localToGlobal(locTrk);
636 auto locg2lRes = surface->globalToLocal(gctx, glbTrk, Acts::Vector3::Zero());
637 if (locg2lRes.ok()) {
639 locg2l = locg2lRes.value();
643 auto gId = surface->geometryId();
646 <<
"," << gId.volume()
647 <<
"," << gId.layer()
648 <<
"," << gId.sensitive()
652 <<
"," << surface->insideBounds(loc)
655 <<
"," << trkSurface.insideBounds(locTrk)
667 return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
668 locg2lOk ? isApprox(loc, locg2l) :
true,
669 locTrkRes ? isApprox(glb, glbTrk) :
true};
673 constexpr double envelope = 10.0 * Acts::UnitConstants::mm;
675 std::array<bool,3> allOk{
true,
true,
true};
676 if(
const auto* bounds =
dynamic_cast<const Acts::PlanarBounds*
>(&surface->bounds()); bounds) {
679 const Acts::RectangleBounds& boundingBox = bounds->boundingBox();
680 Acts::Vector2
min = boundingBox.min().array() - envelope;
681 Acts::Vector2
max = boundingBox.max().array() + envelope;
682 Acts::Vector2 diag =
max -
min;
684 for(
const auto& testPoint : localPoints) {
685 Acts::Vector2 loc =
min.array() + (testPoint.array() * diag.array());
686 auto pointOk = doPoints(0, loc);
687 for (
size_t i=0; i<pointOk.size(); ++i) {
696 else if(
const auto* bounds =
dynamic_cast<const Acts::AnnulusBounds*
>(&surface->bounds()); bounds) {
700 std::vector<Acts::Vector2> vertices = bounds->vertices(5);
701 Acts::Vector2
min{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()};
702 Acts::Vector2
max{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()};
703 for (
const auto& vtx : vertices) {
704 min =
min.array().min(vtx.array());
705 max =
max.array().max(vtx.array());
707 min.array() -= envelope;
708 max.array() += envelope;
709 Acts::Vector2 diag =
max -
min;
711 for(
const auto& testPoint : localPoints) {
712 Acts::Vector2 locXY =
min.array() + (testPoint.array() * diag.array());
713 Acts::Vector2 locPC =
dynamic_cast<const Acts::DiscSurface&
>(*surface).localCartesianToPolar(locXY);
715 auto pointOk = doPoints(1, locPC);
716 for (
size_t i=0; i<pointOk.size(); ++i) {
729 for (
size_t i=0; i<allOk.size(); ++i) {
737 ATH_MSG_INFO(
"Total number of sensors : " << nTotalSensors);
738 ATH_MSG_INFO(
"Number of sensors with mismatched centers : " << nMismatchedCenters);
739 ATH_MSG_INFO(
"Number of sensors with mismatched normals : " << nMismatchedNormals);
740 ATH_MSG_INFO(
"Number of sensors with inconsistent inside: " << nInconsistent[0]);
741 ATH_MSG_INFO(
"Number of sensors with inconsistent g2l : " << nInconsistent[1]);
742 ATH_MSG_INFO(
"Number of sensors with inconsistent l2g : " << nInconsistent[2]);
909 const Acts::GeometryContext &gctx,
const Acts::ILayerBuilder &sct_lb,
910 const Acts::ILayerBuilder &trt_lb,
const Acts::CylinderVolumeHelper &cvh,
911 const std::shared_ptr<const Acts::TrackingVolume> &
pixel) {
914 Acts::CylinderVolumeBuilder::Config cvbCfg;
915 Acts::CylinderVolumeBuilder cvb(
919 Acts::VolumeConfig sctNegEC =
920 cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
922 Acts::VolumeConfig sctPosEC =
923 cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
925 Acts::VolumeConfig sctBrl =
926 cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
929 Acts::VolumeConfig trtNegEC =
930 cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
932 Acts::VolumeConfig trtPosEC =
933 cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
935 Acts::VolumeConfig trtBrl =
936 cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
940 double absZMinEC = std::min(std::abs(trtNegEC.zMax), std::abs(trtPosEC.zMin));
941 double absZMaxEC = std::max(std::abs(trtNegEC.zMin), std::abs(trtPosEC.zMax));
943 trtNegEC.zMin = -absZMaxEC;
944 trtNegEC.zMax = -absZMinEC;
945 trtPosEC.zMin = absZMinEC;
946 trtPosEC.zMax = absZMaxEC;
948 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
951 bool isSCTSmallerInZ =
false;
953 ATH_MSG_VERBOSE(
"Shrinking SCT in R (and maybe in increase size in Z) to fit around Pixel");
954 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
955 &
pixel->volumeBounds());
956 double sctNegECzMin = std::min(sctNegEC.zMin, -pixelBounds->get(CVBBV::eHalfLengthZ));
957 double sctPosECzMax = std::max(sctPosEC.zMax, pixelBounds->get(CVBBV::eHalfLengthZ));
959 ATH_MSG_VERBOSE(
"- SCT +-EC.rMin: " << sctNegEC.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
960 ATH_MSG_VERBOSE(
"- SCT BRL.rMin: " << sctBrl.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
961 ATH_MSG_VERBOSE(
"- SCT EC.zMin: " << sctNegEC.zMin <<
" -> " << sctNegECzMin);
962 ATH_MSG_VERBOSE(
"- SCT EC.zMax: " << sctPosEC.zMax <<
" -> " << sctPosECzMax);
964 sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
965 sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
966 sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
968 isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
970 sctNegEC.zMin = sctNegECzMin;
971 sctPosEC.zMax = sctPosECzMax;
981 << sctNegEC.toString());
982 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
983 << sctBrl.toString());
986 << sctPosEC.toString());
991 << trtNegEC.toString());
992 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
993 << trtBrl.toString());
996 << trtPosEC.toString());
1000 sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
1001 sctBrl.zMin = -sctBrl.zMax;
1005 trtBrl.zMin = sctBrl.zMin;
1006 trtBrl.zMax = sctBrl.zMax;
1009 trtNegEC.zMin = sctNegEC.zMin;
1010 trtPosEC.zMax = sctPosEC.zMax;
1013 trtNegEC.zMax = trtBrl.zMin;
1014 sctNegEC.zMax = trtBrl.zMin;
1015 trtPosEC.zMin = trtBrl.zMax;
1016 sctPosEC.zMin = trtBrl.zMax;
1019 sctBrl.rMax = trtBrl.rMin;
1020 sctNegEC.rMax = trtNegEC.rMin;
1021 sctPosEC.rMax = trtPosEC.rMin;
1024 trtNegEC.rMax = trtBrl.rMax;
1025 trtPosEC.rMax = trtBrl.rMax;
1027 ATH_MSG_VERBOSE(
"Dimensions after synchronization between SCT and TRT");
1031 << sctNegEC.toString());
1032 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
1033 << sctBrl.toString());
1036 << sctPosEC.toString());
1041 << trtNegEC.toString());
1042 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
1043 << trtBrl.toString());
1046 << trtPosEC.toString());
1048 auto makeTVol = [&](
const auto &vConf,
const auto &name) {
1049 return cvh.createTrackingVolume(gctx, vConf.layers, {},
1051 vConf.rMin, vConf.rMax, vConf.zMin,
1056 auto tvSctNegEC = makeTVol(sctNegEC,
"SCT::NegativeEndcap");
1057 auto tvSctBrl = makeTVol(sctBrl,
"SCT::Barrel");
1058 auto tvSctPosEC = makeTVol(sctPosEC,
"SCT::PositiveEndcap");
1060 auto tvTrtNegEC = makeTVol(trtNegEC,
"TRT::NegativeEndcap");
1061 auto tvTrtBrl = makeTVol(trtBrl,
"TRT::Barrel");
1062 auto tvTrtPosEC = makeTVol(trtPosEC,
"TRT::PositiveEndcap");
1066 cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
1068 cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
1069 auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
1074 cvh.createContainerTrackingVolume(gctx, {negEC,
barrel, posEC});
1079 auto containerBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1081 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1082 &
pixel->volumeBounds());
1083 std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
1085 if(!isSCTSmallerInZ) {
1087 auto posGap = cvh.createGapTrackingVolume(
1090 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1091 pixelBounds->get(CVBBV::eHalfLengthZ),
1092 containerBounds->get(CVBBV::eHalfLengthZ),
1095 "Pixel::PositiveGap");
1096 auto negGap = cvh.createGapTrackingVolume(
1099 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1100 -containerBounds->get(CVBBV::eHalfLengthZ),
1101 -pixelBounds->get(CVBBV::eHalfLengthZ),
1104 "Pixel::NegativeGap");
1106 auto pixelContainer =
1107 cvh.createContainerTrackingVolume(gctx, {negGap,
pixel, posGap});
1110 cvh.createContainerTrackingVolume(gctx, {pixelContainer,
container});
1140 std::shared_ptr<const Acts::CylinderVolumeHelper> cvh)
const {
1144 PVConstLink beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0);
1147 beamPipeTopVolume =
p_beamPipeMgr->getTreeTop(0)->getChildVol(0)->getChildVol(0);
1150 Acts::Transform3 beamPipeTransform;
1151 beamPipeTransform.setIdentity();
1153 beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1155 double beamPipeRadius = 20;
1157 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1158 const GeoTube* beamPipeTube =
nullptr;
1161 if (beamPipeLogVolume ==
nullptr) {
1163 throw std::runtime_error(
"Beam pip volume has no log volume");
1166 beamPipeTube =
dynamic_cast<const GeoTube*
>(beamPipeLogVolume->getShape());
1167 if (beamPipeTube ==
nullptr){
1169 throw std::runtime_error{
"BeamPipeLogVolume was not of type GeoTube"};
1172 for(
unsigned int i=0;i<beamPipeTopVolume->getNChildVols();i++) {
1174 if(beamPipeTopVolume->getNameOfChildVol(i) ==
"SectionC03"){
1176 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(i);
1177 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1178 const GeoTube* childTube =
nullptr;
1180 if (childLogVolume){
1181 childTube =
dynamic_cast<const GeoTube*
>(childLogVolume->getShape());
1183 beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1192 ATH_MSG_VERBOSE(
"BeamPipe constructed from Database: translation (yes) - radius "
1193 << ( beamPipeTube ?
"(yes)" :
"(no)") <<
" - r = " << beamPipeRadius );
1197 Acts::CylinderVolumeBuilder::Config cfg;
1199 Acts::PassiveLayerBuilder::Config bplConfig;
1200 bplConfig.layerIdentification =
"BeamPipe";
1201 bplConfig.centralLayerRadii = {beamPipeRadius * 1_mm};
1202 bplConfig.centralLayerHalflengthZ = {3000_mm};
1203 bplConfig.centralLayerThickness = {1_mm};
1204 auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
1208 cfg.trackingVolumeHelper = cvh;
1209 cfg.volumeName =
"BeamPipe";
1210 cfg.layerBuilder = beamPipeBuilder;
1211 cfg.layerEnvelopeR = {1_mm, 1_mm};
1212 cfg.buildToRadiusZero =
true;