ATLAS Offline Software
Loading...
Searching...
No Matches
ChamberAssembleTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#ifndef SIMULATIONBASE
5
7
14#include <sstream>
15
16#include <Acts/Geometry/CuboidVolumeBounds.hpp>
17#include <Acts/Geometry/TrapezoidVolumeBounds.hpp>
18#include <Acts/Surfaces/RectangleBounds.hpp>
19#include <Acts/Surfaces/TrapezoidBounds.hpp>
20#include <Acts/Surfaces/PlaneSurface.hpp>
21
22#include <Acts/Geometry/Volume.hpp>
23
24#include <GeoModelHelpers/TransformToStringConverter.h>
25#include <GeoModelKernel/GeoDefinitions.h>
26
27using namespace Acts::UnitLiterals;
28namespace {
29 constexpr int sign(int numb) {
30 return numb > 0 ? 1 : (numb == 0 ? 0 : -1);
31 }
33 Amg::Vector3D projectIntoXY(const Amg::Vector3D& v) {
34 return Amg::Vector3D{v.x(), v.y(), 0.};
35 }
36}
37
38
39
40namespace MuonGMR4{
41
45
55 ActsTrk::DetectorType t = re->detectorType();
57 return Amg::Transform3D::Identity();
58 }
59 return Amg::getRotateZ3D(-90. * Gaudi::Units::deg) *
60 Amg::getRotateY3D(-90. * Gaudi::Units::deg);
61}
63 return Amg::Transform3D::Identity();
64}
66 return re->idHelperSvc()->toStringDetEl(re->identify());
67}
68std::string toString(const ChamberPtr& ch) {
69 return ch->identString();
70}
71
72
74 const Amg::Vector3D& lineDir,
75 const Amg::Vector3D& testMe,
76 bool leftEdge) {
78 const Amg::Vector3D normal = lineDir.cross((leftEdge ? 1. : -1.) *Amg::Vector3D::UnitZ());
79 const Amg::Vector3D closest = linePos + lineDir.dot(testMe - linePos) * lineDir;
80 return normal.dot(testMe - closest);
81}
82
85 Acts::VolumeBoundFactory& volBoundSet) {
86
87 switch(chambEle->detectorType()) {
89 const auto* techEle = static_cast<const MdtReadoutElement*>(chambEle);
90 const auto& pars = techEle->getParameters();
91 if (std::abs(pars.shortHalfX - pars.longHalfX) < Acts::s_epsilon) {
92 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.shortHalfX, pars.halfY, pars.halfHeight);
93 }
94 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.shortHalfX, pars.longHalfX,
95 pars.halfY, pars.halfHeight );
97 const auto* techEle = static_cast<const RpcReadoutElement*>(chambEle);
98 const auto& pars = techEle->getParameters();
99 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.halfWidth, pars.halfLength, pars.halfThickness);
101 const auto* techEle = static_cast<const TgcReadoutElement*>(chambEle);
102 const auto& pars = techEle->getParameters();
103 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfWidthShort, pars.halfWidthLong,
104 pars.halfHeight, pars.halfThickness );
106 const auto* techEle = static_cast<const sTgcReadoutElement*>(chambEle);
107 const auto& pars = techEle->getParameters();
108 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.sHalfChamberLength, pars.lHalfChamberLength,
109 pars.halfChamberHeight, pars.halfChamberTck );
111 const auto* techEle = static_cast<const MmReadoutElement*>(chambEle);
112 const auto& pars = techEle->getParameters();
113 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfShortWidth, pars.halfLongWidth,
114 pars.halfHeight, pars.halfThickness );
115 } default:
116 THROW_EXCEPTION("Unsupported detector type "<<to_string(chambEle->detectorType()));
117 }
118 return nullptr;
119}
120VolBoundPtr_t ChamberAssembleTool::boundingBox(const ChamberPtr& chamber, Acts::VolumeBoundFactory& /*boundSet*/) {
121 return chamber->bounds();
122}
123
124
125std::array<Amg::Vector3D, 4> ChamberAssembleTool::cornerPointsPlane(const Amg::Transform3D& localToGlob,
126 const VolBounds_t& bounds) {
127 std::array<Amg::Vector3D,4> planePoints{localToGlob * Amg::Vector3D(-halfXlowY(bounds), - halfY(bounds), 0.),
128 localToGlob * Amg::Vector3D(-halfXhighY(bounds), halfY(bounds), 0.),
129 localToGlob * Amg::Vector3D( halfXlowY(bounds), -halfY(bounds), 0.),
130 localToGlob * Amg::Vector3D( halfXhighY(bounds), halfY(bounds), 0.)};
131 return planePoints;
132}
133std::array<Amg::Vector3D, 8> ChamberAssembleTool::cornerPoints(const Amg::Transform3D& localToGlob,
134 const VolBounds_t& bounds) {
135 std::array<Amg::Vector3D, 8> toRet{make_array<Amg::Vector3D,8>(Amg::Vector3D::Zero())};
136 const std::array<Amg::Vector3D, 4> plane = cornerPointsPlane(localToGlob, bounds);
137 for (unsigned int z : {0, 1}) {
138 const Amg::Vector3D stretch = halfZ(bounds) * (z ? 1. : -1.) * Amg::Vector3D::UnitZ();
139 for (unsigned int b = 0; b < plane.size(); ++b){
140 toRet[b + z * plane.size()] = plane[b] + stretch;
141 }
142 }
143 return toRet;
144}
145Amg::Transform3D ChamberAssembleTool::centerTrapezoid(const std::array<Amg::Vector3D, 8>& corners) {
146
147 static constexpr double maxSize = 200._km;
148 double minX{maxSize}, maxX{-maxSize}, minY{maxSize}, maxY{-maxSize}, minZ{maxSize}, maxZ{-maxSize};
149 for (const Amg::Vector3D& corner : corners) {
150 minX = std::min(corner.x(), minX); maxX = std::max(corner.x(), maxX);
151 minY = std::min(corner.y(), minY); maxY = std::max(corner.y(), maxY);
152 minZ = std::min(corner.z(), minZ); maxZ = std::max(corner.z(), maxZ);
153 }
154 return Amg::getTranslate3D(-0.5*(minX + maxX), -0.5*(minY + maxY), -0.5*(minZ + maxZ));
155}
156
159 const double margin,
160 Acts::VolumeBoundFactory& volBoundSet) {
161 if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
162 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
163 halfY(enlargeMe) + 0.5*margin,
164 halfZ(enlargeMe) + 0.5*margin);
165 } else if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
166 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
167 halfXhighY(enlargeMe) + 0.5*margin,
168 halfY(enlargeMe) + 0.5*margin,
169 halfZ(enlargeMe) + 0.5*margin);
170 }
171 return nullptr;
172}
175 Acts::SurfaceBoundFactory& surfBoundSet){
176 if (volBounds.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
177 return surfBoundSet.makeBounds<Acts::RectangleBounds>(halfXlowY(volBounds), halfY(volBounds));
178 } else if (volBounds.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
179 return surfBoundSet.makeBounds<Acts::TrapezoidBounds>(halfXlowY(volBounds) , halfXhighY(volBounds) , halfY(volBounds));
180 }
181 return nullptr;
182}
183template <typename ReObjType>
186 const std::vector<ReObjType>& constituents,
187 const Amg::Transform3D& toCenter,
188 Acts::VolumeBoundFactory& volBoundSet,
189 Acts::SurfaceBoundFactory& surfBoundSet,
190 const double margin) const
191 requires (Acts::PointerConcept<ReObjType>){
192
193 VolBoundPtr_t envelopeBounds{};
194 ATH_MSG_DEBUG("Conrstuct a new "<<typeid(Acts::RemovePointer_t<ReObjType>).name()<<" object.");
195 Amg::Transform3D newCentreTrf{Amg::Transform3D::Identity()};
196 for (const auto& chambEle : constituents) {
197 Amg::Transform3D trf = newCentreTrf * toCenter *
198 chambEle->localToGlobalTrans(gctx) *
199 axisRotation(chambEle).inverse();
200 VolBoundPtr_t bounds = boundingBox(chambEle, volBoundSet);
203 GeoTrf::CoordEulerAngles rotAngles = GeoTrf::getCoordRotationAngles(trf);
204 if (std::abs(rotAngles.gamma - 180._degree)< Acts::s_epsilon){
205 trf = trf *Amg::getRotateZ3D(180._degree);
206 }
207 if (std::abs(rotAngles.alpha - 180._degree)< Acts::s_epsilon){
208 trf = trf *Amg::getRotateX3D(180._degree);
209 }
210
211 if (!envelopeBounds) {
212 envelopeBounds = bounds;
213 newCentreTrf = centerTrapezoid(cornerPoints(trf, *bounds)) * newCentreTrf;
214 ATH_MSG_VERBOSE("Envelope "<<toString(chambEle)<<", "<<(*envelopeBounds)<<", transform: "<<Amg::toString(newCentreTrf));
215 continue;
216 }
218 const std::array<Amg::Vector3D, 8> corners = cornerPoints(trf, *bounds);
219
221 if (std::ranges::none_of(corners, [&envelopeBounds](const Amg::Vector3D& v) {
222 return !envelopeBounds->inside(v);
223 })) {
224 ATH_MSG_VERBOSE("Element "<<toString(chambEle)<<" "
225 <<(*boundingBox(chambEle, volBoundSet))<<" fully contained. ");
226 continue;
227 }
228 if (msgLvl(MSG::VERBOSE)) {
229 std::stringstream debugStr{};
230 for (const Amg::Vector3D& corner : corners) {
231 debugStr<<" ***** "<<Amg::toString(corner)<<std::endl;
232 }
233 ATH_MSG_VERBOSE(toString(chambEle)<<" corner points "<<GeoTrf::toString(trf, true)<<std::endl<<debugStr.str());
234 }
236 const std::array<Amg::Vector3D, 8> refCorners{cornerPoints(Amg::Transform3D::Identity(), *envelopeBounds)};
238 std::array<Amg::Vector3D, 8> newTrapBounds{make_array<Amg::Vector3D, 8>(Amg::Vector3D::Zero())};
239
241 for (unsigned lowZ : {0, 4}) {
242 for (bool isLeft : {false, true}) {
243
244 const size_t iHigh = 1 + (!isLeft)*2 + lowZ;
245 const size_t iLow = 0 + (!isLeft)*2 + lowZ;
247 const Amg::Vector3D dirRef{projectIntoXY(refCorners[iHigh] - refCorners[iLow]).unit()};
248 const Amg::Vector3D dirCan{projectIntoXY(corners[iHigh] - corners[iLow]).unit()};
249
250
251 ATH_MSG_VERBOSE((isLeft ? "Left" : "Right")<<" edge "<<Amg::toString(dirRef)
252 <<" "<<dirRef.phi() / Gaudi::Units::deg <<" --- "<<toString(chambEle)<<" "
253 <<Amg::toString(dirCan)<<", phi: "<<dirCan.phi() / Gaudi::Units::deg);
254
256 const Amg::Vector3D& pickDir{(dirRef.phi() > dirCan.phi()) == isLeft ? dirRef : dirCan};
259 const double cornerLowD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iLow], isLeft);
260 const double cornerHighD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iHigh], isLeft);
261 ATH_MSG_VERBOSE("Distance "<<cornerLowD<<"/ "<<cornerHighD);
263 const Amg::Vector3D& pickPos{cornerLowD < 0 || cornerHighD < 0 ?
264 cornerLowD < cornerHighD ? corners[iLow] : corners[iHigh]: refCorners[iLow]};
265
266 ATH_MSG_VERBOSE("Low points "<<Amg::toString(corners[iLow])<<" - "<<Amg::toString(refCorners[iLow]));
267 ATH_MSG_VERBOSE("High points "<<Amg::toString(corners[iHigh])<<" - "<<Amg::toString(refCorners[iHigh]));
268
270 newTrapBounds[iHigh] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
271 std::max(corners[iHigh].y(), refCorners[iHigh].y())).value_or(0.) * pickDir;
272
273 newTrapBounds[iHigh].z() = lowZ ? std::max(corners[iHigh].z(),refCorners[iHigh].z())
274 : std::min(corners[iHigh].z(), refCorners[iHigh].z());
275 newTrapBounds[iLow] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
276 std::min(corners[iLow].y(), refCorners[iLow].y())).value_or(0.) * pickDir;
277 newTrapBounds[iLow].z() = lowZ ? std::max(corners[iLow].z(), refCorners[iLow].z())
278 : std::min(corners[iLow].z(), refCorners[iLow].z());
279 ATH_MSG_VERBOSE("New end points "<<Amg::toString(newTrapBounds[iLow])<<" - "<<Amg::toString(newTrapBounds[iHigh]));
280 }
281 }
282 if (msgLvl(MSG::VERBOSE)) {
283 std::stringstream debugStr{};
284 for (const Amg::Vector3D& edge : newTrapBounds) {
285 debugStr<<"***** "<<Amg::toString(edge)<<std::endl;
286 }
287 ATH_MSG_VERBOSE("#############################################################"<<std::endl<<
288 debugStr.str()<<"#############################################################");
289 }
291 const double halfY = 0.5*std::max(newTrapBounds[1].y() - newTrapBounds[0].y(),
292 newTrapBounds[3].y() - newTrapBounds[2].y());
293 const double lHalfX = 0.5*std::abs(newTrapBounds[3].x() - newTrapBounds[1].x());
294 const double sHalfX = 0.5*std::abs(newTrapBounds[2].x() - newTrapBounds[0].x());
295 const double halfZ = 0.5*std::abs(newTrapBounds[4].z() - newTrapBounds[0].z());
296 ATH_MSG_VERBOSE("New bounds "<<sHalfX<<"/"<<lHalfX<<", y:"<<halfY<<", "<<halfZ);
297 if (std::abs(lHalfX - sHalfX) > Acts::s_epsilon) {
298 envelopeBounds = volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(sHalfX, lHalfX, halfY, halfZ);
299 } else {
300 envelopeBounds = volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(sHalfX, halfY, halfZ);
301 }
302 ATH_MSG_VERBOSE(toString(chambEle)<<" "<<(*envelopeBounds));
303
305 const Amg::Transform3D centerShift = centerTrapezoid(newTrapBounds);
306 newCentreTrf = centerShift * newCentreTrf;
307 ATH_MSG_VERBOSE("New trapezoid centering "<<Amg::toString(centerShift)<<" combined: "
308 <<Amg::toString(newCentreTrf));
309 }
310 ATH_MSG_DEBUG("Done");
311 return std::make_tuple(newCentreTrf.inverse(),
312 enlargeBounds(*envelopeBounds, margin, volBoundSet),
313 surfaceBounds(*envelopeBounds, surfBoundSet));
314}
315
317 ATH_CHECK(m_idHelperSvc.retrieve());
319 auto mdtStationIndex = [this] (const std::string& stName) {
320 return m_idHelperSvc->hasMDT() ? m_idHelperSvc->mdtIdHelper().stationNameIndex(stName) : -1;
321 };
322 auto tgcStationIndex = [this] (const std::string& stName) {
323 return m_idHelperSvc->hasTGC() ? m_idHelperSvc->tgcIdHelper().stationNameIndex(stName) : -1;
324 };
325
326 const std::unordered_set<int> stIndicesEM{mdtStationIndex("EML"), mdtStationIndex("EMS"),
327 tgcStationIndex("T1E"), tgcStationIndex("T1F"),
328 tgcStationIndex("T2E"), tgcStationIndex("T2F"),
329 tgcStationIndex("T3E"), tgcStationIndex("T3F")};
330
331
332 std::unordered_set<Identifier> BIS78_ids{};
333 auto fillBIS78 = [&BIS78_ids, this](const MuonIdHelper& idHelper) {
334 const int BIS = idHelper.stationNameIndex("BIS");
335 std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(), std::inserter(BIS78_ids, BIS78_ids.end()),
336 [&](const Identifier& detId){
337 int stEta = idHelper.stationEta(detId);
338 if (m_isRun4) {
339 stEta = std::abs(stEta);
340 }
341 return stEta >= 7 && idHelper.stationName(detId) == BIS;
342 });
343 };
344 if (m_idHelperSvc->hasMDT()) {
345 fillBIS78(m_idHelperSvc->mdtIdHelper());
346 }
347 if (m_idHelperSvc->hasRPC()) {
348 fillBIS78(m_idHelperSvc->rpcIdHelper());
349 }
350
351 std::vector<MuonReadoutElement*> allReadOutEles = mgr.getAllReadoutElements();
352
353 std::vector<chamberArgs> envelopeCandidates{};
354
356 for (const MuonReadoutElement* readOutEle : allReadOutEles) {
357 std::vector<chamberArgs>::iterator exist = std::ranges::find_if(envelopeCandidates,
358 [this, readOutEle, &stIndicesEM](const chamberArgs& args){
359 const MuonReadoutElement* refEle = args.detEles.front();
360 const Identifier refId = refEle->identify();
361 const Identifier testId = readOutEle->identify();
364 if (sign(refEle->stationEta()) * sign(readOutEle->stationEta()) <0) {
365 return false;
366 }
368 if (m_idHelperSvc->sector(testId) != m_idHelperSvc->sector(refId)) {
369 return false;
370 }
371 if (stIndicesEM.count(readOutEle->stationName()) &&
372 stIndicesEM.count(refEle->stationName())) {
373 return true;
374 }
375 // /// Summarize all readout element in the same sector & layer
377 return readOutEle->chamberIndex() == refEle->chamberIndex();
378 });
380 if (exist == envelopeCandidates.end()) {
381 ATH_MSG_VERBOSE("Open envelope "<<(envelopeCandidates.size()+1)
382 <<" for "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
383 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
384 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex()));
385 envelopeCandidates.emplace_back().detEles.push_back(readOutEle);
386 } else {
387 ATH_MSG_VERBOSE("Attach "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
388 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
389 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex())<<" to envelope "
390 <<(std::distance(envelopeCandidates.begin(), exist) + 1)<<". ");
391 exist->detEles.push_back(readOutEle);
392 }
393 }
395 ActsTrk::GeometryContext gctx{};
396
397
398 Acts::VolumeBoundFactory volBoundSet{};
399 Acts::SurfaceBoundFactory surfBoundSet{};
400 unsigned candId{0};
401 for (chamberArgs& candidate : envelopeCandidates) {
402 std::unordered_set<Identifier> reIds{};
403
404 ATH_MSG_VERBOSE("New envelope candidate ");
407 sectorArgs.id = (++candId);
408 using namespace Muon::MuonStationIndex;
409 std::vector<std::vector<const MuonReadoutElement*>> chamberElements{};
410 if (toStationIndex(candidate.detEles.front()->chamberIndex()) != StIndex::EI) {
412 std::map<PVConstLink, std::vector<const MuonReadoutElement*>> stationMap{};
414 for (const MuonReadoutElement* re : candidate.detEles) {
417 if (BIS78_ids.count(re->identify())) {
418 stationMap[re->getMaterialGeom()].push_back(re);
419 } else {
420 stationMap[re->getMaterialGeom()->getParent()].push_back(re);
421 }
422 }
423 for (auto& [parent, stationEles ]: stationMap){
424 chamberElements.push_back(std::move(stationEles));
425 }
426 } else {
429 std::vector<std::vector<const MuonReadoutElement*>> endcapEles(2);
430
431 for (const MuonReadoutElement* sortMe : candidate.detEles){
432 if (sortMe->detectorType() == ActsTrk::DetectorType::Tgc) {
433 endcapEles.emplace_back(1, sortMe);
434 } else {
435 endcapEles[sortMe->detectorType() == ActsTrk::DetectorType::sTgc ||
436 sortMe->detectorType() == ActsTrk::DetectorType::Mm].push_back(sortMe);
437 }
438 }
439 for (auto& stationEles : endcapEles) {
440 if (!stationEles.empty()) {
441 chamberElements.push_back(std::move(stationEles));
442 }
443 }
444 }
445
446 for (auto& detEles: chamberElements) {
447 const MuonReadoutElement* refEle = detEles.front();
448 const Amg::Transform3D toChambCentre = axisRotation(refEle) * refEle->globalToLocalTrans(gctx);
449 ATH_MSG_VERBOSE("New chamber candidate "<<m_idHelperSvc->toStringChamber(refEle->identify()));
450 const auto[chamberCentre, chamberBox, planeBounds] = boundingBox(gctx, detEles, toChambCentre, volBoundSet,
451 surfBoundSet, 0.*Gaudi::Units::cm);
452 chamberArgs chambArgs{};
453 chambArgs.detEles = std::move(detEles);
454 chambArgs.bounds = chamberBox;
455 chambArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toChambCentre.inverse() * chamberCentre, planeBounds);
456 const Chamber* newChamber {sectorArgs.chambers.emplace_back(std::make_unique<Chamber>(std::move(chambArgs))).get()};
457 for (const MuonReadoutElement* re : newChamber->readoutEles()) {
458 reIds.insert(re->identify());
459 mgr.getReadoutElement(re->identify())->setChamberLink(newChamber);
460 ATH_MSG_VERBOSE("Chamber element: "<<m_idHelperSvc->toStringDetEl(re->identify()));
461
462 }
463 ATH_MSG_VERBOSE("Created new chamber: "<<(*newChamber));
464 }
465 std::ranges::sort(sectorArgs.chambers, [](const SpectrometerSector::ChamberPtr& a,
467 return (*a) < (*b);
468 });
469
470 const Amg::Transform3D toCenter = sectorArgs.chambers.front()->globalToLocalTrans(gctx);
471 const auto [envelopeCentre, envelopeBox, envelopePlane] = boundingBox(gctx, sectorArgs.chambers, toCenter,
472 volBoundSet, surfBoundSet, 2.* Gaudi::Units::cm);
473
474 sectorArgs.bounds = envelopeBox;
475 sectorArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toCenter.inverse() * envelopeCentre, envelopePlane);
476
477 const Amg::Transform3D globalToSector = sectorArgs.surface->transform(gctx.context()).inverse();
478
480 for (auto & chamber : sectorArgs.chambers){
481 // split by readout elements - MDT multilayers and trigger chambers for the sector
482 for (auto & RE : chamber->readoutEles()){
483 // get the center of the element in the sector frame
484 const Amg::Transform3D& chamberToGlobal{RE->localToGlobalTrans(gctx)};
485 const Amg::Vector3D origin = (globalToSector * chamberToGlobal).translation();
486 // and then add the bounds of the element - this is technology dependent
487 sectorArgs.detectorLocs.emplace_back(origin, RE, boundingBox(RE, volBoundSet));
488 }
489 }
491 auto newSector = std::make_unique<SpectrometerSector>(std::move(sectorArgs));
492
493 for (const Identifier& chId : reIds) {
494 mgr.getReadoutElement(chId)->setSectorLink(newSector.get());
495 }
496 mgr.addSpectrometerSector(std::move(newSector));
497 }
498 return StatusCode::SUCCESS;
499}
500
501}
502#endif
const boost::regex re(r_e)
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
Definition ArrayHelper.h:10
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static std::string to_string(const std::vector< T > &v)
static Double_t a
@ BIS
Definition RegSelEnums.h:11
int sign(int a)
#define y
#define x
#define z
Acts::GeometryContext context() const
virtual DetectorType detectorType() const =0
Returns the detector element type.
std::shared_ptr< const Acts::PlanarBounds > SurfBoundPtr_t
Abrivation of the surface bounds.
static std::array< Amg::Vector3D, 4 > cornerPointsPlane(const Amg::Transform3D &localToGlob, const VolBounds_t &bounds)
Returns the 4 corners of the trapezoid in the x-y plane.
static std::array< Amg::Vector3D, 8 > cornerPoints(const Amg::Transform3D &localToGlob, const VolBounds_t &bounds)
Returns the 8 corners marking the trapezoid.
Acts::VolumeBounds VolBounds_t
Abrivation of the volume bounds.
virtual StatusCode buildReadOutElements(MuonDetectorManager &mgr) override final
SpectrometerSector::ChamberPtr ChamberPtr
TrfWithBounds boundingBox(const ActsTrk::GeometryContext &gctx, const std::vector< ReObjType > &constituents, const Amg::Transform3D &globToLoc, Acts::VolumeBoundFactory &volBoundSet, Acts::SurfaceBoundFactory &surfBoundSet, const double margin) const
builds the bounding box trapezoidal volume bounds from the set of readout elements Returns a pair of ...
std::shared_ptr< VolBounds_t > VolBoundPtr_t
Abrivation of the Volume bound ptr.
std::tuple< Amg::Transform3D, VolBoundPtr_t, SurfBoundPtr_t > TrfWithBounds
Abrivation of the volume transform together with a set of volume & surface bounds.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
static SurfBoundPtr_t surfaceBounds(const VolBounds_t &volBounds, Acts::SurfaceBoundFactory &surfBoundSet)
Construct surface bounds which measure equal sizes in halfXlow/halfXhigh & halfY as the parsed volume...
static double trapezoidEdgeDist(const Amg::Vector3D &linePos, const Amg::Vector3D &lineDir, const Amg::Vector3D &testMe, bool leftEdge)
Returns the signed distances of an external point to the trapezoidal edge.
static VolBoundPtr_t enlargeBounds(const VolBounds_t &enlargeMe, const double margin, Acts::VolumeBoundFactory &volBoundSet)
Enlarge the parsed volume bounds by an extra margin attached to all 3 dimensions.
static Amg::Transform3D centerTrapezoid(const std::array< Amg::Vector3D, 8 > &cornerPoints)
Returns the translation transform centering the 8 corner points of the trapezoid.
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
GeoModel::TransientConstSharedPtr< Chamber > ChamberPtr
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
@ Mm
Maybe not needed in the migration.
@ Tgc
Resitive Plate Chambers.
@ sTgc
Micromegas (NSW)
@ Rpc
Monitored Drift Tubes.
@ Mdt
MuonSpectrometer.
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
double halfY(const Acts::VolumeBounds &bounds)
Returns the half-Y length for the parsed volume bounds (Trapezoid/ Cuboid)
Chamber::defineArgs chamberArgs
std::string toString(const MuonGMR4::MuonReadoutElement *re)
ChamberAssembleTool::VolBoundPtr_t VolBoundPtr_t
Amg::Transform3D axisRotation(const MuonReadoutElement *re)
Orientation of the readout element coordinate system x-axis: Points towards the sky y-axis: Points al...
SpectrometerSector::ChamberPtr ChamberPtr
double halfZ(const Acts::VolumeBounds &bounds)
Returns the half-Z length for the parsed volume bounds (Trapezoid/ Cuboid)
double halfXhighY(const Acts::VolumeBounds &bounds)
Returns the half-Y length @ posiive Y for the parsed volume bounds (Trapezoid/ Cuboid)
double halfXlowY(const Acts::VolumeBounds &bounds)
Returns the half-X length @ negative Y for the parsed volume bounds (Trapezoid/ Cuboid)
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
const std::string & chName(ChIndex index)
convert ChIndex into a string
unsigned id
Unique Identifier integer of the sector.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10