ATLAS Offline Software
Loading...
Searching...
No Matches
MuonGM::Mdt Class Reference

#include <Mdt.h>

Inheritance diagram for MuonGM::Mdt:
Collaboration diagram for MuonGM::Mdt:

Public Member Functions

 Mdt (const MYSQL &mysql, Component *s1, const std::string &s2)
GeoFullPhysVol * build (StoredMaterialManager &matManager, const MYSQL &mysql)
GeoFullPhysVol * build (StoredMaterialManager &matManager, const MYSQL &mysql, std::vector< Cutout * > &)
void processCutouts (std::vector< Cutout * > &vcutdef)
virtual void print () const override
void setLogVolName (const std::string &str)

Public Attributes

double width {0.}
double length {0.}
double thickness {0.}
double longWidth {0.}
int index {0}
double tubelenStepSize {0.}
double tubePitch {0.}
std::unique_ptr< MultiLayerlayer {}
std::string name {}
std::string logVolName {}

Private Attributes

MdtComponentm_component {nullptr}

Detailed Description

Definition at line 23 of file Mdt.h.

Constructor & Destructor Documentation

◆ Mdt()

MuonGM::Mdt::Mdt ( const MYSQL & mysql,
Component * s1,
const std::string & s2 )

Definition at line 32 of file Mdt.cxx.

33 : DetectorElement(ss->name) {
34 logVolName = lVName;
35 MdtComponent *s = static_cast<MdtComponent *>(ss);
36 const MDT *thism = dynamic_cast<const MDT*>(mysql.GetTechnology(s->name));
37
38 width = s->dx1;
39 longWidth = s->dx2;
40 thickness = s->GetThickness(mysql);
41 length = s->dy;
42 m_component = s;
43 m_component->cutoutTubeXShift = 0.;
44 layer = std::make_unique<MultiLayer>(mysql, s->name);
45 layer->logVolName = lVName;
46 layer->cutoutNsteps = 0;
47 layer->width = width;
48 layer->longWidth = longWidth;
49 tubePitch = thism->pitch;
50 layer->length = length;
51 layer->nrOfTubes = (int)(layer->length / thism->pitch);
52 if (longWidth > width)
53 layer->nrOfSteps = int(length / s->tubelenStepSize);
54 tubelenStepSize = s->tubelenStepSize;
55 index = s->index;
56 }
static Double_t ss
@ MDT
Definition RegSelEnums.h:31
Technology * GetTechnology(const std::string &name)
Definition MYSQL.cxx:105
DetectorElement(const std::string &n)
std::unique_ptr< MultiLayer > layer
Definition Mdt.h:34
double tubePitch
Definition Mdt.h:32
double length
Definition Mdt.h:27
double width
Definition Mdt.h:26
double tubelenStepSize
Definition Mdt.h:31
double longWidth
Definition Mdt.h:29
double thickness
Definition Mdt.h:28
int index
Definition Mdt.h:30
MdtComponent * m_component
Definition Mdt.h:47

Member Function Documentation

◆ build() [1/2]

GeoFullPhysVol * MuonGM::Mdt::build ( StoredMaterialManager & matManager,
const MYSQL & mysql )

Definition at line 60 of file Mdt.cxx.

61 {
62 layer->cutoutNsteps = 1;
63 return layer->build(matManager, mysql);
64 }

◆ build() [2/2]

GeoFullPhysVol * MuonGM::Mdt::build ( StoredMaterialManager & matManager,
const MYSQL & mysql,
std::vector< Cutout * > & vcutdef )

Definition at line 66 of file Mdt.cxx.

68 {
69 MsgStream log(Athena::getMessageSvc(), "Mdt::build");
70
71 int Ncuts = vcutdef.size();
72 if (Ncuts > 0) {
73
74 processCutouts(vcutdef);
75 return layer->build(matManager, mysql);
76
77 } else {
78 return build(matManager, mysql);
79 }
80 }
const size_t Ncuts
void processCutouts(std::vector< Cutout * > &vcutdef)
Definition Mdt.cxx:87
GeoFullPhysVol * build(StoredMaterialManager &matManager, const MYSQL &mysql)
Definition Mdt.cxx:60
IMessageSvc * getMessageSvc(bool quiet=false)

