337 using enum Acts::AxisDirection;
339 ACTS_VERBOSE(
"Build layers: " << (
type < 0 ?
"NEGATIVE" :
"POSITIVE")
341 std::vector<std::shared_ptr<const ActsDetectorElement>> elements =
343 std::map<std::tuple<int, int, int>, std::vector<const Acts::Surface *>>
346 for (
const auto &element : elements) {
354 if(
id.layer_disk() >= 3)
continue;
357 if(
id.layer_disk() <= 2)
continue;
362 std::tuple<int, int, int>
key{
id.bec(),
id.layer_disk(),
id.eta_module()};
364 initialLayers[
key].push_back(&element->surface());
367 ACTS_VERBOSE(
"Found " << initialLayers.size() <<
" "
368 << (
type < 0 ?
"NEGATIVE" :
"POSITIVE")
369 <<
" ENDCAP inital layers");
371 std::vector<Acts::ProtoLayer> protoLayers;
372 protoLayers.reserve(initialLayers.size());
374 for (
const auto &[
key, surfaces] : initialLayers) {
375 auto &pl = protoLayers.emplace_back(gctx, surfaces);
381 std::sort(protoLayers.begin(), protoLayers.end(),
382 [
type](
const Acts::ProtoLayer &
a,
const Acts::ProtoLayer &
b) {
383 double midA = (a.min(AxisZ) + a.max(AxisZ)) / 2.0;
384 double midB = (b.min(AxisZ) + b.max(AxisZ)) / 2.0;
392 auto plPrintZ = [](
const auto &pl) -> std::string {
393 std::stringstream
ss;
394 double zMid = (pl.min(AxisZ) + pl.max(AxisZ)) / 2.0;
395 ss <<
" < " << pl.min(AxisZ) <<
" | " << zMid <<
" | "
396 << pl.max(AxisZ) <<
" > ";
400 for (
const auto &pl : protoLayers) {
402 ACTS_VERBOSE(
" -> at < zMin | zMid | zMax >: " << plPrintZ(pl));
404 ACTS_VERBOSE(
" -> at rMin / rMax: " << pl.min(AxisR) <<
" / "
409 std::vector<Acts::ProtoLayer> mergedProtoLayers;
412 mergedProtoLayers.push_back(protoLayers.front());
413 std::vector<const Acts::Surface *> surfaces;
414 for (
size_t i = 1;
i < protoLayers.size();
i++) {
415 auto &pl = protoLayers[
i];
416 auto &pl_prev = mergedProtoLayers.back();
418 ACTS_VERBOSE(
"Compare: " << plPrintZ(pl_prev) <<
" and " << plPrintZ(pl));
419 bool overlap = (pl.min(AxisZ) <= pl_prev.max(AxisZ) &&
420 pl.max(AxisZ) >= pl_prev.min(AxisZ));
421 ACTS_VERBOSE(
" -> overlap? " << (overlap ?
"yes" :
"no"));
423 ACTS_VERBOSE(
" ===> merging");
425 surfaces.reserve(pl.surfaces().size() + pl_prev.surfaces().size());
426 surfaces.insert(surfaces.end(), pl.surfaces().begin(),
427 pl.surfaces().end());
428 surfaces.insert(surfaces.end(), pl_prev.surfaces().begin(),
429 pl_prev.surfaces().end());
430 mergedProtoLayers.pop_back();
432 mergedProtoLayers.emplace_back(gctx, std::move(surfaces));
433 new_pl.envelope[AxisR] = pl.envelope[AxisR];
434 new_pl.envelope[AxisZ] = pl.envelope[AxisZ];
436 mergedProtoLayers.push_back(std::move(pl));
440 ACTS_VERBOSE(
"" << mergedProtoLayers.size() <<
" "
441 << (
type < 0 ?
"NEGATIVE" :
"POSITIVE")
442 <<
" ENDCAP layers remain after merging");
444 mergedProtoLayers = protoLayers;
448 for (
size_t i = 0;
i < mergedProtoLayers.size();
i++) {
450 std::stringstream
ss;
452 <<
"_disk_" << std::setfill(
'0') << std::setw(2) <<
i <<
".obj";
454 std::ofstream ofs{
ss.str()};
455 Acts::ObjVisualization3D vis{};
456 Acts::ViewConfig vc = Acts::s_viewSensitive;
457 vc.quarterSegments = 200;
458 for (
const auto &surface : mergedProtoLayers[
i].surfaces()) {
459 Acts::GeometryView3D::drawSurface(vis, *surface, gctx,
460 Acts::Transform3::Identity(), vc);
467 std::vector<std::shared_ptr<const Surface>> ownedSurfaces;
468 for (
const auto &pl : mergedProtoLayers) {
470 std::unique_ptr<Acts::ApproachDescriptor> approachDescriptor =
nullptr;
471 std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy =
nullptr;
473 double layerZ = pl.medium(AxisZ);
474 double layerHalfZ = 0.5 * pl.range(AxisZ);
475 double layerThickness = pl.range(AxisZ);
477 double layerZInner = layerZ - layerHalfZ;
478 double layerZOuter = layerZ + layerHalfZ;
480 if (std::abs(layerZInner) > std::abs(layerZOuter))
483 std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces;
485 Acts::Transform3 transformNominal(Translation3(0., 0., layerZ));
486 Acts::Transform3 transformInner(Translation3(0., 0., layerZInner));
487 Acts::Transform3 transformOuter(Translation3(0., 0., layerZOuter));
489 std::shared_ptr<Acts::DiscSurface> innerBoundary =
490 Acts::Surface::makeShared<Acts::DiscSurface>(
491 transformInner, pl.min(AxisR), pl.max(AxisR));
492 aSurfaces.push_back(innerBoundary);
494 std::shared_ptr<Acts::DiscSurface> nominalSurface =
495 Acts::Surface::makeShared<Acts::DiscSurface>(
496 transformNominal, pl.min(AxisR), pl.max(AxisR));
497 aSurfaces.push_back(nominalSurface);
499 std::shared_ptr<Acts::DiscSurface> outerBoundary =
500 Acts::Surface::makeShared<Acts::DiscSurface>(
501 transformOuter, pl.min(AxisR), pl.max(AxisR));
502 aSurfaces.push_back(outerBoundary);
504 if(layerThickness > 2_mm) {
505 ACTS_VERBOSE(
"Wide disc layer ("<< layerThickness <<
") => adding cylinder like approach surfaces");
506 Acts::Transform3
trf{Translation3{0, 0, layerZ}};
508 Acts::Surface::makeShared<Acts::CylinderSurface>(
509 trf, pl.min(AxisR), layerHalfZ);
510 aSurfaces.push_back(cylinderInner);
513 Acts::Surface::makeShared<Acts::CylinderSurface>(
514 trf, pl.max(AxisR), layerHalfZ);
515 aSurfaces.push_back(cylinderOuter);
525 Acts::BinUtility(matBinsR, pl.min(AxisR), pl.max(AxisR),
529 std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
531 ACTS_VERBOSE(
"[L] Layer is marked to carry support material on Surface ( "
532 "inner=0 / center=1 / outer=2 ) : "
534 ACTS_VERBOSE(
"with binning: [" << matBinsPhi <<
", " << matBinsR <<
"]");
536 ACTS_VERBOSE(
"Created ApproachSurfaces for disc layer at:");
537 ACTS_VERBOSE(
" - inner: Z=" << layerZInner);
538 ACTS_VERBOSE(
" - central: Z=" << layerZ);
539 ACTS_VERBOSE(
" - outer: Z=" << layerZOuter);
542 innerBoundary->assignSurfaceMaterial(materialProxy);
550 std::map<int, std::set<int>> phiModuleByRing;
553 for (
const auto &srf : pl.surfaces()) {
555 srf->associatedDetectorElement());
563 ring_number =
id.layer_disk();
565 phiModuleByRing[ring_number].insert(
id.phi_module());
569 for(
const auto& [ring, phiModules] : phiModuleByRing) {
570 nModPhi =
std::min(nModPhi, phiModules.size());
573 size_t nModR = phiModuleByRing.size();
575 ACTS_VERBOSE(
"Identifier reports: " << nModPhi <<
" is lowest for " << nModR
578 size_t nBinsPhi = nModPhi;
579 size_t nBinsR = nModR;
594 ACTS_VERBOSE(
"Creating r x phi binned layer with " << nBinsR <<
" x "
595 << nBinsPhi <<
" bins");
599 std::make_unique<Acts::GenericApproachDescriptor>(aSurfaces);
602 ownedSurfaces.clear();
603 ownedSurfaces.reserve(pl.surfaces().size());
605 std::back_inserter(ownedSurfaces),
606 [](
const auto &
s) { return s->getSharedPtr(); });
609 nBinsPhi, pl, Transform3::Identity(),
610 std::move(approachDescriptor));
612 layersOutput.push_back(
layer);