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