ATLAS Offline Software
MdtChamberGeometry.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
8 #include <algorithm>
9 #include <iostream>
13 #include "GeoModelKernel/throwExcept.h"
14 
15 namespace {
16  constexpr int maxNTubesPerLayer = MdtIdHelper::maxNTubesPerLayer;
17 }
18 namespace TrkDriftCircleMath {
19 
21 
22  MdtChamberGeometry::MdtChamberGeometry(const Identifier& id, const Muon::IMuonIdHelperSvc* idHelperSvc, unsigned int nml, unsigned int nlay, unsigned int ntubesml0,
23  unsigned int ntubesml1, const LocVec2D& tube0ml0, const LocVec2D& tube0ml1, double tubeDist,
24  double tubeStage, double layDist, double stationTheta) :
25  m_id{id} {
26 
27  m_sMdt = idHelperSvc->issMdt(id);
28  m_isBarrel = idHelperSvc->mdtIdHelper().isBarrel(id);
29  init();
30  setGeometry(nml, nlay, ntubesml0, ntubesml1, tube0ml0, tube0ml1, tubeDist, tubeStage, layDist, stationTheta);
31  }
32 
33  void MdtChamberGeometry::setGeometry(unsigned int nml, unsigned int nlay, unsigned int ntubesml0, unsigned int ntubesml1,
34  const LocVec2D& tube0ml0, const LocVec2D& tube0ml1, double tubeDist, double tubeStage,
35  double layDist, double stationTheta) {
36  m_nml = nml;
37  m_nlay = nlay;
38  m_ntubesml.clear();
39  m_ntubesml.push_back(ntubesml0);
40  m_ntubesml.push_back(ntubesml1);
43  m_layDist = layDist;
44 
45  m_firstTube[0] = tube0ml0;
46  m_firstTube[1] = tube0ml1;
47 
48  if (m_nml < 1 || m_nml > 2)
49  THROW_EXCEPTION("MdtChamberGeometry::setGeometry() - got called with nml="<<m_nml<<" which is definitely out of range.");
50  if (m_nlay < 1 || m_nlay > 4)
51  THROW_EXCEPTION("MdtChamberGeometry::setGeometry() - got called with nlay="<<m_nlay<<" which is definitely out of range");
52  if (ntubesml0 < 1 || ntubesml0 > maxNTubesPerLayer)
53  THROW_EXCEPTION("MdtChamberGeometry::setGeometry() - got called with ntubesml0="<<ntubesml0<<" which is definitely out of range");
54  // there can be chambers with only 1 multilayer. Then, the second multilayer will have ntubesml1=0
55  if (ntubesml1 > maxNTubesPerLayer)
56  THROW_EXCEPTION("MdtChamberGeometry::setGeometry() - got called with ntubesml1="<<ntubesml1<<" which is definitely out of range");
57 
59  }
60 
62  m_validGeometry = true;
63  if (m_sMdt) {
64  m_tubeRad = 7.1;
65  } else {
66  m_tubeRad = 14.6;
67  }
68  // initialize first tubes to zero
69  m_ntubesml.push_back(0);
70  m_ntubesml.push_back(0);
71  m_firstTube.emplace_back(0., 0.);
72  m_firstTube.emplace_back(0., 0.);
73  m_wasInit.push_back(true);
74  m_wasInit.push_back(true);
75  }
76 
77  bool MdtChamberGeometry::validId(unsigned int ml, unsigned int lay, unsigned int tube) const {
78  if (!m_validGeometry) return false;
79  if (ml > 1) {
80  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
81  msg <<MSG::ERROR << " Wrong index: ml " << ml << " max " << m_nml << endmsg;
82  print(msg);
83 
84  return false;
85  } else if (lay > m_nlay) {
86  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
87  msg <<MSG::ERROR <<" Wrong index: lay " << lay << " max " << m_nlay << endmsg;
88  print(msg);
89  return false;
90  } else if (tube > m_ntubesml[ml]) {
91  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
92  msg << " wrong index: tube " << tube << " max " << m_ntubesml[ml] << endmsg;
93  print(msg);
94  return false;
95  }
96  return true;
97  }
98 
99  void MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer, DCVec& crossedTubes) const {
100  crossedTubes.reserve(50);
101  ResidualWithLine resLine{line};
102  const LocVec2D& linepos = line.position();
103  const LocVec2D& linedir = line.direction();
104  double dxdy = std::abs(linedir.y()) > 0.0001 ? linedir.x() / linedir.y() : linedir.x() / 0.0001;
105  for (unsigned int ml = 0; ml < m_nml; ++ml) {
106  // check whether geometry was initialized for given multilayer
107  if (!m_wasInit[ml]) continue;
108 
109  // if indicated only scan single multilayer
110  if (inMultilayer != -1 && inMultilayer != (int)ml) { continue; }
111  for (unsigned int lay = 0; lay < m_nlay; ++lay) {
112  double ylay = yPosTube(ml, lay);
113  double xfirsttube = xPosTube(ml, lay, 0);
114  double xintersect = dxdy * (ylay - linepos.y()) + linepos.x();
115  double relpos = (xintersect - xfirsttube) / m_tubeDist;
116  int ctube = (int)relpos;
117  if (ctube < 0) ctube = 0;
118  if (ctube >= (int)m_ntubesml[ml]) ctube = m_ntubesml[ml] - 1;
119 
120  if (inMultilayer != -1)
121 
122  for (int i = ctube - 1; i >= 0; --i) {
123  const LocVec2D& lp = tubePosition(ml, lay, i);
124  double res = resLine.residual(lp);
125  if (std::abs(res) > m_tubeRad) {
126  if (m_tubeDist > 0) {
127  if (res > m_tubeRad) break;
128  } else {
129  if (res < -m_tubeRad) break;
130  }
131  } else {
132  // if this is a chamber with only the second ml, set the ml index accordingly
133  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
134  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i),
135  nullptr);
136  }
137  }
138  for (int i = ctube; i < (int)m_ntubesml[ml]; ++i) {
139  const LocVec2D& lp = tubePosition(ml, lay, i);
140  double res = resLine.residual(lp);
141  if (std::abs(res) > m_tubeRad) {
142  if (m_tubeDist > 0) {
143  if (res < -m_tubeRad) break;
144  } else {
145  if (res > m_tubeRad) break;
146  }
147  } else {
148  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
149  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i), nullptr);
150  }
151  }
152  }
153  }
154  }
155 
156  DCVec MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer) const {
157  DCVec crossedTubes;
158 
159  if (!m_validGeometry) return crossedTubes;
160 
161  tubesPassedByLine(line, inMultilayer, crossedTubes);
162 
163  std::stable_sort(crossedTubes.begin(), crossedTubes.end(), SortDcsByY());
164  return crossedTubes;
165  }
166  void MdtChamberGeometry::print(MsgStream& msg) const {
167  msg << MSG::ALWAYS << " MdtChamberGeometry " << m_id <<std::endl
168  << " nml " << m_nml << " nlay " << m_nlay << " ntube1 " << m_ntubesml[0] << " ntube2 " << m_ntubesml[1] << std::endl
169  << " pos ml1 " << m_firstTube[0] << " ml2 " << m_firstTube[1] << std::endl
170  << " tubeDist " << m_tubeDist << " tubeStage " << m_tubeStage << " layDist " << m_layDist << " tubeRad " << m_tubeRad
171  << endmsg;
172  }
173  LocVec2D MdtChamberGeometry::tubePosition(unsigned int ml, unsigned int lay, unsigned int tube) const {
174  if (!validId(ml, lay, tube)) {
175  THROW_EXCEPTION("Combination of multilayer ml: "<<ml<<", layer: "<<lay<<" and tube: "<<tube<<" given ");
176  }
177  LocVec2D tube_vec{xPosTube(ml, lay, tube), yPosTube(ml, lay)};
178  return tube_vec;
179  }
180 
181  inline double MdtChamberGeometry::xPosTube(unsigned int ml, unsigned int lay, unsigned int tube) const {
182  double xpos = tube * m_tubeDist + m_firstTube[ml].x();
183 
184  // In most cases, staggering between multilayers has the same sign, this is to take care of the exceptions where that is not the case
185  // Stagerring only happens for the 2nd and 4th layers (in this case indexing from 0)
186  if (lay % 2 == 1 ) {
187  if (m_nlay == 4 && ml == 1 && !m_sMdt)
188  xpos -= m_tubeStage;
189  else
190  xpos += m_tubeStage;
191 
192  }
193 
194  return xpos;
195  }
196 
197  double MdtChamberGeometry::yPosTube(unsigned int ml, unsigned int lay) const { return lay * m_layDist + m_firstTube[ml].y(); }
198 
199 } // namespace TrkDriftCircleMath
SortDcsByY.h
MdtReadoutElement.h
TrkDriftCircleMath::MdtChamberGeometry::print
void print(MsgStream &msg) const override
Definition: MdtChamberGeometry.cxx:166
TrkDriftCircleMath::ResidualWithLine
Definition: ResidualWithLine.h:16
TrkDriftCircleMath::MdtChamberGeometry::m_isSecondMultiLayer
bool m_isSecondMultiLayer
Definition: MdtChamberGeometry.h:88
TrkDriftCircleMath::MdtChamberGeometry::tubeDist
double tubeDist() const
Definition: MdtChamberGeometry.h:42
TrkDriftCircleMath::MdtChamberGeometry::m_nml
unsigned int m_nml
Definition: MdtChamberGeometry.h:76
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
TrkDriftCircleMath::MdtId
Definition: MdtId.h:14
TrkDriftCircleMath::MdtChamberGeometry::yPosTube
double yPosTube(unsigned int ml, unsigned int lay) const
Definition: MdtChamberGeometry.cxx:197
TrkDriftCircleMath::MdtChamberGeometry::m_tubeRad
double m_tubeRad
Definition: MdtChamberGeometry.h:80
TrkDriftCircleMath::MdtChamberGeometry::ntubesml1
unsigned int ntubesml1() const
Definition: MdtChamberGeometry.h:35
TrkDriftCircleMath::MdtChamberGeometry::m_ntubesml
std::vector< unsigned int > m_ntubesml
Definition: MdtChamberGeometry.h:78
TrkDriftCircleMath::MdtChamberGeometry::m_isBarrel
bool m_isBarrel
Definition: MdtChamberGeometry.h:75
TrkDriftCircleMath::MdtChamberGeometry::m_layDist
double m_layDist
Definition: MdtChamberGeometry.h:82
TrkDriftCircleMath
Function object to check whether two Segments are sub/super sets or different.
Definition: IMdtSegmentFinder.h:13
TrkDriftCircleMath::LocVec2D::x
double x() const
Returns the x coordinate of the vector.
Definition: LocVec2D.h:27
TrkDriftCircleMath::MdtChamberGeometry::m_id
Identifier m_id
Definition: MdtChamberGeometry.h:73
dq_defect_bulk_create_defects.line
line
Definition: dq_defect_bulk_create_defects.py:27
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
TrkDriftCircleMath::LocVec2D
Implementation of 2 dimensional vector class.
Definition: LocVec2D.h:16
TrkDriftCircleMath::DCVec
std::vector< DriftCircle > DCVec
Definition: DriftCircle.h:117
TrkDriftCircleMath::MdtChamberGeometry::ntubesml0
unsigned int ntubesml0() const
Definition: MdtChamberGeometry.h:34
TrkDriftCircleMath::Line
Definition: Line.h:17
TrkDriftCircleMath::MdtChamberGeometry::m_firstTube
std::vector< LocVec2D > m_firstTube
Definition: MdtChamberGeometry.h:86
TrigConf::MSGTC::ALWAYS
@ ALWAYS
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:29
TrkDriftCircleMath::SortDcsByY
Definition: SortDcsByY.h:17
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrkDriftCircleMath::MdtChamberGeometry::nml
unsigned int nml() const
Definition: MdtChamberGeometry.h:32
TrkDriftCircleMath::MdtChamberGeometry::m_nlay
unsigned int m_nlay
Definition: MdtChamberGeometry.h:77
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:11
TrkDriftCircleMath::LocVec2D::y
double y() const
Returns the y coordinate of the vector.
Definition: LocVec2D.h:29
TrkDriftCircleMath::MdtChamberGeometry::stationTheta
double stationTheta() const override
Definition: MdtChamberGeometry.h:46
MdtIdHelper.h
TrkDriftCircleMath::MdtChamberGeometry::m_wasInit
std::vector< bool > m_wasInit
Definition: MdtChamberGeometry.h:85
MdtChamberGeometry.h
TrkDriftCircleMath::MdtChamberGeometry::xPosTube
double xPosTube(unsigned int ml, unsigned int lay, unsigned int tube) const
Definition: MdtChamberGeometry.cxx:181
TrkDriftCircleMath::MdtChamberGeometry::m_validGeometry
bool m_validGeometry
Definition: MdtChamberGeometry.h:87
TrkDriftCircleMath::MdtChamberGeometry::m_stationTheta
double m_stationTheta
Definition: MdtChamberGeometry.h:83
TrkDriftCircleMath::MdtChamberGeometry::m_tubeStage
double m_tubeStage
Definition: MdtChamberGeometry.h:81
TrkDriftCircleMath::MdtChamberGeometry::tubeStage
double tubeStage() const
Definition: MdtChamberGeometry.h:43
python.PyKernel.init
def init(v_theApp, v_rootStream=None)
Definition: PyKernel.py:45
THROW_EXCEPTION
#define THROW_EXCEPTION(MESSAGE)
Definition: throwExcept.h:10
TrkDriftCircleMath::MdtChamberGeometry::m_tubeDist
double m_tubeDist
Definition: MdtChamberGeometry.h:79
TrkDriftCircleMath::MdtChamberGeometry::setGeometry
void setGeometry(unsigned int nml, unsigned int nlay, unsigned int ntubesml0, unsigned int ntubesml1, const LocVec2D &tube0ml0, const LocVec2D &tube0ml1, double tubeDist, double tubeStage, double layDist, double stationTheta)
Definition: MdtChamberGeometry.cxx:33
TrkDriftCircleMath::MdtChamberGeometry::m_sMdt
bool m_sMdt
Definition: MdtChamberGeometry.h:74
TrkDriftCircleMath::MdtChamberGeometry::tubesPassedByLine
DCVec tubesPassedByLine(const Line &line, int ml) const
Definition: MdtChamberGeometry.cxx:156
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:27
TrkDriftCircleMath::DriftCircle::EmptyTube
@ EmptyTube
drift time too large to be compatible with drift spectrum
Definition: DriftCircle.h:29
TrkDriftCircleMath::MdtChamberGeometry::tubePosition
LocVec2D tubePosition(unsigned int ml, unsigned int lay, unsigned int tube) const override
Definition: MdtChamberGeometry.cxx:173
MdtIdHelper::maxNTubesPerLayer
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition: MdtIdHelper.h:68
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
calibdata.tube
tube
Definition: calibdata.py:30
TrkDriftCircleMath::MdtChamberGeometry::MdtChamberGeometry
MdtChamberGeometry()
Definition: MdtChamberGeometry.cxx:20
TrkDriftCircleMath::MdtChamberGeometry::init
void init()
Definition: MdtChamberGeometry.cxx:61
TrkDriftCircleMath::MdtChamberGeometry::nlay
unsigned int nlay() const override
Definition: MdtChamberGeometry.h:33
TrkDriftCircleMath::MdtChamberGeometry::validId
bool validId(unsigned int ml, unsigned int lay, unsigned int tube) const
Definition: MdtChamberGeometry.cxx:77
Identifier
Definition: IdentifierFieldParser.cxx:14