ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::MdtIntersectGeometry Class Reference

#include <MdtIntersectGeometry.h>

Inheritance diagram for Muon::MdtIntersectGeometry:
Collaboration diagram for Muon::MdtIntersectGeometry:

Public Member Functions

 MdtIntersectGeometry (MsgStream &msg, const Identifier &chid, const IMuonIdHelperSvc *idHelperSvc, const MuonGM::MuonDetectorManager *detMgr, const MdtCondDbData *dbData)
 MdtIntersectGeometry (const MdtIntersectGeometry &right)=delete
MdtIntersectGeometryoperator= (const MdtIntersectGeometry &right)=delete
virtual ~MdtIntersectGeometry ()
MuonStationIntersect intersection (const MuonGM::MuonDetectorManager *detMgr, const Amg::Vector3D &pos, const Amg::Vector3D &dir) const override
const Amg::Transform3Dtransform () const
std::shared_ptr< const TrkDriftCircleMath::MdtChamberGeometrymdtChamberGeometry () const
const IdentifierchamberId () const

Private Member Functions

double tubeLength (const MuonGM::MdtReadoutElement *detElMl0, const MuonGM::MdtReadoutElement *detElMl1, const int ml, const int layer, const int tube) const
void init (const MuonGM::MuonDetectorManager *detMgr, MsgStream &msg)
void fillDeadTubes (const MuonGM::MdtReadoutElement *mydetEl, MsgStream &msg)

Private Attributes

Identifier m_chid {}
Amg::Transform3D m_transform
std::shared_ptr< TrkDriftCircleMath::MdtChamberGeometrym_mdtGeometry {}
IdentifierHash m_hashMl0
IdentifierHash m_hashMl1
const MdtCondDbDatam_dbData {nullptr}
const IMuonIdHelperSvcm_idHelperSvc {nullptr}
std::set< Identifierm_deadTubesML {}
std::vector< Identifierm_deadTubes {}

Detailed Description

Definition at line 23 of file MdtIntersectGeometry.h.

Constructor & Destructor Documentation

◆ MdtIntersectGeometry() [1/2]

Muon::MdtIntersectGeometry::MdtIntersectGeometry ( MsgStream & msg,
const Identifier & chid,
const IMuonIdHelperSvc * idHelperSvc,
const MuonGM::MuonDetectorManager * detMgr,
const MdtCondDbData * dbData )

Definition at line 23 of file MdtIntersectGeometry.cxx.

24 :
25 m_chid(chid), m_dbData(dbData), m_idHelperSvc(idHelperSvc) {
26 init(detMgr, msg);
27 }
const MdtCondDbData * m_dbData
const IMuonIdHelperSvc * m_idHelperSvc
void init(const MuonGM::MuonDetectorManager *detMgr, MsgStream &msg)
MsgStream & msg
Definition testRead.cxx:32

◆ MdtIntersectGeometry() [2/2]

Muon::MdtIntersectGeometry::MdtIntersectGeometry ( const MdtIntersectGeometry & right)
delete

◆ ~MdtIntersectGeometry()

Muon::MdtIntersectGeometry::~MdtIntersectGeometry ( )
virtualdefault

Member Function Documentation

◆ chamberId()

const Identifier & Muon::MdtIntersectGeometry::chamberId ( ) const
inline

Definition at line 39 of file MdtIntersectGeometry.h.

39{ return m_chid; }

◆ fillDeadTubes()

void Muon::MdtIntersectGeometry::fillDeadTubes ( const MuonGM::MdtReadoutElement * mydetEl,
MsgStream & msg )
private

Definition at line 204 of file MdtIntersectGeometry.cxx.

