ATLAS Offline Software
Loading...
Searching...
No Matches
ChamberAssembleTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
44 return re->idHelperSvc()->toStringDetEl(re->identify());
45}
46std::string toString(const ChamberPtr& ch) {
47 return ch->identString();
48}
49
51 const Amg::Vector3D& lineDir,
52 const Amg::Vector3D& testMe,
53 bool leftEdge) {
55 const Amg::Vector3D normal = lineDir.cross((leftEdge ? 1. : -1.) *Amg::Vector3D::UnitZ());
56 const Amg::Vector3D closest = linePos + lineDir.dot(testMe - linePos) * lineDir;
57 return normal.dot(testMe - closest);
58}
59
62 Acts::VolumeBoundFactory& volBoundSet) {
63
64 switch(chambEle->detectorType()) {
66 const auto* techEle = static_cast<const MdtReadoutElement*>(chambEle);
67 const auto& pars = techEle->getParameters();
68 if (std::abs(pars.shortHalfX - pars.longHalfX) < Acts::s_epsilon) {
69 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.shortHalfX, pars.halfY, pars.halfHeight);
70 }
71 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.shortHalfX, pars.longHalfX,
72 pars.halfY, pars.halfHeight );
74 const auto* techEle = static_cast<const RpcReadoutElement*>(chambEle);
75 const auto& pars = techEle->getParameters();
76 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(pars.halfWidth, pars.halfLength, pars.halfThickness);
78 const auto* techEle = static_cast<const TgcReadoutElement*>(chambEle);
79 const auto& pars = techEle->getParameters();
80 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfWidthShort, pars.halfWidthLong,
81 pars.halfHeight, pars.halfThickness );
83 const auto* techEle = static_cast<const sTgcReadoutElement*>(chambEle);
84 const auto& pars = techEle->getParameters();
85 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.sHalfChamberLength, pars.lHalfChamberLength,
86 pars.halfChamberHeight, pars.halfChamberTck );
88 const auto* techEle = static_cast<const MmReadoutElement*>(chambEle);
89 const auto& pars = techEle->getParameters();
90 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfShortWidth, pars.halfLongWidth,
91 pars.halfHeight, pars.halfThickness );
92 } default:
93 THROW_EXCEPTION("Unsupported detector type "<<to_string(chambEle->detectorType()));
94 }
95 return nullptr;
96}
97VolBoundPtr_t ChamberAssembleTool::boundingBox(const ChamberPtr& chamber, Acts::VolumeBoundFactory& /*boundSet*/) {
98 return chamber->bounds();
99}
100
101
102std::array<Amg::Vector3D, 4> ChamberAssembleTool::cornerPointsPlane(const Amg::Transform3D& localToGlob,
103 const VolBounds_t& bounds) {
104 std::array<Amg::Vector3D,4> planePoints{localToGlob * Amg::Vector3D(-halfXlowY(bounds), - halfY(bounds), 0.),
105 localToGlob * Amg::Vector3D(-halfXhighY(bounds), halfY(bounds), 0.),
106 localToGlob * Amg::Vector3D( halfXlowY(bounds), -halfY(bounds), 0.),
107 localToGlob * Amg::Vector3D( halfXhighY(bounds), halfY(bounds), 0.)};
108 return planePoints;
109}
110std::array<Amg::Vector3D, 8> ChamberAssembleTool::cornerPoints(const Amg::Transform3D& localToGlob,
111 const VolBounds_t& bounds) {
112 std::array<Amg::Vector3D, 8> toRet{make_array<Amg::Vector3D,8>(Amg::Vector3D::Zero())};
113 const std::array<Amg::Vector3D, 4> plane = cornerPointsPlane(localToGlob, bounds);
114 for (unsigned int z : {0, 1}) {
115 const Amg::Vector3D stretch = halfZ(bounds) * (z ? 1. : -1.) * Amg::Vector3D::UnitZ();
116 for (unsigned int b = 0; b < plane.size(); ++b){
117 toRet[b + z * plane.size()] = plane[b] + stretch;
118 }
119 }
120 return toRet;
121}
122Amg::Transform3D ChamberAssembleTool::centerTrapezoid(const std::array<Amg::Vector3D, 8>& corners) {
123
124 static constexpr double maxSize = 200._km;
125 double minX{maxSize}, maxX{-maxSize}, minY{maxSize}, maxY{-maxSize}, minZ{maxSize}, maxZ{-maxSize};
126 for (const Amg::Vector3D& corner : corners) {
127 minX = std::min(corner.x(), minX); maxX = std::max(corner.x(), maxX);
128 minY = std::min(corner.y(), minY); maxY = std::max(corner.y(), maxY);
129 minZ = std::min(corner.z(), minZ); maxZ = std::max(corner.z(), maxZ);
130 }
131 return Amg::getTranslate3D(-0.5*(minX + maxX), -0.5*(minY + maxY), -0.5*(minZ + maxZ));
132}
133
136 const double margin,
137 Acts::VolumeBoundFactory& volBoundSet) {
138 if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
139 return volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
140 halfY(enlargeMe) + 0.5*margin,
141 halfZ(enlargeMe) + 0.5*margin);
142 } else if (enlargeMe.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
143 return volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(halfXlowY(enlargeMe) + 0.5*margin,
144 halfXhighY(enlargeMe) + 0.5*margin,
145 halfY(enlargeMe) + 0.5*margin,
146 halfZ(enlargeMe) + 0.5*margin);
147 }
148 return nullptr;
149}
152 Acts::SurfaceBoundFactory& surfBoundSet){
153 if (volBounds.type() == Acts::VolumeBounds::BoundsType::eCuboid) {
154 return surfBoundSet.makeBounds<Acts::RectangleBounds>(halfXlowY(volBounds), halfY(volBounds));
155 } else if (volBounds.type() == Acts::VolumeBounds::BoundsType::eTrapezoid) {
156 return surfBoundSet.makeBounds<Acts::TrapezoidBounds>(halfXlowY(volBounds) , halfXhighY(volBounds) , halfY(volBounds));
157 }
158 return nullptr;
159}
160template <typename ReObjType>
163 const std::vector<ReObjType>& constituents,
164 const Amg::Transform3D& toCenter,
165 Acts::VolumeBoundFactory& volBoundSet,
166 Acts::SurfaceBoundFactory& surfBoundSet,
167 const double margin) const
168 requires (Acts::PointerConcept<ReObjType>){
169
170 VolBoundPtr_t envelopeBounds{};
171 ATH_MSG_DEBUG("Conrstuct a new "<<typeid(Acts::RemovePointer_t<ReObjType>).name()<<" object.");
172 Amg::Transform3D newCentreTrf{Amg::Transform3D::Identity()};
173 for (const auto& chambEle : constituents) {
174 Amg::Transform3D trf = newCentreTrf * toCenter *
175 chambEle->localToGlobalTransform(gctx);
176 VolBoundPtr_t bounds = boundingBox(chambEle, volBoundSet);
179 GeoTrf::CoordEulerAngles rotAngles = GeoTrf::getCoordRotationAngles(trf);
180 if (std::abs(rotAngles.gamma - 180._degree)< Acts::s_epsilon){
181 trf = trf *Amg::getRotateZ3D(180._degree);
182 }
183 if (std::abs(rotAngles.alpha - 180._degree)< Acts::s_epsilon){
184 trf = trf *Amg::getRotateX3D(180._degree);
185 }
186
187 if (!envelopeBounds) {
188 envelopeBounds = bounds;
189 newCentreTrf = centerTrapezoid(cornerPoints(trf, *bounds)) * newCentreTrf;
190 ATH_MSG_VERBOSE("Envelope "<<toString(chambEle)<<", "<<(*envelopeBounds)<<", transform: "<<Amg::toString(newCentreTrf));
191 continue;
192 }
194 const std::array<Amg::Vector3D, 8> corners = cornerPoints(trf, *bounds);
195
197 if (std::ranges::none_of(corners, [&envelopeBounds](const Amg::Vector3D& v) {
198 return !envelopeBounds->inside(v);
199 })) {
200 ATH_MSG_VERBOSE("Element "<<toString(chambEle)<<" "
201 <<(*boundingBox(chambEle, volBoundSet))<<" fully contained. ");
202 continue;
203 }
204 if (msgLvl(MSG::VERBOSE)) {
205 std::stringstream debugStr{};
206 for (const Amg::Vector3D& corner : corners) {
207 debugStr<<" ***** "<<Amg::toString(corner)<<std::endl;
208 }
209 ATH_MSG_VERBOSE(toString(chambEle)<<" corner points "<<GeoTrf::toString(trf, true)<<std::endl<<debugStr.str());
210 }
212 const std::array<Amg::Vector3D, 8> refCorners{cornerPoints(Amg::Transform3D::Identity(), *envelopeBounds)};
214 std::array<Amg::Vector3D, 8> newTrapBounds{make_array<Amg::Vector3D, 8>(Amg::Vector3D::Zero())};
215
217 for (unsigned lowZ : {0, 4}) {
218 for (bool isLeft : {false, true}) {
219
220 const size_t iHigh = 1 + (!isLeft)*2 + lowZ;
221 const size_t iLow = 0 + (!isLeft)*2 + lowZ;
223 const Amg::Vector3D dirRef{projectIntoXY(refCorners[iHigh] - refCorners[iLow]).unit()};
224 const Amg::Vector3D dirCan{projectIntoXY(corners[iHigh] - corners[iLow]).unit()};
225
226
227 ATH_MSG_VERBOSE((isLeft ? "Left" : "Right")<<" edge "<<Amg::toString(dirRef)
228 <<" "<<dirRef.phi() / Gaudi::Units::deg <<" --- "<<toString(chambEle)<<" "
229 <<Amg::toString(dirCan)<<", phi: "<<dirCan.phi() / Gaudi::Units::deg);
230
232 const Amg::Vector3D& pickDir{(dirRef.phi() > dirCan.phi()) == isLeft ? dirRef : dirCan};
235 const double cornerLowD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iLow], isLeft);
236 const double cornerHighD = trapezoidEdgeDist(refCorners[iLow], pickDir, corners[iHigh], isLeft);
237 ATH_MSG_VERBOSE("Distance "<<cornerLowD<<"/ "<<cornerHighD);
239 const Amg::Vector3D& pickPos{cornerLowD < 0 || cornerHighD < 0 ?
240 cornerLowD < cornerHighD ? corners[iLow] : corners[iHigh]: refCorners[iLow]};
241
242 ATH_MSG_VERBOSE("Low points "<<Amg::toString(corners[iLow])<<" - "<<Amg::toString(refCorners[iLow]));
243 ATH_MSG_VERBOSE("High points "<<Amg::toString(corners[iHigh])<<" - "<<Amg::toString(refCorners[iHigh]));
244
246 newTrapBounds[iHigh] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
247 std::max(corners[iHigh].y(), refCorners[iHigh].y())).value_or(0.) * pickDir;
248
249 newTrapBounds[iHigh].z() = lowZ ? std::max(corners[iHigh].z(),refCorners[iHigh].z())
250 : std::min(corners[iHigh].z(), refCorners[iHigh].z());
251 newTrapBounds[iLow] = pickPos + Amg::intersect<3>(pickPos, pickDir, Amg::Vector3D::UnitY(),
252 std::min(corners[iLow].y(), refCorners[iLow].y())).value_or(0.) * pickDir;
253 newTrapBounds[iLow].z() = lowZ ? std::max(corners[iLow].z(), refCorners[iLow].z())
254 : std::min(corners[iLow].z(), refCorners[iLow].z());
255 ATH_MSG_VERBOSE("New end points "<<Amg::toString(newTrapBounds[iLow])<<" - "<<Amg::toString(newTrapBounds[iHigh]));
256 }
257 }
258 if (msgLvl(MSG::VERBOSE)) {
259 std::stringstream debugStr{};
260 for (const Amg::Vector3D& edge : newTrapBounds) {
261 debugStr<<"***** "<<Amg::toString(edge)<<std::endl;
262 }
263 ATH_MSG_VERBOSE("#############################################################"<<std::endl<<
264 debugStr.str()<<"#############################################################");
265 }
267 const double halfY = 0.5*std::max(newTrapBounds[1].y() - newTrapBounds[0].y(),
268 newTrapBounds[3].y() - newTrapBounds[2].y());
269 const double lHalfX = 0.5*std::abs(newTrapBounds[3].x() - newTrapBounds[1].x());
270 const double sHalfX = 0.5*std::abs(newTrapBounds[2].x() - newTrapBounds[0].x());
271 const double halfZ = 0.5*std::abs(newTrapBounds[4].z() - newTrapBounds[0].z());
272 ATH_MSG_VERBOSE("New bounds "<<sHalfX<<"/"<<lHalfX<<", y:"<<halfY<<", "<<halfZ);
273 if (std::abs(lHalfX - sHalfX) > Acts::s_epsilon) {
274 envelopeBounds = volBoundSet.makeBounds<Acts::TrapezoidVolumeBounds>(sHalfX, lHalfX, halfY, halfZ);
275 } else {
276 envelopeBounds = volBoundSet.makeBounds<Acts::CuboidVolumeBounds>(sHalfX, halfY, halfZ);
277 }
278 ATH_MSG_VERBOSE(toString(chambEle)<<" "<<(*envelopeBounds));
279
281 const Amg::Transform3D centerShift = centerTrapezoid(newTrapBounds);
282 newCentreTrf = centerShift * newCentreTrf;
283 ATH_MSG_VERBOSE("New trapezoid centering "<<Amg::toString(centerShift)<<" combined: "
284 <<Amg::toString(newCentreTrf));
285 }
286 ATH_MSG_DEBUG("Done");
287 return std::make_tuple(newCentreTrf.inverse(),
288 enlargeBounds(*envelopeBounds, margin, volBoundSet),
289 surfaceBounds(*envelopeBounds, surfBoundSet));
290}
291
293 ATH_CHECK(m_idHelperSvc.retrieve());
295 auto mdtStationIndex = [this] (const std::string& stName) {
296 return m_idHelperSvc->hasMDT() ? m_idHelperSvc->mdtIdHelper().stationNameIndex(stName) : -1;
297 };
298 auto tgcStationIndex = [this] (const std::string& stName) {
299 return m_idHelperSvc->hasTGC() ? m_idHelperSvc->tgcIdHelper().stationNameIndex(stName) : -1;
300 };
301
302 const std::unordered_set<int> stIndicesEM{mdtStationIndex("EML"), mdtStationIndex("EMS"),
303 tgcStationIndex("T1E"), tgcStationIndex("T1F"),
304 tgcStationIndex("T2E"), tgcStationIndex("T2F"),
305 tgcStationIndex("T3E"), tgcStationIndex("T3F")};
306
307
308 std::unordered_set<Identifier> BIS78_ids{};
309 auto fillBIS78 = [&BIS78_ids, this](const MuonIdHelper& idHelper) {
310 const int BIS = idHelper.stationNameIndex("BIS");
311 std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(), std::inserter(BIS78_ids, BIS78_ids.end()),
312 [&](const Identifier& detId){
313 int stEta = idHelper.stationEta(detId);
314 if (m_isRun4) {
315 stEta = std::abs(stEta);
316 }
317 return stEta >= 7 && idHelper.stationName(detId) == BIS;
318 });
319 };
320 if (m_idHelperSvc->hasMDT()) {
321 fillBIS78(m_idHelperSvc->mdtIdHelper());
322 }
323 if (m_idHelperSvc->hasRPC()) {
324 fillBIS78(m_idHelperSvc->rpcIdHelper());
325 }
326
327 std::vector<MuonReadoutElement*> allReadOutEles = mgr.getAllReadoutElements();
328
329 std::vector<chamberArgs> envelopeCandidates{};
330
332 for (const MuonReadoutElement* readOutEle : allReadOutEles) {
333 std::vector<chamberArgs>::iterator exist = std::ranges::find_if(envelopeCandidates,
334 [this, readOutEle, &stIndicesEM](const chamberArgs& args){
335 const MuonReadoutElement* refEle = args.detEles.front();
336 const Identifier refId = refEle->identify();
337 const Identifier testId = readOutEle->identify();
340 if (Acts::copySign(1, refEle->stationEta()) *
341 Acts::copySign(1, readOutEle->stationEta()) < 0) {
342 return false;
343 }
345 if (m_idHelperSvc->sector(testId) != m_idHelperSvc->sector(refId)) {
346 return false;
347 }
348 if (stIndicesEM.count(readOutEle->stationName()) &&
349 stIndicesEM.count(refEle->stationName())) {
350 return true;
351 }
352 // /// Summarize all readout element in the same sector & layer
354 return readOutEle->chamberIndex() == refEle->chamberIndex();
355 });
357 if (exist == envelopeCandidates.end()) {
358 ATH_MSG_VERBOSE("Open envelope "<<(envelopeCandidates.size()+1)
359 <<" for "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
360 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
361 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex()));
362 envelopeCandidates.emplace_back().detEles.push_back(readOutEle);
363 } else {
364 ATH_MSG_VERBOSE("Attach "<<m_idHelperSvc->toStringDetEl(readOutEle->identify())
365 <<", sector: "<<m_idHelperSvc->sector(readOutEle->identify())
366 <<", chIdx: "<<Muon::MuonStationIndex::chName(readOutEle->chamberIndex())<<" to envelope "
367 <<(std::distance(envelopeCandidates.begin(), exist) + 1)<<". ");
368 exist->detEles.push_back(readOutEle);
369 }
370 }
372 ActsTrk::GeometryContext gctx{};
373
374
375 Acts::VolumeBoundFactory volBoundSet{};
376 Acts::SurfaceBoundFactory surfBoundSet{};
377 unsigned candId{0};
378 for (chamberArgs& candidate : envelopeCandidates) {
379 std::unordered_set<Identifier> reIds{};
380
381 ATH_MSG_VERBOSE("New envelope candidate ");
384 sectorArgs.id = (++candId);
385 using namespace Muon::MuonStationIndex;
386 std::vector<std::vector<const MuonReadoutElement*>> chamberElements{};
387 if (toStationIndex(candidate.detEles.front()->chamberIndex()) != StIndex::EI) {
389 std::map<PVConstLink, std::vector<const MuonReadoutElement*>> stationMap{};
391 for (const MuonReadoutElement* re : candidate.detEles) {
394 if (BIS78_ids.count(re->identify())) {
395 stationMap[re->getMaterialGeom()].push_back(re);
396 } else {
397 stationMap[re->getMaterialGeom()->getParent()].push_back(re);
398 }
399 }
400 for (auto& [parent, stationEles ]: stationMap){
401 chamberElements.push_back(std::move(stationEles));
402 }
403 } else {
406 std::vector<std::vector<const MuonReadoutElement*>> endcapEles(2);
407
408 for (const MuonReadoutElement* sortMe : candidate.detEles){
409 if (sortMe->detectorType() == ActsTrk::DetectorType::Tgc) {
410 endcapEles.emplace_back(1, sortMe);
411 } else {
412 endcapEles[sortMe->detectorType() == ActsTrk::DetectorType::sTgc ||
413 sortMe->detectorType() == ActsTrk::DetectorType::Mm].push_back(sortMe);
414 }
415 }
416 for (auto& stationEles : endcapEles) {
417 if (!stationEles.empty()) {
418 chamberElements.push_back(std::move(stationEles));
419 }
420 }
421 }
422
423 for (auto& detEles: chamberElements) {
424 const MuonReadoutElement* refEle = detEles.front();
425 const Amg::Transform3D toChambCentre = refEle->globalToLocalTransform(gctx);
426 ATH_MSG_VERBOSE("New chamber candidate "<<m_idHelperSvc->toStringChamber(refEle->identify()));
427 const auto[chamberCentre, chamberBox, planeBounds] = boundingBox(gctx, detEles, toChambCentre, volBoundSet,
428 surfBoundSet, 0.*Gaudi::Units::cm);
429 chamberArgs chambArgs{};
430 chambArgs.detEles = std::move(detEles);
431 chambArgs.bounds = chamberBox;
432 chambArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toChambCentre.inverse() * chamberCentre, planeBounds);
433 const Chamber* newChamber {sectorArgs.chambers.emplace_back(std::make_unique<Chamber>(std::move(chambArgs))).get()};
434 for (const MuonReadoutElement* re : newChamber->readoutEles()) {
435 reIds.insert(re->identify());
436 mgr.getReadoutElement(re->identify())->setChamberLink(newChamber);
437 ATH_MSG_VERBOSE("Chamber element: "<<m_idHelperSvc->toStringDetEl(re->identify()));
438
439 }
440 ATH_MSG_VERBOSE("Created new chamber: "<<(*newChamber));
441 }
442 std::ranges::sort(sectorArgs.chambers, [](const SpectrometerSector::ChamberPtr& a,
444 return (*a) < (*b);
445 });
446
447 const Amg::Transform3D toCenter = sectorArgs.chambers.front()->globalToLocalTransform(gctx);
448 const auto [envelopeCentre, envelopeBox, envelopePlane] = boundingBox(gctx, sectorArgs.chambers, toCenter,
449 volBoundSet, surfBoundSet, 2.* Gaudi::Units::cm);
450
451 sectorArgs.bounds = envelopeBox;
452 sectorArgs.surface = Acts::Surface::makeShared<Acts::PlaneSurface>(toCenter.inverse() * envelopeCentre, envelopePlane);
453
454 const Amg::Transform3D globalToSector = sectorArgs.surface->localToGlobalTransform(gctx.context()).inverse();
455
457 for (auto & chamber : sectorArgs.chambers){
458 // split by readout elements - MDT multilayers and trigger chambers for the sector
459 for (auto & RE : chamber->readoutEles()){
460 // get the center of the element in the sector frame
461 const Amg::Transform3D& chamberToGlobal{RE->localToGlobalTransform(gctx)};
462 const Amg::Vector3D origin = (globalToSector * chamberToGlobal).translation();
463 // and then add the bounds of the element - this is technology dependent
464 sectorArgs.detectorLocs.emplace_back(origin, RE, boundingBox(RE, volBoundSet));
465 }
466 }
468 auto newSector = std::make_unique<SpectrometerSector>(std::move(sectorArgs));
469
470 for (const Identifier& chId : reIds) {
471 mgr.getReadoutElement(chId)->setSectorLink(newSector.get());
472 }
473 mgr.addSpectrometerSector(std::move(newSector));
474 }
475 return StatusCode::SUCCESS;
476}
477
478}
479#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.
Chamber represent the volume enclosing a muon station.
Definition Chamber.h:28
Readout element to describe the Monitored Drift Tube (Mdt) chambers Mdt chambers usually comrpise out...
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the global ATLAS coordinate system into the local coordinate system o...
GeoModel::TransientConstSharedPtr< Chamber > ChamberPtr
@ 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
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
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