Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set fused portals correctly to former keep volume #2753

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 122 additions & 69 deletions Core/src/Detector/detail/CylindricalDetectorHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR(
refValues[CylinderVolumeBounds::BoundValues::eHalfPhiSector];
ActsScalar avgPhi = refValues[CylinderVolumeBounds::BoundValues::eAveragePhi];

// Fuse the cylinders - portals can be reused for this operation
// Fuse the cylinders
for (unsigned int iv = 1; iv < volumes.size(); ++iv) {
refValues = volumes[iv]->volumeBounds().values();
// Keep on collecting the outside maximum r for the overall r boundaries
Expand All @@ -423,15 +423,12 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR(
ACTS_VERBOSE("Connect volume '" << volumes[iv - 1]->name() << "' to "
<< volumes[iv]->name() << "'.");

// When fusing volumes at a cylinder boundary, we *keep* one
// portal and transfer the portal link information from the other
//
// In this case the outer cylinder portal of the inner volume is kept,
// the inner cylinder of the outer portal goes to waste
auto& keepCylinder = volumes[iv - 1]->portalPtrs()[2u];
auto& wasteCylinder = volumes[iv]->portalPtrs()[3u];
keepCylinder = Portal::fuse(keepCylinder, wasteCylinder);
volumes[iv]->updatePortal(keepCylinder, 3u);
// Fusing cylinders from inner and outer volume
auto innerCylinder = volumes[iv - 1]->portalPtrs()[2u];
auto outerCylinder = volumes[iv]->portalPtrs()[3u];
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
auto fusedCylinder = Portal::fuse(innerCylinder, outerCylinder);
volumes[iv - 1]->updatePortal(fusedCylinder, 2u);
volumes[iv]->updatePortal(fusedCylinder, 3u);
}
}

Expand Down Expand Up @@ -583,30 +580,26 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ(
if (connectZ) {
ACTS_VERBOSE("Connect volume '" << volumes[iv - 1]->name() << "' to "
<< volumes[iv]->name() << "'.");
// When fusing, one portal survives (keep) and gets the
// portal linking from the waste transferred
//
// In this case we keep the disc at positive z of the volume
// at lower relative z, and trash the disc at negative z of the
// following volume
auto& keepDisc = volumes[iv - 1]->portalPtrs()[1u];
auto& wasteDisc = volumes[iv]->portalPtrs()[0u];
// Fusing the discs: positive at lower z, negative at hgiher z
auto& pDisc = volumes[iv - 1]->portalPtrs()[1u];
auto& nDisc = volumes[iv]->portalPtrs()[0u];
// Throw an exception if the discs are not at the same position
Vector3 keepPosition = keepDisc->surface().center(gctx);
Vector3 wastePosition = wasteDisc->surface().center(gctx);
if (!keepPosition.isApprox(wastePosition)) {
Vector3 pPosition = pDisc->surface().center(gctx);
Vector3 nPosition = nDisc->surface().center(gctx);
if (!pPosition.isApprox(nPosition)) {
std::string message = "CylindricalDetectorHelper: '";
message += volumes[iv - 1]->name();
message += "' does not attach to '";
message += volumes[iv]->name();
message += "'\n";
message += " - along z with values ";
message += Acts::toString(keepPosition);
message += " / " + Acts::toString(wastePosition);
message += Acts::toString(pPosition);
message += " / " + Acts::toString(nPosition);
throw std::runtime_error(message.c_str());
}
keepDisc = Portal::fuse(keepDisc, wasteDisc);
volumes[iv]->updatePortal(keepDisc, 0u);
auto fusedDisc = Portal::fuse(pDisc, nDisc);
volumes[iv - 1]->updatePortal(fusedDisc, 1u);
volumes[iv]->updatePortal(fusedDisc, 0u);
}
}

Expand Down Expand Up @@ -758,16 +751,17 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInPhi(
phiBoundaries.push_back(
refValues[CylinderVolumeBounds::BoundValues::eAveragePhi] +
refValues[CylinderVolumeBounds::BoundValues::eHalfPhiSector]);
// Fuse the sectors - portals can be reused for this operation
// Fuse the sectors
for (unsigned int iv = 1; iv < volumes.size(); ++iv) {
ACTS_VERBOSE("Connect volume '" << volumes[iv - 1]->name() << "' to "
<< volumes[iv]->name() << "'.");

// Fuse and swap
auto& keepSector = volumes[iv - 1]->portalPtrs()[iSecOffset + 1u];
auto& wasteSector = volumes[iv]->portalPtrs()[iSecOffset];
keepSector = Portal::fuse(keepSector, wasteSector);
volumes[iv]->updatePortal(keepSector, iSecOffset);
// Fuse sector surfaces r handed at lower index, l handed at higher index
auto& rSector = volumes[iv - 1]->portalPtrs()[iSecOffset + 1u];
auto& lSector = volumes[iv]->portalPtrs()[iSecOffset];
auto fusedSector = Portal::fuse(rSector, lSector);
volumes[iv - 1]->updatePortal(fusedSector, iSecOffset + 1u);
volumes[iv]->updatePortal(fusedSector, iSecOffset);
// The current values
auto curValues = volumes[iv]->volumeBounds().values();
// Bail out if they do not match
Expand Down Expand Up @@ -875,22 +869,25 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR(
dShell[2u] = volumes[1u]->portalPtrs()[2u];

// Fuse outer cover of first with inner cylinder of wrapping volume
auto& keepCover = volumes[0u]->portalPtrs()[2u];
auto& wasteCover = volumes[1u]->portalPtrs()[3u];
keepCover = Portal::fuse(keepCover, wasteCover);
volumes[1u]->updatePortal(keepCover, 3u);
auto& outerCover = volumes[0u]->portalPtrs()[2u];
auto& innerCover = volumes[1u]->portalPtrs()[3u];
auto fusedCover = Portal::fuse(outerCover, innerCover);
volumes[0u]->updatePortal(fusedCover, 2u);
volumes[1u]->updatePortal(fusedCover, 3u);

// Stitch sides - negative
auto& keepDiscN = volumes[1u]->portalPtrs()[4u];
auto& wasteDiscN = volumes[0u]->portalPtrs()[0u];
keepDiscN = Portal::fuse(keepDiscN, wasteDiscN);
volumes[0u]->updatePortal(keepDiscN, 0u);
auto& firstDiscN = volumes[1u]->portalPtrs()[4u];
auto& secondDiscN = volumes[0u]->portalPtrs()[0u];
auto fusedDiscN = Portal::fuse(firstDiscN, secondDiscN);
volumes[1u]->updatePortal(fusedDiscN, 4u);
volumes[0u]->updatePortal(fusedDiscN, 0u);

// Stich sides - positive
auto& keepDiscP = volumes[0u]->portalPtrs()[1u];
auto& wasteDiscP = volumes[1u]->portalPtrs()[5u];
keepDiscP = Portal::fuse(keepDiscP, wasteDiscP);
volumes[1u]->updatePortal(keepDiscP, 5u);
auto& firstDiscP = volumes[0u]->portalPtrs()[1u];
auto& secondDiscP = volumes[1u]->portalPtrs()[5u];
auto fusedDiscP = Portal::fuse(firstDiscP, secondDiscP);
volumes[0u]->updatePortal(fusedDiscP, 1u);
volumes[1u]->updatePortal(fusedDiscP, 5u);

// If needed, insert new cylinder
if (volumes[0u]->portalPtrs().size() == 4u &&
Expand Down Expand Up @@ -960,13 +957,27 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR(
"not be connected in R");
}

// Fuse and swap
std::shared_ptr<Portal> keepCylinder = containers[ic - 1].find(2u)->second;
std::shared_ptr<Portal> wasteCylinder = containers[ic].find(3u)->second;
keepCylinder = Portal::fuse(keepCylinder, wasteCylinder);
for (auto& av : wasteCylinder->attachedDetectorVolumes()[1u]) {
av->updatePortal(keepCylinder, 3u);
}
// Fuse containers, and update the attached volumes
std::shared_ptr<Portal> innerCylinder = containers[ic - 1].find(2u)->second;
// Direction is explicitly addressed with a direction index
auto innerAttachedVolumes =
innerCylinder
->attachedDetectorVolumes()[Direction(Direction::Backward).index()];
std::shared_ptr<Portal> outerCylinder = containers[ic].find(3u)->second;
auto outerAttachedVolume =
outerCylinder
->attachedDetectorVolumes()[Direction(Direction::Forward).index()];
auto fusedCylinder = Portal::fuse(innerCylinder, outerCylinder);

// Update the attached volumes with the new portal
std::for_each(innerAttachedVolumes.begin(), innerAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedCylinder, 2u);
});
std::for_each(outerAttachedVolume.begin(), outerAttachedVolume.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedCylinder, 3u);
});
}

