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 {
30 Amg::Vector3D projectIntoXY(const Amg::Vector3D& v) {
31 return Amg::Vector3D{v.x(), v.y(), 0.};
32 }
33}
34
35
36
37namespace MuonGMR4{
38
42
52 ActsTrk::DetectorType t = re->detectorType();
54 return Amg::Transform3D::Identity();
55 }
56 return Amg::getRotateZ3D(-90. * Gaudi::Units::deg) *
57 Amg::getRotateY3D(-90. * Gaudi::Units::deg);
58}
60 return Amg::Transform3D::Identity();
61}
63 return re->idHelperSvc()->toStringDetEl(re->identify());
64}
65std::string toString(const ChamberPtr& ch) {
66 return ch->identString();
67}
68
69
71 const Amg::Vector3D& lineDir,
72 const Amg::Vector3D& testMe,
73 bool leftEdge) {
75 const Amg::Vector3D normal = lineDir.cross((leftEdge ? 1. : -1.) *Amg::Vector3D::UnitZ());
76 const Amg::Vector3D closest = linePos + lineDir.dot(testMe - linePos) * lineDir;
77 return normal.dot(testMe - closest);
78}
79
82 Acts::VolumeBoundFactory& volBoundSet) {
83
84 switch(chambEle->detectorType()) {
86 const auto* techEle = static_cast<const MdtReadoutElement*>(chambEle);
87 const auto& pars = techEle->getParameters();
88 if (std::abs(pars.shortHalfX - pars.longHalfX) < Acts::s_epsilon) {
89 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.shortHalfX, pars.halfY, pars.halfHeight);
90 }
91 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.shortHalfX, pars.longHalfX,
92 pars.halfY, pars.halfHeight );
94 const auto* techEle = static_cast<const RpcReadoutElement*>(chambEle);
95 const auto& pars = techEle->getParameters();
96 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.halfWidth, pars.halfLength, pars.halfThickness);
98 const auto* techEle = static_cast<const TgcReadoutElement*>(chambEle);
99 const auto& pars = techEle->getParameters();
100 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfWidthShort, pars.halfWidthLong,
101 pars.halfHeight, pars.halfThickness );
103 const auto* techEle = static_cast<const sTgcReadoutElement*>(chambEle);
104 const auto& pars = techEle->getParameters();
105 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.sHalfChamberLength, pars.lHalfChamberLength,
106 pars.halfChamberHeight, pars.halfChamberTck );
108 const auto* techEle = static_cast<const MmReadoutElement*>(chambEle);
109 const auto& pars = techEle->getParameters();
110 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfShortWidth, pars.halfLongWidth,
111 pars.halfHeight, pars.halfThickness );
112 } default:
113 THROW_EXCEPTION("Unsupported detector type "<<to_string(chambEle->detectorType()));
114 }
115 return nullptr;
116}
117VolBoundPtr_t ChamberAssembleTool::boundingBox(const ChamberPtr& chamber, Acts::VolumeBoundFactory& /*boundSet*/) {
118 return chamber->bounds();
119}
120
121
122std::array<Amg::Vector3D, 4> ChamberAssembleTool::cornerPointsPlane(const Amg::Transform3D& localToGlob,
123 const VolBounds_t& bounds) {
124 std::array<Amg::Vector3D,4> planePoints{localToGlob * Amg::Vector3D(-halfXlowY(bounds), - halfY(bounds), 0.),
125 localToGlob * Amg::Vector3D(-halfXhighY(bounds), halfY(bounds), 0.),
126 localToGlob * Amg::Vector3D( halfXlowY(bounds), -halfY(bounds), 0.),
127 localToGlob * Amg::Vector3D( halfXhighY(bounds), halfY(bounds), 0.)};
128 return planePoints;
129}
130std::array<Amg::Vector3D, 8> ChamberAssembleTool::cornerPoints(const Amg::Transform3D& localToGlob,
131 const VolBounds_t& bounds) {
132 std::array<Amg::Vector3D, 8> toRet{make_array<Amg::Vector3D,8>(Amg::Vector3D::Zero())};
133 const std::array<Amg::Vector3D, 4> plane = cornerPointsPlane(localToGlob, bounds);
134 for (unsigned int z : {0, 1}) {
135 const Amg::Vector3D stretch = halfZ(bounds) * (z ? 1. : -1.) * Amg::Vector3D::UnitZ();
136 for (unsigned int b = 0; b < plane.size(); ++b){
137 toRet[b + z * plane.size()] = plane[b] + stretch;
138 }
139 }
140 return toRet;
141}
142Amg::Transform3D ChamberAssembleTool::centerTrapezoid(const std::array<Amg::Vector3D, 8>& corners) {
143
144 static constexpr double maxSize = 200._km;
145 double minX{maxSize}, maxX{-maxSize}, minY{maxSize}, maxY{-maxSize}, minZ{maxSize}, maxZ{-maxSize};
146 for (const Amg::Vector3D& corner : corners) {
147 minX = std::min(corner.x(), minX); maxX = std::max(corner.x(), maxX);
148 minY = std::min(corner.y(), minY); maxY = std::max(corner.y(), maxY);
149 minZ = std::min(corner.z(), minZ); maxZ = std::max(corner.z(), maxZ);
150 }
151 return Amg::getTranslate3D(-0.5*(minX + maxX), -0.5*(minY + maxY), -0.5*(minZ + maxZ));
152}
153
156 const double margin,
157 Acts::VolumeBoundFactory& volBoundSet) {
158 if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
159 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
160 halfY(enlargeMe) + 0.5*margin,
161 halfZ(enlargeMe) + 0.5*margin);
162 } else if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
163 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
164 halfXhighY(enlargeMe) + 0.5*margin,
165 halfY(enlargeMe) + 0.5*margin,
166 halfZ(enlargeMe) + 0.5*margin);
167 }
168 return nullptr;
169}
172 Acts::SurfaceBoundFactory& surfBoundSet){
173 if (volBounds.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
174 return surfBoundSet.makeBounds<Acts::RectangleBounds>(halfXlowY(volBounds), halfY(volBounds));
175 } else if (volBounds.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
176 return surfBoundSet.makeBounds<Acts::TrapezoidBounds>(halfXlowY(volBounds) , halfXhighY(volBounds) , halfY(volBounds));
177 }
178 return nullptr;
179}
180template <typename ReObjType>
183 const std::vector<ReObjType>& constituents,
184 const Amg::Transform3D& toCenter,
185 Acts::VolumeBoundFactory& volBoundSet,
186 Acts::SurfaceBoundFactory& surfBoundSet,
187 const double margin) const
188 requires (Acts::PointerConcept<ReObjType>){
189
190 VolBoundPtr_t envelopeBounds{};
191 ATH_MSG_DEBUG("Conrstuct a new "<<typeid(Acts::RemovePointer_t<ReObjType>).name()<<" object.");
192 Amg::Transform3D newCentreTrf{Amg::Transform3D::Identity()};
193 for (const auto& chambEle : constituents) {
194 Amg::Transform3D trf = newCentreTrf * toCenter *
195 chambEle->localToGlobalTrans(gctx) *
196 axisRotation(chambEle).inverse();
197 VolBoundPtr_t bounds = boundingBox(chambEle, volBoundSet);
200 GeoTrf::CoordEulerAngles rotAngles = GeoTrf::getCoordRotationAngles(trf);
201 if (std::abs(rotAngles.gamma - 180._degree)< Acts::s_epsilon){
202 trf = trf *Amg::getRotateZ3D(180._degree);
203 }
204 if (std::abs(rotAngles.alpha - 180._degree)< Acts::s_epsilon){
205 trf = trf *Amg::getRotateX3D(180._degree);
206 }
207
208 if (!envelopeBounds) {
209 envelopeBounds = bounds;
210 newCentreTrf = centerTrapezoid(cornerPoints(trf, *bounds)) * newCentreTrf;
211 ATH_MSG_VERBOSE("Envelope "<<toString(chambEle)<<", "<<(*envelopeBounds)<<", transform: "<<Amg::toString(newCentreTrf));
212 continue;
213 }
215 const std::array<Amg::Vector3D, 8> corners = cornerPoints(trf, *bounds);
216
218 if (std::ranges::none_of(corners, [&envelopeBounds](const Amg::Vector3D& v) {
219 return !envelopeBounds->inside(v);
220 })) {
221 ATH_MSG_VERBOSE("Element "<<toString(chambEle)<<" "
222 <<(*boundingBox(chambEle, volBoundSet))<<" fully contained. ");
223 continue;
224 }
225 if (msgLvl(MSG::VERBOSE)) {
226 std::stringstream debugStr{};
227 for (const Amg::Vector3D& corner : corners) {
228 debugStr<<" ***** "<<Amg::toString(corner)<<std::endl;
229 }
230 ATH_MSG_VERBOSE(toString(chambEle)<<" corner points "<<GeoTrf::toString(trf, true)<<std::endl<<debugStr.str());
231 }
233 const std::array<Amg::Vector3D, 8> refCorners{cornerPoints(Amg::Transform3D::Identity(), *envelopeBounds)};
235 std::array<Amg::Vector3D, 8> newTrapBounds{make_array<Amg::Vector3D, 8>(Amg::Vector3D::Zero())};
236
238 for (unsigned lowZ : {0, 4}) {
239 for (bool isLeft : {false, true}) {
240
241 const size_t iHigh = 1 + (!isLeft)*2 + lowZ;
242 const size_t iLow = 0 + (!isLeft)*2 + lowZ;
244 const Amg::Vector3D dirRef{projectIntoXY(refCorners[iHigh] - refCorners[iLow]).unit()};
245 const Amg::Vector3D dirCan{projectIntoXY(corners[iHigh] - corners[iLow]).unit()};
246
247
248 ATH_MSG_VERBOSE((isLeft ? "Left" : "Right")<<" edge "<<Amg::toString(dirRef)
249 <<" "<<dirRef.phi() / Gaudi::Units::deg <<" --- "<<toString(chambEle)<<" "
250 <<Amg::toString(dirCan)<<", phi: "<<dirCan.phi() / Gaudi::Units::deg);
251
253 const Amg::Vector3D& pickDir{(dirRef.phi() > dirCan.phi()) == isLeft ? dirRef : dirCan};
256 const double cornerLowD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iLow], isLeft);
257 const double cornerHighD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iHigh], isLeft);
258 ATH_MSG_VERBOSE("Distance "<<cornerLowD<<"/ "<<cornerHighD);
260 const Amg::Vector3D& pickPos{cornerLowD < 0 || cornerHighD < 0 ?
261 cornerLowD < cornerHighD ? corners[iLow] : corners[iHigh]: refCorners[iLow]};
262
263 ATH_MSG_VERBOSE("Low points "<<Amg::toString(corners[iLow])<<" - "<<Amg::toString(refCorners[iLow]));
264 ATH_MSG_VERBOSE("High points "<<Amg::toString(corners[iHigh])<<" - "<<Amg::toString(refCorners[iHigh]));
265
267 newTrapBounds[iHigh] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
268 std::max(corners[iHigh].y(), refCorners[iHigh].y())).value_or(0.) * pickDir;
269
270 newTrapBounds[iHigh].z() = lowZ ? std::max(corners[iHigh].z(),refCorners[iHigh].z())
271 : std::min(corners[iHigh].z(), refCorners[iHigh].z());
272 newTrapBounds[iLow] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
273 std::min(corners[iLow].y(), refCorners[iLow].y())).value_or(0.) * pickDir;
274 newTrapBounds[iLow].z() = lowZ ? std::max(corners[iLow].z(), refCorners[iLow].z())
275 : std::min(corners[iLow].z(), refCorners[iLow].z());
276 ATH_MSG_VERBOSE("New end points "<<Amg::toString(newTrapBounds[iLow])<<" - "<<Amg::toString(newTrapBounds[iHigh]));
277 }
278 }
279 if (msgLvl(MSG::VERBOSE)) {
280 std::stringstream debugStr{};
281 for (const Amg::Vector3D& edge : newTrapBounds) {
282 debugStr<<"***** "<<Amg::toString(edge)<<std::endl;
283 }
284 ATH_MSG_VERBOSE("#############################################################"<<std::endl<<
285 debugStr.str()<<"#############################################################");
286 }
288 const double halfY = 0.5*std::max(newTrapBounds[1].y() - newTrapBounds[0].y(),
289 newTrapBounds[3].y() - newTrapBounds[2].y());
290 const double lHalfX = 0.5*std::abs(newTrapBounds[3].x() - newTrapBounds[1].x());
291 const double sHalfX = 0.5*std::abs(newTrapBounds[2].x() - newTrapBounds[0].x());
292 const double halfZ = 0.5*std::abs(newTrapBounds[4].z() - newTrapBounds[0].z());
293 ATH_MSG_VERBOSE("New bounds "<<sHalfX<<"/"<<lHalfX<<", y:"<<halfY<<", "<<halfZ);
294 if (std::abs(lHalfX - sHalfX) > Acts::s_epsilon) {
295 envelopeBounds = volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(sHalfX, lHalfX, halfY, halfZ);
296 } else {
297 envelopeBounds = volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(sHalfX, halfY, halfZ);
298 }
299 ATH_MSG_VERBOSE(toString(chambEle)<<" "<<(*envelopeBounds));
300
302 const Amg::Transform3D centerShift = centerTrapezoid(newTrapBounds);
303 newCentreTrf = centerShift * newCentreTrf;
304 ATH_MSG_VERBOSE("New trapezoid centering "<<Amg::toString(centerShift)<<" combined: "
305 <<Amg::toString(newCentreTrf));
306 }
307 ATH_MSG_DEBUG("Done");
308 return std::make_tuple(newCentreTrf.inverse(),
309 enlargeBounds(*envelopeBounds, margin, volBoundSet),
310 surfaceBounds(*envelopeBounds, surfBoundSet));
311}
312
314 ATH_CHECK(m_idHelperSvc.retrieve());
316 auto mdtStationIndex = [this] (const std::string& stName) {
317 return m_idHelperSvc->hasMDT() ? m_idHelperSvc->mdtIdHelper().stationNameIndex(stName) : -1;
318 };
319 auto tgcStationIndex = [this] (const std::string& stName) {
320 return m_idHelperSvc->hasTGC() ? m_idHelperSvc->tgcIdHelper().stationNameIndex(stName) : -1;
321 };
322
323 const std::unordered_set<int> stIndicesEM{mdtStationIndex("EML"), mdtStationIndex("EMS"),
324 tgcStationIndex("T1E"), tgcStationIndex("T1F"),
325 tgcStationIndex("T2E"), tgcStationIndex("T2F"),
326 tgcStationIndex("T3E"), tgcStationIndex("T3F")};
327
328
329 std::unordered_set<Identifier> BIS78_ids{};
330 auto fillBIS78 = [&BIS78_ids, this](const MuonIdHelper& idHelper) {
331 const int BIS = idHelper.stationNameIndex("BIS");
332 std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(), std::inserter(BIS78_ids, BIS78_ids.end()),
333 [&](const Identifier& detId){
334 int stEta = idHelper.stationEta(detId);
335 if (m_isRun4) {
336 stEta = std::abs(stEta);
337 }
338 return stEta >= 7 && idHelper.stationName(detId) == BIS;
339 });
340 };
341 if (m_idHelperSvc->hasMDT()) {
342 fillBIS78(m_idHelperSvc->mdtIdHelper());
343 }
344 if (m_idHelperSvc->hasRPC()) {
345 fillBIS78(m_idHelperSvc->rpcIdHelper());
346 }
347
348 std::vector<MuonReadoutElement*> allReadOutEles = mgr.getAllReadoutElements();
349
350 std::vector<chamberArgs> envelopeCandidates{};
351
353 for (const MuonReadoutElement* readOutEle : allReadOutEles) {
354 std::vector<chamberArgs>::iterator exist = std::ranges::find_if(envelopeCandidates,
355 [this, readOutEle, &stIndicesEM](const chamberArgs& args){
356 const MuonReadoutElement* refEle = args.detEles.front();
357 const Identifier refId = refEle->identify();
358 const Identifier testId = readOutEle->identify();
361 if (Acts::copySign(1, refEle->stationEta()) *
362 Acts::copySign(1, readOutEle->stationEta()) < 0) {
363 return false;
364 }
366 if (m_idHelperSvc->sector(testId) != m_idHelperSvc->sector(refId)) {
367 return false;
368 }
369 if (stIndicesEM.count(readOutEle->stationName()) &&
370 stIndicesEM.count(refEle->stationName())) {
371 return true;
372 }
373 // /// Summarize all readout element in the same sector & layer
375 return readOutEle->chamberIndex() == refEle->chamberIndex();
376 });
378 if (exist == envelopeCandidates.end()) {
379 ATH_MSG_VERBOSE("Open envelope "<<(envelopeCandidates.size()+1)
380 <<" for "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
381 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
382 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex()));
383 envelopeCandidates.emplace_back().detEles.push_back(readOutEle);
384 } else {
385 ATH_MSG_VERBOSE("Attach "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
386 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
387 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex())<<" to envelope "
388 <<(std::distance(envelopeCandidates.begin(), exist) + 1)<<". ");
389 exist->detEles.push_back(readOutEle);
390 }
391 }
393 ActsTrk::GeometryContext gctx{};
394
395
396 Acts::VolumeBoundFactory volBoundSet{};
397 Acts::SurfaceBoundFactory surfBoundSet{};
398 unsigned candId{0};
399 for (chamberArgs& candidate : envelopeCandidates) {
400 std::unordered_set<Identifier> reIds{};
401
402 ATH_MSG_VERBOSE("New envelope candidate ");
405 sectorArgs.id = (++candId);
406 using namespace Muon::MuonStationIndex;
407 std::vector<std::vector<const MuonReadoutElement*>> chamberElements{};
408 if (toStationIndex(candidate.detEles.front()->chamberIndex()) != StIndex::EI) {
410 std::map<PVConstLink, std::vector<const MuonReadoutElement*>> stationMap{};
412 for (const MuonReadoutElement* re : candidate.detEles) {
415 if (BIS78_ids.count(re->identify())) {
416 stationMap[re->getMaterialGeom()].push_back(re);
417 } else {
418 stationMap[re->getMaterialGeom()->getParent()].push_back(re);
419 }
420 }
421 for (auto& [parent, stationEles ]: stationMap){
422 chamberElements.push_back(std::move(stationEles));
423 }
424 } else {
427 std::vector<std::vector<const MuonReadoutElement*>> endcapEles(2);
428
429 for (const MuonReadoutElement* sortMe : candidate.detEles){
430 if (sortMe->detectorType() == ActsTrk::DetectorType::Tgc) {
431 endcapEles.emplace_back(1, sortMe);
432 } else {
433 endcapEles[sortMe->detectorType() == ActsTrk::DetectorType::sTgc ||
434 sortMe->detectorType() == ActsTrk::DetectorType::Mm].push_back(sortMe);
435 }
436 }
437 for (auto& stationEles : endcapEles) {
438 if (!stationEles.empty()) {
439 chamberElements.push_back(std::move(stationEles));
440 }
441 }
442 }
443
444 for (auto& detEles: chamberElements) {
445 const MuonReadoutElement* refEle = detEles.front();
446 const Amg::Transform3D toChambCentre = axisRotation(refEle) * refEle->globalToLocalTrans(gctx);
447 ATH_MSG_VERBOSE("New chamber candidate "<<m_idHelperSvc->toStringChamber(refEle->identify()));
448 const auto[chamberCentre, chamberBox, planeBounds] = boundingBox(gctx, detEles, toChambCentre, volBoundSet,
449 surfBoundSet, 0.*Gaudi::Units::cm);
450 chamberArgs chambArgs{};
451 chambArgs.detEles = std::move(detEles);
452 chambArgs.bounds = chamberBox;
453 chambArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toChambCentre.inverse() * chamberCentre, planeBounds);
454 const Chamber* newChamber {sectorArgs.chambers.emplace_back(std::make_unique<Chamber>(std::move(chambArgs))).get()};
455 for (const MuonReadoutElement* re : newChamber->readoutEles()) {
456 reIds.insert(re->identify());
457 mgr.getReadoutElement(re->identify())->setChamberLink(newChamber);
458 ATH_MSG_VERBOSE("Chamber element: "<<m_idHelperSvc->toStringDetEl(re->identify()));
459
460 }
461 ATH_MSG_VERBOSE("Created new chamber: "<<(*newChamber));
462 }
463 std::ranges::sort(sectorArgs.chambers, [](const SpectrometerSector::ChamberPtr& a,
465 return (*a) < (*b);
466 });
467
468 const Amg::Transform3D toCenter = sectorArgs.chambers.front()->globalToLocalTrans(gctx);
469 const auto [envelopeCentre, envelopeBox, envelopePlane] = boundingBox(gctx, sectorArgs.chambers, toCenter,
470 volBoundSet, surfBoundSet, 2.* Gaudi::Units::cm);
471
472 sectorArgs.bounds = envelopeBox;
473 sectorArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toCenter.inverse() * envelopeCentre, envelopePlane);
474
475 const Amg::Transform3D globalToSector = sectorArgs.surface->transform(gctx.context()).inverse();
476
478 for (auto & chamber : sectorArgs.chambers){
479 // split by readout elements - MDT multilayers and trigger chambers for the sector
480 for (auto & RE : chamber->readoutEles()){
481 // get the center of the element in the sector frame
482 const Amg::Transform3D& chamberToGlobal{RE->localToGlobalTrans(gctx)};
483 const Amg::Vector3D origin = (globalToSector * chamberToGlobal).translation();
484 // and then add the bounds of the element - this is technology dependent
485 sectorArgs.detectorLocs.emplace_back(origin, RE, boundingBox(RE, volBoundSet));
486 }
487 }
489 auto newSector = std::make_unique<SpectrometerSector>(std::move(sectorArgs));
490
491 for (const Identifier& chId : reIds) {
492 mgr.getReadoutElement(chId)->setSectorLink(newSector.get());
493 }
494 mgr.addSpectrometerSector(std::move(newSector));
495 }
496 return StatusCode::SUCCESS;
497}
498
499}
500#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
#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