204 {
205 if ((mydetEl->getStationName()).find("BMG") != std::string::npos) {
206 PVConstLink cv = mydetEl->getMaterialGeom(); // it is "Multilayer"
207 int nGrandchildren = cv->getNChildVols();
208 if (nGrandchildren <= 0) return;
209
210 std::vector<int> tubes;
211 geoGetIds([&](int id) { tubes.push_back(id); }, &*cv);
212 std::sort(tubes.begin(), tubes.end());
213
214 Identifier detElId = mydetEl->identify();
215
216 int name = m_idHelperSvc->mdtIdHelper().stationName(detElId);
217 int eta = m_idHelperSvc->mdtIdHelper().stationEta(detElId);
218 int phi = m_idHelperSvc->mdtIdHelper().stationPhi(detElId);
219 int ml = m_idHelperSvc->mdtIdHelper().multilayer(detElId);
220
221 std::vector<int>::iterator it = tubes.begin();
222 for (int layer = 1; layer <= mydetEl->getNLayers(); layer++) {
223 for (int tube = 1; tube <= mydetEl->getNtubesperlayer(); tube++) {
224 int want_id = layer * MdtIdHelper::maxNTubesPerLayer + tube;
225 if (it != tubes.end() && *it == want_id) {
226 ++it;
227 } else {
228 it = std::lower_bound(tubes.begin(), tubes.end(), want_id);
229 if (it != tubes.end() && *it == want_id) {
230 ++it;
231 } else {
232 Identifier deadTubeId = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, ml, layer, tube);
233 Identifier deadTubeMLId = m_idHelperSvc->mdtIdHelper().multilayerID(deadTubeId);
234 m_deadTubes.push_back(deadTubeId);
235 m_deadTubesML.insert(deadTubeMLId);
236 if (msg.level() == MSG::VERBOSE)
237 msg << MSG::VERBOSE << " MdtIntersectGeometry: adding dead tube (" << tube << "), layer(" << layer
238 << "), phi(" << phi << "), eta(" << eta << "), name(" << name << ") and adding multilayerId("
239 << deadTubeMLId << ")." << endmsg;
240 }
241 }
242 }
243 }
244 }
245 }
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
void geoGetIds(FUNCTION f, const GeoGraphNode *node, int depthLimit=1)
Template helper for running the visitor.
Definition GeoGetIds.h:82
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
int getNLayers() const
Returns the number of tube layers inside the multilayer.
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
std::set< Identifier > m_deadTubesML
std::vector< Identifier > m_deadTubes
@ layer
Definition HitInfo.h:79
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ init()

void Muon::MdtIntersectGeometry::init ( const MuonGM::MuonDetectorManager * detMgr,
MsgStream & msg )
private

Definition at line 100 of file MdtIntersectGeometry.cxx.

