ATLAS Offline Software
Loading...
Searching...
No Matches
ActsTrk::CaloBlueprintNodeBuilder Class Reference

Builds the Calo Blueprint Node. More...

#include <CaloBlueprintNodeBuilder.h>

Inheritance diagram for ActsTrk::CaloBlueprintNodeBuilder:
Collaboration diagram for ActsTrk::CaloBlueprintNodeBuilder:

Public Member Functions

StatusCode initialize () override
StatusCode finalize () override
std::shared_ptr< Acts::BlueprintNode > buildBlueprintNode (const Acts::GeometryContext &gctx, std::shared_ptr< Acts::BlueprintNode > &&childNode) override
 Build the Itk Blueprint Node.

Private Member Functions

void fillMaps (std::map< caloRegion, caloSampleSurfaceMap_t > &caloRegionSampleSurfaceMap, std::map< caloRegion, caloSampleDDEElementsMap_t > &caloRegionSampleDDEElementsMap, std::map< std::string, double > &caloDimensions) const
 fillMaps fills two maps.
void generateCylinderSurfaces (caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap, bool asymmetricZ) 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, bool asymmetricZ) const
 generateCylinderSurface generates a cylindrical surface for a given set of parameters.
void addCylindricalTrackingVolumeToCaloNode (Acts::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.
void generateDiscSurfaces (caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap) const
std::shared_ptr< Acts::DiscSurface > generateDiscSurface (const double &z, const double &maxLArBRadius, const double &minLArBRadius) const
std::string getSampleName (CaloCell_ID::CaloSample currentSample) const
CaloCell_ID::CaloSample getSampleEnum (const std::string &sampleName) const

Private Attributes

std::unique_ptr< CaloDetDescrManagerm_caloDetSecrMgr
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloDiscSampleList
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloCylinderSymmetricSampleList
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloCylinderAsymmetricSampleList
Gaudi::Property< double > m_radiusTolerance
Gaudi::Property< double > m_zTolerance

Detailed Description

Builds the Calo Blueprint Node.

Definition at line 33 of file CaloBlueprintNodeBuilder.h.

Member Function Documentation

◆ addCylindricalTrackingVolumeToCaloNode()

void ActsTrk::CaloBlueprintNodeBuilder::addCylindricalTrackingVolumeToCaloNode ( Acts::CylinderContainerBlueprintNode & containerNode,
const std::string & volumeName,
const std::vector< std::shared_ptr< Acts::Surface > > & surfaces,
int layerIndex,
const bool & isDisc ) const
private

addCylindricalTrackingVolumeToCaloNode adds a cylindrical tracking volume to the calo node.

It takes as input the container node, the calo dimensions map, the name of the volume and the vector of surfaces to be added to the volume. It creates a new CylinderContainerBlueprintNode in the container node, then creates a new Acts::TrackingVolume with the appropriate dimensions. Finally it adds the Acts::CylinderSurface to that Acts::TrackingVolume, then adds the tracking volume to the container node.

Definition at line 545 of file CaloBlueprintNodeBuilder.cxx.

545 {
546
547 // Construct the container node with geometry identifier and layer, and add the surfaces to the layer.
548 Acts::GeometryIdentifierBlueprintNode& geoIdNode = containerNode.withGeometryIdentifier();
549 geoIdNode.setAllVolumeIdsTo(s_caloBarrelId +
550 layerIndex);
551
552 AxisDirection axis = AxisDirection::AxisZ;
553 if (isDisc) axis = AxisDirection::AxisR;
554 CylinderContainerBlueprintNode& cylinder = geoIdNode.addCylinderContainer(volumeName,
555 axis);
556
557 cylinder.addLayer(volumeName + "_Layer", [&](auto& layer) {
558 layer.setSurfaces(surfaces);
559 layer.setEnvelope(Acts::ExtentEnvelope{{
560 .z = {0.1_mm, 0.1_mm},
561 .r = {2_mm, 2_mm},
562 }});
563 });
564
565}
constexpr std::size_t s_caloBarrelId
@ layer
Definition HitInfo.h:79

◆ buildBlueprintNode()

std::shared_ptr< BlueprintNode > ActsTrk::CaloBlueprintNodeBuilder::buildBlueprintNode ( const Acts::GeometryContext & gctx,
std::shared_ptr< Acts::BlueprintNode > && childNode )
override

Build the Itk Blueprint Node.

Parameters
gctxGeometry context
childThe child node which is added to the itk node.

Definition at line 46 of file CaloBlueprintNodeBuilder.cxx.

47 {
48
49
50 std::map<caloRegion, caloSampleSurfaceMap_t> caloRegionSampleSurfaceMap;
51 std::map<caloRegion, caloSampleDDEElementsMap_t> caloRegionSampleDDEElementsMap;
52 std::map<std::string, double> caloDimensions;
53
54 fillMaps(caloRegionSampleSurfaceMap, caloRegionSampleDDEElementsMap, caloDimensions);
55
56 ATH_MSG_DEBUG("Have filled first two maps");
57
58 generateCylinderSurfaces(caloRegionSampleSurfaceMap[caloRegion::CylinderSymmetricZZero], caloRegionSampleDDEElementsMap[caloRegion::CylinderSymmetricZZero],false);
59 generateCylinderSurfaces(caloRegionSampleSurfaceMap[caloRegion::CylinderNegativeZ], caloRegionSampleDDEElementsMap[caloRegion::CylinderNegativeZ],true);
60 generateCylinderSurfaces(caloRegionSampleSurfaceMap[caloRegion::CylinderPositiveZ], caloRegionSampleDDEElementsMap[caloRegion::CylinderPositiveZ],true);
61 generateDiscSurfaces(caloRegionSampleSurfaceMap[caloRegion::DiscNegativeZ], caloRegionSampleDDEElementsMap[caloRegion::DiscNegativeZ]);
62 generateDiscSurfaces(caloRegionSampleSurfaceMap[caloRegion::DiscPositiveZ], caloRegionSampleDDEElementsMap[caloRegion::DiscPositiveZ]);
63
64 ATH_MSG_DEBUG("Have generated calorimeter cylindrical surfaces");
65
66 // The calo node is a container node that will hold the itk and calo nodes as children.
67 // The calo cylinder is static in order to avoid merging issues with the itk portals
68 // that are supposed to carry material.
69 // The envelope of the calo node is set to the maximum radius and half length in z of the calorimeter,
70 // which is via a loop over all CaloDetDescrElements in the CaloDetDescrManager in the fillMaps function.
71
72 double caloEvelopeMaxR = caloDimensions.at("maxR");
73 double caloEnvelopeHalfLenghtZ = (caloDimensions.at("maxPosZ") - caloDimensions.at("minNegZ"))/2.0;
74
75 ATH_MSG_INFO("Calo envelope dimensions: maxR = " << caloEvelopeMaxR << ", halfLengthZ = " << caloEnvelopeHalfLenghtZ);
76 std::shared_ptr<StaticBlueprintNode> itkCaloNode{};
77 {
78 auto envelope = std::make_unique<TrackingVolume>(Amg::Transform3D::Identity(),
79 std::make_shared<CylinderVolumeBounds>(0., caloEvelopeMaxR, caloEnvelopeHalfLenghtZ),"ITkCalo");
80 envelope->assignGeometryId(Acts::GeometryIdentifier{}.withVolume(s_caloEnvelopeID));
81 itkCaloNode = std::make_shared<StaticBlueprintNode>(std::move(envelope));
82 }
83 if (childNode) {
84 itkCaloNode->addChild(std::move(childNode));
85 }
86
87 ATH_MSG_DEBUG("Top level calorimeter node created");
88
89 auto caloNode = std::make_shared<CylinderContainerBlueprintNode>("CaloNode", AxisDirection::AxisZ);
90 CylinderContainerBlueprintNode& caloBarrelCylinderNode = caloNode->addCylinderContainer("CaloBarrelSymmetricZZeroCylinders", AxisDirection::AxisR);
91 caloBarrelCylinderNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
92 caloBarrelCylinderNode.setResizeStrategy(ResizeStrategy::Gap);
93
94 ATH_MSG_DEBUG("EM Barrel container node created");
95
96 unsigned int volumeCounter = 0;
97
98 //Barrel cylinders symmetric about z = 0
99 for (unsigned int sampleIndex = 0; sampleIndex < m_caloCylinderSymmetricSampleList.size(); ++sampleIndex) {
100 auto& sampleName = m_caloCylinderSymmetricSampleList.at(sampleIndex).first;
101 addCylindricalTrackingVolumeToCaloNode(caloBarrelCylinderNode, sampleName, caloRegionSampleSurfaceMap[caloRegion::CylinderSymmetricZZero].at({sampleName, getSampleEnum(sampleName)}), volumeCounter, false);
102 volumeCounter++;
103 }
104
105 //now do asymmetric cylinders, first negative z
106
107 CylinderContainerBlueprintNode& caloBarrelCylinderNegativeZNode = caloNode->addCylinderContainer("CaloBarrelNegativeZAsymmetricCylinders", AxisDirection::AxisR);
108 caloBarrelCylinderNegativeZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
109 caloBarrelCylinderNegativeZNode.setResizeStrategy(ResizeStrategy::Gap);
110
111 //then positive z
112 CylinderContainerBlueprintNode& caloBarrelCylinderPositiveZNode = caloNode->addCylinderContainer("CaloBarrelPositiveZAsymmetricCylinders", AxisDirection::AxisR);
113 caloBarrelCylinderPositiveZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
114 caloBarrelCylinderPositiveZNode.setResizeStrategy(ResizeStrategy::Gap);
115
116 for (unsigned int sampleIndex = 0; sampleIndex < m_caloCylinderAsymmetricSampleList.size(); ++sampleIndex) {
117 auto& sampleName = m_caloCylinderAsymmetricSampleList.at(sampleIndex).first;
118 //We only add TileGap1 and 2 here, because the TileExt0,1,2
119 //will need a special treatment to avoid clashes in Z.
120 if (sampleIndex < 2){
121 addCylindricalTrackingVolumeToCaloNode(caloBarrelCylinderNegativeZNode, sampleName+"NegZ", caloRegionSampleSurfaceMap[caloRegion::CylinderNegativeZ].at({sampleName, getSampleEnum(sampleName)}), volumeCounter, false);
122 volumeCounter++;
123 addCylindricalTrackingVolumeToCaloNode(caloBarrelCylinderPositiveZNode, sampleName+"PosZ", caloRegionSampleSurfaceMap[caloRegion::CylinderPositiveZ].at({sampleName, getSampleEnum(sampleName)}), volumeCounter, false);
124 volumeCounter++;
125 }
126 else{
127 //Tile extended barrel surfaces must be added to top level node directly because they always overlap in R
128 //or Z with other calorimeter surfaces, volumes etc.
129 //Note there is a speed penalty to do it this way.
130 itkCaloNode->addLayer(sampleName+"NegZ" + "_Layer", [&](auto& layer) {
131 layer.setSurfaces(caloRegionSampleSurfaceMap[caloRegion::CylinderNegativeZ].at({sampleName, getSampleEnum(sampleName)}));
132 layer.setEnvelope(Acts::ExtentEnvelope{{
133 .z = {0.1_mm, 0.1_mm},
134 .r = {2_mm, 2_mm},
135 }});
136 });
137 itkCaloNode->addLayer(sampleName+"PosZ" + "_Layer", [&](auto& layer) {
138 layer.setSurfaces(caloRegionSampleSurfaceMap[caloRegion::CylinderPositiveZ].at({sampleName, getSampleEnum(sampleName)}));
139 layer.setEnvelope(Acts::ExtentEnvelope{{
140 .z = {0.1_mm, 0.1_mm},
141 .r = {2_mm, 2_mm},
142 }});
143 });
144 }
145 }
146
147
148 CylinderContainerBlueprintNode& caloEndCapDiscNegativeZNode = caloNode->addCylinderContainer("CaloEndCapDiscNegativeZ", AxisDirection::AxisZ);
149 caloEndCapDiscNegativeZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
150 // The -z end of this container defines the calorimeter's global minZ, so the
151 // enclosing envelope's -z edge coincides with this container's own -z edge to
152 // within floating-point rounding. With ResizeStrategy::Gap on that side, the
153 // resize mints a degenerate (~1e-13 mm) end-gap volume whose two disc faces
154 // coincide, which CylinderNavigationPolicy cannot resolve. Expand the
155 // outermost wheel on the boundary (-z) side instead; keep Gap on the interior
156 // (+z) side. NOTE: (inner, outer) map to (minZ, maxZ) for an AxisZ stack.
157 caloEndCapDiscNegativeZNode.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Gap);
158
159 CylinderContainerBlueprintNode& caloEndCapDiscPositiveZNode = caloNode->addCylinderContainer("CaloEndCapDiscPositiveZ", AxisDirection::AxisZ);
160 caloEndCapDiscPositiveZNode.setAttachmentStrategy(VolumeAttachmentStrategy::Gap);
161 // Mirror of the negative endcap: the +z (maxZ, outer) end is the global maxZ
162 // boundary, so Expand there and keep Gap on the interior (-z) side.
163 caloEndCapDiscPositiveZNode.setResizeStrategies(ResizeStrategy::Gap, ResizeStrategy::Expand);
164
165 for (unsigned int sampleIndex = 0; sampleIndex < m_caloDiscSampleList.size(); ++sampleIndex) {
166 auto& sampleName = m_caloDiscSampleList.at(sampleIndex).first;
167 addCylindricalTrackingVolumeToCaloNode(caloEndCapDiscNegativeZNode, sampleName+"NegZ", caloRegionSampleSurfaceMap[caloRegion::DiscNegativeZ].at({sampleName, getSampleEnum(sampleName)}), volumeCounter, true);
168 volumeCounter++;
169 addCylindricalTrackingVolumeToCaloNode(caloEndCapDiscPositiveZNode, sampleName+"PosZ", caloRegionSampleSurfaceMap[caloRegion::DiscPositiveZ].at({sampleName, getSampleEnum(sampleName)}), volumeCounter, true);
170 volumeCounter++;
171 }
172
173 ATH_MSG_DEBUG("Have added all Barrel layers to caloBarrelCylinderNode");
174
175 // Add calo barrel node to the top level calo node.
176 itkCaloNode->addChild(caloNode);
177
178 //return the top level calo node
179 return itkCaloNode;
180}
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
void addCylindricalTrackingVolumeToCaloNode(Acts::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.
void fillMaps(std::map< caloRegion, caloSampleSurfaceMap_t > &caloRegionSampleSurfaceMap, std::map< caloRegion, caloSampleDDEElementsMap_t > &caloRegionSampleDDEElementsMap, std::map< std::string, double > &caloDimensions) const
fillMaps fills two maps.
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloDiscSampleList
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloCylinderAsymmetricSampleList
void generateCylinderSurfaces(caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap, bool asymmetricZ) const
generateCylinderSurfaces generates cylindrical surfaces for each calo sampling.
std::vector< std::pair< std::string, CaloCell_ID::CaloSample > > m_caloCylinderSymmetricSampleList
CaloCell_ID::CaloSample getSampleEnum(const std::string &sampleName) const
void generateDiscSurfaces(caloSampleSurfaceMap_t &caloSampleSurfaceMap, caloSampleDDEElementsMap_t &caloSampleDDEElementsMap) const
constexpr std::size_t s_caloEnvelopeID
Volume Ids ofthe Calorimeter.
mapped_type at(key_type key) const
Look up an element in the map.

◆ fillMaps()

void ActsTrk::CaloBlueprintNodeBuilder::fillMaps ( std::map< caloRegion, caloSampleSurfaceMap_t > & caloRegionSampleSurfaceMap,
std::map< caloRegion, caloSampleDDEElementsMap_t > & caloRegionSampleDDEElementsMap,
std::map< std::string, double > & caloDimensions ) const
private

fillMaps fills two maps.

The first maps each calo sampling to a vector of surfaces (initially empty) The second maps each calo sampling to a vector of CaloDetDescrElements The second map is filled by looping over all DDE in the CaloDetDescrManager and adding each DDE to the vector corresponding to its sampling in the map

Definition at line 187 of file CaloBlueprintNodeBuilder.cxx.

188 {
189
190
191 //loop over all possible calo sampling layers
192 //and create empty vectors of surfaces in the map
193
194 //Create map between each calorimeter sampling and a vector of
195 //cylinder surfaces. We can have N cylinders in a given sampling,
196 //and the value of N is determined by how often the average radius
197 //calculated for a given phi ring, at fixed Z, changes by more than
198 //a tolerance value
199
200 //Use the same loop to create map bwteeen sampling and vectors of DDE
201 for (const auto & currentSample : m_caloCylinderSymmetricSampleList) {
202 caloRegionSampleSurfaceMap[caloRegion::CylinderSymmetricZZero][currentSample] = std::vector<std::shared_ptr<Surface> >();
203 caloRegionSampleDDEElementsMap[caloRegion::CylinderSymmetricZZero][currentSample] = std::vector<const CaloDetDescrElement*>();
204 }
205
206 for (const auto & currentSample : m_caloCylinderAsymmetricSampleList) {
207 caloRegionSampleSurfaceMap[caloRegion::CylinderNegativeZ][currentSample] = std::vector<std::shared_ptr<Surface> >();
208 caloRegionSampleDDEElementsMap[caloRegion::CylinderNegativeZ][currentSample] = std::vector<const CaloDetDescrElement*>();
209 caloRegionSampleSurfaceMap[caloRegion::CylinderPositiveZ][currentSample] = std::vector<std::shared_ptr<Surface> >();
210 caloRegionSampleDDEElementsMap[caloRegion::CylinderPositiveZ][currentSample] = std::vector<const CaloDetDescrElement*>();
211 }
212
213 for (const auto & currentSample : m_caloDiscSampleList) {
214 caloRegionSampleSurfaceMap[caloRegion::DiscNegativeZ][currentSample] = std::vector<std::shared_ptr<Surface> >();
215 caloRegionSampleDDEElementsMap[caloRegion::DiscNegativeZ][currentSample] = std::vector<const CaloDetDescrElement*>();
216 caloRegionSampleSurfaceMap[caloRegion::DiscPositiveZ][currentSample] = std::vector<std::shared_ptr<Surface> >();
217 caloRegionSampleDDEElementsMap[caloRegion::DiscPositiveZ][currentSample] = std::vector<const CaloDetDescrElement*>();
218 }
219
220 double maxR = 0.0;
221 double maxPosZ = 0.0;
222 double minNegZ = 0.0;
223
224 //for each calo sampling collect all the DDE in a vector
225 for (const CaloDetDescrElement* theDDE : m_caloDetSecrMgr->element_range()){
226 if (!theDDE){
227 ATH_MSG_ERROR("Null pointer to CaloDetDescrElement");
228 continue;
229 }
230
231 if (theDDE->r() > maxR) maxR = theDDE->r();
232 if (theDDE->z() > maxPosZ) maxPosZ = theDDE->z();
233 if (theDDE->z() < minNegZ) minNegZ = theDDE->z();
234
235 CaloCell_ID::CaloSample currentSample=theDDE->getSampling();
236 std::pair <std::string, CaloCell_ID::CaloSample> samplePair = std::make_pair(getSampleName(currentSample), currentSample);
237
238 //check if have cylinder symmetric about z = 0
240 caloRegionSampleDDEElementsMap[caloRegion::CylinderSymmetricZZero][{samplePair.first,samplePair.second}].push_back(theDDE);
241 }
242
243 //check if have cylinder asymmetric about z = 0, if so check if in negative or positive z
245 if (theDDE->z() < 0.0) {
246 caloRegionSampleDDEElementsMap[caloRegion::CylinderNegativeZ][{samplePair.first,samplePair.second}].push_back(theDDE);
247 }
248 else {
249 caloRegionSampleDDEElementsMap[caloRegion::CylinderPositiveZ][{samplePair.first,samplePair.second}].push_back(theDDE);
250 }
251 }
252
253 //check if sampling is in disc list
254 if (std::find(m_caloDiscSampleList.begin(), m_caloDiscSampleList.end(), std::make_pair(samplePair.first,samplePair.second)) != m_caloDiscSampleList.end()) {
255 //check if in negative or positive z
256 if (theDDE->z() < 0.0) {
257 caloRegionSampleDDEElementsMap[caloRegion::DiscNegativeZ][{getSampleName(currentSample), currentSample}].push_back(theDDE);
258 }
259 else {
260 caloRegionSampleDDEElementsMap[caloRegion::DiscPositiveZ][{getSampleName(currentSample), currentSample}].push_back(theDDE);
261 }
262 }
263
264 }
265
266 caloDimensions["maxR"] = maxR;
267 caloDimensions["maxPosZ"] = maxPosZ;
268 caloDimensions["minNegZ"] = minNegZ;
269
270 auto sortAllLayersInZ = [&caloRegionSampleDDEElementsMap](const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList, const caloRegion& region) {
271 for (const auto & currentSample : caloSampleList) {
272 std::vector<const CaloDetDescrElement*> currentElements = caloRegionSampleDDEElementsMap[region][currentSample];
273 std::sort(currentElements.begin(), currentElements.end(), [](const CaloDetDescrElement* a, const CaloDetDescrElement* b) {return a->z() < b->z();});
274 caloRegionSampleDDEElementsMap[region][currentSample] = std::move(currentElements);
275 }
276 };
277
278 //Sort the DDE, by Z, in all possible layers
282
283 auto sortAllLayersInR = [&caloRegionSampleDDEElementsMap](const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList, const caloRegion& region) {
284 for (const auto& currentSample : caloSampleList) {
285 std::vector<const CaloDetDescrElement*> currentElements = caloRegionSampleDDEElementsMap[region][currentSample];
286 std::sort(currentElements.begin(), currentElements.end(), [](const CaloDetDescrElement* a, const CaloDetDescrElement* b) {return a->r() < b->r();});
287 caloRegionSampleDDEElementsMap[region][currentSample] = std::move(currentElements);
288 }
289 };
290
291 //Sort the DDE, by R, in all possible layers
294
295}
#define ATH_MSG_ERROR(x)
static Double_t a
std::string getSampleName(CaloCell_ID::CaloSample currentSample) const
std::unique_ptr< CaloDetDescrManager > m_caloDetSecrMgr
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ finalize()

