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_tubeDist = 15.10;
65  m_tubeRad = 7.1;
66  m_layDist = 13.085;
67  } else {
68  m_tubeDist = 30.035;
69  m_tubeRad = 14.6;
70  m_layDist = 26.011;
71  }
72  // initialize first tubes to zero
73  m_ntubesml.push_back(0);
74  m_ntubesml.push_back(0);
75  m_firstTube.emplace_back(0., 0.);
76  m_firstTube.emplace_back(0., 0.);
77  m_wasInit.push_back(true);
78  m_wasInit.push_back(true);
79  }
80 
81  bool MdtChamberGeometry::validId(unsigned int ml, unsigned int lay, unsigned int tube) const {
82  if (!m_validGeometry) return false;
83  if (ml > 1) {
84  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
85  msg <<MSG::ERROR << " Wrong index: ml " << ml << " max " << m_nml << endmsg;
86  print(msg);
87 
88  return false;
89  } else if (lay > m_nlay) {
90  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
91  msg <<MSG::ERROR <<" Wrong index: lay " << lay << " max " << m_nlay << endmsg;
92  print(msg);
93  return false;
94  } else if (tube > m_ntubesml[ml]) {
95  MsgStream msg{Athena::getMessageSvc(), "MdtChamberGeometry::validId"};
96  msg << " wrong index: tube " << tube << " max " << m_ntubesml[ml] << endmsg;
97  print(msg);
98  return false;
99  }
100  return true;
101  }
102 
103  void MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer, DCVec& crossedTubes) const {
104  crossedTubes.reserve(50);
105  ResidualWithLine resLine{line};
106  const LocVec2D& linepos = line.position();
107  const LocVec2D& linedir = line.direction();
108  double dxdy = std::abs(linedir.y()) > 0.0001 ? linedir.x() / linedir.y() : linedir.x() / 0.0001;
109  for (unsigned int ml = 0; ml < m_nml; ++ml) {
110  // check whether geometry was initialized for given multilayer
111  if (!m_wasInit[ml]) continue;
112 
113  // if indicated only scan single multilayer
114  if (inMultilayer != -1 && inMultilayer != (int)ml) { continue; }
115  for (unsigned int lay = 0; lay < m_nlay; ++lay) {
116  double ylay = yPosTube(ml, lay);
117  double xfirsttube = xPosTube(ml, lay, 0);
118  double xintersect = dxdy * (ylay - linepos.y()) + linepos.x();
119  double relpos = (xintersect - xfirsttube) / m_tubeDist;
120  int ctube = (int)relpos;
121  if (ctube < 0) ctube = 0;
122  if (ctube >= (int)m_ntubesml[ml]) ctube = m_ntubesml[ml] - 1;
123 
124  if (inMultilayer != -1)
125 
126  for (int i = ctube - 1; i >= 0; --i) {
127  const LocVec2D& lp = tubePosition(ml, lay, i);
128  double res = resLine.residual(lp);
129  if (std::abs(res) > m_tubeRad) {
130  if (m_tubeDist > 0) {
131  if (res > m_tubeRad) break;
132  } else {
133  if (res < -m_tubeRad) break;
134  }
135  } else {
136  // if this is a chamber with only the second ml, set the ml index accordingly
137  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
138  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i),
139  nullptr);
140  }
141  }
142  for (int i = ctube; i < (int)m_ntubesml[ml]; ++i) {
143  const LocVec2D& lp = tubePosition(ml, lay, i);
144  double res = resLine.residual(lp);
145  if (std::abs(res) > m_tubeRad) {
146  if (m_tubeDist > 0) {
147  if (res < -m_tubeRad) break;
148  } else {
149  if (res > m_tubeRad) break;
150  }
151  } else {
152  unsigned int actualMl = m_isSecondMultiLayer ? 1 : ml;
153  crossedTubes.emplace_back(lp, m_tubeRad, res, DriftCircle::EmptyTube, MdtId(m_isBarrel, actualMl, lay, i), nullptr);
154  }
155  }
156  }
157  }
158  }
159 
160  DCVec MdtChamberGeometry::tubesPassedByLine(const Line& line, int inMultilayer) const {
161  DCVec crossedTubes;
162 
163  if (!m_validGeometry) return crossedTubes;
164 
165  tubesPassedByLine(line, inMultilayer, crossedTubes);
166 
167  std::stable_sort(crossedTubes.begin(), crossedTubes.end(), SortDcsByY());
168  return crossedTubes;
169  }
170  void MdtChamberGeometry::print(MsgStream& msg) const {
171  msg << MSG::ALWAYS << " MdtChamberGeometry " << m_id <<std::endl
172  << " nml " << m_nml << " nlay " << m_nlay << " ntube1 " << m_ntubesml[0] << " ntube2 " << m_ntubesml[1] << std::endl
173  << " pos ml1 " << m_firstTube[0] << " ml2 " << m_firstTube[1] << std::endl
174  << " tubeDist " << m_tubeDist << " tubeStage " << m_tubeStage << " layDist " << m_layDist << " tubeRad " << m_tubeRad
175  << endmsg;
176  }
177  LocVec2D MdtChamberGeometry::tubePosition(unsigned int ml, unsigned int lay, unsigned int tube) const {
178  if (!validId(ml, lay, tube)) {
179  THROW_EXCEPTION("Combination of multilayer ml: "<<ml<<", layer: "<<lay<<" and tube: "<<tube<<" given ");
180  }
181  LocVec2D tube_vec{xPosTube(ml, lay, tube), yPosTube(ml, lay)};
182  return tube_vec;
183  }
184 
185  inline double MdtChamberGeometry::xPosTube(unsigned int ml, unsigned int lay, unsigned int tube) const {
186  double xpos = tube * m_tubeDist + m_firstTube[ml].x();
187 
188  if (lay % 2 == 1) {
189  if (m_nlay == 4 && ml == 1)
190  xpos -= m_tubeStage;
191  else
192  xpos += m_tubeStage;
193  }
194 
195  return xpos;
196  }
197 
198  double MdtChamberGeometry::yPosTube(unsigned int ml, unsigned int lay) const { return lay * m_layDist + m_firstTube[ml].y(); }
199 
200 } // namespace TrkDriftCircleMath
SortDcsByY.h
MdtReadoutElement.h
TrkDriftCircleMath::MdtChamberGeometry::print
void print(MsgStream &msg) const override
Definition: MdtChamberGeometry.cxx:170
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:198
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
THROW_EXCEPTION
#define THROW_EXCEPTION(MSG)
Definition: MMReadoutElement.cxx:48
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: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: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:185
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:160
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:177
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: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:81
Identifier
Definition: IdentifierFieldParser.cxx:14