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 <TString.h> // for Form
9 #include <algorithm>
10 #include <iostream>
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 std::runtime_error(
50  Form("File: %s, Line: %d\nMdtChamberGeometry::setGeometry() - got called with nml=%d which is definitely out of range",
51  __FILE__, __LINE__, m_nml));
52  if (m_nlay < 1 || m_nlay > 4)
53  throw std::runtime_error(
54  Form("File: %s, Line: %d\nMdtChamberGeometry::setGeometry() - got called with nlay=%d which is definitely out of range",
55  __FILE__, __LINE__, m_nlay));
56  if (ntubesml0 < 1 || ntubesml0 > maxNTubesPerLayer)
57  throw std::runtime_error(Form(
58  "File: %s, Line: %d\nMdtChamberGeometry::setGeometry() - got called with ntubesml0=%d which is definitely out of range",
59  __FILE__, __LINE__, ntubesml0));
60  // there can be chambers with only 1 multilayer. Then, the second multilayer will have ntubesml1=0
61  if (ntubesml1 > maxNTubesPerLayer)
62  throw std::runtime_error(Form(
63  "File: %s, Line: %d\nMdtChamberGeometry::setGeometry() - got called with ntubesml1=%d which is definitely out of range",
64  __FILE__, __LINE__, ntubesml1));
65 
67  }
68 
70  m_validGeometry = true;
71  if (m_sMdt) {
72  m_tubeDist = 15.10;
73  m_tubeRad = 7.1;
74  m_layDist = 13.085;
75  } else {
76  m_tubeDist = 30.035;
77  m_tubeRad = 14.6;
78  m_layDist = 26.011;
79  }
80  // initialize first tubes to zero
81  m_ntubesml.push_back(0);
82  m_ntubesml.push_back(0);
83  m_firstTube.emplace_back(0., 0.);
84  m_firstTube.emplace_back(0., 0.);
85  m_wasInit.push_back(true);
86  m_wasInit.push_back(true);
87  }
88 
89  bool MdtChamberGeometry::validId(unsigned int ml, unsigned int lay, unsigned int tube) const {
90  if (!m_validGeometry) return false;
91  if (ml > 1) {
92  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
93  msg <<MSG::ERROR << " Wrong index: ml " << ml << " max " << m_nml << endmsg;
94  print(msg);
95 
96  return false;
97  } else if (lay > m_nlay) {
98  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
99  msg <<MSG::ERROR <<" Wrong index: lay " << lay << " max " << m_nlay << endmsg;
100  print(msg);
101  return false;
102  } else if (tube > m_ntubesml[ml]) {
103  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
104  msg << " wrong index: tube " << tube << " max " << m_ntubesml[ml] << endmsg;
105  print(msg);
106  return false;
107  }
108  return true;
109  }
110 
111  void MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer, DCVec& crossedTubes) const {
112  crossedTubes.reserve(50);
113  ResidualWithLine resLine{line};
114  const LocVec2D& linepos = line.position();
115  const LocVec2D& linedir = line.direction();
116  double dxdy = std::abs(linedir.y()) > 0.0001 ? linedir.x() / linedir.y() : linedir.x() / 0.0001;
117  for (unsigned int ml = 0; ml < m_nml; ++ml) {
118  // check whether geometry was initialized for given multilayer
119  if (!m_wasInit[ml]) continue;
120 
121  // if indicated only scan single multilayer
122  if (inMultilayer != -1 && inMultilayer != (int)ml) { continue; }
123  for (unsigned int lay = 0; lay < m_nlay; ++lay) {
124  double ylay = yPosTube(ml, lay);
125  double xfirsttube = xPosTube(ml, lay, 0);
126  double xintersect = dxdy * (ylay - linepos.y()) + linepos.x();
127  double relpos = (xintersect - xfirsttube) / m_tubeDist;
128  int ctube = (int)relpos;
129  if (ctube < 0) ctube = 0;
130  if (ctube >= (int)m_ntubesml[ml]) ctube = m_ntubesml[ml] - 1;
131 
132  if (inMultilayer != -1)
133 
134  for (int i = ctube - 1; i >= 0; --i) {
135  const LocVec2D& lp = tubePosition(ml, lay, i);
136  double res = resLine.residual(lp);
137  if (std::abs(res) > m_tubeRad) {
138  if (m_tubeDist > 0) {
139  if (res > m_tubeRad) break;
140  } else {
141  if (res < -m_tubeRad) break;
142  }
143  } else {
144  // if this is a chamber with only the second ml, set the ml index accordingly
145  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
146  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i),
147  nullptr);
148  }
149  }
150  for (int i = ctube; i < (int)m_ntubesml[ml]; ++i) {
151  const LocVec2D& lp = tubePosition(ml, lay, i);
152  double res = resLine.residual(lp);
153  if (std::abs(res) > m_tubeRad) {
154  if (m_tubeDist > 0) {
155  if (res < -m_tubeRad) break;
156  } else {
157  if (res > m_tubeRad) break;
158  }
159  } else {
160  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
161  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i), nullptr);
162  }
163  }
164  }
165  }
166  }
167 
168  DCVec MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer) const {
169  DCVec crossedTubes;
170 
171  if (!m_validGeometry) return crossedTubes;
172 
173  tubesPassedByLine(line, inMultilayer, crossedTubes);
174 
175  std::stable_sort(crossedTubes.begin(), crossedTubes.end(), SortDcsByY());
176  return crossedTubes;
177  }
178  void MdtChamberGeometry::print(MsgStream& msg) const {
179  msg << MSG::ALWAYS << " MdtChamberGeometry " << m_id <<std::endl
180  << " nml " << m_nml << " nlay " << m_nlay << " ntube1 " << m_ntubesml[0] << " ntube2 " << m_ntubesml[1] << std::endl
181  << " pos ml1 " << m_firstTube[0] << " ml2 " << m_firstTube[1] << std::endl
182  << " tubeDist " << m_tubeDist << " tubeStage " << m_tubeStage << " layDist " << m_layDist << " tubeRad " << m_tubeRad
183  << endmsg;
184  }
185  LocVec2D MdtChamberGeometry::tubePosition(unsigned int ml, unsigned int lay, unsigned int tube) const {
186  if (!validId(ml, lay, tube)) {
187  throw std::runtime_error(Form("%s:%d -- Invalid combination of multilayer ml: %u, layer: %u and tube: %d given: ", __FILE__,
188  __LINE__, ml, lay, tube));
189  }
190  LocVec2D tube_vec{xPosTube(ml, lay, tube), yPosTube(ml, lay)};
191  return tube_vec;
192  }
193 
194  inline double MdtChamberGeometry::xPosTube(unsigned int ml, unsigned int lay, unsigned int tube) const {
195  double xpos = tube * m_tubeDist + m_firstTube[ml].x();
196 
197  if (lay % 2 == 1) {
198  if (m_nlay == 4 && ml == 1)
199  xpos -= m_tubeStage;
200  else
201  xpos += m_tubeStage;
202  }
203 
204  return xpos;
205  }
206 
207  double MdtChamberGeometry::yPosTube(unsigned int ml, unsigned int lay) const { return lay * m_layDist + m_firstTube[ml].y(); }
208 
209 } // namespace TrkDriftCircleMath
SortDcsByY.h
MdtReadoutElement.h
TrkDriftCircleMath::MdtChamberGeometry::print
void print(MsgStream &msg) const override
Definition: MdtChamberGeometry.cxx:178
checkFileSG.line
line
Definition: checkFileSG.py:75
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TrkDriftCircleMath::MdtChamberGeometry::yPosTube
double yPosTube(unsigned int ml, unsigned int lay) const
Definition: MdtChamberGeometry.cxx:207
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
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:92
TrkDriftCircleMath::MdtChamberGeometry::nml
unsigned int nml() const
Definition: MdtChamberGeometry.h:32
TrkDriftCircleMath::MdtChamberGeometry::m_nlay
unsigned int m_nlay
Definition: MdtChamberGeometry.h:77
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
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:194
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
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:168
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:26
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:185
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:31
TrkDriftCircleMath::MdtChamberGeometry::MdtChamberGeometry
MdtChamberGeometry()
Definition: MdtChamberGeometry.cxx:20
TrkDriftCircleMath::MdtChamberGeometry::init
void init()
Definition: MdtChamberGeometry.cxx:69
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:89