// Proto container refurbishment
Expand Down Expand Up @@ -1017,13 +1028,26 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ(
"CylindricalDetectorHelper: proto container has no positive disc, "
"can not be connected in Z");
}
std::shared_ptr<Portal> keepDisc = formerContainer.find(1u)->second;
std::shared_ptr<Portal> wasteDisc = currentContainer.find(0u)->second;
keepDisc = Portal::fuse(keepDisc, wasteDisc);
for (auto& av : wasteDisc->attachedDetectorVolumes()[1u]) {
ACTS_VERBOSE("Update portal of detector volume '" << av->name() << "'.");
av->updatePortal(keepDisc, 0u);
}
// Container attachment positive Disc of lower, negative Disc at higher
std::shared_ptr<Portal> pDisc = formerContainer.find(1u)->second;
auto pAttachedVolumes =
pDisc
->attachedDetectorVolumes()[Direction(Direction::Backward).index()];

std::shared_ptr<Portal> nDisc = currentContainer.find(0u)->second;
auto nAttachedVolumes =
nDisc->attachedDetectorVolumes()[Direction(Direction::Forward).index()];

auto fusedDisc = Portal::fuse(pDisc, nDisc);

std::for_each(pAttachedVolumes.begin(), pAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedDisc, 1u);
});
std::for_each(nAttachedVolumes.begin(), nAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedDisc, 0u);
});
}

// Proto container refurbishment
Expand Down Expand Up @@ -1119,22 +1143,51 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR(
dShell[2u] = wrappingVolume->portalPtrs()[2u];

// Fuse outer cover of first with inner cylinder of wrapping volume
auto& keepCover = innerContainer[2u];
auto& wasteCover = wrappingVolume->portalPtrs()[3u];
keepCover = Portal::fuse(keepCover, wasteCover);
wrappingVolume->updatePortal(keepCover, 3u);
auto& innerCover = innerContainer[2u];
auto innerAttachedVolumes =
innerCover
->attachedDetectorVolumes()[Direction(Direction::Backward).index()];
auto& innerTube = wrappingVolume->portalPtrs()[3u];
auto fusedCover = Portal::fuse(innerCover, innerTube);

std::for_each(innerAttachedVolumes.begin(), innerAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedCover, 2u);
});
wrappingVolume->updatePortal(fusedCover, 3u);

// Stitch sides - negative
auto& keepDiscN = innerContainer[0u];
auto& wasteDiscN = wrappingVolume->portalPtrs()[4u];
keepDiscN = Portal::fuse(keepDiscN, wasteDiscN);
wrappingVolume->updatePortal(keepDiscN, 4u);
// positive disc of lower , negative disc of higher
auto& firstDiscN = innerContainer[0u];

auto firstNAttachedVolumes =
firstDiscN
->attachedDetectorVolumes()[Direction(Direction::Forward).index()];

auto& secondDiscN = wrappingVolume->portalPtrs()[4u];
auto fusedDiscN = Portal::fuse(firstDiscN, secondDiscN);

std::for_each(firstNAttachedVolumes.begin(), firstNAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedDiscN, 0u);
});
wrappingVolume->updatePortal(fusedDiscN, 4u);

// Stich sides - positive
auto& keepDiscP = innerContainer[1u];
auto& wasteDiscP = wrappingVolume->portalPtrs()[5u];
keepDiscP = Portal::fuse(keepDiscP, wasteDiscP);
wrappingVolume->updatePortal(keepDiscP, 5u);
auto& firstDiscP = innerContainer[1u];
auto firstPAttachedVolumes =
firstDiscP
->attachedDetectorVolumes()[Direction(Direction::Backward).index()];

auto& secondDiscP = wrappingVolume->portalPtrs()[5u];
auto fusedDiscP = Portal::fuse(firstDiscP, secondDiscP);

std::for_each(firstPAttachedVolumes.begin(), firstPAttachedVolumes.end(),
[&](std::shared_ptr<DetectorVolume>& av) {
av->updatePortal(fusedDiscP, 1u);
});

wrappingVolume->updatePortal(fusedDiscP, 5u);

// If inner stitching is necessary
if (innerContainer.size() == 4u &&
Expand Down
Loading