243 {
244
245
248 throw std::runtime_error("ITkPixel manager not available");
249 }
250
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) {
263 throw std::runtime_error{"Corrupt detector element collection"};
264 }
265 elements.push_back(std::make_shared<ActsDetectorElement>(*siDetElement));
266 }
268
269
271 elements.begin(), elements.end());
272
273
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
287 auto& barrelGeoId = innerPixelContainer.withGeometryIdentifier();
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();
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
332
333 for (const auto& [ilayer, surfaces] : layers) {
334 ATH_MSG_DEBUG(
"- Layer " << ilayer <<
" has " << surfaces.size()
335 << " surfaces");
336
338 std::format("InnerPixel_Brl_{}_Material", ilayer), [&](auto& lmat) {
339 lmat.configureFace(OuterCylinder, {AxisRPhi, Closed, 40},
340 {AxisZ, Bound, 20});
341
343 lmat.addLayer(std::format("InnerPixel_Brl_{}", ilayer));
344
345 layer.setNavigationPolicyFactory(
346 Acts::NavigationPolicyFactory{}
347 .add<Acts::SurfaceArrayNavigationPolicy>(
348 Acts::SurfaceArrayNavigationPolicy::Config{
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
365 for (int bec : {-2, 2}) {
366 std::string
s =
bec > 0 ?
"p" :
"n";
367 auto& ecGeoId = innerPixelContainer.withGeometryIdentifier();
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
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
431
432 layer.setNavigationPolicyFactory(
433 Acts::NavigationPolicyFactory{}
434 .add<Acts::SurfaceArrayNavigationPolicy>(
435 Acts::SurfaceArrayNavigationPolicy::Config{
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
450 << key << " / " << mergedLayers.size()
451 << " at z = " << pl.protoLayer.medium(AxisZ));
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
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();
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();
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
507
508 for (const auto& [ilayer, surfaces] : layers) {
509 ATH_MSG_DEBUG(
"- Layer " << ilayer <<
" has " << surfaces.size()
510 << " surfaces");
511
513 std::format("OuterPixel_Brl_{}_Material", ilayer), [&](auto& lmat) {
514 lmat.configureFace(OuterCylinder, {AxisRPhi, Closed, 40},
515 {AxisZ, Bound, 20});
516
518 lmat.addLayer("OuterPixel_Brl_" + std::to_string(ilayer));
519
520 layer.setNavigationPolicyFactory(
521 Acts::NavigationPolicyFactory{}
522 .add<Acts::SurfaceArrayNavigationPolicy>(
523 Acts::SurfaceArrayNavigationPolicy::Config{
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
561 .incrementLayerIds(1);
562
563 auto& ec_outer =
564 ec_outer_geoId.addCylinderContainer("OuterPixel_" + s + "EC", AxisR);
565
566
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_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
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