100 {
101 /* calculate chamber geometry
102 it takes as input:
103 distance between the first and second tube in the chamber within a layer along the tube layer (tube distance)
104 distance between the first tube in the first layer and the first tube in the second layer along the tube layer (tube stagering)
105 distance between the first and second layer perpendicular to the tube layers (layer distance)
106 position of the first hit in ml 0 and ml 1 (2D in plane)
107 total number of multilayers
108 total number of layers
109 total number of tubes per layer for each multilayer
110 an identifier uniquely identifying the chamber
111 */
112
113 // get id
114 int eta = m_idHelperSvc->mdtIdHelper().stationEta(m_chid);
115 int phi = m_idHelperSvc->mdtIdHelper().stationPhi(m_chid);
116 int name = m_idHelperSvc->mdtIdHelper().stationName(m_chid);
117 // get detEL for first ml (always there)
118 Identifier firstIdml0 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 1, 1, 1);
119 Identifier firstIdml1;
120
121 const MuonGM::MdtReadoutElement* detElMl0 = detMgr->getMdtReadoutElement(firstIdml0);
122 const MuonGM::MdtReadoutElement* detElMl1 = nullptr;
123
124 if (!detElMl0) {
125 msg << MSG::WARNING << "MdtIntersectGeometry::init() - failed to get readout element for ML0" << endmsg;
126 return;
127 }
128
129 // number of multilayers in chamber
130 int nml = detElMl0->nMDTinStation();
131
132 // treament of chambers with two ml
133 if (nml == 2) {
134 firstIdml1 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 2, 1, 1);
135 detElMl1 = detMgr->getMdtReadoutElement(firstIdml1);
136 }
137
138 // if one of the two ml is dead treat the chamber as a single ML station
139 // if both are dead give a WARNING
140 // check status of the two multilayers using the MdtCondDbData if it exists
141 // otherwise (i.e. online) they are treated as both good by default
142 bool goodMl0{false}, goodMl1{false};
143 if (m_dbData) {
144 goodMl0 = m_dbData->isGoodMultilayer(firstIdml0);
145 goodMl1 = detElMl1 ? m_dbData->isGoodMultilayer(firstIdml1) : false;
146 } else {
147 goodMl0 = true;
148 goodMl1 = true;
149 }
150 int firstMlIndex = 1;
151 if (goodMl0 && !goodMl1) {
152 nml = 1;
153 detElMl1 = nullptr;
154 } else if (!goodMl0 && goodMl1) {
155 nml = 1;
156 // swap detEl1 and detEl0
157 detElMl0 = detElMl1;
158 detElMl1 = nullptr;
159 firstIdml0 = firstIdml1;
160 firstMlIndex = 2;
161 } else if (!goodMl0 && !goodMl1) {
162 msg << MSG::WARNING << "MdtIntersectGeometry::init() - neither multilayer is good" << endmsg;
163 return;
164 }
166
167 // number of layers and tubes
168 int nlay = detElMl0->getNLayers();
169 int ntube0 = detElMl0->getNtubesperlayer();
170 int ntube1 = detElMl1 ? detElMl1->getNtubesperlayer() : 0;
171
172 // position first tube in ml 0 and 1
173 Amg::Vector3D firstTubeMl0 = transform() * (detElMl0->tubePos(firstIdml0));
174 Amg::Vector3D firstTubeMl1 = detElMl1 ? transform() * (detElMl1->tubePos(firstIdml1)) : Amg::Vector3D{0., 0., 0.};
175
176 TrkDriftCircleMath::LocVec2D firstTube0(firstTubeMl0.y(), firstTubeMl0.z());
177 TrkDriftCircleMath::LocVec2D firstTube1(firstTubeMl1.y(), firstTubeMl1.z());
178
179 // position second tube in ml 0
180 Identifier secondIdml0 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, firstMlIndex, 1, 2);
181 Amg::Vector3D secondTubeMl0 = transform() * (detElMl0->tubePos(secondIdml0));
182
183 fillDeadTubes(detElMl0, msg);
184 if (detElMl1) fillDeadTubes(detElMl1, msg);
185
186 // position first tube in second layer ml 0
187 Identifier firstIdml0lay1 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, firstMlIndex, 2, 1);
188 Amg::Vector3D firstTubeMl0lay1 = transform() * (detElMl0->tubePos(firstIdml0lay1));
189
190 double tubeDist = (secondTubeMl0 - firstTubeMl0).y(); // distance between tube in a given layer
191 double tubeStage = (firstTubeMl0lay1 - firstTubeMl0).y(); // tube stagering distance
192 double layDist = (firstTubeMl0lay1 - firstTubeMl0).z(); // distance between layers
193
194 m_mdtGeometry = std::make_unique<TrkDriftCircleMath::MdtChamberGeometry>(
195 m_chid, m_idHelperSvc, nml, nlay, ntube0, ntube1, firstTube0, firstTube1, tubeDist, tubeStage, layDist, detElMl0->center().theta());
196
197 // finally if the first ml is dead, configure the MdtChamberGeometry accordingly
198 if (!goodMl0 && goodMl1) m_mdtGeometry->isSecondMultiLayer(true);
199
200 m_hashMl0 = detElMl0->detectorElementHash();
201 if (detElMl1) m_hashMl1 = detElMl1->detectorElementHash();
202 }
#define y
#define z
unsigned int nMDTinStation() const
How many MDT chambers are in the station.
Amg::Vector3D tubePos(const Identifier &id) const
Returns the global position of the given tube.
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
IdentifierHash detectorElementHash() const
Returns the IdentifierHash of the detector element.
const Amg::Transform3D & transform() const
void fillDeadTubes(const MuonGM::MdtReadoutElement *mydetEl, MsgStream &msg)
std::shared_ptr< TrkDriftCircleMath::MdtChamberGeometry > m_mdtGeometry
Eigen::Matrix< double, 3, 1 > Vector3D

