7#include "Acts/Geometry/Blueprint.hpp"
8#include "Acts/Geometry/PortalShell.hpp"
9#include "Acts/Geometry/Volume.hpp"
10#include "Acts/Geometry/StaticBlueprintNode.hpp"
11#include "Acts/Geometry/GeometryIdentifierBlueprintNode.hpp"
12#include <Acts/Navigation/SurfaceArrayNavigationPolicy.hpp>
13#include <Acts/Navigation/TryAllNavigationPolicy.hpp>
14#include <Acts/Utilities/AxisDefinitions.hpp>
15#include <Acts/Geometry/ContainerBlueprintNode.hpp>
16#include <Acts/Geometry/Extent.hpp>
17#include <Acts/Definitions/Units.hpp>
18#include <Acts/Geometry/LayerBlueprintNode.hpp>
19#include <Acts/Geometry/VolumeResizeStrategy.hpp>
20#include <Acts/Geometry/VolumeAttachmentStrategy.hpp>
21#include <Acts/Geometry/TrackingVolume.hpp>
22#include <Acts/Geometry/CylinderVolumeBounds.hpp>
26#include <Acts/Surfaces/SurfaceArray.hpp>
31using namespace Acts::UnitLiterals;
37 constexpr std::size_t s_caloBarrelId = 40;
46 return StatusCode::SUCCESS;
50 std::shared_ptr<BlueprintNode>&& childNode) {
53 std::map<caloRegion, caloSampleSurfaceMap_t> caloRegionSampleSurfaceMap;
54 std::map<caloRegion, caloSampleDDEElementsMap_t> caloRegionSampleDDEElementsMap;
56 fillMaps(caloRegionSampleSurfaceMap, caloRegionSampleDDEElementsMap);
71 ATH_MSG_DEBUG(
"Have generated calorimeter cylindrical surfaces");
78 auto itkCaloNode = std::make_shared<StaticBlueprintNode>(
79 std::make_unique<TrackingVolume>(Transform3::Identity(),
80 std::make_shared<CylinderVolumeBounds>(0.,
81 caloDimensionMap[
"CaloMaxR"] + 2.0,
82 caloDimensionMap[
"CaloHalfLengthZ"] + 2.0),
"ITkCalo"));
84 if (childNode) itkCaloNode->addChild(std::move(childNode));
88 auto caloNode = std::make_shared<CylinderContainerBlueprintNode>(
"CaloNode", AxisDirection::AxisZ);
89 CylinderContainerBlueprintNode& caloBarrelCylinderNode = caloNode->addCylinderContainer(
"CaloBarrelCylinders", AxisDirection::AxisR);
90 caloBarrelCylinderNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
91 caloBarrelCylinderNode.setResizeStrategy(ResizeStrategy::Gap);
96 std::vector<std::string> caloBarrelCylindricalLayerNames = {
"PreSamplerB",
"EMB1",
"EMB2",
"EMB3",
"TileBar0",
"TileBar1",
"TileBar2"};
97 for (
unsigned int sampleIndex = 0; sampleIndex < caloBarrelCylindricalLayerNames.size(); ++sampleIndex) {
98 auto& sampleName = caloBarrelCylindricalLayerNames.at(sampleIndex);
102 CylinderContainerBlueprintNode& caloEndCapDiscNegativeZNode = caloNode->addCylinderContainer(
"CaloEndCapDiscNegativeZ", AxisDirection::AxisZ);
103 caloEndCapDiscNegativeZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
104 caloEndCapDiscNegativeZNode.setResizeStrategy(ResizeStrategy::Gap);
106 CylinderContainerBlueprintNode& caloEndCapDiscPositiveZNode = caloNode->addCylinderContainer(
"CaloEndCapDiscPositiveZ", AxisDirection::AxisZ);
107 caloEndCapDiscPositiveZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
108 caloEndCapDiscPositiveZNode.setResizeStrategy(ResizeStrategy::Gap);
116 ATH_MSG_DEBUG(
"Have added all Barrel layers to caloBarrelCylinderNode");
119 itkCaloNode->addChild(caloNode);
127 return StatusCode::SUCCESS;
131 std::map<caloRegion, caloSampleDDEElementsMap_t>& caloRegionSampleDDEElementsMap)
const {
145 caloRegionSampleSurfaceMap[
caloRegion::Global][currentSample] = std::vector<std::shared_ptr<Surface> >();
146 caloRegionSampleDDEElementsMap[
caloRegion::Global][currentSample] = std::vector<const CaloDetDescrElement*>();
167 if (theDDE->z() < 0.0) {
177 auto sortAllLayersInZ = [&caloRegionSampleDDEElementsMap](
const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList) {
178 for (
const auto & currentSample : caloSampleList) {
179 std::vector<const CaloDetDescrElement*> currentElements = caloRegionSampleDDEElementsMap[
caloRegion::Global][currentSample];
181 caloRegionSampleDDEElementsMap[
caloRegion::Global][currentSample] = std::move(currentElements);
188 auto sortAllLayersInR = [&caloRegionSampleDDEElementsMap](
const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList,
const caloRegion& region) {
189 for (
const auto& currentSample : caloSampleList) {
190 std::vector<const CaloDetDescrElement*> currentElements = caloRegionSampleDDEElementsMap[region][currentSample];
192 caloRegionSampleDDEElementsMap[region][currentSample] = std::move(currentElements);
206 std::vector<const CaloDetDescrElement*> currentElements = caloSampleDDEElementsMap[currentSample];
208 double maxLArBRadius = 0.0, minLArBRadius = std::numeric_limits<double>::max();
209 double lowZLarB = 0.0, highZLarB = 0.0;
214 double totalRadiusFixedPhi = 0.0;
215 bool firstCellInPhiRing =
true;
216 unsigned int phiCounter = 0;
220 bool firstPhiRing =
true;
221 double initialRadius = 0.0;
222 double initialZ = -std::numeric_limits<double>::max();
226 double z = theDDE->z();
227 double radius = theDDE->r();
231 if (firstCellInPhiRing) {
232 ATH_MSG_DEBUG(
"First Cell in phi ring " << currentSample.first <<
" has z = " <<
z <<
" and r = " << radius);
234 firstCellInPhiRing =
false;
238 ATH_MSG_DEBUG(
"First Cell in layer " << currentSample.first <<
" has z = " <<
z <<
" and r = " << radius);
239 initialRadius = theDDE->r();
240 firstPhiRing =
false;
248 if (std::abs(
z - initialZ) < 0.0001) {
249 ATH_MSG_DEBUG(
"phiCounter is " << phiCounter <<
" and radius is " << radius <<
" and totalRadiusFixedPhi is " << totalRadiusFixedPhi <<
" and hash is " << theDDE->calo_hash());
250 totalRadiusFixedPhi += radius;
255 firstCellInPhiRing =
true;
256 if (phiCounter > 0) {
257 double cellRingRadius = totalRadiusFixedPhi / phiCounter;
258 totalRadiusFixedPhi = 0.0;
261 if (cellRingRadius > maxLArBRadius) maxLArBRadius = radius;
262 if (cellRingRadius < minLArBRadius) minLArBRadius = radius;
267 ATH_MSG_DEBUG(
"Values of cellRingRadius, initialRadius, highZLarB and lowZLarB are " << cellRingRadius <<
", " << initialRadius <<
", " << highZLarB <<
" and " << lowZLarB);
268 if (std::abs(cellRingRadius - initialRadius) >
m_radiusTolerance && highZLarB - lowZLarB > 0.0) {
269 ATH_MSG_DEBUG(
"CYLINDER: Create cylinder for layer " << currentSample.first);
270 ATH_MSG_DEBUG(
"CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius <<
" " << maxLArBRadius);
271 ATH_MSG_DEBUG(
"CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB <<
" " << highZLarB);
273 caloSampleSurfaceMap[currentSample].push_back(
generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB));
278 minLArBRadius = std::numeric_limits<double>::max();
288 if (0 == caloSampleSurfaceMap[currentSample].
size()){
289 ATH_MSG_DEBUG(
"CYLINDER: Zero size Vector: Create cylinder for layer " << currentSample.first);
290 ATH_MSG_DEBUG(
"CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius <<
" " << maxLArBRadius);
291 ATH_MSG_DEBUG(
"CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB <<
" " << highZLarB);
292 caloSampleSurfaceMap[currentSample].push_back(
generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB));
300 double LArBRadius = (maxLArBRadius + minLArBRadius) / 2.0;
301 double LArBLength = std::abs(highZLarB - lowZLarB);
303 ATH_MSG_DEBUG(
"Cylinder radius and length are " << LArBRadius <<
" and " << LArBLength);
305 auto surface = Surface::makeShared<CylinderSurface>(Transform3::Identity(), LArBRadius, LArBLength/2);
315 const std::vector<const CaloDetDescrElement*> & currentElements = caloSampleDDEElementsMap[currentSample];
317 double totalZFixedPhi = 0.0;
318 bool firstCellInPhiRing =
true;
319 unsigned int phiCounter = 0;
321 bool firstPhiRing =
true;
322 double initialRadius = 0.0;
323 double initialZ = -std::numeric_limits<double>::max();
328 double minDiscRadius = std::numeric_limits<double>::max(), maxDiscRadius = 0.0;
330 unsigned int currentElementsSize = currentElements.size();
331 unsigned int DDECounter = 0;
335 bool isLastDDE = (DDECounter == (currentElementsSize-1));
337 ATH_MSG_DEBUG(
"Disc DDE with sampling, r and z of " << currentSample <<
", " << theDDE->r() <<
", " << theDDE->z());
340 double z = theDDE->z();
341 double radius = theDDE->r();
343 if (firstCellInPhiRing) {
344 initialRadius = radius;
345 firstCellInPhiRing =
false;
350 firstPhiRing =
false;
351 minDiscRadius = radius;
356 if (std::abs(radius - initialRadius) < 0.0001 && !isLastDDE) {
363 firstCellInPhiRing =
true;
364 if (phiCounter > 0) {
365 double cellRingZ = totalZFixedPhi / phiCounter;
366 totalZFixedPhi = 0.0;
372 maxDiscRadius = radius;
374 if (std::abs(cellRingZ - initialZ) >
m_zTolerance || isLastDDE) {
375 ATH_MSG_DEBUG(
"DISC: About to create disc surface for sampling " << currentSample);
376 caloSampleSurfaceMap[currentSample].push_back(
generateDiscSurface(cellRingZ,maxDiscRadius, minDiscRadius));
379 minDiscRadius = std::numeric_limits<double>::max();
393 ATH_MSG_DEBUG(
"DISC: Disc min and max radius are " << minLArBRadius <<
" and " << maxLArBRadius <<
" with z of " <<
z);
395 auto transform = Acts::Transform3(Acts::Translation3(0.0,0.0,
z));
396 auto surface = Surface::makeShared<DiscSurface>(transform, minLArBRadius, maxLArBRadius);
407 double minR = std::numeric_limits<double>::max();
409 double minZ = std::numeric_limits<double>::max();
410 double maxZ = -std::numeric_limits<double>::max();
413 auto checkMinR = [&minR](
const CaloDetDescrElement* theDDE){
double r = theDDE->r();
if (
r < minR) minR =
r;};
414 auto checkMaxR = [&maxR](
const CaloDetDescrElement* theDDE){
double r = theDDE->r();
if (
r > maxR) maxR =
r;};
415 auto checkMinMaxZ = [&minZ,&maxZ](
const CaloDetDescrElement* theDDE){
double z = theDDE->z();
if (
z > maxZ) maxZ =
z;
if (
z < minZ) minZ =
z;};
416 auto calcHalfLengthZ = [&minZ, &maxZ](){
return (maxZ - minZ) / 2.0;};
419 for (
const CaloDetDescrElement* theDDE : caloSampleDDEElementsMap.at({getSampleName(CaloCell_ID::PreSamplerB), CaloCell_ID::PreSamplerB})) checkMinR(theDDE);
422 for (
auto& currentSample : std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>{{
"TileBar2", CaloCell_ID::TileBar2}, {
"TileGap2", CaloCell_ID::TileGap2}, {
"TileExt2", CaloCell_ID::TileExt2}}) {
423 for (
const CaloDetDescrElement* theDDE : caloSampleDDEElementsMap.at(currentSample)) checkMaxR(theDDE);
427 ATH_MSG_DEBUG(
"Max R in TileBar2, TileGap2 and TileExt2 is " << maxR);
429 caloDimensionsMap[
"CaloMinR"] = minR;
430 caloDimensionsMap[
"CaloMaxR"] = maxR;
434 for (
const CaloDetDescrElement* theDDE : caloSampleDDEElementsMap.at(currentSample)) checkMinMaxZ(theDDE);
437 caloDimensionsMap[
"CaloMinZ"] = minZ;
438 caloDimensionsMap[
"CaloMaxZ"] = maxZ;
440 double halfLengthZ = calcHalfLengthZ();
441 ATH_MSG_DEBUG(
"Half length in Z for entire barrel is " << halfLengthZ);
442 caloDimensionsMap[
"CaloHalfLengthZ"] = halfLengthZ;
449 Acts::Experimental::GeometryIdentifierBlueprintNode& geoIdNode = containerNode.withGeometryIdentifier();
450 geoIdNode.setAllVolumeIdsTo(s_caloBarrelId +
453 AxisDirection axis = AxisDirection::AxisZ;
454 if (isDisc) axis = AxisDirection::AxisR;
455 CylinderContainerBlueprintNode& cylinder = geoIdNode.addCylinderContainer(volumeName,
458 cylinder.addLayer(volumeName +
"_Layer", [&](
auto& layer) {
459 layer.setSurfaces(surfaces);
460 layer.setEnvelope(Acts::ExtentEnvelope{{
461 .z = {0.1_mm, 0.1_mm},
Acts::VolumeResizeStrategy ResizeStrategy
Acts::VolumeAttachmentStrategy AttachmentStrategy
std::map< std::string, double > caloDimensionMap_t
std::map< std::pair< std::string, CaloCell_ID::CaloSample >, std::vector< std::shared_ptr< Acts::Surface > > > caloSampleSurfaceMap_t
std::map< std::pair< std::string, CaloCell_ID::CaloSample >, std::vector< const CaloDetDescrElement * > > caloSampleDDEElementsMap_t
std::unique_ptr< CaloDetDescrManager > buildCaloDetDescrNoAlign(ISvcLocator *svcLocator, IMessageSvc *msgSvc)
size_t size() const
Number of registered mappings.
void fillMaps(std::map< caloRegion, caloSampleSurfaceMap_t > &caloRegionSampleSurfaceMap, std::map< caloRegion, caloSampleDDEElementsMap_t > &caloRegionSampleDDEElementsMap) const
fillMaps fills two maps.
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloDiscSampleList
std::string getSampleName(CaloCell_ID::CaloSample currentSample) const
void fillCaloDimensionsMap(caloDimensionMap_t &caloDimensionsMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap) const
fillCaloDimensionsMap fills a map of calorimeter dimensions for each sampling layer.
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloCylinderSampleList
Gaudi::Property< double > m_radiusTolerance
void generateCylinderSurfaces(caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap) const
generateCylinderSurfaces generates cylindrical surfaces for each calo sampling.
std::shared_ptr< Acts::CylinderSurface > generateCylinderSurface(const double &maxLArBRadius, const double &minLArBRadius, const double &lowZLarB, const double &highZLarB) const
generateCylinderSurface generates a cylindrical surface for a given set of parameters.
void addCylindricalTrackingVolumeToCaloNode(Acts::Experimental::CylinderContainerBlueprintNode &containerNode, const std::string &volumeName, const std::vector< std::shared_ptr< Acts::Surface > > &surfaces, int layerIndex, const bool &isDisc) const
addCylindricalTrackingVolumeToCaloNode adds a cylindrical tracking volume to the calo node.
StatusCode initialize() override
std::shared_ptr< Acts::DiscSurface > generateDiscSurface(const double &z, const double &maxLArBRadius, const double &minLArBRadius) const
std::shared_ptr< Acts::Experimental::BlueprintNode > buildBlueprintNode(const Acts::GeometryContext &gctx, std::shared_ptr< Acts::Experimental::BlueprintNode > &&childNode) override
Build the Itk Blueprint Node.
StatusCode finalize() override
Gaudi::Property< double > m_zTolerance
std::unique_ptr< CaloDetDescrManager > m_caloDetSecrMgr
CaloCell_ID::CaloSample getSampleEnum(const std::string &sampleName) const
void generateDiscSurfaces(caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap) const
CaloSampling::CaloSample CaloSample
This class groups all DetDescr information related to a CaloCell.
This class is not to needed in AthSimulation.
IMessageSvc * getMessageSvc(bool quiet=false)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.