◆ print()

void MuonGM::Mdt::print ( ) const
overridevirtual

Implements MuonGM::DetectorElement.

Definition at line 82 of file Mdt.cxx.

82 {
83 MsgStream log(Athena::getMessageSvc(), "MuonGM::Mdt");
84 log << MSG::INFO << "Mdt " << name.c_str() << " :" << endmsg;
85 }
#define endmsg

◆ processCutouts()

void MuonGM::Mdt::processCutouts ( std::vector< Cutout * > & vcutdef)

Definition at line 87 of file Mdt.cxx.

87 {
88 MsgStream log(Athena::getMessageSvc(), "Mdt::processCutouts");
89 if (verbose_mdt) {
90 log << MSG::VERBOSE << " mdt cutouts are on " << endmsg;
91 }
92
93 int Ncuts = vcutdef.size();
94 bool cutoutsVsX {false}, cutoutsVsY{false};
95 // first check whether there are several cutouts with different amdb x or y coordinates
96 float lastX{FLT_MAX}, lastY{FLT_MAX};
97 for (int i = 0; i < Ncuts; ++i) {
98 log<<MSG::DEBUG<<__FILE__":"<<__LINE__
99 <<" name: "<<name
100 <<" logVolName: "<<logVolName
101 <<" Ncuts: "<<Ncuts
102 <<" lastX: "<<lastX
103 <<" cutDef->dX "<<vcutdef[i]->dx
104 <<" lastY: "<<lastY
105 <<" dutDef->dY "<<vcutdef[i]->dy<<endmsg;
106
107 if (lastX != FLT_MAX && lastX * vcutdef[i]->dx < 0)
108 cutoutsVsX = true;
109 lastX = vcutdef[i]->dx;
110 if (lastY != FLT_MAX && lastY * vcutdef[i]->dy < 0)
111 cutoutsVsY = true;
112 lastY = vcutdef[i]->dy;
113 }
114 if (cutoutsVsX && cutoutsVsY) {
115 throw std::runtime_error(
116 Form("%s:%d \nMdt::build() - Found more than one cutout in amdb-x direction and more than one cutout in amdb-y direction, currently not supported",
117 __FILE__, __LINE__));
118 }
119
120 if (!cutoutsVsX) { // nominal case (used for BMS/BOG/BMG etc.)
121 std::array<int, 5> cutoutNtubes{}; // Number of tubes in sub-multilayer[i]
122 std::array<bool, 5> cutoutFullLength{}; // True if this region is outside the cutout
123 std::array<double, 5> cutoutXtubes{}; // Location of tube center within sub-ml[i] along x-amdb
124 std::array<double, 5> cutoutTubeLength{}; // Tube length
125 std::array<double, 5> cutoutYmax{};
126
127 for (int i = 0; i < 5; i++) {
128 cutoutFullLength[i] = true;
129 cutoutTubeLength[i] = width;
130 }
131
132 // Order cutouts by increasing dy
133 for (int i = 0; i < Ncuts; i++) {
134 for (int j = i + 1; j < Ncuts; j++) {
135 if (vcutdef[j]->dy < vcutdef[i]->dy) {
136 Cutout *c = vcutdef[i];
137 vcutdef[i] = vcutdef[j];
138 vcutdef[j] = c;
139 }
140 }
141 }
142
143 // Set up cut location code
144 double top = length - tubePitch / 2.;
145 int cutLocationCode[3] = {0, 0, 0};
146 for (int i = 0; i < Ncuts; i++) {
147 if (vcutdef[i]->dy <= 0)
148 cutLocationCode[i] = -1;
149 if (round(vcutdef[i]->dy + vcutdef[i]->lengthY, 2) >= round(top, 2))
150 cutLocationCode[i] = 1;
151 }
152
153 // Calculate quantities needed by multilayer
154 double twidth{0.}, xmin{0.}, xmax{0.};
155 bool cutAtAngle = false;
156 int Nsteps = 0;
157 for (int i = 0; i < Ncuts; i++) {
158 Cutout *c = vcutdef[i];
159 if (c->dead1 > 1.)
160 cutAtAngle = true;
161 twidth = width + (longWidth - width) * c->dy / length;
162 xmin = -twidth / 2. < c->dx - c->widthXs / 2. ? -twidth / 2. : c->dx + c->widthXs / 2.;
163 xmax = twidth / 2. > c->dx + c->widthXs / 2. ? twidth / 2. : c->dx - c->widthXs / 2.;
164 if (cutLocationCode[i] == -1) {
165 cutoutYmax[Nsteps] = c->lengthY;
166 cutoutTubeLength[Nsteps] = xmax - xmin;
167 cutoutXtubes[Nsteps] = (xmax + xmin) / 2.;
168 cutoutFullLength[Nsteps] = false;
169 Nsteps++;
170 } else if (cutLocationCode[i] == 1) {
171 cutoutYmax[Nsteps] = c->dy;
172 Nsteps++;
173 cutoutTubeLength[Nsteps] = xmax - xmin;
174 cutoutXtubes[Nsteps] = (xmax + xmin) / 2.;
175 cutoutFullLength[Nsteps] = false;
176 } else {
177 cutoutYmax[Nsteps] = c->dy;
178 Nsteps++;
179 cutoutYmax[Nsteps] = c->dy + c->lengthY;
180 cutoutTubeLength[Nsteps] = xmax - xmin;
181 cutoutXtubes[Nsteps] = (xmax + xmin) / 2.;
182 cutoutFullLength[Nsteps] = false;
183 Nsteps++;
184 }
185 }
186 cutoutYmax[Nsteps] = top;
187 Nsteps++;
188
189 double regionLength{0.}, low{0.};
190 int fullLengthCounter{0}, tubeCounter{0};
191 for (int i = 0; i < Nsteps; i++) {
192 if (cutoutFullLength[i])
193 fullLengthCounter++;
194
195 regionLength = cutoutYmax[i] - low;
196 cutoutNtubes[i] = int(regionLength / tubePitch);
197 if ((regionLength / tubePitch - cutoutNtubes[i]) > 0.5)
198 cutoutNtubes[i] += 1;
199
200 if (fullLengthCounter > 1)
201 cutoutNtubes[i]++;
202 low = cutoutYmax[i];
203 tubeCounter += cutoutNtubes[i];
204 }
205 if (tubeCounter > layer->nrOfTubes)
206 --cutoutNtubes[Nsteps - 1];
207
208 if (verbose_mdt) {
209 for (int i = 0; i < Nsteps; i++) {
210 log << MSG::VERBOSE << " cutoutYmax[" << i << "] = " << cutoutYmax[i] << " cutoutTubeLength[" << i << "] = " << cutoutTubeLength[i] << " cutoutXtubes[" << i
211 << "] = " << cutoutXtubes[i] << " cutoutFullLength[" << i << "] = " << cutoutFullLength[i] << " cutoutNtubes[" << i << "] = " << cutoutNtubes[i]
212 << endmsg;
213 }
214 }
215
216 // encoding BMG chambers in Nsteps: Nsteps negative => BMG chamber
217 // a/ 1st digit: eta index (1 to 3)
218 // b/ 2nd digit: 1 == A side, 2 == C side
219 // c/ 3rd digit: multilayer (1 or 2)
220 // d/ last 2 digits: sector (12 or 14)
221
222 if (logVolName.find("MDT10") != std::string::npos) {
223 // multilayer 1 of BMG1A12, BMG2A12, BMG3A12, BMG1C14, BMG2C14, BMG3C14
224 if (vcutdef[0]->icut == 1) { // these are BMG1A12 and BMG1C14
225 if (vcutdef[0]->dead1 > 0.)
226 Nsteps = -11112; // cut angle for A side positive BMG1A12
227 else
228 Nsteps = -12114; // cut angle for C side negative BMG1C14
229 } else if (vcutdef[0]->icut == 2) {
230 if (vcutdef[0]->dead1 > 0.)
231 Nsteps = -21112; // cut angle for A side positive BMG2A12
232 else
233 Nsteps = -22114; // cut angle for C side negative BMG2C14
234 } else if (vcutdef[0]->icut == 3) {
235 if (vcutdef[0]->dead1 > 0.)
236 Nsteps = -31112; // cut angle for A side positive BMG3A12
237 else
238 Nsteps = -32114; // cut angle for C side negative BMG3C14
239 } else {
240 log << MSG::ERROR << "massive error with MDT10 (BMG chambers)" << endmsg;
241 std::abort();
242 }
243 } else if (logVolName.find("MDT11") != std::string::npos) {
244 // multilayer 1 of BMG1A14, BMG2A14, BMG3A14, BMG1C12, BMG2C12, BMG3C12
245 if (vcutdef[0]->icut == 1) { // these are BMG1A12 and BMG1C14
246 if (vcutdef[0]->dead1 > 0.)
247 Nsteps = -11114; // cut angle for A side positive BMG1A14
248 else
249 Nsteps = -12112; // cut angle for C side negative BMG1C12
250 } else if (vcutdef[0]->icut == 2) {
251 if (vcutdef[0]->dead1 > 0.)
252 Nsteps = -21114; // cut angle for A side positive BMG2A14
253 else
254 Nsteps = -22112; // cut angle for C side negative BMG2C12
255 } else if (vcutdef[0]->icut == 3) {
256 if (vcutdef[0]->dead1 > 0.)
257 Nsteps = -31114; // cut angle for A side positive BMG3A14
258 else
259 Nsteps = -32112; // cut angle for C side negative BMG3C12
260 } else {
261 log << MSG::ERROR << "massive error with MDT10 (BMG chambers)" << endmsg;
262 std::abort();
263 }
264 } else if (logVolName.find("MDT12") != std::string::npos) {
265 // multilayer 2 of BMG1A12, BMG2A12, BMG3A12, BMG1C14, BMG2C14, BMG3C14
266 if (vcutdef[0]->icut == 1) { // these are BMG1A12 and BMG1C14
267 if (vcutdef[0]->dead1 > 0.)
268 Nsteps = -11212; // cut angle for A side positive BMG1A12
269 else
270 Nsteps = -12214; // cut angle for C side negative BMG1C14
271 } else if (vcutdef[0]->icut == 2) {
272 if (vcutdef[0]->dead1 > 0.)
273 Nsteps = -21212; // cut angle for A side positive BMG2A12
274 else
275 Nsteps = -22214; // cut angle for C side negative BMG2C14
276 } else if (vcutdef[0]->icut == 3) {
277 if (vcutdef[0]->dead1 > 0.)
278 Nsteps = -31212; // cut angle for A side positive BMG3A12
279 else
280 Nsteps = -32214; // cut angle for C side negative BMG3C14
281 } else {
282 log << MSG::ERROR << "massive error with MDT10 (BMG chambers)" << endmsg;
283 std::abort();
284 }
285 } else if (logVolName.find("MDT13") != std::string::npos) {
286 // multilayer 2 of BMG1A14, BMG2A14, BMG3A14, BMG1C12, BMG2C12, BMG3C12
287 if (vcutdef[0]->icut == 1) { // these are BMG1A12 and BMG1C14
288 if (vcutdef[0]->dead1 > 0.)
289 Nsteps = -11214; // cut angle for A side positive BMG1A14
290 else
291 Nsteps = -12212; // cut angle for C side negative BMG1C12
292 } else if (vcutdef[0]->icut == 2) {
293 if (vcutdef[0]->dead1 > 0.)
294 Nsteps = -21214; // cut angle for A side positive BMG2A14
295 else
296 Nsteps = -22212; // cut angle for C side negative BMG2C12
297 } else if (vcutdef[0]->icut == 3) {
298 if (vcutdef[0]->dead1 > 0.)
299 Nsteps = -31214; // cut angle for A side positive BMG3A14
300 else
301 Nsteps = -32212; // cut angle for C side negative BMG3C12
302 } else {
303 log << MSG::ERROR << "massive error with MDT10 (BMG chambers)" << endmsg;
304 std::abort();
305 }
306 }
307
308 if (logVolName.find("MDT10") != std::string::npos || logVolName.find("MDT11") != std::string::npos || logVolName.find("MDT12") != std::string::npos ||
309 logVolName.find("MDT13") != std::string::npos) {
310
311 for (int i = 0; i < 5; i++) {
312 cutoutNtubes[i] = 0;
313 cutoutFullLength[i] = true;
314 cutoutXtubes[i] = 0.;
315 cutoutTubeLength[i] = width;
316 cutoutYmax[i] = 0.;
317 }
318 }
319
320 // Pass information to multilayer and MdtComponent
321 layer->cutoutNsteps = Nsteps;
322 m_component->cutoutTubeXShift = 0.;
323 for (int i = 0; i < 5; i++) {
324 layer->cutoutNtubes[i] = cutoutNtubes[i];
325 layer->cutoutTubeLength[i] = cutoutTubeLength[i];
326 layer->cutoutFullLength[i] = cutoutFullLength[i];
327 layer->cutoutXtubes[i] = cutoutXtubes[i];
328 layer->cutoutYmax[i] = cutoutYmax[i];
329 if (!cutoutFullLength[i])
330 m_component->cutoutTubeXShift = cutoutXtubes[i];
331 // For now assume multiple cutouts have same width and take only the last value
332 }
333
334 layer->cutoutAtAngle = cutAtAngle;
335 } else {
336 // there are several cutouts along the amdb-x coordinate
337
338 if (longWidth != width) {
339 throw std::runtime_error(Form("File: %s, Line: %d\nMdt::build() - only support cutouts along amdb-x for rectangular chambers", __FILE__, __LINE__));
340 }
341
342 std::vector<std::pair<double, double>> nonCutoutXSteps;
343 std::vector<std::pair<double, double>> nonCutoutYSteps;
344
345 // Order cutouts by increasing dx
346 std::sort(vcutdef.begin(),vcutdef.end(),[](const Cutout *a ,const Cutout* b ){
347 return a->dx < b->dx;
348 });
349 // in amdb-coordinates
350 double xminChamber = round(-width / 2, 2);
351 double xmaxChamber = round(width / 2, 2);
352 double yminChamber = 0;
353 double ymaxChamber = round(length - tubePitch / 2, 2);
354
355 double latestXMax = xminChamber;
356
357 for (int i = 0; i < Ncuts; ++i) {
358 Cutout *c = vcutdef[i];
359 double lowerX = round(c->dx - c->widthXs / 2, 2);
360 double xmin = std::max(lowerX, xminChamber);
361 log<<MSG::DEBUG<<__FILE__<<":"<<__LINE__
362 <<" name: "<<name
363 <<" logVolName: "<<logVolName
364 <<" xminChamber: "<<xminChamber<<" xmaxChamber: "<<xmaxChamber
365 <<" ymaxChamber: "<<ymaxChamber
366 <<" yminChamber: "<<yminChamber
367 <<" latestXMax: "<<latestXMax
368 <<" c->dx: "<<c->dx
369 <<" c->widthXs/2 "<<c->widthXs / 2<<endmsg;
370 if (xmin < latestXMax) {
371 throw std::runtime_error(Form("File: %s, Line: %d\nMdt::build() - cannot have cutouts along amdb-x which overlap in amdb-x %f > %f",
372 __FILE__, __LINE__, latestXMax, xmin));
373 }
374 if (i == 0 && xmin > xminChamber) {
375 // we start with a full slice without cutout
376 nonCutoutXSteps.emplace_back(xminChamber, lowerX);
377 nonCutoutYSteps.emplace_back(yminChamber, ymaxChamber);
378 }
379 double upperX = round(c->dx + c->widthXs / 2, 2);
380 double xmax = (upperX >= xmaxChamber) ? xmaxChamber : upperX;
381
382 double ymin = round(c->dy + c->lengthY, 2) < ymaxChamber ? c->dy + c->lengthY : 0;
383 double ymax = ymaxChamber <= round(c->dy + c->lengthY, 2) ? c->dy : ymaxChamber;
384
385 if (latestXMax < xmin) {
386 // there is a full slice between latestXMax and xmin
387 nonCutoutXSteps.emplace_back(latestXMax, xmin);
388 nonCutoutYSteps.emplace_back(yminChamber, ymaxChamber);
389 }
390
391 nonCutoutXSteps.emplace_back(xmin, xmax);
392 nonCutoutYSteps.emplace_back(ymin, ymax);
393
394 if (i == Ncuts - 1 && xmax < xmaxChamber) {
395 // we end with a full slice without cutout
396 nonCutoutXSteps.emplace_back(xmax, xmaxChamber);
397 nonCutoutYSteps.emplace_back(yminChamber, ymaxChamber);
398 }
399
400 latestXMax = xmax;
401 }
402
403 // Pass information to multilayer and MdtComponent
404 m_component->cutoutTubeXShift = 0;
405 layer->cutoutNsteps = nonCutoutXSteps.size();
406 layer->m_nonCutoutXSteps = nonCutoutXSteps;
407 layer->m_nonCutoutYSteps = nonCutoutYSteps;
408 layer->cutoutAtAngle = false;
409 }
410 }
static Double_t a
#define verbose_mdt
Definition Mdt.cxx:23
@ top
double xmax
Definition listroot.cxx:61
double ymin
Definition listroot.cxx:63
double xmin
Definition listroot.cxx:60
double ymax
Definition listroot.cxx:64
float round(const float toRound, const unsigned int decimals)
Definition Mdt.cxx:27
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ setLogVolName()

void MuonGM::DetectorElement::setLogVolName ( const std::string & str)
inlineinherited

Member Data Documentation

◆ index

int MuonGM::Mdt::index {0}

Definition at line 30 of file Mdt.h.

30{0};

◆ layer

std::unique_ptr<MultiLayer> MuonGM::Mdt::layer {}

Definition at line 34 of file Mdt.h.

34{};

◆ length

double MuonGM::Mdt::length {0.}

Definition at line 27 of file Mdt.h.

27{0.};

◆ logVolName

std::string MuonGM::DetectorElement::logVolName {}
inherited

Definition at line 18 of file DetectorElement.h.

18{};

◆ longWidth

double MuonGM::Mdt::longWidth {0.}

Definition at line 29 of file Mdt.h.

29{0.}; // for trapezoidal layers

◆ m_component

MdtComponent* MuonGM::Mdt::m_component {nullptr}
private

Definition at line 47 of file Mdt.h.

47{nullptr};

◆ name

std::string MuonGM::DetectorElement::name {}
inherited

Definition at line 17 of file DetectorElement.h.

17{};

◆ thickness

double MuonGM::Mdt::thickness {0.}

Definition at line 28 of file Mdt.h.

28{0.};

◆ tubelenStepSize

double MuonGM::Mdt::tubelenStepSize {0.}

Definition at line 31 of file Mdt.h.

31{0.};

◆ tubePitch

double MuonGM::Mdt::tubePitch {0.}

Definition at line 32 of file Mdt.h.

32{0.};

◆ width

double MuonGM::Mdt::width {0.}

Definition at line 26 of file Mdt.h.

26{0.};

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