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, 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) 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< CaloDetDescrManager > m_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 512 of file CaloBlueprintNodeBuilder.cxx.

512 {
513
514 // Construct the container node with geometry identifier and layer, and add the surfaces to the layer.
515 Acts::GeometryIdentifierBlueprintNode& geoIdNode = containerNode.withGeometryIdentifier();
516 geoIdNode.setAllVolumeIdsTo(s_caloBarrelId +
517 layerIndex);
518
519 AxisDirection axis = AxisDirection::AxisZ;
520 if (isDisc) axis = AxisDirection::AxisR;
521 CylinderContainerBlueprintNode& cylinder = geoIdNode.addCylinderContainer(volumeName,
522 axis);
523
524 cylinder.addLayer(volumeName + "_Layer", [&](auto& layer) {
525 layer.setSurfaces(surfaces);
526 layer.setEnvelope(Acts::ExtentEnvelope{{
527 .z = {0.1_mm, 0.1_mm},
528 .r = {2_mm, 2_mm},
529 }});
530 });
531
532}
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 47 of file CaloBlueprintNodeBuilder.cxx.

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

173 {
174
175
176 //loop over all possible calo sampling layers
177 //and create empty vectors of surfaces in the map
178
179 //Create map between each calorimeter sampling and a vector of
180 //cylinder surfaces. We can have N cylinders in a given sampling,
181 //and the value of N is determined by how often the average radius
182 //calculated for a given phi ring, at fixed Z, changes by more than
183 //a tolerance value
184
185 float maxR{0.}, maxPosZ{-std::numeric_limits<float>::max()}, minNegZ{std::numeric_limits<float>::max()};
186
187 //for each calo sampling collect all the DDE in a vector
188 for (const CaloDetDescrElement* theDDE : m_caloDetSecrMgr->element_range()){
189 if (!theDDE){
190 ATH_MSG_ERROR("Null pointer to CaloDetDescrElement");
191 continue;
192 }
193
194 maxR = std::max(theDDE->r(), maxR);
195 maxPosZ = std::max(maxPosZ, theDDE->z());
196 minNegZ = std::min(minNegZ, theDDE->z());
197
198 CaloCell_ID::CaloSample currentSample=theDDE->getSampling();
199 std::pair <std::string, CaloCell_ID::CaloSample> samplePair = std::make_pair(getSampleName(currentSample), currentSample);
200
201 //check if have cylinder symmetric about z = 0
202 if (Acts::rangeContainsValue(m_caloCylinderSymmetricSampleList, samplePair)){
203 caloRegionSampleDDEElementsMap[caloRegion::CylinderSymmetricZZero][samplePair].push_back(theDDE);
204 }
205
206 //check if have cylinder asymmetric about z = 0, if so check if in negative or positive z
207 if (Acts::rangeContainsValue(m_caloCylinderAsymmetricSampleList, samplePair)){
208 if (theDDE->z() < 0.0) {
209 caloRegionSampleDDEElementsMap[caloRegion::CylinderNegativeZ][samplePair].push_back(theDDE);
210 }
211 else {
212 caloRegionSampleDDEElementsMap[caloRegion::CylinderPositiveZ][samplePair].push_back(theDDE);
213 }
214 }
215
216 //check if sampling is in disc list
217 if (Acts::rangeContainsValue(m_caloDiscSampleList, samplePair)) {
218 //check if in negative or positive z
219 if (theDDE->z() < 0.0) {
220 caloRegionSampleDDEElementsMap[caloRegion::DiscNegativeZ][samplePair].push_back(theDDE);
221 } else {
222 caloRegionSampleDDEElementsMap[caloRegion::DiscPositiveZ][samplePair].push_back(theDDE);
223 }
224 }
225 }
226
227 caloDimensions["maxR"] = maxR;
228 caloDimensions["maxPosZ"] = maxPosZ;
229 caloDimensions["minNegZ"] = minNegZ;
230
231 auto sortAllLayersInZ = [&caloRegionSampleDDEElementsMap](const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList, const caloRegion& region) {
232 for (const auto & currentSample : caloSampleList) {
233 std::vector<const CaloDetDescrElement*>& currentElements = caloRegionSampleDDEElementsMap[region][currentSample];
234 std::ranges::sort(currentElements,
235 [](const CaloDetDescrElement* a,
236 const CaloDetDescrElement* b) {
237 return a->z() < b->z();
238 });
239 }
240 };
241
242 //Sort the DDE, by Z, in all possible layers
246
247 auto sortAllLayersInR = [&caloRegionSampleDDEElementsMap](const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& caloSampleList, const caloRegion& region) {
248 for (const auto& currentSample : caloSampleList) {
249 std::vector<const CaloDetDescrElement*>& currentElements = caloRegionSampleDDEElementsMap[region][currentSample];
250 std::ranges::sort(currentElements,
251 [](const CaloDetDescrElement* a,
252 const CaloDetDescrElement* b) {
253 return a->r() < b->r();
254 });
255 }
256 };
257
258 //Sort the DDE, by R, in all possible layers
261
262}
#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

◆ finalize()

StatusCode ActsTrk::CaloBlueprintNodeBuilder::finalize ( )
override

Definition at line 167 of file CaloBlueprintNodeBuilder.cxx.

167 {
168 ATH_MSG_DEBUG("Finalizing CaloBlueprintNodeBuilder");
169 return StatusCode::SUCCESS;
170}

◆ generateCylinderSurface()

std::shared_ptr< CylinderSurface > ActsTrk::CaloBlueprintNodeBuilder::generateCylinderSurface ( const double maxLArBRadius,
const double minLArBRadius,
const double lowZLarB,
const double highZLarB ) 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 379 of file CaloBlueprintNodeBuilder.cxx.

382 {
383
384 //Characterise the dimensions of the cylinder
385 double LArBRadius = (maxLArBRadius + minLArBRadius) / 2.0;
386 double LArBLength = std::abs(highZLarB - lowZLarB);
387
388 double zShift = (highZLarB + lowZLarB) / 2.0;
389 ATH_MSG_DEBUG("Cylinder radius and length are " << LArBRadius << " and " << 0.5*(LArBLength) << " with shift of " << zShift
390 <<"lowZLarB: "<<lowZLarB<<", highZLarB: "<<highZLarB);
391 return Surface::makeShared<CylinderSurface>(Amg::getTranslateZ3D(zShift), LArBRadius, LArBLength/2);
392
393}
Amg::Isometry3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis

◆ 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 264 of file CaloBlueprintNodeBuilder.cxx.

