87 auto mdtStationIndex = [
this] (
const std::string& stName) {
90 auto tgcStationIndex = [
this] (
const std::string& stName) {
94 const std::unordered_set<int> stIndicesEM{mdtStationIndex(
"EML"), mdtStationIndex(
"EMS"),
95 tgcStationIndex(
"T1E"), tgcStationIndex(
"T1F"),
96 tgcStationIndex(
"T2E"), tgcStationIndex(
"T2F"),
97 tgcStationIndex(
"T3E"), tgcStationIndex(
"T3F")};
100 std::unordered_set<Identifier> BIS78_ids{};
101 auto fillBIS78 = [&BIS78_ids,
this](
const MuonIdHelper& idHelper) {
102 const int BIS = idHelper.stationNameIndex(
"BIS");
103 std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(), std::inserter(BIS78_ids, BIS78_ids.end()),
105 int stEta = idHelper.stationEta(detId);
107 stEta = std::abs(stEta);
109 return stEta >= 7 && idHelper.stationName(detId) ==
BIS;
112 if (m_idHelperSvc->hasMDT()) {
113 fillBIS78(m_idHelperSvc->mdtIdHelper());
115 if (m_idHelperSvc->hasRPC()) {
116 fillBIS78(m_idHelperSvc->rpcIdHelper());
119 std::vector<MuonReadoutElement*> allReadOutEles =
mgr.getAllReadoutElements();
121 std::vector<chamberArgs> envelopeCandidates{};
125 std::vector<chamberArgs>::iterator
exist = std::ranges::find_if(envelopeCandidates,
126 [
this, readOutEle, &stIndicesEM](
const chamberArgs& args){
128 const Identifier refId = refEle->identify();
129 const Identifier testId = readOutEle->identify();
132 if (Acts::copySign(1, refEle->stationEta()) *
133 Acts::copySign(1, readOutEle->stationEta()) < 0) {
137 if (m_idHelperSvc->sector(testId) != m_idHelperSvc->sector(refId)) {
140 if (stIndicesEM.count(readOutEle->stationName()) &&
141 stIndicesEM.count(refEle->stationName())) {
146 return readOutEle->chamberIndex() == refEle->chamberIndex();
149 if (exist == envelopeCandidates.end()) {
150 ATH_MSG_VERBOSE(__func__<<
" () "<<__LINE__<<
" - Open envelope "<<(envelopeCandidates.size()+1)
151 <<
" for "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
152 <<
", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
154 envelopeCandidates.emplace_back().detEles.push_back(readOutEle);
156 ATH_MSG_VERBOSE(__func__<<
" () "<<__LINE__<<
" - Attach "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
157 <<
", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
159 <<(std::distance(envelopeCandidates.begin(), exist) + 1)<<
". ");
160 exist->detEles.push_back(readOutEle);
164 ActsTrk::GeometryContext gctx{};
167 Acts::VolumeBoundFactory volBoundSet{};
168 Acts::SurfaceBoundFactory surfBoundSet{};
170 for (
chamberArgs& candidate : envelopeCandidates) {
171 std::unordered_set<Identifier> reIds{};
173 ATH_MSG_DEBUG(__func__<<
" () "<<__LINE__<<
" - New envelope candidate ");
176 sectorArgs.
id = (++candId);
177 using namespace Muon::MuonStationIndex;
178 std::vector<std::vector<const MuonReadoutElement*>> chamberElements{};
179 if (
toStationIndex(candidate.detEles.front()->chamberIndex()) != StIndex::EI) {
181 std::map<PVConstLink, std::vector<const MuonReadoutElement*>> stationMap{};
186 if (BIS78_ids.count(
re->identify())) {
187 stationMap[
re->getMaterialGeom()].push_back(
re);
189 stationMap[
re->getMaterialGeom()->getParent()].push_back(
re);
192 for (
auto& [parent, stationEles ]: stationMap){
193 chamberElements.push_back(std::move(stationEles));
198 std::vector<std::vector<const MuonReadoutElement*>> endcapEles(2);
202 endcapEles.emplace_back(1, sortMe);
208 for (
auto& stationEles : endcapEles) {
209 if (!stationEles.empty()) {
210 chamberElements.push_back(std::move(stationEles));
215 for (
auto& detEles: chamberElements) {
218 ATH_MSG_DEBUG(__func__<<
" () "<<__LINE__<<
" - New chamber candidate "<<m_idHelperSvc->toStringChamber(refEle->identify()));
219 const auto[chamberCentre, chamberBox, planeBounds] = boundingBox(gctx, detEles, toChambCentre, volBoundSet,
220 surfBoundSet, 0.1*Gaudi::Units::cm);
222 chambArgs.detEles = std::move(detEles);
223 chambArgs.bounds = chamberBox;
224 chambArgs.placement = std::make_unique<ActsTrk::VolumePlacement>(*refEle, chamberCentre);
225 auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(Acts::Transform3::Identity(), planeBounds);
226 chambArgs.placement->connectCenterSurface(surface);
227 chambArgs.surface = surface;
228 const Chamber* newChamber {sectorArgs.chambers.emplace_back(std::make_unique<Chamber>(std::move(chambArgs))).get()};
230 reIds.insert(
re->identify());
231 mgr.getReadoutElement(
re->identify())->setChamberLink(newChamber);
232 ATH_MSG_VERBOSE(__func__<<
" () "<<__LINE__<<
" - Chamber element: "<<m_idHelperSvc->toStringDetEl(
re->identify()));
235 ATH_MSG_DEBUG(__func__<<
" () "<<__LINE__<<
" - Created new chamber: "<<(*newChamber));
237 if (sectorArgs.chambers.empty()) {
245 const Acts::Transform3 toCenter = sectorArgs.chambers.front()->globalToLocalTransform(gctx);
246 const auto [envelopeCentre, envelopeBox, envelopePlane] = boundingBox(gctx, sectorArgs.chambers, toCenter,
247 volBoundSet, surfBoundSet, 2.* Gaudi::Units::cm);
249 sectorArgs.bounds = envelopeBox;
250 sectorArgs.localToGlobalTrf = make_intrusive<GeoAlignableTransform>(toCenter.inverse() * envelopeCentre);
253 sectorArgs.localToGlobalTrf);
255 auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(Acts::Transform3::Identity(), envelopePlane);
256 sectorArgs.placement->connectCenterSurface(surface);
257 sectorArgs.surface = surface ;
258 const Acts::Transform3 globalToSector = sectorArgs.placement->globalToLocalTransform(gctx.
context());
261 for (
auto & chamber : sectorArgs.chambers){
263 for (
auto & RE :
chamber->readoutEles()){
265 const Acts::Transform3& chamberToGlobal{RE->localToGlobalTransform(gctx)};
266 const Amg::Vector3D origin = (globalToSector * chamberToGlobal).translation();
272 auto newSector = std::make_unique<SpectrometerSector>(std::move(sectorArgs));
274 for (
const Identifier& chId : reIds) {
275 mgr.getReadoutElement(chId)->setSectorLink(newSector.get());
277 mgr.addSpectrometerSector(std::move(newSector));
279 return StatusCode::SUCCESS;