StatusCode ActsTrk::CaloBlueprintNodeBuilder::finalize ( )
override

Definition at line 182 of file CaloBlueprintNodeBuilder.cxx.

182 {
183 ATH_MSG_DEBUG("Finalizing CaloBlueprintNodeBuilder");
184 return StatusCode::SUCCESS;
185}

◆ generateCylinderSurface()

std::shared_ptr< CylinderSurface > ActsTrk::CaloBlueprintNodeBuilder::generateCylinderSurface ( const double & maxLArBRadius,
const double & minLArBRadius,
const double & lowZLarB,
const double & highZLarB,
bool asymmetricZ ) const
private

generateCylinderSurface generates a cylindrical surface for a given set of parameters.

To do this it calculates the radius and length of the cylinder, then shifts it in Z to the midpoint of the Z values used to build it. It then creates the Acts::CylinderSurface and returns it via a shared pointer.

Definition at line 411 of file CaloBlueprintNodeBuilder.cxx.

411 {
412
413 //Characterise the dimensions of the cylinder
414 double LArBRadius = (maxLArBRadius + minLArBRadius) / 2.0;
415 double LArBLength = std::abs(highZLarB - lowZLarB);
416
417 ATH_MSG_DEBUG("Cylinder radius and length are " << LArBRadius << " and " << LArBLength);
418
419 if (asymmetricZ) {
420 double zShift = (highZLarB + lowZLarB) / 2.0;
421 ATH_MSG_DEBUG("Cylinder is asymmetric in Z, with shift of " << zShift);
422 return Surface::makeShared<CylinderSurface>(Transform3(Translation3(0.0, 0.0, zShift)), LArBRadius, LArBLength/2);
423 }
424 else return Surface::makeShared<CylinderSurface>(Transform3::Identity(), LArBRadius, LArBLength/2);
425
426}

◆ generateCylinderSurfaces()

void ActsTrk::CaloBlueprintNodeBuilder::generateCylinderSurfaces ( caloSampleSurfaceMap_t & caloSampleSurfaceMap,
caloSampleDDEElementsMap_t & caloSampleDDEElementsMap,
bool asymmetricZ ) const
private

generateCylinderSurfaces generates cylindrical surfaces for each calo sampling.

It does this for cylindrical layers by scanning in Z, for each Z finding the average radius of the cells in a phi ring If the average radius changes by more than a tolerance value (m_radiusTolerance), a new cylinder surface is created. The surfaces are added to the relevant vector of surfaces in the caloSampleSurfaceMap.

Definition at line 297 of file CaloBlueprintNodeBuilder.cxx.

297 {
298
299 std::vector<std::pair<std::string, CaloCell_ID::CaloSample>> sampleList;
300 if (asymmetricZ) sampleList = m_caloCylinderAsymmetricSampleList;
301 else sampleList = m_caloCylinderSymmetricSampleList;
302
303 for (const auto & currentSample : sampleList) {
304
305 std::vector<const CaloDetDescrElement*> currentElements = caloSampleDDEElementsMap[currentSample];
306
307 double maxLArBRadius = 0.0, minLArBRadius = std::numeric_limits<double>::max();
308 double lowZLarB = 0.0, highZLarB = 0.0;
309
310 //loop over cells runs from -z to +z in a given sampling layer
311 //There are many cells with the same z value, but different phi values
312 //We will find the average radius of the cells in a given phi ring
313 double totalRadiusFixedPhi = 0.0;
314 bool firstCellInPhiRing = true;
315 unsigned int phiCounter = 0;
316
317 //Then we will also track changes in radius as we move in Z from
318 //each ring of cells in phi to the next ring of cells in phi
319 bool firstPhiRing = true;
320 double initialRadius = 0.0;
321 double initialZ = -std::numeric_limits<double>::max();
322
323 //check if we ever move along in Z value
324 bool movedInZ = false;
325
326 for (const CaloDetDescrElement* theDDE : currentElements){
327
328 double z = theDDE->z();
329 double radius = theDDE->r();
330
331 ATH_MSG_DEBUG(" Calo Sampling is " << currentSample.first);
332
333 if (firstCellInPhiRing) {
334 ATH_MSG_DEBUG("First Cell in phi ring " << currentSample.first << " has z = " << z << " and r = " << radius);
335 initialZ = z;
336 firstCellInPhiRing = false;
337 }
338
339 if (firstPhiRing) {
340 ATH_MSG_DEBUG("First Cell in layer " << currentSample.first << " has z = " << z << " and r = " << radius);
341 initialRadius = theDDE->r();
342 firstPhiRing = false;
343 lowZLarB = z;
344 }
345
346 ATH_MSG_DEBUG("Z and initialZ are " << z << " and " << initialZ);
347
348 //if z has not changed then we add the radius to the summed radius for this phi ring
349 //and increment the counter of cells in this phi ring
350 if (std::abs(z - initialZ) < 0.0001) {
351 ATH_MSG_DEBUG("phiCounter is " << phiCounter << " and radius is " << radius << " and totalRadiusFixedPhi is " << totalRadiusFixedPhi << " and hash is " << theDDE->calo_hash());
352 totalRadiusFixedPhi += radius;
353 phiCounter++;
354 continue;
355 }
356 else {
357 movedInZ = true;
358 firstCellInPhiRing = true;
359 if (phiCounter > 0) {
360 double cellRingRadius = totalRadiusFixedPhi / phiCounter;
361 totalRadiusFixedPhi = 0.0;
362 phiCounter = 0;
363
364 if (cellRingRadius > maxLArBRadius) maxLArBRadius = radius;
365 if (cellRingRadius < minLArBRadius) minLArBRadius = radius;
366
367 //if radius changes by more than tolerance, then we will create a cylinder
368 //with the average cell radius and length from neg to pos z
369 highZLarB = z;
370 ATH_MSG_DEBUG("Values of cellRingRadius, initialRadius, highZLarB and lowZLarB are " << cellRingRadius << ", " << initialRadius << ", " << highZLarB << " and " << lowZLarB);
371 if (std::abs(cellRingRadius - initialRadius) > m_radiusTolerance && highZLarB - lowZLarB > 0.0) {
372 ATH_MSG_DEBUG("CYLINDER: Create cylinder for layer " << currentSample.first);
373 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius << " " << maxLArBRadius);
374 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB << " " << highZLarB);
375
376 caloSampleSurfaceMap[currentSample].push_back(generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB, asymmetricZ));
377
378 //reset the dimensions of the cylinder to the initial conditions, in
379 //preparation for the next cylinder
380 firstPhiRing = true;
381 minLArBRadius = std::numeric_limits<double>::max();
382 maxLArBRadius = 0.0;
383 lowZLarB = 0.0;
384 highZLarB = 0.0;
385 }//if radius changes by more than tolerance
386 }//if at least one cell in phi (should always be the case!)
387 else ATH_MSG_ERROR("phiCounter is zero!");
388 }//if z has changed
389 }//loop over calorimeter DDE
390
391 if (0 == caloSampleSurfaceMap[currentSample].size()){
392 //If we never found any shift in Z whilst looping over the DDE
393 //then thee min/max Z and radius were not set
394 //so we set them here.
395 if (!movedInZ) {
396 lowZLarB = initialZ;
397 highZLarB = initialZ+0.001;
398 if (phiCounter > 0) {
399 maxLArBRadius = totalRadiusFixedPhi / phiCounter;
400 minLArBRadius = 0.0;
401 }
402 }
403 ATH_MSG_DEBUG("CYLINDER: Zero size Vector: Create cylinder for layer " << currentSample.first);
404 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius << " " << maxLArBRadius);
405 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB << " " << highZLarB);
406 caloSampleSurfaceMap[currentSample].push_back(generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB, asymmetricZ));
407 }
408 }
409}
size_t size() const
Number of registered mappings.
#define z
std::shared_ptr< Acts::CylinderSurface > generateCylinderSurface(const double &maxLArBRadius, const double &minLArBRadius, const double &lowZLarB, const double &highZLarB, bool asymmetricZ) const
generateCylinderSurface generates a cylindrical surface for a given set of parameters.