264 {
265
266 const std::vector<std::pair<std::string, CaloCell_ID::CaloSample>>& sampleList{asymmetricZ ?
268
269 for (const auto & currentSample : sampleList) {
270
271 const std::vector<const CaloDetDescrElement*>& currentElements = caloSampleDDEElementsMap[currentSample];
272
273 double maxLArBRadius = 0.0, minLArBRadius = std::numeric_limits<double>::max();
274 double lowZLarB = std::numeric_limits<double>::max(),
275 highZLarB = -std::numeric_limits<double>::max();
276
277 //loop over cells runs from -z to +z in a given sampling layer
278 //There are many cells with the same z value, but different phi values
279 //We will find the average radius of the cells in a given phi ring
280 double totalRadiusFixedPhi = 0.0;
281 bool firstCellInPhiRing = true;
282 unsigned int phiCounter = 0;
283
284 //Then we will also track changes in radius as we move in Z from
285 //each ring of cells in phi to the next ring of cells in phi
286 bool firstPhiRing = true;
287 double initialRadius = 0.0;
288 double initialZ = -std::numeric_limits<double>::max();
289
290 //check if we ever move along in Z value
291 bool movedInZ = false;
292
293 for (const CaloDetDescrElement* theDDE : currentElements){
294
295 double z = theDDE->z();
296 double radius = theDDE->r();
297
298 ATH_MSG_DEBUG(" Calo Sampling is " << currentSample.first);
299
300 if (firstCellInPhiRing) {
301 ATH_MSG_DEBUG("First Cell in phi ring " << currentSample.first << " has z = " << z << " and r = " << radius);
302 initialZ = z;
303 firstCellInPhiRing = false;
304 }
305
306 if (firstPhiRing) {
307 ATH_MSG_DEBUG("First Cell in layer " << currentSample.first << " has z = " << z << " and r = " << radius);
308 initialRadius = theDDE->r();
309 firstPhiRing = false;
310 lowZLarB = z;
311 }
312
313 ATH_MSG_DEBUG("Z and initialZ are " << z << " and " << initialZ);
314
315 //if z has not changed then we add the radius to the summed radius for this phi ring
316 //and increment the counter of cells in this phi ring
317 if (std::abs(z - initialZ) < 0.0001) {
318 ATH_MSG_DEBUG("phiCounter is " << phiCounter << " and radius is " << radius << " and totalRadiusFixedPhi is " << totalRadiusFixedPhi << " and hash is " << theDDE->calo_hash());
319 totalRadiusFixedPhi += radius;
320 phiCounter++;
321 continue;
322 }
323 else {
324 movedInZ = true;
325 firstCellInPhiRing = true;
326 if (phiCounter > 0) {
327 double cellRingRadius = totalRadiusFixedPhi / phiCounter;
328 totalRadiusFixedPhi = 0.0;
329 phiCounter = 0;
330
331 maxLArBRadius = std::max(maxLArBRadius, cellRingRadius);
332 minLArBRadius = std::min(minLArBRadius, cellRingRadius);
333
334 //if radius changes by more than tolerance, then we will create a cylinder
335 //with the average cell radius and length from neg to pos z
336 highZLarB = z;
337 ATH_MSG_DEBUG("Values of cellRingRadius, initialRadius, highZLarB and lowZLarB are " << cellRingRadius << ", " << initialRadius << ", " << highZLarB << " and " << lowZLarB);
338 if (std::abs(cellRingRadius - initialRadius) > m_radiusTolerance &&
339 highZLarB - lowZLarB > 0.0) {
340 ATH_MSG_DEBUG("CYLINDER: Create cylinder for layer " << currentSample.first);
341 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius << " " << maxLArBRadius);
342 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB << " " << highZLarB);
343
344 caloSampleSurfaceMap[currentSample].push_back(generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB));
345
346 //reset the dimensions of the cylinder to the initial conditions, in
347 //preparation for the next cylinder
348 firstPhiRing = true;
349 minLArBRadius = std::numeric_limits<double>::max();
350 maxLArBRadius = 0.0;
351 lowZLarB = 0.0;
352 highZLarB = 0.0;
353 }//if radius changes by more than tolerance
354 }//if at least one cell in phi (should always be the case!)
355 else ATH_MSG_ERROR("phiCounter is zero!");
356 }//if z has changed
357 }//loop over calorimeter DDE
358
359 if (0 == caloSampleSurfaceMap[currentSample].size()){
360 //If we never found any shift in Z whilst looping over the DDE
361 //then thee min/max Z and radius were not set
362 //so we set them here.
363 if (!movedInZ) {
364 lowZLarB = initialZ;
365 highZLarB = initialZ+0.001;
366 if (phiCounter > 0) {
367 maxLArBRadius = totalRadiusFixedPhi / phiCounter;
368 minLArBRadius = 0.0;
369 }
370 }
371 ATH_MSG_DEBUG("CYLINDER: Zero size Vector: Create cylinder for layer " << currentSample.first);
372 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B radius are " << minLArBRadius << " " << maxLArBRadius);
373 ATH_MSG_DEBUG("CYLINDER: Create Cylinder: Min and Max LAr B z are " << lowZLarB << " " << highZLarB);
374 caloSampleSurfaceMap[currentSample].push_back(generateCylinderSurface(maxLArBRadius, minLArBRadius, lowZLarB, highZLarB));
375 }
376 }
377}
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) 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 503 of file CaloBlueprintNodeBuilder.cxx.

503 {
504
505 ATH_MSG_DEBUG("DISC: Disc min and max radius are " << minLArBRadius << " and " << maxLArBRadius << " with z of " << z);
506 auto surface = Surface::makeShared<DiscSurface>(Amg::getTranslateZ3D(z), minLArBRadius, maxLArBRadius);
507
508 return surface;
509
510}

◆ generateDiscSurfaces()

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

Definition at line 395 of file CaloBlueprintNodeBuilder.cxx.

395 {
396
397 for (const auto & currentSample : m_caloDiscSampleList) {
398
399 const std::vector<const CaloDetDescrElement*> & currentElements = caloSampleDDEElementsMap[currentSample];
400
401 //FCAL is treated differently because it is non-projective
402 //We create one surface for each of FCAL0, FCAL1 and FCAL2
403 if (CaloCell_ID::FCAL0 == currentSample.second || CaloCell_ID::FCAL1 == currentSample.second || CaloCell_ID::FCAL2 == currentSample.second) {
404 ATH_MSG_DEBUG("TOM3: FCAL sampling " << currentSample.second);
405
406 double fcalRMin = std::numeric_limits<double>::max();
407 double fcalRMax = std::numeric_limits<double>::min();
408 double fcalZSum = 0;
409 size_t cellCount = 0;
410
411 for (const CaloDetDescrElement* theDDE : currentElements) {
412 double r = theDDE->r();
413 fcalRMin = std::min(fcalRMin,r);
414 fcalRMax = std::max(fcalRMax,r);
415 fcalZSum += theDDE->z();
416 cellCount++;
417 }
418 if (cellCount == 0)[[unlikely]]{
419 ATH_MSG_WARNING("cellCount is zero in CaloBlueprintNodeBuilder::generateDiscSurfaces");
420 continue;
421 }
422 double fcalZ = fcalZSum / cellCount;
423 caloSampleSurfaceMap[currentSample].push_back(generateDiscSurface(fcalZ,fcalRMax, fcalRMin));
424 //now continue to the next sampling
425 continue;
426 }
427
428 //For other disc calorimeter layers we proceed to create many surfaces as needed.
429 double totalZFixedPhi = 0.0;
430 bool firstCellInPhiRing = true;
431 unsigned int phiCounter = 0;
432
433 bool firstPhiRing = true;
434 double initialRadius = 0.0;
435 double initialZ = -std::numeric_limits<double>::max();
436
437 //loop over cells runs from -z to +z in a given sampling layer
438 //There are many cells with the same z value, but different phi values
439 //We will find a min amd max radius in this phi ring.
440 double minDiscRadius = std::numeric_limits<double>::max(), maxDiscRadius = 0.0;
441
442 unsigned int currentElementsSize = currentElements.size();
443 unsigned int DDECounter = 0;
444
445 for (const CaloDetDescrElement* theDDE : currentElements){
446
447 bool isLastDDE = (DDECounter == (currentElementsSize-1));
448
449 ATH_MSG_DEBUG("Disc DDE with sampling, r and z of " << currentSample << ", " << theDDE->r() << ", " << theDDE->z());
450 ATH_MSG_DEBUG("isLastDDE is " << isLastDDE);
451
452 double z = theDDE->z();
453 double radius = theDDE->r();
454
455 if (firstCellInPhiRing) {
456 initialRadius = radius;
457 firstCellInPhiRing = false;
458 }
459
460 if (firstPhiRing) {
461 initialZ = z;
462 firstPhiRing = false;
463 minDiscRadius = radius;
464 }
465
466 //if radius is unchanged then we add the z to the summed z for this phi ring
467 //and increment the counter of cells in this phi ring
468 if (std::abs(radius - initialRadius) < 0.0001 && !isLastDDE) {
469 totalZFixedPhi += z;
470 phiCounter++;
471 DDECounter++;
472 continue;
473 }
474 else {
475 firstCellInPhiRing = true;
476 if (phiCounter > 0) {
477 double cellRingZ = totalZFixedPhi / phiCounter;
478 totalZFixedPhi = 0.0;
479 phiCounter = 0;
480
481 //if z changes by more than tolerance, then we will create a disc
482 //with the min and max radius found
483 //if we reach the last DDE and no new surface has been created, then we also create a disc surface
484 maxDiscRadius = radius;
485 ATH_MSG_DEBUG("cellRingZ, initialZ and z tolerance are " << cellRingZ << ", " << initialZ << " and " << m_zTolerance);
486 if (std::abs(cellRingZ - initialZ) > m_zTolerance || isLastDDE) {
487 ATH_MSG_DEBUG("DISC: About to create disc surface for sampling " << currentSample);
488 caloSampleSurfaceMap[currentSample].push_back(generateDiscSurface(cellRingZ,maxDiscRadius, minDiscRadius));
489 //reset the dimensions of the disc to the initial conditions, in
490 //preparation for the next disc
491 minDiscRadius = std::numeric_limits<double>::max();
492 maxDiscRadius = 0.0;
493 firstPhiRing = true;
494 }//if z changes by more than tolerance
495 }//if at least one cell in phi (should always be the case!)
496 else ATH_MSG_ERROR("phiCounter is zero!");
497 }//if radius has changed
498 DDECounter++;
499 }//loop over calorimeter DDE
500 }//loop over calo samplings
501}
#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 156 of file CaloBlueprintNodeBuilder.h.

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

◆ getSampleName()

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

Definition at line 129 of file CaloBlueprintNodeBuilder.h.

129 {
130 std::string sampleName = "";
131 for ( auto& [name, sample] : m_caloCylinderSymmetricSampleList) {
132 if (currentSample == sample) {
134 break;
135 }
136 }
137 if (sampleName == "") {
138 for ( auto& [name, sample] : m_caloCylinderAsymmetricSampleList) {
139 if (currentSample == sample) {
141 break;
142 }
143 }
144 }
145 if (sampleName == "") {
146 for ( auto& [name, sample] : m_caloDiscSampleList) {
147 if (currentSample == sample) {
149 break;
150 }
151 }
152 }
153 return sampleName;
154 }

◆ initialize()

StatusCode ActsTrk::CaloBlueprintNodeBuilder::initialize ( )
override

Definition at line 39 of file CaloBlueprintNodeBuilder.cxx.

39 {
40 ATH_MSG_DEBUG("Initializing CaloBlueprintNodeBuilder");
41
43
44 return StatusCode::SUCCESS;
45}
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 111 of file CaloBlueprintNodeBuilder.h.

111 {
112 {"TileGap1", CaloCell_ID::TileGap1},
113 {"TileGap2", CaloCell_ID::TileGap2},
114 {"TileExt0", CaloCell_ID::TileExt0},
115 {"TileExt1", CaloCell_ID::TileExt1},
116 {"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 102 of file CaloBlueprintNodeBuilder.h.

102 {
103 { "PreSamplerB", CaloCell_ID::PreSamplerB},
104 {"EMB1", CaloCell_ID::EMB1},
105 {"EMB2", CaloCell_ID::EMB2},
106 {"EMB3", CaloCell_ID::EMB3},
107 {"TileBar0", CaloCell_ID::TileBar0},
108 {"TileBar1", CaloCell_ID::TileBar1},
109 {"TileBar2", CaloCell_ID::TileBar2}};

◆ m_caloDetSecrMgr

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

Definition at line 83 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 88 of file CaloBlueprintNodeBuilder.h.

88 {
89 {"PreSamplerE", CaloCell_ID::PreSamplerE},
90 {"EME1",CaloCell_ID::EME1},
91 {"EME2",CaloCell_ID::EME2},
92 {"EME3",CaloCell_ID::EME3},
93 {"HEC0",CaloCell_ID::HEC0},
94 {"HEC1",CaloCell_ID::HEC1},
95 {"HEC2",CaloCell_ID::HEC2},
96 {"HEC3",CaloCell_ID::HEC3},
97 {"TileGap3",CaloCell_ID::TileGap3},
98 {"FCAL0",CaloCell_ID::FCAL0},
99 {"FCAL1",CaloCell_ID::FCAL1},
100 {"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 118 of file CaloBlueprintNodeBuilder.h.

118 { this
119 , "RadiusTolerance"
120 , 2.0
121 , "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 123 of file CaloBlueprintNodeBuilder.h.

123 { this
124 , "ZTolerance"
125 , 2.0
126 , "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: