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>
54 #include <Acts/Utilities/AxisDefinitions.hpp>
59 using namespace Acts::UnitLiterals;
64 m_detStore(
"StoreGateSvc/DetectorStore",
name),
76 return StatusCode::FAILURE;
83 m_autoRetrieveTools =
false;
84 m_checkToolDeps =
false;
87 << Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"."
88 << Acts::VersionPatch <<
" [" << Acts::CommitHash <<
"]");
93 ATH_MSG_INFO(
"Configured to build " << buildSubdet.size()
95 for (
const auto &
s : buildSubdet) {
100 if (buildSubdet.find(
"Pixel") != buildSubdet.end()) {
103 if (buildSubdet.find(
"SCT") != buildSubdet.end()) {
106 if (buildSubdet.find(
"TRT") != buildSubdet.end()) {
110 if (buildSubdet.find(
"ITkPixel") != buildSubdet.end()) {
113 if (buildSubdet.find(
"ITkStrip") != buildSubdet.end()) {
116 if (buildSubdet.find(
"HGTD") != buildSubdet.end()) {
128 ATH_MSG_FATAL(
"Consistency check for ITk inner pixel barrel passive layer construction failed. Please check your inputs! ");
129 return StatusCode::FAILURE;
134 ATH_MSG_FATAL(
"Consistency check for ITk outer pixel barrel passive layer construction failed. Please check your inputs! ");
135 return StatusCode::FAILURE;
140 ATH_MSG_FATAL(
"Consistency check for ITk strip barrel passive layer construction failed. Please check your inputs! ");
141 return StatusCode::FAILURE;
146 Acts::LayerArrayCreator::Config lacCfg;
147 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
150 Acts::TrackingVolumeArrayCreator::Config tvcCfg;
151 auto trackingVolumeArrayCreator =
152 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
155 Acts::CylinderVolumeHelper::Config cvhConfig;
156 cvhConfig.layerArrayCreator = layerArrayCreator;
157 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
159 auto cylinderVolumeHelper =
160 std::make_shared<const Acts::CylinderVolumeHelper>(
163 Acts::TrackingGeometryBuilder::Config tgbConfig;
164 tgbConfig.trackingVolumeHelper = cylinderVolumeHelper;
167 std::shared_ptr<const Acts::IMaterialDecorator> matDeco =
nullptr;
170 if (matFileFullPath.empty()) {
172 return StatusCode::FAILURE;
174 ATH_MSG_INFO(
"Configured to use material input: " << matFileFullPath);
176 if (matFileFullPath.find(
".json") != std::string::npos) {
178 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
180 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
183 tgbConfig.materialDecorator = matDeco;
186 std::array<double, 2> sctECEnvelopeZ{20_mm, 20_mm};
191 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
195 Acts::CylinderVolumeBuilder::Config bpvConfig =
198 Acts::CylinderVolumeBuilder beamPipeVolumeBuilder {
201 return beamPipeVolumeBuilder.trackingVolume(gctx, inner);
208 if (buildSubdet.count(
"Pixel") > 0) {
209 tgbConfig.trackingVolumeBuilders.push_back([&](
const auto &gctx,
214 auto lb = std::make_shared<ActsLayerBuilder>(
216 Acts::CylinderVolumeBuilder::Config cvbConfig;
217 cvbConfig.layerEnvelopeR = {3_mm, 3_mm};
218 cvbConfig.layerEnvelopeZ = 1_mm;
219 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
220 cvbConfig.volumeName =
"Pixel";
221 cvbConfig.layerBuilder =
lb;
224 Acts::CylinderVolumeBuilder cvb(
227 return cvb.trackingVolume(gctx, inner);
232 if (buildSubdet.count(
"ITkPixel") > 0) {
233 tgbConfig.trackingVolumeBuilders.push_back(
234 [&](
const auto &gctx,
const auto &inner,
const auto &) {
238 cfg.doEndcapLayerMerging =
true;
242 auto lb = std::make_shared<ActsLayerBuilder>(
245 Acts::CylinderVolumeBuilder::Config cvbConfig;
246 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
247 cvbConfig.layerEnvelopeZ = 1_mm;
248 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
249 cvbConfig.volumeName =
"ITkPixelInner";
250 cvbConfig.layerBuilder =
lb;
253 Acts::CylinderVolumeBuilder cvb(
257 return cvb.trackingVolume(gctx, inner);
260 tgbConfig.trackingVolumeBuilders.push_back(
261 [&](
const auto &gctx,
const auto &inner,
const auto &) {
265 cfg.doEndcapLayerMerging =
false;
269 auto lb = std::make_shared<ActsLayerBuilder>(
272 Acts::CylinderVolumeBuilder::Config cvbConfig;
273 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
274 cvbConfig.layerEnvelopeZ = 1_mm;
275 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
276 cvbConfig.volumeName =
"ITkPixelOuter";
277 cvbConfig.layerBuilder =
lb;
278 cvbConfig.buildToRadiusZero =
false;
279 cvbConfig.checkRingLayout =
true;
280 cvbConfig.ringTolerance = 10_mm;
282 Acts::CylinderVolumeBuilder cvb(
286 return cvb.trackingVolume(gctx, inner);
291 if (buildSubdet.count(
"ITkStrip") > 0) {
292 tgbConfig.trackingVolumeBuilders.push_back(
293 [&](
const auto &gctx,
const auto &inner,
const auto &) {
300 auto lb = std::make_shared<ActsLayerBuilder>(
303 Acts::CylinderVolumeBuilder::Config cvbConfig;
304 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
305 cvbConfig.layerEnvelopeZ = 1_mm;
306 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
307 cvbConfig.volumeName =
"ITkStrip";
308 cvbConfig.layerBuilder =
lb;
309 cvbConfig.buildToRadiusZero =
312 Acts::CylinderVolumeBuilder cvb(
316 return cvb.trackingVolume(gctx, inner);
320 bool buildSCT = buildSubdet.count(
"SCT") > 0;
321 bool buildTRT = buildSubdet.count(
"TRT") > 0;
323 if (buildSCT && buildTRT) {
325 tgbConfig.trackingVolumeBuilders.push_back(
326 [&](
const auto &gctx,
const auto &inner,
const auto &) {
329 cfg.endcapEnvelopeZ = sctECEnvelopeZ;
330 auto sct_lb = std::make_shared<ActsLayerBuilder>(
336 *cylinderVolumeHelper, inner);
339 }
else if (buildSCT) {
340 tgbConfig.trackingVolumeBuilders.push_back(
341 [&](
const auto &gctx,
const auto &inner,
const auto &) {
344 lbCfg.endcapEnvelopeZ = sctECEnvelopeZ;
345 auto lb = std::make_shared<ActsLayerBuilder>(
349 Acts::CylinderVolumeBuilder::Config cvbConfig;
350 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
351 cvbConfig.layerEnvelopeZ = 2_mm;
352 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
353 cvbConfig.volumeName =
"SCT";
354 cvbConfig.layerBuilder =
lb;
355 cvbConfig.buildToRadiusZero =
false;
357 Acts::CylinderVolumeBuilder cvb(
361 return cvb.trackingVolume(gctx, inner);
363 }
else if (buildTRT) {
364 tgbConfig.trackingVolumeBuilders.push_back(
365 [&](
const auto &gctx,
const auto &inner,
const auto &) {
367 Acts::CylinderVolumeBuilder::Config cvbConfig;
368 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
369 cvbConfig.layerEnvelopeZ = 2_mm;
370 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
371 cvbConfig.volumeName =
"TRT";
372 cvbConfig.layerBuilder =
lb;
373 cvbConfig.buildToRadiusZero =
false;
375 Acts::CylinderVolumeBuilder cvb(
379 return cvb.trackingVolume(gctx, inner);
384 if(buildSubdet.count(
"HGTD") > 0) {
385 tgbConfig.trackingVolumeBuilders.push_back(
386 [&](
const auto &gctx,
const auto &inner,
const auto &) {
388 Acts::CylinderVolumeBuilder::Config cvbConfig;
389 cvbConfig.layerEnvelopeR = {5_mm, 5_mm};
390 cvbConfig.layerEnvelopeZ = 1_mm;
391 cvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
392 cvbConfig.volumeName =
"HGTD";
393 cvbConfig.layerBuilder =
lb;
394 cvbConfig.buildToRadiusZero =
false;
396 Acts::CylinderVolumeBuilder cvb(
400 return cvb.trackingVolume(gctx, inner);
405 if (buildSubdet.count(
"Calo") > 0) {
406 tgbConfig.trackingVolumeBuilders.push_back(
407 [&](
const auto &gctx,
const auto &inner,
const auto &) {
412 ATH_MSG_ERROR(
"Encountered error when building Acts tracking geometry");
414 return StatusCode::FAILURE;
417 auto trackingGeometryBuilder =
418 std::make_shared<const Acts::TrackingGeometryBuilder>(
427 ATH_MSG_ERROR(
"No ACTS tracking geometry was built. Cannot proceeed");
428 return StatusCode::FAILURE;
433 ATH_MSG_INFO(
"Running extra consistency check! (this is SLOW)");
435 ATH_MSG_ERROR(
"Consistency check has failed! Geometry is not consistent");
436 return StatusCode::FAILURE;
440 ATH_MSG_INFO(
"Acts TrackingGeometry construction completed");
442 return StatusCode::SUCCESS;
448 std::vector<Acts::Vector2> localPoints;
451 std::uniform_real_distribution<> dist(0.0, 1.0);
453 std::optional<std::ofstream>
os;
457 throw std::runtime_error{
"Failed to open consistency check output file"};
462 (*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;
465 localPoints.emplace_back(dist(
gen), dist(
gen));
470 size_t nTotalSensors = 0;
471 std::array<size_t,3> nInconsistent{0,0,0};
472 size_t nMismatchedCenters = 0;
473 size_t nMismatchedNormals = 0;
477 auto isApprox = [](
auto&
a,
auto&
b) ->
bool {
478 return ((
a -
b).array().abs() < 1
e-5).
all();
484 const auto* actsDetElem =
dynamic_cast<const ActsDetectorElement*
>(surface->associatedDetectorElement());
485 if(actsDetElem ==
nullptr) {
491 if(siDetElem ==
nullptr) {
495 const auto* regSurface =
dynamic_cast<const Acts::RegularSurface*
>(surface);
496 const auto& trkSurface = siDetElem->
surface();
497 if(regSurface ==
nullptr) {
503 Acts::Vector3 center{regSurface->center(gctx)};
505 if (
dynamic_cast<const Acts::AnnulusBounds *
>(&surface->bounds()))
510 center.head<2>() = trkCenter.head<2>();
513 if(!isApprox(trkCenter, center)) {
515 if (
auto idHelper = siDetElem->getIdHelper())
517 trkName = idHelper->show_to_string(siDetElem->identify());
520 << surface->geometryId()
521 <<
" center (" << center[0] <<
',' << center[1] <<
',' << center[2]
522 <<
") does not match Trk surface " << trkName
523 <<
" center (" << trkCenter[0] <<
',' << trkCenter[1] <<
',' << trkCenter[2] <<
')');
524 nMismatchedCenters++;
528 const auto* lineSurface =
dynamic_cast<const Acts::LineSurface*
>(surface);
529 if(lineSurface ==
nullptr) {
530 Acts::Vector3
norm{regSurface->normal(gctx, regSurface->center(gctx))};
532 if(!isApprox(trkNorm,
norm)) {
534 if (
auto idHelper = siDetElem->getIdHelper())
536 trkName = idHelper->show_to_string(siDetElem->identify());
539 << surface->geometryId()
540 <<
" normal (" <<
norm[0] <<
',' <<
norm[1] <<
',' <<
norm[2]
541 <<
") does not match Trk surface " << trkName
542 <<
" normal (" << trkNorm[0] <<
',' << trkNorm[1] <<
',' << trkNorm[2] <<
')');
543 nMismatchedNormals++;
548 auto doPoints = [&](
unsigned int type,
const Acts::Vector2& loc) -> std::array<bool,3> {
554 bool locg2lOk =
false;
555 auto locTrkRes = trkSurface.globalToLocal(glb);
557 locTrk = locTrkRes.value();
558 glbTrk = trkSurface.localToGlobal(locTrk);
561 if (locg2lRes.ok()) {
563 locg2l = locg2lRes.value();
567 auto gId = surface->geometryId();
570 <<
"," << gId.volume()
571 <<
"," << gId.layer()
572 <<
"," << gId.sensitive()
576 <<
"," << surface->insideBounds(loc)
579 <<
"," << trkSurface.insideBounds(locTrk)
591 return {surface->insideBounds(loc) == trkSurface.insideBounds(locTrk),
592 locg2lOk ? isApprox(loc, locg2l) :
true,
593 locTrkRes ? isApprox(glb, glbTrk) :
true};
599 std::array<bool,3> allOk{
true,
true,
true};
600 if(
const auto* bounds =
dynamic_cast<const Acts::PlanarBounds*
>(&surface->bounds()); bounds) {
603 const Acts::RectangleBounds& boundingBox = bounds->boundingBox();
604 Acts::Vector2
min = boundingBox.min().array() - envelope;
605 Acts::Vector2
max = boundingBox.max().array() + envelope;
606 Acts::Vector2 diag =
max -
min;
608 for(
const auto& testPoint : localPoints) {
609 Acts::Vector2 loc =
min.array() + (testPoint.array() * diag.array());
610 auto pointOk = doPoints(0, loc);
611 for (
size_t i=0;
i<pointOk.size(); ++
i) {
620 else if(
const auto* bounds =
dynamic_cast<const Acts::AnnulusBounds*
>(&surface->bounds()); bounds) {
624 std::vector<Acts::Vector2> vertices = bounds->vertices(5);
626 Acts::Vector2
max{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()};
627 for (
const auto& vtx : vertices) {
628 min =
min.array().min(vtx.array());
629 max =
max.array().max(vtx.array());
631 min.array() -= envelope;
632 max.array() += envelope;
633 Acts::Vector2 diag =
max -
min;
635 for(
const auto& testPoint : localPoints) {
636 Acts::Vector2 locXY =
min.array() + (testPoint.array() * diag.array());
637 Acts::Vector2 locPC =
dynamic_cast<const Acts::DiscSurface&
>(*surface).localCartesianToPolar(locXY);
639 auto pointOk = doPoints(1, locPC);
640 for (
size_t i=0;
i<pointOk.size(); ++
i) {
653 for (
size_t i=0;
i<allOk.size(); ++
i) {
661 ATH_MSG_INFO(
"Total number of sensors : " << nTotalSensors);
662 ATH_MSG_INFO(
"Number of sensors with mismatched centers : " << nMismatchedCenters);
663 ATH_MSG_INFO(
"Number of sensors with mismatched normals : " << nMismatchedNormals);
664 ATH_MSG_INFO(
"Number of sensors with inconsistent inside: " << nInconsistent[0]);
665 ATH_MSG_INFO(
"Number of sensors with inconsistent g2l : " << nInconsistent[1]);
666 ATH_MSG_INFO(
"Number of sensors with inconsistent l2g : " << nInconsistent[2]);
671 std::shared_ptr<const Acts::TrackingGeometry>
678 std::shared_ptr<const Acts::ILayerBuilder>
682 std::string managerName =
manager->getName();
683 auto matcher = [](
const Acts::GeometryContext & ,
684 Acts::AxisDirection ,
const Acts::Surface * ,
685 const Acts::Surface *
686 ) ->
bool {
return false; };
688 Acts::SurfaceArrayCreator::Config sacCfg;
689 sacCfg.surfaceMatcher = matcher;
690 sacCfg.doPhiBinningOptimization =
false;
692 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
695 Acts::LayerCreator::Config lcCfg;
696 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
697 auto layerCreator = std::make_shared<Acts::LayerCreator>(
703 cfg.layerCreator = layerCreator;
705 return std::make_shared<const ActsStrawLayerBuilder>(
709 std::shared_ptr<const Acts::ILayerBuilder>
713 std::string managerName =
manager->getName();
714 auto matcher = [](
const Acts::GeometryContext & ,
715 Acts::AxisDirection ,
const Acts::Surface * ,
716 const Acts::Surface *
717 ) ->
bool {
return false; };
719 Acts::SurfaceArrayCreator::Config sacCfg;
720 sacCfg.surfaceMatcher = matcher;
721 sacCfg.doPhiBinningOptimization =
false;
723 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
726 Acts::LayerCreator::Config lcCfg;
727 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
728 auto layerCreator = std::make_shared<Acts::LayerCreator>(
734 cfg.layerCreator = layerCreator;
736 return std::make_shared<const ActsHGTDLayerBuilder>(
742 using enum Acts::AxisDirection;
744 std::string managerName =
manager->getName();
746 std::shared_ptr<const Acts::ILayerBuilder> gmLayerBuilder;
747 auto matcher = [](
const Acts::GeometryContext & ,
748 Acts::AxisDirection aDir,
const Acts::Surface *aS,
749 const Acts::Surface *bS) ->
bool {
751 aS->associatedDetectorElement());
753 bS->associatedDetectorElement());
754 if ((not
a) or (not
b)) {
755 throw std::runtime_error(
756 "Cast of surface associated element to ActsDetectorElement failed "
757 "in ActsTrackingGeometrySvc::makeVolumeBuilder");
765 if (idA.
bec() != idB.
bec())
768 if (aDir == AxisPhi) {
787 Acts::SurfaceArrayCreator::Config sacCfg;
788 sacCfg.surfaceMatcher = matcher;
790 auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
793 Acts::LayerCreator::Config lcCfg;
794 lcCfg.surfaceArrayCreator = surfaceArrayCreator;
795 auto layerCreator = std::make_shared<Acts::LayerCreator>(
799 cfg.surfaceMatcher = matcher;
803 throw std::invalid_argument(
"Number of barrel material bin counts != 2");
806 cfg.barrelMaterialBins = {brlBins.at(0), brlBins.at(1)};
809 throw std::invalid_argument(
"Number of endcap material bin counts != 2");
812 cfg.endcapMaterialBins = {ecBins.at(0), ecBins.at(1)};
817 cfg.layerCreator = layerCreator;
827 std::shared_ptr<Acts::TrackingVolume>
829 const Acts::GeometryContext &gctx,
const Acts::ILayerBuilder &sct_lb,
830 const Acts::ILayerBuilder &trt_lb,
const Acts::CylinderVolumeHelper &cvh,
831 const std::shared_ptr<const Acts::TrackingVolume> &pixel) {
834 Acts::CylinderVolumeBuilder::Config cvbCfg;
835 Acts::CylinderVolumeBuilder cvb(
839 Acts::VolumeConfig sctNegEC =
840 cvb.analyzeContent(gctx, sct_lb.negativeLayers(gctx), {});
842 Acts::VolumeConfig sctPosEC =
843 cvb.analyzeContent(gctx, sct_lb.positiveLayers(gctx), {});
845 Acts::VolumeConfig sctBrl =
846 cvb.analyzeContent(gctx, sct_lb.centralLayers(gctx), {});
849 Acts::VolumeConfig trtNegEC =
850 cvb.analyzeContent(gctx, trt_lb.negativeLayers(gctx), {});
852 Acts::VolumeConfig trtPosEC =
853 cvb.analyzeContent(gctx, trt_lb.positiveLayers(gctx), {});
855 Acts::VolumeConfig trtBrl =
856 cvb.analyzeContent(gctx, trt_lb.centralLayers(gctx), {});
860 double absZMinEC =
std::min(std::abs(trtNegEC.zMax), std::abs(trtPosEC.zMin));
861 double absZMaxEC =
std::max(std::abs(trtNegEC.zMin), std::abs(trtPosEC.zMax));
863 trtNegEC.zMin = -absZMaxEC;
864 trtNegEC.zMax = -absZMinEC;
865 trtPosEC.zMin = absZMinEC;
866 trtPosEC.zMax = absZMaxEC;
868 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
871 bool isSCTSmallerInZ =
false;
873 ATH_MSG_VERBOSE(
"Shrinking SCT in R (and maybe in increase size in Z) to fit around Pixel");
874 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
875 &
pixel->volumeBounds());
876 double sctNegECzMin =
std::min(sctNegEC.zMin, -pixelBounds->get(CVBBV::eHalfLengthZ));
877 double sctPosECzMax =
std::max(sctPosEC.zMax, pixelBounds->get(CVBBV::eHalfLengthZ));
879 ATH_MSG_VERBOSE(
"- SCT +-EC.rMin: " << sctNegEC.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
880 ATH_MSG_VERBOSE(
"- SCT BRL.rMin: " << sctBrl.rMin <<
" -> " << pixelBounds->get(CVBBV::eMaxR));
881 ATH_MSG_VERBOSE(
"- SCT EC.zMin: " << sctNegEC.zMin <<
" -> " << sctNegECzMin);
882 ATH_MSG_VERBOSE(
"- SCT EC.zMax: " << sctPosEC.zMax <<
" -> " << sctPosECzMax);
884 sctNegEC.rMin = pixelBounds->get(CVBBV::eMaxR);
885 sctPosEC.rMin = pixelBounds->get(CVBBV::eMaxR);
886 sctBrl.rMin = pixelBounds->get(CVBBV::eMaxR);
888 isSCTSmallerInZ = sctPosEC.zMax < pixelBounds->get(CVBBV::eHalfLengthZ);
890 sctNegEC.zMin = sctNegECzMin;
891 sctPosEC.zMax = sctPosECzMax;
901 << sctNegEC.toString());
902 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
903 << sctBrl.toString());
906 << sctPosEC.toString());
911 << trtNegEC.toString());
912 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
913 << trtBrl.toString());
916 << trtPosEC.toString());
920 sctBrl.zMax = (sctBrl.zMax + sctPosEC.zMin) / 2.;
921 sctBrl.zMin = -sctBrl.zMax;
925 trtBrl.zMin = sctBrl.zMin;
926 trtBrl.zMax = sctBrl.zMax;
929 trtNegEC.zMin = sctNegEC.zMin;
930 trtPosEC.zMax = sctPosEC.zMax;
933 trtNegEC.zMax = trtBrl.zMin;
934 sctNegEC.zMax = trtBrl.zMin;
935 trtPosEC.zMin = trtBrl.zMax;
936 sctPosEC.zMin = trtBrl.zMax;
939 sctBrl.rMax = trtBrl.rMin;
940 sctNegEC.rMax = trtNegEC.rMin;
941 sctPosEC.rMax = trtPosEC.rMin;
944 trtNegEC.rMax = trtBrl.rMax;
945 trtPosEC.rMax = trtBrl.rMax;
947 ATH_MSG_VERBOSE(
"Dimensions after synchronization between SCT and TRT");
951 << sctNegEC.toString());
952 ATH_MSG_VERBOSE(
"- SCT::Barrel: " << sctBrl.layers.size() <<
" layers, "
953 << sctBrl.toString());
956 << sctPosEC.toString());
961 << trtNegEC.toString());
962 ATH_MSG_VERBOSE(
"- TRT::Barrel: " << trtBrl.layers.size() <<
" layers, "
963 << trtBrl.toString());
966 << trtPosEC.toString());
968 auto makeTVol = [&](
const auto &vConf,
const auto &
name) {
969 return cvh.createTrackingVolume(gctx, vConf.layers, {},
971 vConf.rMin, vConf.rMax, vConf.zMin,
976 auto tvSctNegEC = makeTVol(sctNegEC,
"SCT::NegativeEndcap");
977 auto tvSctBrl = makeTVol(sctBrl,
"SCT::Barrel");
978 auto tvSctPosEC = makeTVol(sctPosEC,
"SCT::PositiveEndcap");
980 auto tvTrtNegEC = makeTVol(trtNegEC,
"TRT::NegativeEndcap");
981 auto tvTrtBrl = makeTVol(trtBrl,
"TRT::Barrel");
982 auto tvTrtPosEC = makeTVol(trtPosEC,
"TRT::PositiveEndcap");
986 cvh.createContainerTrackingVolume(gctx, {tvSctNegEC, tvTrtNegEC});
988 cvh.createContainerTrackingVolume(gctx, {tvSctPosEC, tvTrtPosEC});
989 auto barrel = cvh.createContainerTrackingVolume(gctx, {tvSctBrl, tvTrtBrl});
994 cvh.createContainerTrackingVolume(gctx, {negEC,
barrel, posEC});
999 auto containerBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1000 &container->volumeBounds());
1001 auto pixelBounds =
dynamic_cast<const Acts::CylinderVolumeBounds *
>(
1002 &
pixel->volumeBounds());
1003 std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
1005 if(!isSCTSmallerInZ) {
1007 auto posGap = cvh.createGapTrackingVolume(
1010 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1011 pixelBounds->get(CVBBV::eHalfLengthZ),
1012 containerBounds->get(CVBBV::eHalfLengthZ),
1015 "Pixel::PositiveGap");
1016 auto negGap = cvh.createGapTrackingVolume(
1019 pixelBounds->get(CVBBV::eMinR), pixelBounds->get(CVBBV::eMaxR),
1020 -containerBounds->get(CVBBV::eHalfLengthZ),
1021 -pixelBounds->get(CVBBV::eHalfLengthZ),
1024 "Pixel::NegativeGap");
1027 cvh.createContainerTrackingVolume(gctx, {negGap,
pixel, posGap});
1030 cvh.createContainerTrackingVolume(gctx, {
pixelContainer, container});
1035 cvh.createContainerTrackingVolume(gctx, {
pixel, container});
1044 ATH_MSG_DEBUG(
"Populate the alignment store with all detector elements");
1045 unsigned int nElements = 0;
1047 const Acts::DetectorElementBase *detElem = srf->associatedDetectorElement();
1051 ATH_MSG_DEBUG(
"Populated with " << nElements <<
" elements");
1056 Acts::CylinderVolumeBuilder::Config
1058 std::shared_ptr<const Acts::CylinderVolumeHelper> cvh)
const {
1068 Acts::Transform3 beamPipeTransform;
1069 beamPipeTransform.setIdentity();
1071 beamPipeTransform = Acts::Translation3(beamPipeTopVolume->getX().translation());
1073 double beamPipeRadius = 20;
1075 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
1076 const GeoTube* beamPipeTube =
nullptr;
1079 if (beamPipeLogVolume ==
nullptr) {
1081 throw std::runtime_error(
"Beam pip volume has no log volume");
1084 beamPipeTube =
dynamic_cast<const GeoTube*
>(beamPipeLogVolume->getShape());
1085 if (beamPipeTube ==
nullptr){
1087 throw std::runtime_error{
"BeamPipeLogVolume was not of type GeoTube"};
1090 for(
unsigned int i=0;
i<beamPipeTopVolume->getNChildVols();
i++) {
1092 if(beamPipeTopVolume->getNameOfChildVol(
i) ==
"SectionC03"){
1094 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(
i);
1095 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
1096 const GeoTube* childTube =
nullptr;
1098 if (childLogVolume){
1099 childTube =
dynamic_cast<const GeoTube*
>(childLogVolume->getShape());
1101 beamPipeRadius = 0.5 * (childTube->getRMax()+childTube->getRMin());
1110 ATH_MSG_VERBOSE(
"BeamPipe constructed from Database: translation (yes) - radius "
1111 << ( beamPipeTube ?
"(yes)" :
"(no)") <<
" - r = " << beamPipeRadius );
1115 Acts::CylinderVolumeBuilder::Config
cfg;
1117 Acts::PassiveLayerBuilder::Config bplConfig;
1118 bplConfig.layerIdentification =
"BeamPipe";
1119 bplConfig.centralLayerRadii = {beamPipeRadius * 1_mm};
1120 bplConfig.centralLayerHalflengthZ = {3000_mm};
1121 bplConfig.centralLayerThickness = {1_mm};
1122 auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
1126 cfg.trackingVolumeHelper = cvh;
1127 cfg.volumeName =
"BeamPipe";
1128 cfg.layerBuilder = beamPipeBuilder;
1129 cfg.layerEnvelopeR = {1_mm, 1_mm};
1130 cfg.buildToRadiusZero =
true;