◆ intersection()

MuonStationIntersect Muon::MdtIntersectGeometry::intersection ( const MuonGM::MuonDetectorManager * detMgr,
const Amg::Vector3D & pos,
const Amg::Vector3D & dir ) const
overridevirtual

Implements Muon::MuonIntersectGeometry.

Definition at line 31 of file MdtIntersectGeometry.cxx.

32 {
33 MuonStationIntersect intersect;
34 if (!m_mdtGeometry) {
35 MsgStream log(Athena::getMessageSvc(), "MdtIntersectGeometry");
36 log << MSG::WARNING << "MdtIntersectGeometry::intersection() - MdtIntersectGeometry not correctly initialized "
37 << m_idHelperSvc->mdtIdHelper().print_to_string(m_chid) << endmsg;
38 return intersect;
39 }
40
41 Amg::Vector3D lpos = transform() * pos;
42 Amg::Vector3D ldir = (transform().linear() * dir).unit();
43
44 double dxdy = std::abs(ldir.y()) > 0.001 ? ldir.x() / ldir.y() : 1000.;
45
46 double lineAngle = std::atan2(ldir.z(), ldir.y());
47 TrkDriftCircleMath::LocVec2D linePos(lpos.y(), lpos.z());
48 TrkDriftCircleMath::Line line(linePos, lineAngle);
49 const TrkDriftCircleMath::DCVec dcs = m_mdtGeometry->tubesPassedByLine(line);
50
52
53 const MuonGM::MdtReadoutElement* detElMl0 = m_hashMl0.is_valid() ? detMgr->getMdtReadoutElement (m_hashMl0) : nullptr;
54 const MuonGM::MdtReadoutElement* detElMl1 = m_hashMl1.is_valid() ? detMgr->getMdtReadoutElement (m_hashMl1) : nullptr;
55
56 TrkDriftCircleMath::DCCit dit = dcs.begin();
57 TrkDriftCircleMath::DCCit dit_end = dcs.end();
58 for (; dit != dit_end; ++dit) {
59 const TrkDriftCircleMath::MdtId& mdtId = dit->id();
60
61 double xint = dxdy * (dit->position().x() - lpos.y()) + lpos.x();
62 Identifier tubeid = m_idHelperSvc->mdtIdHelper().channelID(m_chid, mdtId.ml() + 1, mdtId.lay() + 1, mdtId.tube() + 1);
63 if (m_deadTubesML.find(m_idHelperSvc->mdtIdHelper().multilayerID(tubeid)) != m_deadTubesML.end()) {
64 if (std::find(m_deadTubes.begin(), m_deadTubes.end(), tubeid) != m_deadTubes.end()) continue;
65 }
66 double distWall = std::abs(xint) - 0.5 * tubeLength(detElMl0, detElMl1,
67 mdtId.ml(), mdtId.lay(), mdtId.tube());
68 intersects.emplace_back(tubeid, dit->dr(), distWall);
69 }
70 intersect.setTubeIntersects(std::move(intersects));
71
72 return intersect;
73 }
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
double tubeLength
#define x
std::vector< MuonTubeIntersect > TubeIntersects
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.
IMessageSvc * getMessageSvc(bool quiet=false)
DCVec::const_iterator DCCit
std::vector< DriftCircle > DCVec

◆ mdtChamberGeometry()

std::shared_ptr< const TrkDriftCircleMath::MdtChamberGeometry > Muon::MdtIntersectGeometry::mdtChamberGeometry ( ) const

Definition at line 203 of file MdtIntersectGeometry.cxx.

203{ return m_mdtGeometry; }

◆ operator=()

MdtIntersectGeometry & Muon::MdtIntersectGeometry::operator= ( const MdtIntersectGeometry & right)
delete

◆ transform()

const Amg::Transform3D & Muon::MdtIntersectGeometry::transform ( ) const
inline

Definition at line 36 of file MdtIntersectGeometry.h.

36{ return m_transform; }

◆ tubeLength()

double Muon::MdtIntersectGeometry::tubeLength ( const MuonGM::MdtReadoutElement * detElMl0,
const MuonGM::MdtReadoutElement * detElMl1,
const int ml,
const int layer,
const int tube ) const
private

Definition at line 75 of file MdtIntersectGeometry.cxx.

77 {
78#ifndef NDEBUG
79 if (ml < 0 || ml > 1){
80 THROW_EXCEPTION(__func__<<"() got called with ml="<<ml<<" which is definetly out of range");
81 }
82 if (layer < 0 || layer > 3) {
83 THROW_EXCEPTION(__func__<<"() got called with layer="<<layer<<" which is definetly out of range");
84 }
85 if (tube < 0 || tube >= int(MdtIdHelper::maxNTubesPerLayer)){
86 THROW_EXCEPTION(__func__<<"() got called with tube="<<tube<<" which is definetly out of range");
87 }
88#endif
89 // shift by one to account for MuonGeoModel scheme
90 int theTube = tube + 1;
91 int theLayer = layer + 1;
92 // handle case where first ml is dead
93 if (ml == 1 && !detElMl1) return detElMl0->getActiveTubeLength(theLayer, theTube);
94 if (ml == 0)
95 return detElMl0->getActiveTubeLength(theLayer, theTube);
96 else
97 return detElMl1->getActiveTubeLength(theLayer, theTube);
98 }
double getActiveTubeLength(const int tubeLayer, const int tube) const
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

Member Data Documentation

◆ m_chid

Identifier Muon::MdtIntersectGeometry::m_chid {}
private

Definition at line 48 of file MdtIntersectGeometry.h.

48{};

◆ m_dbData

const MdtCondDbData* Muon::MdtIntersectGeometry::m_dbData {nullptr}
private

Definition at line 53 of file MdtIntersectGeometry.h.

53{nullptr};

◆ m_deadTubes

std::vector<Identifier> Muon::MdtIntersectGeometry::m_deadTubes {}
private

Definition at line 56 of file MdtIntersectGeometry.h.

56{};

◆ m_deadTubesML

std::set<Identifier> Muon::MdtIntersectGeometry::m_deadTubesML {}
private

Definition at line 55 of file MdtIntersectGeometry.h.

55{};

◆ m_hashMl0

IdentifierHash Muon::MdtIntersectGeometry::m_hashMl0
private

Definition at line 51 of file MdtIntersectGeometry.h.

◆ m_hashMl1

IdentifierHash Muon::MdtIntersectGeometry::m_hashMl1
private

Definition at line 52 of file MdtIntersectGeometry.h.

◆ m_idHelperSvc

const IMuonIdHelperSvc* Muon::MdtIntersectGeometry::m_idHelperSvc {nullptr}
private

Definition at line 54 of file MdtIntersectGeometry.h.

54{nullptr};

◆ m_mdtGeometry

std::shared_ptr<TrkDriftCircleMath::MdtChamberGeometry> Muon::MdtIntersectGeometry::m_mdtGeometry {}
private

Definition at line 50 of file MdtIntersectGeometry.h.

50{};

◆ m_transform

Amg::Transform3D Muon::MdtIntersectGeometry::m_transform
private

Definition at line 49 of file MdtIntersectGeometry.h.


The documentation for this class was generated from the following files: