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

Helper class to build the ItkBlueprint node It adds the system as a node to the Blueprint. More...

#include <ItkBlueprintNodeBuilder.h>

Inheritance diagram for ActsTrk::ItkBlueprintNodeBuilder:
Collaboration diagram for ActsTrk::ItkBlueprintNodeBuilder:

Public Member Functions

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

Private Member Functions

void buildItkStripBlueprintNode (const Acts::GeometryContext &gctx, Acts::Experimental::BlueprintNode &node)
void buildItkPixelBlueprintNode (const Acts::GeometryContext &gctx, Acts::Experimental::BlueprintNode &node)

Private Attributes

const InDetDD::SiDetectorManagerm_itkPixelMgr {nullptr}
const InDetDD::SiDetectorManagerm_itkStripMgr {nullptr}
std::shared_ptr< ActsElementVectorm_elementStore {nullptr}
Gaudi::Property< bool > m_doEndcapLayerMerging
Gaudi::Property< bool > m_buildPixel {this, "buildPixel", true}
Gaudi::Property< bool > m_buildStrip {this, "buildStrip", true}

Detailed Description

Helper class to build the ItkBlueprint node It adds the system as a node to the Blueprint.

Definition at line 19 of file ItkBlueprintNodeBuilder.h.

Member Function Documentation

◆ buildBlueprintNode()

std::shared_ptr< Acts::Experimental::BlueprintNode > ActsTrk::ItkBlueprintNodeBuilder::buildBlueprintNode ( const Acts::GeometryContext & gctx,
std::shared_ptr< Acts::Experimental::BlueprintNode > && child )
override

Build the Itk Blueprint Node.

Parameters
gctxGeometry context
childOptional beam pipe node to nest inside the ITk AxisR container.

Definition at line 203 of file ItkBlueprintNodeBuilder.cxx.

205 {
206
207 auto itkNode =
208 std::make_shared<Acts::Experimental::CylinderContainerBlueprintNode>(
209 "itkNode", AxisZ);
210 itkNode->setAttachmentStrategy(AttachmentStrategy::Gap);
211 itkNode->setResizeStrategy(ResizeStrategy::Gap);
212
213 auto& itk = itkNode->addCylinderContainer("ItkNodeMain", AxisR);
214 itk.setAttachmentStrategy(AttachmentStrategy::Gap);
215 itk.setResizeStrategy(ResizeStrategy::Gap);
216
217 itk.addMaterial("ItkNodeMain_Material", [&](auto& mat) {
218 if (m_buildStrip) {
219 mat.configureFace(NegativeDisc, {AxisR, Bound, 20}, {AxisPhi, Closed, 40});
220 mat.configureFace(PositiveDisc, {AxisR, Bound, 20}, {AxisPhi, Closed, 40});
221 }
222
223 auto& innerContainer = mat.addCylinderContainer("ITkInnerContainer", AxisR);
224
225 // Beam pipe is passed in as an optional child from BeamPipeBlueprintNodeBuilder
226 if (childNode) {
227 innerContainer.addChild(std::move(childNode));
228 }
229
230 if (m_buildPixel) {
231 buildItkPixelBlueprintNode(gctx, innerContainer);
232 }
233 if (m_buildStrip) {
234 buildItkStripBlueprintNode(gctx, innerContainer);
235 }
236 });
237
238 return itkNode;
239}
void buildItkPixelBlueprintNode(const Acts::GeometryContext &gctx, Acts::Experimental::BlueprintNode &node)
void buildItkStripBlueprintNode(const Acts::GeometryContext &gctx, Acts::Experimental::BlueprintNode &node)

◆ buildItkPixelBlueprintNode()

void ActsTrk::ItkBlueprintNodeBuilder::buildItkPixelBlueprintNode ( const Acts::GeometryContext & gctx,
Acts::Experimental::BlueprintNode & node )
private

Definition at line 241 of file ItkBlueprintNodeBuilder.cxx.

243 {
244
245 // Get ITkPixel parameters from detector manager
246 if (!m_itkPixelMgr) {
247 ATH_MSG_ERROR("ITkPixel manager not available");
248 throw std::runtime_error("ITkPixel manager not available");
249 }
250
251 ATH_MSG_DEBUG("Detector manager has "
252 << m_itkPixelMgr->getDetectorElementCollection()->size()
253 << " elements");
254
255 std::vector<std::shared_ptr<ActsDetectorElement>> elements;
256
258 for (const auto* element : *m_itkPixelMgr->getDetectorElementCollection()) {
259 const InDetDD::SiDetectorElement* siDetElement =
260 dynamic_cast<const InDetDD::SiDetectorElement*>(element);
261 if (siDetElement == nullptr) {
262 ATH_MSG_ERROR("Detector element was nullptr");
263 throw std::runtime_error{"Corrupt detector element collection"};
264 }
265 elements.push_back(std::make_shared<ActsDetectorElement>(*siDetElement));
266 }
267 ATH_MSG_VERBOSE("Retrieved " << elements.size() << " elements");
268
269 // Copy to service level store to extend lifetime
270 m_elementStore->vector().insert(m_elementStore->vector().end(),
271 elements.begin(), elements.end());
272
273 // Inner pixel: 2 innermost barrel layers + inner endcap disks
274 auto& innerPixel = node.addCylinderContainer("InnerPixel", AxisR);
275 innerPixel.setAttachmentStrategy(AttachmentStrategy::Gap);
276 innerPixel.setResizeStrategy(ResizeStrategy::Gap);
277
278 innerPixel.addMaterial("InnerPixelMaterial", [&](auto& mat) {
279 mat.configureFace(OuterCylinder, {AxisRPhi, Closed, 20},
280 {AxisZ, Bound, 20});
281 mat.configureFace(InnerCylinder, {AxisRPhi, Closed, 20},
282 {AxisZ, Bound, 20});
283
284 auto& innerPixelContainer = mat.addCylinderContainer("InnerPixel", AxisZ);
285
286 // Add barrel container
287 auto& barrelGeoId = innerPixelContainer.withGeometryIdentifier();
288 barrelGeoId.setAllVolumeIdsTo(s_innerPixelVolumeId)
289 .incrementLayerIds(1)
290 .sortBy([](auto& a, auto& b) {
291 auto& boundsA =
292 dynamic_cast<const Acts::CylinderVolumeBounds&>(a.volumeBounds());
293 auto& boundsB =
294 dynamic_cast<const Acts::CylinderVolumeBounds&>(b.volumeBounds());
295
296 using enum Acts::CylinderVolumeBounds::BoundValues;
297 double aMidR = (boundsA.get(eMinR) + boundsA.get(eMaxR)) / 2.0;
298 double bMidR = (boundsB.get(eMinR) + boundsB.get(eMaxR)) / 2.0;
299
300 return aMidR < bMidR;
301 });
302
303 auto& brl_mat =
304 barrelGeoId.addMaterial("InnerPixel_Material", [&](auto& mat) {
305 mat.configureFace(NegativeDisc, {AxisR, Bound, 10},
306 {AxisPhi, Closed, 10});
307 mat.configureFace(PositiveDisc, {AxisR, Bound, 10},
308 {AxisPhi, Closed, 10});
309 });
310 auto& barrel = brl_mat.addCylinderContainer("InnerPixel_Brl", AxisR);
311
312 barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
313 barrel.setResizeStrategy(ResizeStrategy::Gap);
314
315 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>> layers{};
316
317 for (auto& element : elements) {
318 IdentityHelper id = element->identityHelper();
319 if (id.bec() != 0) {
320 continue;
321 }
322
323 if (id.layer_disk() >= 2) {
324 continue;
325 }
326
327 int elementLayer = id.layer_disk();
328 layers[elementLayer].push_back(element->surface().getSharedPtr());
329 }
330
331 ATH_MSG_DEBUG("Adding " << layers.size() << " layers to InnerPixel barrel");
332
333 for (const auto& [ilayer, surfaces] : layers) {
334 ATH_MSG_DEBUG("- Layer " << ilayer << " has " << surfaces.size()
335 << " surfaces");
336
337 barrel.addMaterial(
338 std::format("InnerPixel_Brl_{}_Material", ilayer), [&](auto& lmat) {
339 lmat.configureFace(OuterCylinder, {AxisRPhi, Closed, 40},
340 {AxisZ, Bound, 20});
341
342 auto& layer =
343 lmat.addLayer(std::format("InnerPixel_Brl_{}", ilayer));
344
345 layer.setNavigationPolicyFactory(
346 Acts::NavigationPolicyFactory{}
347 .add<Acts::SurfaceArrayNavigationPolicy>(
348 Acts::SurfaceArrayNavigationPolicy::Config{
349 .layerType = Cylinder,
350 .bins = {30, 10}})
351 .add<Acts::TryAllNavigationPolicy>(
352 Acts::TryAllNavigationPolicy::Config{.sensitives =
353 false})
354 .asUniquePtr());
355
356 layer.setSurfaces(surfaces);
357 layer.setEnvelope(Acts::ExtentEnvelope{{
358 .z = {5_mm, 5_mm},
359 .r = {2_mm, 2_mm},
360 }});
361 });
362 }
363
364 // Add endcap containers
365 for (int bec : {-2, 2}) {
366 std::string s = bec > 0 ? "p" : "n";
367 auto& ecGeoId = innerPixelContainer.withGeometryIdentifier();
368 ecGeoId.setAllVolumeIdsTo(s_innerPixelVolumeId + std::floor(bec / 2))
369 .incrementLayerIds(1);
370 auto& ec = ecGeoId.addCylinderContainer("InnerPixel_" + s + "EC", AxisZ);
371 ec.setAttachmentStrategy(AttachmentStrategy::Gap);
372 ec.setResizeStrategy(ResizeStrategy::Gap);
373
374 std::map<std::tuple<int, int, int>,
375 std::vector<std::shared_ptr<Acts::Surface>>>
376 initialLayers{};
377
378 for (auto& element : elements) {
379 IdentityHelper id = element->identityHelper();
380 if (id.bec() * bec <= 0) {
381 continue;
382 }
383
384 if (id.layer_disk() >= 3) {
385 continue;
386 }
387
388 std::tuple<int, int, int> key{id.bec(), id.layer_disk(),
389 id.eta_module()};
390 initialLayers[key].push_back(element->surface().getSharedPtr());
391 }
392
393 ATH_MSG_DEBUG("Found " << initialLayers.size()
394 << " initial layers to InnerPixel " << s << "EC");
395
396 std::vector<LayerData> protoLayers;
397 protoLayers.reserve(initialLayers.size());
398
399 for (const auto& [key, surfaces] : initialLayers) {
400 auto& layer = protoLayers.emplace_back(gctx, surfaces);
401 layer.protoLayer.envelope[AxisR] = {2_mm, 2_mm};
402 layer.protoLayer.envelope[AxisZ] = {1_mm, 1_mm};
403 }
404
405 std::ranges::sort(protoLayers,
406 [](const LayerData& a, const LayerData& b) {
407 return std::abs(a.protoLayer.medium(AxisZ)) <
408 std::abs(b.protoLayer.medium(AxisZ));
409 });
410
411 ATH_MSG_DEBUG("Found " << protoLayers.size() << " initial layers");
412
413 std::vector<LayerData> mergedLayers;
415 mergedLayers = mergeLayers(gctx, std::move(protoLayers));
416 } else {
417 mergedLayers = std::move(protoLayers);
418 }
419
420 ATH_MSG_DEBUG("After merging: " << mergedLayers.size() << " layers");
421
422 for (const auto [key, pl] : Acts::enumerate(mergedLayers)) {
423 ATH_MSG_DEBUG("- Layer " << key << " has " << pl.surfaces.size()
424 << " surfaces");
425
426 pl.protoLayer.medium(AxisZ);
427 auto layerName = std::format("InnerPixel_{}EC_{}", key, s);
428
429 auto addLayer = [&layerName, &pl](auto& parent) {
430 auto& layer = parent.addLayer(layerName);
431
432 layer.setNavigationPolicyFactory(
433 Acts::NavigationPolicyFactory{}
434 .add<Acts::SurfaceArrayNavigationPolicy>(
435 Acts::SurfaceArrayNavigationPolicy::Config{
436 .layerType = Disc,
437 .bins = {30, 30}})
438 .add<Acts::TryAllNavigationPolicy>(
439 Acts::TryAllNavigationPolicy::Config{.sensitives = false})
440 .asUniquePtr());
441
442 layer.setSurfaces(pl.surfaces);
443 layer.setEnvelope(Acts::ExtentEnvelope{{
444 .z = {1_mm, 1_mm},
445 .r = {2_mm, 2_mm},
446 }});
447 };
448
449 ATH_MSG_VERBOSE("Add inner pixel layer"
450 << key << " / " << mergedLayers.size()
451 << " at z = " << pl.protoLayer.medium(AxisZ));
452 ATH_MSG_VERBOSE("Adding material for layer " << layerName);
453 ec.addMaterial(layerName + "_Material", [&](auto& lmat) {
454 lmat.configureFace(NegativeDisc, {AxisR, Bound, 10},
455 {AxisPhi, Closed, 40});
456 lmat.configureFace(PositiveDisc, {AxisR, Bound, 10},
457 {AxisPhi, Closed, 40});
458 addLayer(lmat);
459 });
460 }
461 }
462 });
463
464 // Outer pixel: 3 outer barrel layers + outer endcaps
465 auto& outerPixel = node.addCylinderContainer("OuterPixel", AxisR);
466 outerPixel.setAttachmentStrategy(AttachmentStrategy::Gap);
467 outerPixel.setResizeStrategy(ResizeStrategy::Gap);
468
469 outerPixel.addMaterial("OuterPixelMaterial", [&](auto& opmat) {
470 opmat.configureFace(OuterCylinder, {AxisRPhi, Bound, 20}, {AxisZ, Bound, 20});
471 opmat.configureFace(InnerCylinder, {AxisRPhi, Bound, 20}, {AxisZ, Bound, 20});
472
473 auto& outerPixelContainer = opmat.addCylinderContainer("OuterPixel", AxisZ);
474
475 auto& barrelGeoId = outerPixelContainer.withGeometryIdentifier();
476 barrelGeoId.setAllVolumeIdsTo(s_outerPixelVolumeId).incrementLayerIds(1);
477
478 auto& brl_mat =
479 barrelGeoId.addMaterial("OuterPixel_Material", [&](auto& bmat) {
480 bmat.configureFace(NegativeDisc, {AxisR, Bound, 10},
481 {AxisPhi, Closed, 10});
482 bmat.configureFace(PositiveDisc, {AxisR, Bound, 10},
483 {AxisPhi, Closed, 10});
484 });
485 auto& barrel = brl_mat.addCylinderContainer("OuterPixel_Brl", AxisR);
486
487 barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
488 barrel.setResizeStrategy(ResizeStrategy::Gap);
489
490 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>> layers{};
491
492 for (auto& element : elements) {
493 IdentityHelper id = element->identityHelper();
494 if (id.bec() != 0) {
495 continue;
496 }
497
498 if (id.layer_disk() <= 1) {
499 continue;
500 }
501
502 int elementLayer = id.layer_disk();
503 layers[elementLayer].push_back(element->surface().getSharedPtr());
504 }
505
506 ATH_MSG_DEBUG("Adding " << layers.size() << " layers to OuterPixel barrel");
507
508 for (const auto& [ilayer, surfaces] : layers) {
509 ATH_MSG_DEBUG("- Layer " << ilayer << " has " << surfaces.size()
510 << " surfaces");
511
512 barrel.addMaterial(
513 std::format("OuterPixel_Brl_{}_Material", ilayer), [&](auto& lmat) {
514 lmat.configureFace(OuterCylinder, {AxisRPhi, Closed, 40},
515 {AxisZ, Bound, 20});
516
517 auto& layer =
518 lmat.addLayer("OuterPixel_Brl_" + std::to_string(ilayer));
519
520 layer.setNavigationPolicyFactory(
521 Acts::NavigationPolicyFactory{}
522 .add<Acts::SurfaceArrayNavigationPolicy>(
523 Acts::SurfaceArrayNavigationPolicy::Config{
524 .layerType = Cylinder,
525 .bins = {30, 10}})
526 .add<Acts::TryAllNavigationPolicy>(
527 Acts::TryAllNavigationPolicy::Config{.sensitives =
528 false})
529 .asUniquePtr());
530
531 layer.setSurfaces(surfaces);
532 layer.setEnvelope(Acts::ExtentEnvelope{{
533 .z = {5_mm, 5_mm},
534 .r = {2_mm, 2_mm},
535 }});
536 });
537 }
538
539 constexpr static auto addEndcapLayer = [](auto& parent, const auto& name,
540 const auto& surfaces) {
541 parent.addLayer(name, [&surfaces](auto& layer) {
542 layer.setNavigationPolicyFactory(
543 Acts::NavigationPolicyFactory{}
544 .add<Acts::SurfaceArrayNavigationPolicy>(
545 Acts::SurfaceArrayNavigationPolicy::Config{
546 .layerType = Disc, .bins = {30, 30}})
547 .add<Acts::TryAllNavigationPolicy>(
548 Acts::TryAllNavigationPolicy::Config{.sensitives = false})
549 .asUniquePtr());
550
551 layer.setSurfaces(surfaces);
552 });
553 };
554
555 for (int bec : {-2, 2}) {
556 const std::string s = bec > 0 ? "p" : "n";
557
558 auto& ec_outer_geoId = outerPixelContainer.withGeometryIdentifier();
559 ec_outer_geoId
560 .setAllVolumeIdsTo(s_outerPixelVolumeId + std::floor(bec / 2))
561 .incrementLayerIds(1);
562
563 auto& ec_outer =
564 ec_outer_geoId.addCylinderContainer("OuterPixel_" + s + "EC", AxisR);
565
566 // Three groups of disks stacked in R
567 std::array diskGroups{std::pair{3, 4}, std::pair{6, 5}, std::pair{7, 8}};
568
569 for (size_t idx = 0; idx < diskGroups.size(); ++idx) {
570 auto [disk1, disk2] = diskGroups[idx];
571
572 Acts::Experimental::MaterialDesignatorBlueprintNode* material = nullptr;
573 if (idx < (diskGroups.size() - 1)) {
574 material = &ec_outer.addMaterial(
575 "OuterPixel_" + s + "EC_" + std::to_string(idx) + "_Material",
576 [&](auto& mat) {
577 mat.configureFace(OuterCylinder, {AxisRPhi, Closed, 20},
578 {AxisZ, Bound, 20});
579 });
580 }
581
582 auto& ec_stack =
583 material
584 ? material->addCylinderContainer(
585 "OuterPixel_" + s + "EC_" + std::to_string(idx), AxisZ)
586 : ec_outer.addCylinderContainer(
587 "OuterPixel_" + s + "EC_" + std::to_string(idx), AxisZ);
588
589 ec_stack.setAttachmentStrategy(AttachmentStrategy::Gap);
590 ec_stack.setResizeStrategy(ResizeStrategy::Gap);
591
592 std::map<std::tuple<int, int>,
593 std::vector<std::shared_ptr<Acts::Surface>>>
594 eta_rings;
595
596 for (auto& element : elements) {
597 IdentityHelper id = element->identityHelper();
598 if (id.bec() != bec ||
599 (id.layer_disk() != disk1 && id.layer_disk() != disk2)) {
600 continue;
601 }
602 std::tuple<int, int> key{id.layer_disk(), id.eta_module()};
603 eta_rings[key].push_back(element->surface().getSharedPtr());
604 }
605
606 ATH_MSG_DEBUG("Found " << eta_rings.size() << " eta rings in group "
607 << idx);
608
609 std::vector<std::vector<std::shared_ptr<Acts::Surface>>> sorted_rings;
610 sorted_rings.reserve(eta_rings.size());
611 for (const auto& [key, surfaces] : eta_rings) {
612 sorted_rings.push_back(surfaces);
613 }
614
615 std::ranges::sort(sorted_rings, [&gctx](const auto& a, const auto& b) {
616 Acts::ProtoLayer pl_a(gctx, makeConstPtrVector(a));
617 Acts::ProtoLayer pl_b(gctx, makeConstPtrVector(b));
618 return std::abs(pl_a.min(AxisZ)) < std::abs(pl_b.min(AxisZ));
619 });
620
621 for (size_t i = 0; i < sorted_rings.size(); ++i) {
622 const auto& surfaces = sorted_rings[i];
623 auto layerName = "OuterPixel_" + s + "EC_" + std::to_string(idx) +
624 "_" + std::to_string(i);
625
626 ec_stack.addMaterial(layerName + "_Material", [&](auto& mat) {
627 mat.configureFace(PositiveDisc, {AxisR, Bound, 10},
628 {AxisPhi, Closed, 40});
629 mat.configureFace(NegativeDisc, {AxisR, Bound, 10},
630 {AxisPhi, Closed, 40});
631 addEndcapLayer(mat, layerName, surfaces);
632 });
633 }
634 }
635 }
636 });
637}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static Double_t a
const InDetDD::SiDetectorManager * m_itkPixelMgr
std::shared_ptr< ActsElementVector > m_elementStore
Gaudi::Property< bool > m_doEndcapLayerMerging
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
constexpr std::size_t s_outerPixelVolumeId
constexpr std::size_t s_innerPixelVolumeId
layers(flags, cells_name, *args, **kw)
Here we define wrapper functions to set up all of the standard corrections.
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
@ layer
Definition HitInfo.h:79

◆ buildItkStripBlueprintNode()

void ActsTrk::ItkBlueprintNodeBuilder::buildItkStripBlueprintNode ( const Acts::GeometryContext & gctx,
Acts::Experimental::BlueprintNode & node )
private

Definition at line 639 of file ItkBlueprintNodeBuilder.cxx.

641 {
642
643 // Get ITkStrip parameters from detector manager
644 if (!m_itkStripMgr) {
645 ATH_MSG_ERROR("ITkStrip manager not available");
646 throw std::runtime_error("ITkStrip manager not available");
647 }
648
649 ATH_MSG_DEBUG("Detector manager has "
650 << m_itkStripMgr->getDetectorElementCollection()->size()
651 << " elements");
652
653 std::vector<std::shared_ptr<ActsDetectorElement>> elements;
654
656 for (const auto* element : *m_itkStripMgr->getDetectorElementCollection()) {
657 const InDetDD::SiDetectorElement* siDetElement =
658 dynamic_cast<const InDetDD::SiDetectorElement*>(element);
659 if (siDetElement == nullptr) {
660 ATH_MSG_ERROR("Detector element was nullptr");
661 throw std::runtime_error{"Corrupt detector element collection"};
662 }
663 elements.push_back(std::make_shared<ActsDetectorElement>(*siDetElement));
664 }
665 ATH_MSG_VERBOSE("Retrieved " << elements.size() << " elements");
666
667 // Copy to service level store to extend lifetime
668 m_elementStore->vector().insert(m_elementStore->vector().end(),
669 elements.begin(), elements.end());
670
671 auto& strip = node.addCylinderContainer("Strip", AxisR);
672 strip.setAttachmentStrategy(AttachmentStrategy::Gap);
673 strip.setResizeStrategy(ResizeStrategy::Gap);
674
675 strip.addMaterial("StripMaterial", [&](auto& mat) {
676 mat.configureFace(OuterCylinder, {AxisRPhi, Closed, 20},
677 {AxisZ, Bound, 20});
678 mat.configureFace(InnerCylinder, {AxisRPhi, Closed, 20},
679 {AxisZ, Bound, 20});
680
681 auto& stripContainer = mat.addCylinderContainer("Strip", AxisZ);
682
683 // Add barrel container
684 stripContainer.withGeometryIdentifier([this, &elements](auto& geoId) {
685 geoId.setAllVolumeIdsTo(s_stripVolumeId).incrementLayerIds(1);
686
687 auto& brl_mat = geoId.addMaterial("Strip_Brl_Material", [&](auto& mat) {
688 mat.configureFace(NegativeDisc, {AxisR, Bound, 10},
689 {AxisPhi, Closed, 10});
690 mat.configureFace(PositiveDisc, {AxisR, Bound, 10},
691 {AxisPhi, Closed, 10});
692 });
693 brl_mat.addCylinderContainer(
694 "Strip_Brl", AxisR, [this, &elements](auto& barrel) {
695 barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
696 barrel.setResizeStrategy(ResizeStrategy::Gap);
697
698 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>> layers{};
699
700 for (auto& element : elements) {
701 IdentityHelper id = element->identityHelper();
702 if (id.bec() != 0) {
703 continue;
704 }
705
706 int elementLayer = id.layer_disk();
707 layers[elementLayer].push_back(element->surface().getSharedPtr());
708 }
709
710 ATH_MSG_DEBUG("Adding " << layers.size()
711 << " layers to Strip barrel");
712
713 for (const auto& [ilayer, surfaces] : layers) {
714 ATH_MSG_DEBUG("- Layer " << ilayer << " has " << surfaces.size()
715 << " surfaces");
716 addStripBarrelLayer(barrel, ilayer, surfaces);
717 }
718 });
719 });
720
721 // Add endcap containers
722 for (int bec : {-2, 2}) {
723 const std::string s = bec > 0 ? "p" : "n";
724
725 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>> layers{};
726
727 for (auto& element : elements) {
728 IdentityHelper id = element->identityHelper();
729 if (id.bec() * bec <= 0) {
730 continue;
731 }
732
733 layers[id.layer_disk()].push_back(element->surface().getSharedPtr());
734 }
735
736 ATH_MSG_DEBUG("Found " << layers.size() << " layers in Strip " << s
737 << "EC");
738
739 std::vector<std::vector<std::shared_ptr<Acts::Surface>>> sorted_layers;
740 sorted_layers.reserve(layers.size());
741 for (const auto& [key, surfaces] : layers) {
742 sorted_layers.push_back(surfaces);
743 }
744
745 std::sort(sorted_layers.begin(), sorted_layers.end(),
746 [&gctx](const auto& a, const auto& b) {
747 Acts::ProtoLayer pl_a(gctx, makeConstPtrVector(a));
748 Acts::ProtoLayer pl_b(gctx, makeConstPtrVector(b));
749 return std::abs(pl_a.min(AxisZ)) < std::abs(pl_b.min(AxisZ));
750 });
751
752 stripContainer.withGeometryIdentifier([&sorted_layers, bec,
753 &s](auto& geoId) {
754 geoId.setAllVolumeIdsTo(s_stripVolumeId + std::floor(bec / 2))
755 .incrementLayerIds(1);
756
757 geoId.addCylinderContainer(
758 "Strip_" + s + "EC", AxisZ, [&sorted_layers, &s](auto& ec) {
759 ec.setAttachmentStrategy(AttachmentStrategy::Gap);
760 ec.setResizeStrategy(ResizeStrategy::Gap);
761
762 for (size_t i = 0; i < sorted_layers.size(); ++i) {
763 const auto& surfaces = sorted_layers[i];
764 auto layerName = "Strip_" + s + "EC_" + std::to_string(i);
765 addStripEndcapLayer(ec, layerName, surfaces);
766 }
767 });
768 });
769 };
770 });
771
772 // Explicit spacer volume beyond the strip detector's natural outer radius.
773 // Without it, the outer cylinder carrying the strip container material
774 // coincides with the ITk node boundary, causing volume merging issues.
775 std::vector<std::shared_ptr<Acts::Surface>> allStripSurfaces;
776 allStripSurfaces.reserve(elements.size());
777 for (auto& element : elements) {
778 allStripSurfaces.push_back(element->surface().getSharedPtr());
779 }
780 Acts::ProtoLayer stripExtent(gctx, makeConstPtrVector(allStripSurfaces));
781
782 constexpr double spacerClearance = 5_mm;
783 constexpr double spacerThickness = 5_mm;
784 double spacerRmin = stripExtent.max(AxisR) + spacerClearance;
785 double spacerHalfZ = std::max(std::abs(stripExtent.min(AxisZ)),
786 std::abs(stripExtent.max(AxisZ))) +
787 spacerClearance;
788
789 strip.addStaticVolume(
790 Acts::Transform3::Identity(),
791 std::make_shared<Acts::CylinderVolumeBounds>(
792 spacerRmin, spacerRmin + spacerThickness, spacerHalfZ),
793 "Strip_OuterSpacer");
794}
const InDetDD::SiDetectorManager * m_itkStripMgr
constexpr std::size_t s_stripVolumeId
Volume Ids used within the ITk.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ initialize()

StatusCode ActsTrk::ItkBlueprintNodeBuilder::initialize ( )
override

Definition at line 190 of file ItkBlueprintNodeBuilder.cxx.

190 {
191 // Retrieve the detector managers from the detector store for enabled systems
192 if (m_buildPixel) {
193 ATH_CHECK(detStore()->retrieve(m_itkPixelMgr, "ITkPixel"));
194 }
195 if (m_buildStrip) {
196 ATH_CHECK(detStore()->retrieve(m_itkStripMgr, "ITkStrip"));
197 }
198 m_elementStore = std::make_shared<ActsElementVector>();
199 return StatusCode::SUCCESS;
200}
#define ATH_CHECK
Evaluate an expression and check for errors.

Member Data Documentation

◆ m_buildPixel

Gaudi::Property<bool> ActsTrk::ItkBlueprintNodeBuilder::m_buildPixel {this, "buildPixel", true}
private

Definition at line 41 of file ItkBlueprintNodeBuilder.h.

41{this, "buildPixel", true};

◆ m_buildStrip

Gaudi::Property<bool> ActsTrk::ItkBlueprintNodeBuilder::m_buildStrip {this, "buildStrip", true}
private

Definition at line 42 of file ItkBlueprintNodeBuilder.h.

42{this, "buildStrip", true};

◆ m_doEndcapLayerMerging

Gaudi::Property<bool> ActsTrk::ItkBlueprintNodeBuilder::m_doEndcapLayerMerging
private
Initial value:
{this, "doEndcapLayerMerging",
true}

Definition at line 39 of file ItkBlueprintNodeBuilder.h.

39 {this, "doEndcapLayerMerging",
40 true};

◆ m_elementStore

std::shared_ptr<ActsElementVector> ActsTrk::ItkBlueprintNodeBuilder::m_elementStore {nullptr}
private

Definition at line 37 of file ItkBlueprintNodeBuilder.h.

37{nullptr};

◆ m_itkPixelMgr

const InDetDD::SiDetectorManager* ActsTrk::ItkBlueprintNodeBuilder::m_itkPixelMgr {nullptr}
private

Definition at line 35 of file ItkBlueprintNodeBuilder.h.

35{nullptr};

◆ m_itkStripMgr

const InDetDD::SiDetectorManager* ActsTrk::ItkBlueprintNodeBuilder::m_itkStripMgr {nullptr}
private

Definition at line 36 of file ItkBlueprintNodeBuilder.h.

36{nullptr};

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