317 {
318
319
322 throw std::runtime_error("ITkPixel manager not available");
323 }
324
327 << " elements");
328
329 std::vector<std::shared_ptr<ActsDetectorElement>> elements;
330
332 for (
const auto* element : *
m_itkPixelMgr->getDetectorElementCollection()) {
333 const InDetDD::SiDetectorElement* siDetElement =
334 dynamic_cast<const InDetDD::SiDetectorElement*>(element);
335 if (siDetElement == nullptr) {
337 throw std::runtime_error{"Corrupt detector element collection"};
338 }
339 elements.push_back(std::make_shared<ActsDetectorElement>(*siDetElement));
340 }
342
343
345 elements.begin(), elements.end());
346
347
348 auto& innerPixel = node.addCylinderContainer("InnerPixel", AxisR);
349 innerPixel.setAttachmentStrategy(AttachmentStrategy::Gap);
350
351
352
353
354
355 innerPixel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Gap);
356
357 innerPixel.addMaterial("InnerPixelMaterial", [&](auto& mat) {
358 mat.configureFace(OuterCylinder,
359 AxisSpec::DeferredEquidistant(50, AxisRPhi),
360 AxisSpec::DeferredEquidistant(100, AxisZ),
361 "InnerPixelMaterial");
362
363 auto& innerPixelContainer =
mat.addCylinderContainer(
"InnerPixel", AxisZ);
364
365
366 auto& barrelGeoId = innerPixelContainer.withGeometryIdentifier();
368 .incrementLayerIds(1)
369 .sortBy([](
auto&
a,
auto& b) {
370 auto& boundsA =
371 dynamic_cast<const Acts::CylinderVolumeBounds&
>(
a.volumeBounds());
372 auto& boundsB =
373 dynamic_cast<const Acts::CylinderVolumeBounds&
>(
b.volumeBounds());
374
375 using enum Acts::CylinderVolumeBounds::BoundValues;
376 double aMidR = (boundsA.get(eMinR) + boundsA.get(eMaxR)) / 2.0;
377 double bMidR = (boundsB.get(eMinR) + boundsB.get(eMaxR)) / 2.0;
378
379 return aMidR < bMidR;
380 });
381
382 auto& brl_mat =
383 barrelGeoId.addMaterial("InnerPixel_Material", [&](auto& material) {
384 material.configureFace(NegativeDisc,
385 AxisSpec::DeferredEquidistant(50, AxisR),
386 AxisSpec::DeferredEquidistant(50, AxisPhi),
387 "InnerPixel_Material_NegativeDisc");
388 material.configureFace(PositiveDisc,
389 AxisSpec::DeferredEquidistant(50, AxisR),
390 AxisSpec::DeferredEquidistant(50, AxisPhi),
391 "InnerPixel_Material_PositiveDisc");
392 });
393 auto&
barrel = brl_mat.addCylinderContainer(
"InnerPixel_Brl", AxisR);
394
395
396
397
398
399 barrel.setAttachmentStrategy(AttachmentStrategy::Second);
400
401
402
403
404
405
406
407
408
409 barrel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Expand);
410
411 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>>
layers{};
412
413 for (auto& element : elements) {
414 IdentityHelper id = element->identityHelper();
416 continue;
417 }
418
419 if (id.layer_disk() >= 2) {
420 continue;
421 }
422
423 int elementLayer = id.layer_disk();
424 layers[elementLayer].push_back(element->surface().getSharedPtr());
425 }
426
428
429 const int outermostBrlLayer =
layers.rbegin()->first;
430 for (const auto& [ilayer, surfaces] : layers) {
431 ATH_MSG_DEBUG(
"- Layer " << ilayer <<
" has " << surfaces.size()
432 << " surfaces");
433
434 auto configureLayer = [&](auto& node) {
435 auto&
layer = node.addLayer(std::format(
"InnerPixel_Brl_{}", ilayer));
436 layer.setNavigationPolicyFactory(
437 Acts::NavigationPolicyFactory{}
440 .add<Acts::CylinderNavigationPolicy>()
441 .asUniquePtr());
442 layer.setSurfaces(surfaces);
443 layer.setEnvelope(Acts::ExtentEnvelope{{
444 .z = {5_mm, 5_mm},
445 .r = {2_mm, 2_mm},
446 }});
447 };
448
449
450
451
452 if (ilayer != outermostBrlLayer) {
453 const std::string materialName =
454 std::format("InnerPixel_Brl_{}_Material", ilayer);
456 materialName,
457 [&](auto& lmat) {
458 lmat.configureFace(OuterCylinder,
459 AxisSpec::DeferredEquidistant(50, AxisRPhi),
460 AxisSpec::DeferredEquidistant(100, AxisZ),
461 materialName);
462 configureLayer(lmat);
463 });
464 } else {
466 }
467 }
468
469
470 for (int bec : {-2, 2}) {
471 std::string
s =
bec > 0 ?
"p" :
"n";
472 auto& ecGeoId = innerPixelContainer.withGeometryIdentifier();
474 .incrementLayerIds(1);
475 auto& ec = ecGeoId.addCylinderContainer(std::format("InnerPixel_{:}EC", s), AxisZ);
476
477
478
479
480 ec.setAttachmentStrategy(bec > 0 ? AttachmentStrategy::Second
481 : AttachmentStrategy::First);
482
483
484
485
486
487
488 ec.setResizeStrategies(
489 bec > 0 ? ResizeStrategy::Expand : ResizeStrategy::Gap,
490 bec > 0 ? ResizeStrategy::Gap : ResizeStrategy::Expand);
491
492 std::map<std::tuple<int, int, int>,
493 std::vector<std::shared_ptr<Acts::Surface>>>
494 initialLayers{};
495
496 for (auto& element : elements) {
497 IdentityHelper id = element->identityHelper();
498 if (
id.
bec() * bec <= 0) {
499 continue;
500 }
501
502 if (id.layer_disk() >= 3) {
503 continue;
504 }
505
506 std::tuple<int, int, int>
key{
id.bec(),
id.layer_disk(),
507 id.eta_module()};
508 initialLayers[
key].push_back(element->surface().getSharedPtr());
509 }
510
512 << " initial layers to InnerPixel " << s << "EC");
513
514 std::vector<LayerData> protoLayers;
515 protoLayers.reserve(initialLayers.size());
516
517 for (const auto& [key, surfaces] : initialLayers) {
518 auto&
layer = protoLayers.emplace_back(gctx, surfaces);
519 layer.protoLayer.envelope[AxisR] = {2_mm, 2_mm};
520 layer.protoLayer.envelope[AxisZ] = {1_mm, 1_mm};
521 }
522
523 std::ranges::sort(protoLayers,
524 [](
const LayerData&
a,
const LayerData& b) {
525 return std::abs(
a.protoLayer.medium(AxisZ)) <
526 std::abs(
b.protoLayer.medium(AxisZ));
527 });
528
529 ATH_MSG_DEBUG(
"Found " << protoLayers.size() <<
" initial layers");
530
531 std::vector<LayerData> mergedLayers;
533 mergedLayers = mergeLayers(gctx, std::move(protoLayers));
534 } else {
535 mergedLayers = std::move(protoLayers);
536 }
537
538 ATH_MSG_DEBUG(
"After merging: " << mergedLayers.size() <<
" layers");
539
540 for (const auto [key, pl] : Acts::enumerate(mergedLayers)) {
541 ATH_MSG_DEBUG(
"- Layer " << key <<
" has " << pl.surfaces.size()
542 << " surfaces");
543
544 pl.protoLayer.medium(AxisZ);
545 auto layerName = std::format(
"InnerPixel_{}EC_{}", key, s);
546
549
550 layer.setNavigationPolicyFactory(
551 Acts::NavigationPolicyFactory{}
554 .add<Acts::CylinderNavigationPolicy>()
555 .asUniquePtr());
556
557 layer.setSurfaces(pl.surfaces);
558 layer.setEnvelope(Acts::ExtentEnvelope{{
559 .z = {1_mm, 1_mm},
560 .r = {2_mm, 2_mm},
561 }});
562 };
563
565 << key << " / " << mergedLayers.size()
566 << " at z = " << pl.protoLayer.medium(AxisZ));
568
569
570
571
572
573
574 const auto outwardDisc = (
bec > 0) ? PositiveDisc : NegativeDisc;
575 const std::string materialName =
layerName +
"_Material";
576 ec.addMaterial(materialName, [&](auto& lmat) {
577 lmat.configureFace(outwardDisc,
578 AxisSpec::DeferredEquidistant(50, AxisR),
579 AxisSpec::DeferredEquidistant(50, AxisPhi),
580 materialName);
581 addLayer(lmat);
582 });
583 }
584 }
585 });
586
587
588 auto& outerPixel = node.addCylinderContainer("OuterPixel", AxisR);
589 outerPixel.setAttachmentStrategy(AttachmentStrategy::Gap);
590
591
592
593
594
595 outerPixel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Gap);
596
597 outerPixel.addMaterial("OuterPixelMaterial", [&](auto& opmat) {
598 opmat.configureFace(OuterCylinder,
599 AxisSpec::DeferredEquidistant(50, AxisRPhi),
600 AxisSpec::DeferredEquidistant(100, AxisZ),
601 "OuterPixelMaterial");
602
603 auto& outerPixelContainer = opmat.addCylinderContainer("OuterPixel", AxisZ);
604
605 auto& barrelGeoId = outerPixelContainer.withGeometryIdentifier();
607
608 auto& brl_mat =
609 barrelGeoId.addMaterial("OuterPixel_Material", [&](auto& bmat) {
610 bmat.configureFace(NegativeDisc,
611 AxisSpec::DeferredEquidistant(50, AxisR),
612 AxisSpec::DeferredEquidistant(50, AxisPhi),
613 "OuterPixel_Material_NegativeDisc");
614 bmat.configureFace(PositiveDisc,
615 AxisSpec::DeferredEquidistant(50, AxisR),
616 AxisSpec::DeferredEquidistant(50, AxisPhi),
617 "OuterPixel_Material_PositiveDisc");
618 });
619 auto&
barrel = brl_mat.addCylinderContainer(
"OuterPixel_Brl", AxisR);
620
621
622
623
624 barrel.setAttachmentStrategy(AttachmentStrategy::Second);
625
626
627
628
629
630
631
632 barrel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Expand);
633
634 std::map<int, std::vector<std::shared_ptr<Acts::Surface>>>
layers{};
635
636 for (auto& element : elements) {
637 IdentityHelper id = element->identityHelper();
639 continue;
640 }
641
642 if (id.layer_disk() <= 1) {
643 continue;
644 }
645
646 int elementLayer = id.layer_disk();
647 layers[elementLayer].push_back(element->surface().getSharedPtr());
648 }
649
651
652 const int outermostBrlLayer =
layers.rbegin()->first;
653 for (const auto& [ilayer, surfaces] : layers) {
654 ATH_MSG_DEBUG(
"- Layer " << ilayer <<
" has " << surfaces.size()
655 << " surfaces");
656
657 auto configureLayer = [&](auto& node) {
658 auto&
layer = node.addLayer(std::format(
"OuterPixel_Brl_{:}", ilayer));
659 layer.setNavigationPolicyFactory(
660 Acts::NavigationPolicyFactory{}
663 .add<Acts::CylinderNavigationPolicy>()
664 .asUniquePtr());
665 layer.setSurfaces(surfaces);
666 layer.setEnvelope(Acts::ExtentEnvelope{{
667 .z = {5_mm, 5_mm},
668 .r = {2_mm, 2_mm},
669 }});
670 };
671
672
673
674
675 if (ilayer != outermostBrlLayer) {
676 const std::string materialName =
677 std::format("OuterPixel_Brl_{}_Material", ilayer);
679 materialName,
680 [&](auto& lmat) {
681 lmat.configureFace(OuterCylinder,
682 AxisSpec::DeferredEquidistant(50, AxisRPhi),
683 AxisSpec::DeferredEquidistant(100, AxisZ),
684 materialName);
685 configureLayer(lmat);
686 });
687 } else {
689 }
690 }
691
692 const auto endcapSurfaceArrayConfig =
694 auto addEndcapLayer = [&endcapSurfaceArrayConfig](
696 const auto& surfaces) {
697 parent.addLayer(name, [&surfaces, &endcapSurfaceArrayConfig](
auto& layer) {
698 layer.setNavigationPolicyFactory(
699 Acts::NavigationPolicyFactory{}
700 .add<Acts::SurfaceArrayNavigationPolicy>(endcapSurfaceArrayConfig)
701 .add<Acts::CylinderNavigationPolicy>()
702 .asUniquePtr());
703
704 layer.setSurfaces(surfaces);
705 });
706 };
707
708 for (int bec : {-2, 2}) {
709 const std::string
s =
bec > 0 ?
"p" :
"n";
710
711 auto& ec_outer_geoId = outerPixelContainer.withGeometryIdentifier();
712 ec_outer_geoId
714 .incrementLayerIds(1);
715
716 auto& ec_outer =
717 ec_outer_geoId.addCylinderContainer(std::format("OuterPixel_{:}EC", s), AxisR);
718
719
720 std::array diskGroups{std::pair{3, 4}, std::pair{6, 5}, std::pair{7, 8}};
721
722 for (
size_t idx = 0;
idx < diskGroups.size(); ++
idx) {
723 auto [disk1, disk2] = diskGroups[
idx];
724
725 Acts::MaterialDesignatorBlueprintNode* material = nullptr;
726 if (idx < (diskGroups.size() - 1)) {
727 const std::string materialName =
728 "OuterPixel_" +
s +
"EC_" + std::to_string(idx) +
"_Material";
729 material = &ec_outer.addMaterial(
730 materialName,
731 [&](auto& mat) {
732 mat.configureFace(OuterCylinder,
733 AxisSpec::DeferredEquidistant(50, AxisRPhi),
734 AxisSpec::DeferredEquidistant(100, AxisZ),
735 materialName);
736 });
737 }
738
739 auto& ec_stack =
740 material
741 ? material->addCylinderContainer(
742 std::format("OuterPixel_{:}EC_{:}", s, idx), AxisZ)
743 : ec_outer.addCylinderContainer(
744 std::format("OuterPixel_{:}EC_{:}", s, idx), AxisZ);
745
746
747
748
749 ec_stack.setAttachmentStrategy(bec > 0 ? AttachmentStrategy::Second
750 : AttachmentStrategy::First);
751
752
753
754
755 ec_stack.setResizeStrategies(
756 bec > 0 ? ResizeStrategy::Expand : ResizeStrategy::Gap,
757 bec > 0 ? ResizeStrategy::Gap : ResizeStrategy::Expand);
758
759 std::map<std::tuple<int, int>,
760 std::vector<std::shared_ptr<Acts::Surface>>>
761 eta_rings;
762
763 for (auto& element : elements) {
764 IdentityHelper id = element->identityHelper();
765 if (
id.
bec() != bec ||
766 (id.layer_disk() != disk1 && id.layer_disk() != disk2)) {
767 continue;
768 }
769 std::tuple<int, int>
key{
id.layer_disk(),
id.eta_module()};
770 eta_rings[
key].push_back(element->surface().getSharedPtr());
771 }
772
773 ATH_MSG_DEBUG(
"Found " << eta_rings.size() <<
" eta rings in group "
774 << idx);
775
776 std::vector<std::vector<std::shared_ptr<Acts::Surface>>> sorted_rings;
777 sorted_rings.reserve(eta_rings.size());
778 for (const auto& [key, surfaces] : eta_rings) {
779 sorted_rings.push_back(surfaces);
780 }
781
782 std::ranges::sort(sorted_rings, [&gctx](
const auto&
a,
const auto& b) {
783 Acts::ProtoLayer pl_a(gctx, Acts::unpackConstSmartPointers(
a));
784 Acts::ProtoLayer pl_b(gctx, Acts::unpackConstSmartPointers(b));
785 return std::abs(pl_a.min(AxisZ)) < std::abs(pl_b.min(AxisZ));
786 });
787
788 for (
size_t i = 0;
i < sorted_rings.size(); ++
i) {
789 const auto& surfaces = sorted_rings[
i];
790 const std::string
layerName = std::format(
"OuterPixel_{:}EC_{:}_{:}", s,idx, i);
791
792 const auto outwardDisc = (
bec > 0) ? PositiveDisc : NegativeDisc;
793 const std::string materialName =
layerName +
"_Material";
794 ec_stack.addMaterial(materialName, [&](auto& mat) {
795 mat.configureFace(outwardDisc,
796 AxisSpec::DeferredEquidistant(50, AxisR),
797 AxisSpec::DeferredEquidistant(50, AxisPhi),
798 materialName);
799 addEndcapLayer(mat, layerName, surfaces);
800 });
801 }
802 }
803 }
804 });
805}
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_VERBOSE(x,...)
Gaudi::Property< std::vector< unsigned int > > m_itkPixelInnerEndcapNeighborWindow
Gaudi::Property< std::vector< unsigned int > > m_itkPixelOuterBarrelNeighborWindow
Gaudi::Property< std::vector< unsigned int > > m_itkPixelOuterEndcapNeighborWindow
const InDetDD::SiDetectorManager * m_itkPixelMgr
std::shared_ptr< ActsElementVector > m_elementStore
Acts::SurfaceArrayNavigationPolicy::Config surfaceArrayConfig(Acts::SurfaceArrayNavigationPolicy::LayerType layerType, const Gaudi::Property< std::vector< unsigned int > > &neighborWindow) const
Configuration of the surface array navigation policy of one layer.
Gaudi::Property< std::vector< unsigned int > > m_itkPixelInnerBarrelNeighborWindow
Most bins the surface array lookup serves on each side of the crossing, as {phi, z}...
Gaudi::Property< bool > m_doEndcapLayerMerging
DataModel_detail::const_iterator< DataVector > const_iterator
constexpr std::size_t s_outerPixelVolumeId
constexpr std::size_t s_innerPixelVolumeId
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string