◆ generateDiscSurface()

std::shared_ptr< Acts::DiscSurface > ActsTrk::CaloBlueprintNodeBuilder::generateDiscSurface ( const double & z,
const double & maxLArBRadius,
const double & minLArBRadius ) const
private

Definition at line 536 of file CaloBlueprintNodeBuilder.cxx.

536 {
537
538 ATH_MSG_DEBUG("DISC: Disc min and max radius are " << minLArBRadius << " and " << maxLArBRadius << " with z of " << z);
539 auto surface = Surface::makeShared<DiscSurface>(Amg::getTranslateZ3D(z), minLArBRadius, maxLArBRadius);
540
541 return surface;
542
543}
Amg::Transform3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis

◆ generateDiscSurfaces()

void ActsTrk::CaloBlueprintNodeBuilder::generateDiscSurfaces ( caloSampleSurfaceMap_t & caloSampleSurfaceMap,
caloSampleDDEElementsMap_t & caloSampleDDEElementsMap ) const
private

Definition at line 428 of file CaloBlueprintNodeBuilder.cxx.

428 {
429
430 for (const auto & currentSample : m_caloDiscSampleList) {
431
432 const std::vector<const CaloDetDescrElement*> & currentElements = caloSampleDDEElementsMap[currentSample];
433
434 //FCAL is treated differently because it is non-projective
435 //We create one surface for each of FCAL0, FCAL1 and FCAL2
436 if (CaloCell_ID::FCAL0 == currentSample.second || CaloCell_ID::FCAL1 == currentSample.second || CaloCell_ID::FCAL2 == currentSample.second) {
437 ATH_MSG_DEBUG("TOM3: FCAL sampling " << currentSample.second);
438
439 double fcalRMin = std::numeric_limits<double>::max();
440 double fcalRMax = std::numeric_limits<double>::min();
441 double fcalZSum = 0;
442 size_t cellCount = 0;
443
444 for (const CaloDetDescrElement* theDDE : currentElements) {
445 double r = theDDE->r();
446 if (r < fcalRMin) fcalRMin = r;
447 if (r > fcalRMax) fcalRMax = r;
448 fcalZSum += theDDE->z();
449 cellCount++;
450 }
451 if (cellCount == 0)[[unlikely]]{
452 ATH_MSG_WARNING("cellCount is zero in CaloBlueprintNodeBuilder::generateDiscSurfaces");
453 continue;
454 }
455 double fcalZ = fcalZSum / cellCount;
456 caloSampleSurfaceMap[currentSample].push_back(generateDiscSurface(fcalZ,fcalRMax, fcalRMin));
457 //now continue to the next sampling
458 continue;
459 }
460
461 //For other disc calorimeter layers we proceed to create many surfaces as needed.
462 double totalZFixedPhi = 0.0;
463 bool firstCellInPhiRing = true;
464 unsigned int phiCounter = 0;
465
466 bool firstPhiRing = true;
467 double initialRadius = 0.0;
468 double initialZ = -std::numeric_limits<double>::max();
469
470 //loop over cells runs from -z to +z in a given sampling layer
471 //There are many cells with the same z value, but different phi values
472 //We will find a min amd max radius in this phi ring.
473 double minDiscRadius = std::numeric_limits<double>::max(), maxDiscRadius = 0.0;
474
475 unsigned int currentElementsSize = currentElements.size();
476 unsigned int DDECounter = 0;
477
478 for (const CaloDetDescrElement* theDDE : currentElements){
479
480 bool isLastDDE = (DDECounter == (currentElementsSize-1));
481
482 ATH_MSG_DEBUG("Disc DDE with sampling, r and z of " << currentSample << ", " << theDDE->r() << ", " << theDDE->z());
483 ATH_MSG_DEBUG("isLastDDE is " << isLastDDE);
484
485 double z = theDDE->z();
486 double radius = theDDE->r();
487
488 if (firstCellInPhiRing) {
489 initialRadius = radius;
490 firstCellInPhiRing = false;
491 }
492
493 if (firstPhiRing) {
494 initialZ = z;
495 firstPhiRing = false;
496 minDiscRadius = radius;
497 }
498
499 //if radius is unchanged then we add the z to the summed z for this phi ring
500 //and increment the counter of cells in this phi ring
501 if (std::abs(radius - initialRadius) < 0.0001 && !isLastDDE) {
502 totalZFixedPhi += z;
503 phiCounter++;
504 DDECounter++;
505 continue;
506 }
507 else {
508 firstCellInPhiRing = true;
509 if (phiCounter > 0) {
510 double cellRingZ = totalZFixedPhi / phiCounter;
511 totalZFixedPhi = 0.0;
512 phiCounter = 0;
513
514 //if z changes by more than tolerance, then we will create a disc
515 //with the min and max radius found
516 //if we reach the last DDE and no new surface has been created, then we also create a disc surface
517 maxDiscRadius = radius;
518 ATH_MSG_DEBUG("cellRingZ, initialZ and z tolerance are " << cellRingZ << ", " << initialZ << " and " << m_zTolerance);
519 if (std::abs(cellRingZ - initialZ) > m_zTolerance || isLastDDE) {
520 ATH_MSG_DEBUG("DISC: About to create disc surface for sampling " << currentSample);
521 caloSampleSurfaceMap[currentSample].push_back(generateDiscSurface(cellRingZ,maxDiscRadius, minDiscRadius));
522 //reset the dimensions of the disc to the initial conditions, in
523 //preparation for the next disc
524 minDiscRadius = std::numeric_limits<double>::max();
525 maxDiscRadius = 0.0;
526 firstPhiRing = true;
527 }//if z changes by more than tolerance
528 }//if at least one cell in phi (should always be the case!)
529 else ATH_MSG_ERROR("phiCounter is zero!");
530 }//if radius has changed
531 DDECounter++;
532 }//loop over calorimeter DDE
533 }//loop over calo samplings
534}
#define ATH_MSG_WARNING(x)
std::shared_ptr< Acts::DiscSurface > generateDiscSurface(const double &z, const double &maxLArBRadius, const double &minLArBRadius) const
int r
Definition globals.cxx:22
#define unlikely(x)

◆ getSampleEnum()

CaloCell_ID::CaloSample ActsTrk::CaloBlueprintNodeBuilder::getSampleEnum ( const std::string & sampleName) const
inlineprivate

Definition at line 153 of file CaloBlueprintNodeBuilder.h.

153 {
154 CaloCell_ID::CaloSample sampleEnum = CaloCell_ID::Unknown;
155 for (auto& [name, sample] : m_caloCylinderSymmetricSampleList) {
156 if (sampleName == name) {
157 sampleEnum = sample;
158 break;
159 }
160 }
161 if (sampleEnum == CaloCell_ID::Unknown) {
162 for (auto& [name, sample] : m_caloCylinderAsymmetricSampleList) {
163 if (sampleName == name) {
164 sampleEnum = sample;
165 break;
166 }
167 }
168 }
169 if (sampleEnum == CaloCell_ID::Unknown) {
170 for (auto& [name, sample] : m_caloDiscSampleList) {
171 if (sampleName == name) {
172 sampleEnum = sample;
173 break;
174 }
175 }
176 }
177 return sampleEnum;
178 }

◆ getSampleName()

std::string ActsTrk::CaloBlueprintNodeBuilder::getSampleName ( CaloCell_ID::CaloSample currentSample) const
inlineprivate

Definition at line 126 of file CaloBlueprintNodeBuilder.h.

126 {
127 std::string sampleName = "";
128 for ( auto& [name, sample] : m_caloCylinderSymmetricSampleList) {
129 if (currentSample == sample) {
131 break;
132 }
133 }
134 if (sampleName == "") {
135 for ( auto& [name, sample] : m_caloCylinderAsymmetricSampleList) {
136 if (currentSample == sample) {
138 break;
139 }
140 }
141 }
142 if (sampleName == "") {
143 for ( auto& [name, sample] : m_caloDiscSampleList) {
144 if (currentSample == sample) {
146 break;
147 }
148 }
149 }
150 return sampleName;
151 }

◆ initialize()

StatusCode ActsTrk::CaloBlueprintNodeBuilder::initialize ( )
override

Definition at line 38 of file CaloBlueprintNodeBuilder.cxx.

38 {
39 ATH_MSG_DEBUG("Initializing CaloBlueprintNodeBuilder");
40
42
43 return StatusCode::SUCCESS;
44}
std::unique_ptr< CaloDetDescrManager > buildCaloDetDescrNoAlign(ISvcLocator *svcLocator, IMessageSvc *msgSvc)
IMessageSvc * getMessageSvc(bool quiet=false)

Member Data Documentation

◆ m_caloCylinderAsymmetricSampleList

std::vector<std::pair<std::string, CaloCell_ID::CaloSample> > ActsTrk::CaloBlueprintNodeBuilder::m_caloCylinderAsymmetricSampleList
private
Initial value:
{
{"TileGap1", CaloCell_ID::TileGap1},
{"TileGap2", CaloCell_ID::TileGap2},
{"TileExt0", CaloCell_ID::TileExt0},
{"TileExt1", CaloCell_ID::TileExt1},
{"TileExt2", CaloCell_ID::TileExt2}}

Definition at line 108 of file CaloBlueprintNodeBuilder.h.

108 {
109 {"TileGap1", CaloCell_ID::TileGap1},
110 {"TileGap2", CaloCell_ID::TileGap2},
111 {"TileExt0", CaloCell_ID::TileExt0},
112 {"TileExt1", CaloCell_ID::TileExt1},
113 {"TileExt2", CaloCell_ID::TileExt2}};

◆ m_caloCylinderSymmetricSampleList

std::vector<std::pair<std::string, CaloCell_ID::CaloSample> > ActsTrk::CaloBlueprintNodeBuilder::m_caloCylinderSymmetricSampleList
private
Initial value:
{
{ "PreSamplerB", CaloCell_ID::PreSamplerB},
{"EMB1", CaloCell_ID::EMB1},
{"EMB2", CaloCell_ID::EMB2},
{"EMB3", CaloCell_ID::EMB3},
{"TileBar0", CaloCell_ID::TileBar0},
{"TileBar1", CaloCell_ID::TileBar1},
{"TileBar2", CaloCell_ID::TileBar2}}

Definition at line 99 of file CaloBlueprintNodeBuilder.h.

99 {
100 { "PreSamplerB", CaloCell_ID::PreSamplerB},
101 {"EMB1", CaloCell_ID::EMB1},
102 {"EMB2", CaloCell_ID::EMB2},
103 {"EMB3", CaloCell_ID::EMB3},
104 {"TileBar0", CaloCell_ID::TileBar0},
105 {"TileBar1", CaloCell_ID::TileBar1},
106 {"TileBar2", CaloCell_ID::TileBar2}};

◆ m_caloDetSecrMgr

std::unique_ptr<CaloDetDescrManager> ActsTrk::CaloBlueprintNodeBuilder::m_caloDetSecrMgr
private

Definition at line 80 of file CaloBlueprintNodeBuilder.h.

◆ m_caloDiscSampleList

std::vector<std::pair<std::string, CaloCell_ID::CaloSample> > ActsTrk::CaloBlueprintNodeBuilder::m_caloDiscSampleList
private
Initial value:
{
{"PreSamplerE", CaloCell_ID::PreSamplerE},
{"EME1",CaloCell_ID::EME1},
{"EME2",CaloCell_ID::EME2},
{"EME3",CaloCell_ID::EME3},
{"HEC0",CaloCell_ID::HEC0},
{"HEC1",CaloCell_ID::HEC1},
{"HEC2",CaloCell_ID::HEC2},
{"HEC3",CaloCell_ID::HEC3},
{"TileGap3",CaloCell_ID::TileGap3},
{"FCAL0",CaloCell_ID::FCAL0},
{"FCAL1",CaloCell_ID::FCAL1},
{"FCAL2",CaloCell_ID::FCAL2}}

Definition at line 85 of file CaloBlueprintNodeBuilder.h.

85 {
86 {"PreSamplerE", CaloCell_ID::PreSamplerE},
87 {"EME1",CaloCell_ID::EME1},
88 {"EME2",CaloCell_ID::EME2},
89 {"EME3",CaloCell_ID::EME3},
90 {"HEC0",CaloCell_ID::HEC0},
91 {"HEC1",CaloCell_ID::HEC1},
92 {"HEC2",CaloCell_ID::HEC2},
93 {"HEC3",CaloCell_ID::HEC3},
94 {"TileGap3",CaloCell_ID::TileGap3},
95 {"FCAL0",CaloCell_ID::FCAL0},
96 {"FCAL1",CaloCell_ID::FCAL1},
97 {"FCAL2",CaloCell_ID::FCAL2}};

◆ m_radiusTolerance

Gaudi::Property<double> ActsTrk::CaloBlueprintNodeBuilder::m_radiusTolerance
private
Initial value:
{ this
, "RadiusTolerance"
, 2.0
, "Tolerance for determining if a ring of cells in phi has changed the radius w.r.t to the previous ring in phi" }

Definition at line 115 of file CaloBlueprintNodeBuilder.h.

115 { this
116 , "RadiusTolerance"
117 , 2.0
118 , "Tolerance for determining if a ring of cells in phi has changed the radius w.r.t to the previous ring in phi" };

◆ m_zTolerance

Gaudi::Property<double> ActsTrk::CaloBlueprintNodeBuilder::m_zTolerance
private
Initial value:
{ this
, "ZTolerance"
, 2.0
, "Tolerance for determining if a ring of cells in phi has changed the z w.r.t to the previous ring in phi" }

Definition at line 120 of file CaloBlueprintNodeBuilder.h.

120 { this
121 , "ZTolerance"
122 , 2.0
123 , "Tolerance for determining if a ring of cells in phi has changed the z w.r.t to the previous ring in phi" };

The documentation for this class was generated from the following files: