ATLAS Offline Software
MuonChamberLite.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "GaudiKernel/MsgStream.h"
7 //
9 #include "MuonGeoModel/Csc.h"
10 #include "MuonGeoModel/Cutout.h"
11 #include "MuonGeoModel/Ded.h"
12 #include "MuonGeoModel/Mdt.h"
14 #include "MuonGeoModel/Position.h"
15 #include "MuonGeoModel/Rpc.h"
16 #include "MuonGeoModel/Spacer.h"
18 #include "MuonGeoModel/Station.h"
19 #include "MuonGeoModel/Tgc.h"
22 //
35 
36 // just to check subtype, cutout:
40 #include "MuonGeoModel/MYSQL.h"
43 //
48 //
49 #include "GaudiKernel/SystemOfUnits.h"
50 #include "GeoModelKernel/GeoDefinitions.h"
51 
52 
53 #include <fstream>
54 #include <format>
55 #include <iomanip>
56 #include <vector>
57 #include <stdexcept>
58 #include <set>
59 
60 #define RPCON true
61 #define useAssemblies false
62 namespace {
63  // const maps holding the y/z translation for BIS RPCs (since they cannot be parsed by amdb)
64  const std::map<std::string, float> rpcYTrans = {
65  std::make_pair<std::string, float>("RPC26", -9.1), // big RPC7
66  std::make_pair<std::string, float>("RPC27", -9.1), // small RPC7
67  std::make_pair<std::string, float>("RPC28", -27.7), // big RPC8
68  std::make_pair<std::string, float>("RPC29", -8.8), // small RPC8
69  };
70  const std::map<std::string, float> rpcZTrans = {
71  std::make_pair<std::string, float>("RPC26", 3.22), // big RPC7
72  std::make_pair<std::string, float>("RPC27", 3.06), // small RPC7
73  std::make_pair<std::string, float>("RPC28", 3.11), // big RPC8
74  std::make_pair<std::string, float>("RPC29", 3.11), // small RPC8
75  };
76 } // namespace
77 
78 
79 
80 namespace MuonGM {
81 
82  // cutouts for BMS at eta=+-1 and phi=4 (RPC/DED/MDT) ok //16 tubes shorter + entire RPC and DED (of dbz1) narrower
83 
85  std::map<std::string, GeoFullPhysVol*> * mapFPV,
86  std::map<std::string, GeoAlignableTransform *> *mapAXF) :
87  DetectorElement(s->GetName()),
88  AthMessaging{"MuonchamberLite"},
89  m_mapFPV(mapFPV),
90  m_mapAXF(mapAXF)
91  {
92  width = s->GetWidth1();
93  longWidth = s->GetWidth2();
94  thickness = s->GetThickness(mysql);
95  length = s->GetLength();
96  m_station = s;
97 
98  // CSL envelope is too small for its components - enlarge it slightly
99  std::string stname(m_station->GetName(), 0, 3);
100  if (stname == "CSL")
101  longWidth *= 1.015;
102 
103 
104  }
105 
107  const MYSQL& mysql,
108  MuonDetectorManager *manager, int zi, int fi, bool is_mirrored, bool &isAssembly) {
109 
110 
111 
112  ATH_MSG_VERBOSE( " Building a MuonChamberLite for m_station " << m_station->GetName() << " at zi, fi " << zi << " " << fi + 1 << " is_mirrored " << is_mirrored
113  << " is assembly = " << isAssembly );
114 
115  std::string stname(m_station->GetName(), 0, 3);
116 
117  double halfpitch = m_station->mdtHalfPitch(mysql);
118  const std::string stName = m_station->GetName();
119 
120  const MdtIdHelper *mdt_id = manager->mdtIdHelper();
121  int stationType = mdt_id->stationNameIndex(stName.substr(0, 3));
122 
123  double extratop = m_station->GetExtraTopThickness();
124  double extrabottom = m_station->GetExtraBottomThickness();
125  double totthick = thickness + extratop + extrabottom;
126 
127 
128  double amdbOrigine_along_length = m_station->getAmdbOrigine_along_length();
129  double amdbOrigine_along_thickness = m_station->getAmdbOrigine_along_thickness(mysql);
130 
131 
132  // This will allow the MDT tube structure to be mirrored w.r.t. the chamber at z>0
133  // and to correctly place any other component in the m_station
134  if (zi < 0 && !is_mirrored && stName[0] == 'B') {
135  if (m_station->hasMdts()) {
136  amdbOrigine_along_length += halfpitch;
137  }
138  }
139  ATH_MSG_VERBOSE( "amdb origine: in the length direction = "
140  << amdbOrigine_along_length << " in the thickness direction = " << amdbOrigine_along_thickness);
141 
142  if (isAssembly) {
143  ATH_MSG_DEBUG("Station " << stName << " at zi, fi " << zi << " " << fi + 1 << " will be described as Assembly" );
144 
145  }
146 
147  // for BOG in layout Q we will have to shorten CHV, CMI as these
148  // are not shortened in AMDB
149 
150 
151  // if this is a BOG, we want to make cutouts in the MOTHER VOLUME
152  if (stName.compare(0, 3, "BOG") == 0 && (manager->IncludeCutoutsBogFlag() || manager->IncludeCutoutsFlag())) {
153 
154  ATH_MSG_VERBOSE( "amdb org: length= " << amdbOrigine_along_length << " thickness= " << amdbOrigine_along_thickness );
155 
156  std::string statType = stName.substr(0, 3);
157  if (m_station->GetNrOfCutouts() > 0) {
158  ATH_MSG_DEBUG( "Station " << stName << " at zi, fi " << zi << " " << fi + 1 << " has components with cutouts " );
159  isAssembly = true;
160 
161  // look for FIRST component with cutouts and loop over all of the cutouts:
162  bool foundCutouts = false;
163  for (int j = 0; j < m_station->GetNrOfComponents(); j++) {
165 
166  if (!foundCutouts) {
167  for (int ii = 0; ii < m_station->GetNrOfCutouts(); ii++) {
168  Cutout *cut = m_station->GetCutout(ii);
169  // if this is a BOG in layout Q, set the CP param:
170  // (both cuts have same length so ok to reset it)
171  // also do here some tweaking to prevent undershoot
172  // of the cutouts wrt mother volume:
173  if (std::abs(cut->dx - 600.7) < 0.1) {
174  cut->dx = cut->dx + 10. * Gaudi::Units::mm;
175  cut->widthXs = cut->widthXs + 20. * Gaudi::Units::mm;
176  cut->widthXl = cut->widthXl + 20. * Gaudi::Units::mm;
177  }
178  if (std::abs(cut->dx + 600.7) < 0.1) {
179  cut->dx = cut->dx - 10. * Gaudi::Units::mm;
180  cut->widthXs = cut->widthXs + 20. * Gaudi::Units::mm;
181  cut->widthXl = cut->widthXl + 20. * Gaudi::Units::mm;
182  }
183  if (std::abs(cut->lengthY - 180.2) < 0.001) {
184  cut->lengthY = cut->lengthY + (0.010) * Gaudi::Units::mm;
185  }
186  if (std::abs(cut->dy - 1019.8) < 0.001) {
187  cut->dy = 1216.4185 - cut->lengthY;
188  }
189  // create the cutout with the full thickness of the STATION
190  cut->setThickness(totthick * 1.01); // extra to be sure
191  if ((cut->subtype == mysql.allocPosFindSubtype(std::string(statType), fi, zi)) && (cut->icut == mysql.allocPosFindCutout(std::string(statType), fi, zi)) &&
192  (cut->ijob == c->index)) {
193 
194  foundCutouts = true;
195  }
196  } // Loop over cutouts
197  } // If no cutouts
198  } // Loop over components
199  }
200  } // end of special loop just for cutouts
201 
202 
203 
204  double ypos{0.}, zpos{0.}, xpos{0.}, irad{0.};
205  std::array<int, 2 > ndbz{0, 0};
206 
207  // Compute how many RPC modules there are in the m_station
208  int nDoubletR{0}, nRpc{0}, nTgc{0}, nCsc{0}, nMdt{0};
209  double previous_depth = 0.;
210 
211  ATH_MSG_VERBOSE( " Station Name = " << stName << " fi/zi " << fi << "/" << zi << " defining the n. of DoubletR to " );
212 
213 
214  for (int j = 0; j < m_station->GetNrOfComponents(); j++) {
216  std::string_view cn = std::string_view(d->name).substr(0, 3);
217  if (cn == "RPC") {
218  nRpc++;
219  if (nRpc == 1)
220  nDoubletR++;
221  double depth = -thickness / 2. + d->posz + d->GetThickness(mysql) / 2.;
222  // BI RPC Chambers have one one doubletR
223  if (!(stname.compare(0, 2, "BI") == 0) && nDoubletR == 1 && nRpc > 1 && depth * previous_depth < 0)
224  nDoubletR++;
225 
226  previous_depth = depth;
227  }
228  else if (cn == "CSC") {
229  nCsc++;
230  }
231  else if (cn == "TGC") {
232  nTgc++;
233  }
234  else if (cn == "MDT") {
235  nMdt++;
236  }
237  }
238  ATH_MSG_DEBUG( "nDoubletR: " << nDoubletR<<" nMdt/Rpc/Tgc/Csc " << nMdt << "/" << nRpc << "/" << nTgc << "/" << nCsc );
239 
240  // Get location and dimensions of long beams and pass them to cross beams
241  // in order to make holes
242  int numLB = -1;
243  double LBheight{0.}, LBwidth{0.};
244  std::array<double, 2> LBpos{-1, -1};
245  for (int i = 0; i < m_station->GetNrOfComponents(); i++) {
247  std::string_view cname = std::string_view(c->name).substr(0, 2);
248  if (cname == "LB") {
249  const LBI *lb = dynamic_cast<const LBI *>(mysql.GetTechnology(c->name));
250  numLB++;
251  LBpos[numLB] = c->posy + c->dy / 2.;
252  LBheight = lb->height;
253  LBwidth = c->dy;
254  }
255  if (numLB > 0)
256  break; // only 2 LBs per chamber
257  }
258 
259  for (int i = 0; i < m_station->GetNrOfComponents(); i++) {
261  std::string_view cname = std::string_view(c->name).substr(0, 3);
262  if (cname == "CRO" || cname == "CMI" || cname == "CHV") {
263  CbmComponent *ccbm = static_cast<CbmComponent *>(c);
264  ccbm->lb_height = LBheight;
265  ccbm->lb_width = LBwidth;
266  ccbm->hole_pos1 = LBpos[0];
267  ccbm->hole_pos2 = LBpos[1];
268  }
269  }
270 
271  // Look for the subtype of the CMI in the chamber to let LB know ...
272  std::string CMIcomponentNumber = "";
273  for (int j = 0; j < m_station->GetNrOfComponents(); j++) {
275  std::string_view cn = std::string_view(d->name).substr(0, 3);
276  if (cn == "CMI") {
277  CMIcomponentNumber = (d->name).substr(3, 2);
278  break;
279  }
280  }
281 
282  for (int j = 0; j < m_station->GetNrOfComponents(); j++) {
284  std::string_view cn = std::string_view(d->name).substr(0, 2);
285  if (cn == "LB") {
286  LbiComponent *lbic = static_cast<LbiComponent *>(d);
287  if (lbic) {
288  lbic->associated_CMIsubtype = CMIcomponentNumber;
289  } else
290  ATH_MSG_ERROR( "MuonChamberLite :: cannot associate a CMI subtype to the LB component " );
291  }
292  }
293 
294  // Build the MuonStation(readout-geometry) corresponding to this MuonChamberLite(raw-geometry)
295  MuonStation *mstat;
296  if (stName.compare(0, 1, "B") == 0) {
297  mstat = new MuonStation(stName.substr(0, 3), width, totthick, length, longWidth, totthick, length, zi, fi + 1,
298  (zi < 0 && !is_mirrored));
299  } else {
300  mstat = new MuonStation(stName.substr(0, 3), width, length, totthick, longWidth, length, totthick, zi, fi + 1,
301  (zi < 0 && !is_mirrored));
302  }
303 
304  manager->addMuonStation(std::unique_ptr<MuonStation>(mstat));
305  ATH_MSG_DEBUG( " Building a MuonStation for this MuonChamberLite " << m_station->GetName()
306  << " at zi, fi " << zi << " " << fi + 1 << " is_mirrored " << is_mirrored);
307 
308  GeoFullPhysVol *ptrd=(*m_mapFPV)[std::string(stName)+"_Station"+"_"+std::to_string(zi)+"_"+std::to_string(fi)];
309  mstat->setPhysVol(ptrd);
310  // here the big loop over the components !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
311  for (int i = 0; i < m_station->GetNrOfComponents(); i++) {
313  ATH_MSG_VERBOSE( " Component index " << c->index << " in loop for " << stName << " " << stationType << " at zi, fi " << zi << " " << fi + 1 << " cName "
314  << c->name << " thickness " << c->GetThickness(mysql) << " length " << c->dy << " w, lw " << c->dx1 << " " << c->dx2 );
315  ATH_MSG_VERBOSE( " Component local (amdb) coords " << c->posx << " " << c->posy << " " << c->posz );
316 
317  ypos = -thickness / 2. + c->posz + c->GetThickness(mysql) / 2.;
318  zpos = 0.;
319  xpos = 0.;
320 
321  ypos = -thickness / 2. + (c->posz + amdbOrigine_along_thickness) + c->GetThickness(mysql) / 2.;
322  zpos = -length / 2. + amdbOrigine_along_length + c->posy + c->dy / 2.;
323  xpos = c->posx;
324 
325  const std::string &techname = c->name;
326  std::string_view type = std::string_view(techname).substr(0, 3);
327 
328 
329 
330  GeoIntrusivePtr<GeoFullPhysVol> lvm{}, lvr{}, lvt{}, lvc{};
331 
332 
333 
334  // Are there cutouts?
335  std::string statType = stName.substr(0, 3);
336  double cthickness = c->GetThickness(mysql);
337  int ncutouts = 0;
338  std::vector<Cutout *> vcutdef;
339  std::vector<std::unique_ptr<Cutout>> vcutdef_todel;
340  for (int ii = 0; ii < m_station->GetNrOfCutouts(); ii++) {
341  Cutout *cut = m_station->GetCutout(ii);
342  cut->setThickness(cthickness * 1.01); // extra thickness to be sure
343 
344  if ((cut->subtype == mysql.allocPosFindSubtype(std::string(statType), fi, zi)) && (cut->icut == mysql.allocPosFindCutout(std::string(statType), fi, zi)) && (cut->ijob == c->index)) {
345 
346  double tempdx = cut->dx;
347  double tempdy = cut->dy;
348  double templengthY = cut->lengthY;
349  cut->dx = 0.;
350  cut->dy = 0.;
351 
352  if (stName.compare(0, 3, "BOG") == 0) {
353  // make the cutouts a bit longer
354  cut->lengthY = templengthY + 31.;
355  }
356 
357  cut->dx = tempdx;
358  cut->dy = tempdy;
359 
360  if (std::abs(cut->dead1) > 1. && techname == "MDT03")
361  cut->dy = cut->dy + 15.0 * cos(cut->dead1 * Gaudi::Units::deg);
362  // should compensate for the dy position defined in amdb at the bottom of the foam in ML 1 of EMS1,3 and BOS 6
363  // can be applied only for layout >=r.04.04 in rel 15.6.X.Y due to the frozen Tier0 policy
364 
365  cut->lengthY = templengthY;
366  // in thickness, cutout will coincide with component
367  // not needed (DHW) double xposcut = 0.; // rel. to component thickness
368  ncutouts++;
369  ATH_MSG_VERBOSE( "A new cutout for this component " );
370  ATH_MSG_VERBOSE( *cut );
371 
372  // Corrected cutout values for BMS7, BMS14
373  if (stName.compare(0, 3, "BMS") == 0) {
374  if (fi == 3) { // stationPhi = 4
375  if (std::abs(zi) == 1) { // stationEta = +-1
376  double margin = 1.0; // make cutout a little bigger to avoid coincident boundaries
377 
378  if (type == "RPC" || type == "DED") {
379  cut->widthXl += 2 * margin;
380  cut->widthXs += 2 * margin;
381  cut->dx += margin;
382  cut->lengthY += 2 * margin;
383 
384  if (zi > 0)
385  cut->dy = -margin;
386  }
387  }
388 
389  if (zi == -1) {
390  if (type == "MDT")
391  cut->dy = 0.;
392  }
393  }
394  }
395 
396  // the following is a fine tuning ----- MUST CHECK for a better solution
397  if (stName.compare(0, 3,"BOS") == 0 && zi == -6 && type == "MDT") {
398  cut->dy = c->dy - cut->dy - cut->lengthY - halfpitch;
399  cut->dead1 = 30.; // why this is not 30. or -30. already ?????
400  if (techname == "MDT03")
401  cut->dy = cut->dy + 30.0; // *cos(cut->dead1*Gaudi::Units::deg);
402  ATH_MSG_VERBOSE( "Cut dead1 for BOS 6 on C side is " << cut->dead1 );
403 
404  }
405 
406  // this mirroring of the cutout is necessary only for barrel MDT chambers; for EC the cutout will be automatically mirrored
407  // this fix cannot be applied in 15.6.X.Y for layout < r.04.04 due to the frozen tier0 policy
408 
409  if (type == "MDT" && (is_mirrored || zi < 0) && stName.compare(0, 1, "B") == 0) {
410  // MDT in chambers explicitly described at z<0 have to be
411  // rotated by 180deg to adj. tube staggering
412  // reverse the position (x amdb) of the cutout if the m_station is mirrored
413  Cutout *cutmirr = new Cutout(*cut);
414  cutmirr->dx = -cutmirr->dx;
415  // this way, after the rotation by 180 Gaudi::Units::deg, the cut will be at the same global phi
416  // it has for the m_station at z>0
417  vcutdef.push_back(cutmirr);
418  vcutdef_todel.emplace_back(cutmirr);
419  ATH_MSG_VERBOSE( "adding for application mirrored cut \n" << *cutmirr );
420 
421  } else if (type == "RPC" || type == "DED") {
422  Cutout *cutRpcType = new Cutout(*cut);
423  // temporary for testing fixes to r.03.09
424  if (stName.compare(0, 3, "BMS") == 0 && zi == 4 && (c->index == 20 || c->index == 21 || c->index == 24 || c->index == 25)) {
425  cutRpcType->dy = 1102.5;
426  }
427 
428  if (stName.compare(0, 3, "BOS") == 0 && zi == 6 && type == "DED")
429  cutRpcType->dy = 706.;
430 
431  cutRpcType->dy = cutRpcType->dy - c->posy;
432  cutRpcType->dx = cutRpcType->dx - c->posx;
433 
434  if (type == "RPC") {
435  RpcComponent *rp = static_cast<RpcComponent *>(c);
436  if (rp->iswap == -1) {
437  cutRpcType->dy = c->dy - (cutRpcType->dy + cutRpcType->lengthY);
438  }
439  }
440 
441  ATH_MSG_VERBOSE( " Rpc or ded cutout redefined as follows \n" << *cutRpcType );
442  vcutdef.push_back(cutRpcType);
443  vcutdef_todel.emplace_back(cutRpcType);
444  } else if (type == "TGC") {
445  // In AMDB, y coordinates of cutout and component are given by
446  // radius from detector z-axis. To get standard y value of cutout,
447  // subtract radius of component from radius of cutout
448  Cutout *tgccut = new Cutout(*cut);
449  tgccut->dy -= c->posy; //
450 
451  ATH_MSG_VERBOSE( " Tgc cutout redefined as follows \n" << *tgccut );
452  vcutdef.push_back(tgccut);
453  vcutdef_todel.emplace_back(tgccut);
454  } else {
455  vcutdef.push_back(cut);
456  }
457  }
458  } // Loop over cutouts in m_station
459 
460  if (ncutouts > 0) {
461  ATH_MSG_DEBUG( c->name << " of station " << stName << " at fi/zi " << fi + 1 << "/" << zi << " has " << ncutouts << " cutouts " );
462  }
463  // define here the total transform that will be applied to component:
464  GeoTrf::Transform3D htcomponent(GeoTrf::Transform3D::Identity());
465  GeoAlignableTransform *xfaligncomponent{nullptr};
466  // for RPCs we need a vector of transforms for M28 geometry...
467 
468  if (type == "CRO") {
469  if (stName.compare(0, 1, "B") != 0 && is_mirrored)
470  mstat->setxAmdbCRO(-xpos);
471  else
472  mstat->setxAmdbCRO(xpos);
473  }
474 
475  if (type == "MDT") {
476  MdtComponent *md= static_cast<MdtComponent *> (c);
477  htcomponent = GeoTrf::TranslateX3D(ypos) * GeoTrf::TranslateZ3D(zpos) * GeoTrf::TranslateY3D(xpos);
478 
479  if (zi < 0 && !is_mirrored && stName[0] == 'B') {
480  // this (rotation + shift of halfpitch) will mirror the tube structure w.r.t. the chamber at z>0
481  htcomponent = htcomponent * GeoTrf::RotateX3D(180. * Gaudi::Units::deg);
482  htcomponent = htcomponent * GeoTrf::TranslateZ3D(halfpitch);
483  }
484 
485  // ss - 24-05-2006 I don't really understand if this is needed at all
486  // it was introduced by Isabel T.
487  if (zi < 0 && stName.compare(0, 3, "BOG") == 0 && is_mirrored) {
488  // htcomponent = htcomponent*GeoTrf::RotateX3D(180.*Gaudi::Units::deg);
489  // tubes OK but chambers wrong
490  // htcomponent = GeoTrf::RotateX3D(180.*Gaudi::Units::deg)*htcomponent;
491  // chambers OK but tubes wrong
492  htcomponent = GeoTrf::RotateX3D(180. * Gaudi::Units::deg) * htcomponent * GeoTrf::RotateX3D(180. * Gaudi::Units::deg); // turn chambers but go back for tubes
493  } // ss - 24-05-2006 I don't really understand if this is needed at all
494 
495  std::string key =std::string( stName) + techname;
496  xfaligncomponent = (*m_mapAXF)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)+"_"+std::to_string(md->index)];
497 
498  // for cutouts:
499  // MDT cutouts for BOS1,5, BMS7,14, (problem with BMS4,10), EMS, BMG and BIS MDT14
500  bool mdtCutoutFlag = ((stname == "BOS" && std::abs(zi) == 6) || stname == "BMG" || techname == "MDT14" || (stname == "BMS" && (std::abs(zi) == 1 && fi == 3)) ||
501  (stname == "EMS" && (std::abs(zi) == 1 || std::abs(zi) == 3)));
502  if (((manager->IncludeCutoutsFlag() && mdtCutoutFlag) || (manager->IncludeCutoutsBogFlag() && stName.compare(0, 3, "BOG") == 0)) && zi >= 0) {
503  key += "p" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
504  } else if (((manager->IncludeCutoutsFlag() && mdtCutoutFlag) || (manager->IncludeCutoutsBogFlag() && stName.compare(0, 3, "BOG")) == 0) && zi < 0) {
505  key += "m" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
506  }
507  if (m_keySet->find(key)==m_keySet->end()) {
508  std::unique_ptr<Mdt> r = std::make_unique<Mdt>(mysql, c, stName + techname);
509  if ((manager->IncludeCutoutsFlag() && mdtCutoutFlag) || (manager->IncludeCutoutsBogFlag() && stName.compare(0, 3, "BOG") == 0)) {
510  if (!vcutdef.empty()) r->processCutouts(vcutdef);
511  }
512  m_keySet->insert(key);
513  }
514  lvm = (*m_mapFPV)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)+"_"+std::to_string(md->index)];
515 
516  } else if (type == "RPC") {
517  // position stuff needed for cutout, used to be below:
518  RpcComponent *rp = static_cast<RpcComponent *>(c);
519  int ndivy = rp->ndivy;
520  int ndivz = rp->ndivz;
521 
522  if (ndivz != 1 || ndivy != 1) {
523  ATH_MSG_ERROR( " RPC segmentation z,y " << ndivz << " " << ndivy );
524  }
525 
526  double xpos = c->posx;
527  // implement really the mirror symmetry
528  if (is_mirrored)
529  xpos = -xpos;
530 
531  ATH_MSG_VERBOSE( " In station " << stName << " with " << nDoubletR << " doubletR,"
532  << " RPC " << (c->name).substr(3, 2) << " has swap flag = " << rp->iswap << " ypos, zpos " << ypos << " " << zpos << " " );
533 
534  htcomponent = GeoTrf::TranslateX3D(ypos) * GeoTrf::TranslateY3D(xpos) * GeoTrf::TranslateZ3D(zpos);
535  if (rp->iswap == -1) { // this is like amdb iswap
536  htcomponent = htcomponent * GeoTrf::RotateY3D(180 * Gaudi::Units::deg);
537  }
538 
539  // end of position stuff
540 
541  bool rpcCutoutFlag = (stname == "BOS" && std::abs(zi) == 6) || (stname == "BMS" && (std::abs(zi) == 2 || std::abs(zi) == 4 || std::abs(zi) == 6)) ||
542  (stname == "BMS" && std::abs(zi) == 1 && fi == 3);
543  std::string key = stName + techname;
544  if (((manager->IncludeCutoutsFlag() && rpcCutoutFlag) || (manager->IncludeCutoutsBogFlag() && stName.compare(0, 3, "BOG") == 0)) && zi >= 0) {
545  key += "p" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0) + "_" +
546  buildString(vcutdef.size(), 0) + "_" + buildString(rp->iswap, 0);
547  } else if (((manager->IncludeCutoutsFlag() && rpcCutoutFlag) || (manager->IncludeCutoutsBogFlag() && stName.compare(0, 3, "BOG") == 0)) && zi < 0) {
548  key += "m" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0) + "_" +
549  buildString(vcutdef.size(), 0) + "_" + buildString(rp->iswap, 0);
550  }
551  xfaligncomponent = (*m_mapAXF)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)+"_"+std::to_string(rp->index)];
552  lvr = (*m_mapFPV)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)+"_"+std::to_string(rp->index)];
553  } else if (type == "TGC") {
554  TgcComponent *tg = static_cast<TgcComponent *>(m_station->GetComponent(i));
555  TgcComponent *tgInner = static_cast<TgcComponent *>(m_station->GetComponent(0));
556  irad = tgInner->posy;
557  TgcComponent *tgOuter = static_cast<TgcComponent *>(m_station->GetComponent(m_station->GetNrOfComponents() - 1));
558  double orad = tgOuter->posy + tgOuter->dy;
559  double start = -(orad - irad) / 2. + (tg->posy - irad) + tg->dy / 2;
560  double xstart = -thickness / 2. + tg->GetThickness(mysql) / 2.;
561  htcomponent = GeoTrf::TranslateX3D(xstart + tg->posz) * GeoTrf::TranslateZ3D(start);
562 
563  // Define key for this TGC component
564  std::string key = std::string(stName) + techname;
565  if (manager->IncludeCutoutsFlag()) {
566  if (mysql.allocPosFindCutout(statType, fi, zi) > 0) {
567  // If there is a cutout for this chamber, give it a special key
568  if (zi >= 0) {
569  key += "p" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
570  } else if (zi < 0) {
571  key += "m" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
572  }
573  }
574  }
575 
576  key += std::to_string(int(10 * c->dx1));
577  xfaligncomponent = (*m_mapAXF)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)];
578 
579  lvt = (*m_mapFPV)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)];
580 
581  } else if (type == "CSC") {
582  htcomponent = GeoTrf::TranslateX3D(ypos) * GeoTrf::TranslateZ3D(zpos);
583  // Here define the key for this CSC component
584  std::string key = std::string(stName) + techname;
585  if (manager->IncludeCutoutsFlag() && zi >= 0) {
586  key += "p" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
587  } else if (manager->IncludeCutoutsFlag() && zi < 0) {
588  key += "m" + buildString(mysql.allocPosFindSubtype(statType, fi, zi), 0) + "_" + buildString(mysql.allocPosFindCutout(statType, fi, zi), 0);
589  }
590 
591  xfaligncomponent = (*m_mapAXF)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)];
592  lvc=(*m_mapFPV)[key+"_"+std::to_string(zi)+"_"+std::to_string(fi)];
593  } else {
594  if (type != "MDT" && type != "RPC" && type != "TGC" && type != "SUP" && type != "DED" && type != "SPA" && type != "CHV" && type != "CRO" && type != "CMI" &&
595  type != "LB0" && type != "LBI") {
596  ATH_MSG_WARNING("Unknown component " << type );
597  }
598  }
599 
600  // Place components in chamber envelope
601  if (lvm && manager->mdtIdHelper()) {
602  int stationEta = zi;
603  int stationPhi = fi + 1;
604  int ml = 1;
605  int tubel = 1;
606  int tube = 1;
607  if (ypos > 5.)
608  ml = 2; // Need >5 instead of >0 because BIS78 is not perfectly centered
609 
610 
611  const MdtIdHelper *mdt_id = manager->mdtIdHelper();
612  std::unique_ptr<MdtReadoutElement> det = std::make_unique<MdtReadoutElement>(lvm, stName, manager);
613  Position ip = mysql.GetStationPosition(stName.substr(0, 3), fi, zi);
614  setMdtReadoutGeom(mysql, det.get(), static_cast<MdtComponent *>(c), ip);
615  det->setHasCutouts(ncutouts > 0);
616  det->setNMdtInStation(nMdt);
617  Identifier id = mdt_id->channelID(stationType, stationEta, stationPhi, ml, tubel, tube);
618  det->setIdentifier(id);
619  det->setMultilayer(ml);
620  det->setParentStationPV(PVConstLink(ptrd));
621  det->setParentMuonStation(mstat);
622  det->geoInitDone();
623 
624  if (ml == 1) {
625  // set fixed point for MDT deformations: s0,z0,t0 for the point at lowest t,z (z,y amdb) and s=x=0
626  mstat->setBlineFixedPointInAmdbLRS(c->posx, c->posy, c->posz);
627  } else {
628  const Amg::Vector3D b0 = mstat->getBlineFixedPointInAmdbLRS();
629  if (c->posy < b0.y())
630  mstat->setBlineFixedPointInAmdbLRS(b0.x(), c->posy, b0.z());
631  }
632 
633  int jobIndex = c->index;
634 
635  mstat->addMuonReadoutElementWithAlTransf(det.get(), xfaligncomponent, jobIndex);
636  manager->addMdtReadoutElement(std::move(det));
637  }
638 
639  if (lvc && manager->cscIdHelper()) {
640  CscComponent *cs = static_cast<CscComponent *>(m_station->GetComponent(i));
641  int stationEta = zi;
642  int stationPhi = fi + 1;
643  int chamberLayer = 1;
644  if (ypos > 0.)
645  chamberLayer = 2;
646 
647  std::unique_ptr<CscReadoutElement> det = std::make_unique<CscReadoutElement>(lvc, stName, manager);
648  Position ip = mysql.GetStationPosition(stName.substr(0, 3), fi, zi);
649  setCscReadoutGeom(mysql, det.get(), cs, ip);
650 
651  const CscIdHelper *csc_id = manager->cscIdHelper();
652  det->setHasCutouts(ncutouts > 0);
653  Identifier id = csc_id->channelID(stationType, stationEta, stationPhi, chamberLayer, 1, 0, 1);
654  det->setIdentifier(id);
655 
656  det->setChamberLayer(chamberLayer);
657  det->setParentStationPV(PVConstLink(ptrd));
658  det->setParentMuonStation(mstat);
659 
660  int jobIndex = c->index;
661  //
662  mstat->addMuonReadoutElementWithAlTransf(det.get(), xfaligncomponent, jobIndex);
663 
664 
665 
666  // set alignment parameters for the wire layers
667  manager->addCscReadoutElement(std::move(det));
668  }
669 
670  if (lvt && manager->tgcIdHelper()) {
671 
672  ATH_MSG_DEBUG( " Adding a TGC chamber to the tree zi,fi, is_mirrored " << zi << " " << fi + 1 << " " << is_mirrored );
673 
674 
675  TgcComponent *tg = static_cast<TgcComponent *>(m_station->GetComponent(i));
676 
677  ATH_MSG_VERBOSE( "There's a TGC named " << techname << " of thickness " << tg->GetThickness(mysql) );
678 
679  const TgcIdHelper *tgc_id = manager->tgcIdHelper();
680  int stationEta = 0;
681  stationEta = tg->index;
682  if (zi < 0)
683  stationEta = -stationEta;
684  int stationPhi = 0;
685  stationPhi = stationPhiTGC(stName, fi + 1,zi);
686 
687  std::unique_ptr<TgcReadoutElement> det = std::make_unique<TgcReadoutElement>(lvt, stName, manager);
688  Position ip = mysql.GetStationPosition(stName.substr(0, 3), fi, zi);
689  setTgcReadoutGeom(mysql, det.get(), tg, ip, stName);
690  det->setHasCutouts(ncutouts > 0);
691  Identifier id = tgc_id->channelID(stationType, stationEta, stationPhi, 1, false, 1);
692  det->setIdentifier(id);
693  det->setParentStationPV(PVConstLink(ptrd));
694  det->setParentMuonStation(mstat);
695 
696  int jobIndex = c->index;
697 
698  mstat->addMuonReadoutElementWithAlTransf(det.get(), xfaligncomponent, jobIndex);
699 
700  manager->addTgcReadoutElement(std::move(det));
701  }
702  if (lvr && RPCON && manager->rpcIdHelper()) {
703  RpcComponent *rp = static_cast<RpcComponent *>(c);
704  int ndivy = rp->ndivy;
705  int ndivz = rp->ndivz;
706 
707  if (ndivz != 1 || ndivy != 1) {
708  ATH_MSG_ERROR( " RPC segmentation z,y " << ndivz << " " << ndivy );
709  }
710 
711  double zpos = -length / 2. + c->posy + c->dy / 2.;
712  double xpos = c->posx;
713 
714  // implement really the mirror symmetry
715  if (is_mirrored)
716  xpos = -xpos;
717  // ... putting back to here!
718 
719  const RpcIdHelper *rpc_id = manager->rpcIdHelper();
720  int stationEta = zi;
721  int stationPhi = fi + 1;
722  int doubletR = 1;
723  int doubletZ = 1;
724 
725  if (nRpc > 1 && nDoubletR == 2 && ypos > 0.)
726  doubletR = 2;
727  ndbz[doubletR - 1]++;
728 
729  // the BI RPCs are 3-gap RPCs mounted inside of the BI (s)MDTs
730  if (stname.find("BI") != std::string::npos) {
731  if (stname.find("BIS") != std::string::npos) {
732  // for BIS78, there is a second RPC doubletZ at amdb-y (MuonGeoModel-z)=144mm inside the station
733  if (std::abs(stationEta)>= 7){
734  ATH_MSG_DEBUG("BIS78 station eta: "<<stationEta<<" phi: "<<stationPhi<<" dR: "<<doubletR<<" dZ:"<< doubletZ <<" rp: "<<rp->posz);
735  }
736  if (std::abs(stationEta) >= 7 && rp->posz > 80)
737  doubletZ = 2;
738  else
739  doubletZ = 1;
740  } else {
741  // for BIL/BIM/BIR, we have 10 RPCs put on 6 MDT stations, thus, need to exploit doubletZ as additional variable on top of stationEta
742  // only for BIL, there are sometimes 2 RPCs per 1 MDT station, namely for stationEta 1,3,4,6
743  if (stname.find("BIL") != std::string::npos && std::abs(stationEta) < 7 && std::abs(stationEta) != 2 && std::abs(stationEta) != 5) {
744  if (rp->posy > 1)
745  doubletZ = 2; // put the chamber with positive amdb-z to doubletZ=2
746  } else
747  doubletZ = 1;
748  }
749  } else {
750  if (zi <= 0 && !is_mirrored) {
751  if (zpos < -100 * Gaudi::Units::mm)
752  doubletZ = 2;
753  } else {
754  if (zpos > 100 * Gaudi::Units::mm)
755  doubletZ = 2;
756  }
757  }
758 
759  // BMS (BOG) RPCs can have |xpos|=950 (|xpos|=350)
760  if (std::abs(xpos) > 100. * Gaudi::Units::mm) {
761  if (ndbz[doubletR - 1] > 2) {
762  doubletZ = 3;
763  }
764  ndbz[doubletR - 1]--;
765  }
766 
767  int dbphi = 1;
768 
769  // this special patch is needed for BMS in the ribs where xpos is ~950mm;
770  // the theshold to 100mm (too low) caused a bug
771  // in BOG at eta +/-4 and stationEta 7 (not 6) ==>> 28 Jan 2016 raising the threshold to 400.mm
772  // doublet phi not aware of pos. in space !!!
773  if (xpos > 400. * Gaudi::Units::mm)
774  dbphi = 2;
775 
776  int doubletPhi = dbphi;
777  //
778  if (zi < 0 && is_mirrored && doubletZ == 3) {
779  doubletPhi++;
780  if (doubletPhi > 2)
781  doubletPhi = 1;
782  } else if (zi < 0 && is_mirrored && doubletZ == 2 && doubletR == 1 && stName == "BMS6") {
783  doubletPhi++;
784  if (doubletPhi > 2)
785  doubletPhi = 1;
786  }
787  // never defined fields: set to the lower limit
788  int gasGap = 1;
789  int measuresPhi = 0;
790  int strip = 1;
791 
792  int tag = doubletZ + doubletR * 100 + dbphi * 1000;
793  if (rp->iswap == -1)
794  tag = -1 * tag;
795  if (useAssemblies || isAssembly) {
796  //
797  } else {
798  int tag = rp->index + doubletR * 100 + dbphi * 1000;
799  if (rp->iswap == -1)
800  tag = -1 * tag;
801 
802  }
803 
804 
805  std::unique_ptr<RpcReadoutElement> det = std::make_unique<RpcReadoutElement>(lvr, stName, zi, fi + 1, is_mirrored, manager);
806  Position ip = mysql.GetStationPosition(stName.substr(0, 3), fi, zi);
807  setRpcReadoutGeom(mysql, det.get(), rp, ip);
808  det->setHasCutouts(ncutouts > 0);
809  Identifier id = rpc_id->channelID(stationType, stationEta, stationPhi, doubletR, doubletZ, doubletPhi, gasGap, measuresPhi, strip);
810  det->setIdentifier(id);
811  det->setDoubletR(doubletR);
812  det->setDoubletZ(doubletZ);
813  det->setDoubletPhi(doubletPhi);
814  if (stName.find("BI") != std::string::npos)
815  det->setNumberOfLayers(3); // all BI RPCs always have 3 gas gaps
816  det->setParentStationPV(PVConstLink(ptrd));
817  det->setParentMuonStation(mstat);
818 
819  int jobIndex = c->index;
820 
821  mstat->addMuonReadoutElementWithAlTransf(det.get(), xfaligncomponent, jobIndex);
822 
823 
824 
825  if (stName.find("BI") != std::string::npos) {
826  std::map<std::string, float>::const_iterator yItr = rpcYTrans.find(techname);
827  if (yItr != rpcYTrans.end())
828  det->setYTranslation(yItr->second);
829  std::map<std::string, float>::const_iterator zItr = rpcZTrans.find(techname);
830  if (zItr != rpcZTrans.end())
831  det->setZTranslation(zItr->second);
832  }
833 
834  det->fillCache(); // fill temporary cache (global position on known yet)
835  det->initDesign();
836  det->clearCache(); // clear temporary cache
837  manager->addRpcReadoutElement(std::move(det));
838 
839  } // if (lvr && RPCON && manager->rpcIdHelper()) {
840 
841  } // End big loop over components
843 
844  return ptrd;
845  }
846 
848  CscReadoutElement *re, const CscComponent *cc, const Position &ip) {
849 
850  re->m_Ssize = cc->dx1;
851  re->m_LongSsize = cc->dx2;
852  re->m_Rsize = cc->dy;
853  re->m_LongRsize = cc->dy;
854  re->m_Zsize = cc->GetThickness(mysql);
855  re->m_LongZsize = cc->GetThickness(mysql);
856  re->m_RlengthUpToMaxWidth = cc->maxwdy;
857  re->m_excent = cc->excent;
858 
859  // Csc features specific to this readout element
860  std::string tname = cc->name;
861  re->setTechnologyName(tname);
862 
863  if (ip.isAssigned) {
864  re->setStationS(ip.shift);
865  } else {
866  throw std::runtime_error(" MuonChamberLite::setCscReadoutGeom: position not found ");
867  }
868 
869  const CSC *thisc = dynamic_cast<const CSC*>(mysql.GetTechnology(tname));
870  re->m_anodecathode_distance = thisc->anocathodist;
871  re->m_ngasgaps = thisc->numOfLayers;
872  re->m_nstriplayers = thisc->numOfLayers;
873  re->m_nwirelayers = thisc->numOfLayers;
874  re->m_roxacellwidth = thisc->roxacellwith;
875  re->m_nEtastripsperlayer = thisc->nEtastrips;
876  re->m_nPhistripsperlayer = thisc->nPhistrips;
877  re->m_Etastrippitch = thisc->cathreadoutpitch;
878  re->m_Phistrippitch = thisc->phireadoutpitch;
879  re->m_Etastripwidth = re->m_Etastrippitch;
880  re->m_Phistripwidth = re->m_Phistrippitch;
881  }
882 
884  MdtReadoutElement *re, const MdtComponent *cc, const Position &ip) {
885  re->m_Ssize = cc->dx1;
886  re->m_LongSsize = cc->dx2;
887 
888  if (re->m_inBarrel) {
889  re->m_Rsize = cc->GetThickness(mysql);
890  re->m_LongRsize = cc->GetThickness(mysql);
891  re->m_Zsize = cc->dy;
892  re->m_LongZsize = cc->dy;
893  } else {
894  re->m_Rsize = cc->dy;
895  re->m_LongRsize = cc->dy;
896  re->m_Zsize = cc->GetThickness(mysql);
897  re->m_LongZsize = cc->GetThickness(mysql);
898  }
899 
900  re->m_cutoutShift = cc->cutoutTubeXShift;
901  re->m_tubelenStepSize = cc->tubelenStepSize;
902 
903  if (ip.isAssigned) {
904  re->setStationS(ip.shift);
905  } else {
906  throw std::runtime_error(" MuonChamberLite::setMdtReadoutGeom: position not found ");
907  }
908 
909  std::string tname = cc->name;
910  re->setTechnologyName(tname);
911  const MDT *thism = dynamic_cast<const MDT*>(mysql.GetTechnology(tname));
912  re->m_nlayers = thism->numOfLayers;
913  re->m_tubepitch = thism->pitch;
914  re->m_tubelayerpitch = thism->y[1] - thism->y[0];
915  re->m_endpluglength = thism->tubeEndPlugLength;
916  re->m_deadlength = cc->deadx; // thism->tubeDeadLength;
917  re->m_innerRadius = thism->innerRadius;
918  re->m_tubeWallThickness = thism->tubeWallThickness;
919 
920  if (re->m_inBarrel) {
921  re->m_ntubesperlayer = int(re->m_Zsize / re->m_tubepitch);
922  re->m_nsteps = 1; // all tubes have the same length
923  re->m_ntubesinastep = re->m_ntubesperlayer;
924  re->m_tubelength[0] = re->m_Ssize;
925  } else {
926  re->m_ntubesperlayer = int(re->m_Rsize / re->m_tubepitch);
927  re->m_nsteps = int(re->m_Rsize / re->m_tubelenStepSize);
928  re->m_ntubesinastep = int(re->m_tubelenStepSize / re->m_tubepitch);
929  re->m_tubelength[0] = re->m_Ssize;
930  double diff = (re->m_LongSsize - re->m_Ssize) * (re->m_LongRsize - re->m_tubepitch / 2.) / re->m_LongRsize;
931  for (int is = 0; is < re->m_nsteps; ++is) {
932  double len = re->m_Ssize + is * diff / re->m_nsteps;
933  re->m_tubelength[is] = len;
934  }
935  }
936 
937  for (int tl = 0; tl < re->m_nlayers; ++tl) {
938  re->m_firstwire_x[tl] = thism->x[tl];
939  re->m_firstwire_y[tl] = thism->y[tl];
940  }
941  }
942 
945  const RpcComponent *cc,
946  const Position &ip) {
947 
948  re->m_Ssize = cc->dx1;
949  re->m_LongSsize = cc->dx2;
950  re->m_Rsize = cc->GetThickness(mysql);
951  re->m_LongRsize = cc->GetThickness(mysql);
952  re->m_Zsize = cc->dy;
953  re->m_LongZsize = cc->dy;
954 
955  re->m_hasDEDontop = true;
956  if (cc->iswap == -1)
957  re->m_hasDEDontop = false;
958 
959  if (ip.isAssigned) {
960  re->setStationS(ip.shift);
961  } else {
962  ATH_MSG_ERROR( " MuonChamber::setRpcReadoutGeom: position not found " );
963  assert(0);
964  }
965 
966  std::string tname = cc->name;
967  re->setTechnologyName(tname);
968  const RPC *thisr = dynamic_cast<const RPC*>(mysql.GetTechnology(tname));
969  re->m_nphigasgaps = thisr->NGasGaps_in_s;
970  re->m_gasgapssize = re->m_Ssize / re->m_nphigasgaps - 2. * thisr->bakeliteframesize;
971  re->m_gasgapzsize = re->m_Zsize - 2. * thisr->bakeliteframesize;
972  re->m_nphistrippanels = thisr->NstripPanels_in_s;
973  re->m_phistrippitch = thisr->stripPitchS;
974  re->m_etastrippitch = thisr->stripPitchZ;
975 
976  if (re->getStationName().find("BI") != std::string::npos) {
977  re->setNumberOfLayers(3); // all BI RPCs always have 3 gas gaps
978 
979  }
980  const RPC* genericRpc = dynamic_cast<const RPC*>(mysql.GetATechnology("RPC0"));
981 
982  if (re->numberOfLayers() == 3) {
983  constexpr double rpc3GapLayerThickness = 11.8; // gas vol. + ( bakelite + graphite + PET )x2
984  for (int gasGap =1 ; gasGap <= re->numberOfLayers(); ++gasGap) {
987  re->m_gasGap_xPos[gasGap -1] = (gasGap - 2) * rpc3GapLayerThickness - 0.74;
988  }
989  } else {
990  re->m_gasGap_xPos[0] = -re->m_Rsize / 2. + thisr->externalSupPanelThickness + genericRpc->stripPanelThickness
991  + genericRpc->GasGapThickness / 2;
992  re->m_gasGap_xPos[1] = re->m_gasGap_xPos[0] + genericRpc->rpcLayerThickness +
993  genericRpc->centralSupPanelThickness;
994  if (!re->m_hasDEDontop) {
995  std::swap(re->m_gasGap_xPos[0], re->m_gasGap_xPos[1]);
996  }
997  }
998 
999  re->m_phistripwidth = re->m_phistrippitch - genericRpc->stripSeparation;
1000  re->m_etastripwidth = re->m_etastrippitch - genericRpc->stripSeparation;
1001  re->m_nphistripsperpanel = int((re->m_Ssize / re->m_nphistrippanels) / re->m_phistrippitch);
1002  if (re->getStationName().compare(0, 3, "BME") != 0) {
1003  re->m_nphistripsperpanel-=(re->m_nphistripsperpanel % 8) ;
1004  }
1005  re->m_netastripsperpanel = int((re->m_Zsize) / re->m_etastrippitch);
1006  re->m_netastripsperpanel -= (re->m_netastripsperpanel % 8);
1007 
1008  re->m_phipaneldead = re->m_Ssize / re->m_nphistrippanels -
1009  re->m_nphistripsperpanel * re->m_phistrippitch +
1010  genericRpc->stripSeparation;
1011  re->m_phipaneldead = re->m_phipaneldead / 2.;
1012  re->m_etapaneldead = re->m_Zsize - re->m_netastripsperpanel * re->m_etastrippitch + genericRpc->stripSeparation;
1013  re->m_etapaneldead = re->m_etapaneldead / 2.;
1014  re->m_phistriplength = re->m_LongZsize;
1015  re->m_etastriplength = re->m_LongSsize / re->m_nphistrippanels;
1016 
1017  re->m_first_phistrip_s[0] = -re->m_Ssize / 2. + re->m_phipaneldead + re->m_phistripwidth / 2.;
1018  if (re->m_nphistrippanels == 2) {
1019  re->m_first_phistrip_s[1] = re->m_phipaneldead + re->m_phistripwidth / 2.;
1020  }
1021 
1022  double offset = 0.;
1023  re->m_phistrip_z = -re->m_Zsize / 2. + offset + re->m_phistriplength / 2.;
1024 
1025  // first strip position on each eta panel
1026  re->m_first_etastrip_z = -re->m_Zsize / 2. + re->m_etapaneldead + re->m_etastripwidth / 2.;
1027  re->m_etastrip_s[0] = -re->m_Ssize / 2. + offset + re->m_etastriplength / 2.;
1028  if (re->m_nphistrippanels == 2) {
1029  re->m_etastrip_s[1] = re->m_Ssize / 2. - offset - re->m_etastriplength / 2.;
1030  }
1031 
1032  }
1033 
1036  const TgcComponent *cc,
1037  const Position &ip,
1038  const std::string& stName) {
1039 
1040  re->setSsize(cc->dx1);
1041  re->setLongSsize(cc->dx2);
1042  re->setRsize(cc->dy);
1043  re->setLongRsize(cc->dy);
1044  re->setZsize(cc->GetThickness(mysql));
1045  re->setLongZsize(cc->GetThickness(mysql));
1046 
1047 
1048  const TGC *genericTgc = dynamic_cast<const TGC*>(mysql.GetATechnology("TGC0"));
1049  re->setFrameThickness(genericTgc->frame_h,
1050  genericTgc->frame_ab);
1051 
1052 
1053  const std::string &tname = cc->name;
1054  int tname_index = MuonGM::strtoint(tname, 3, 2);
1055  re->setTechnologyName(tname);
1056 
1057  if (ip.isAssigned) {
1058  re->setStationS(ip.shift);
1059  } else {
1060  throw std::runtime_error(" MuonChamberLite::setTgcReadoutGeom position not found ");
1061  }
1062 
1063  re->setReadOutName(stName.substr(0, 4) + '_' + std::to_string(cc->index));
1064  re->setReadOutParams(mysql.GetTgcRPars(tname_index));
1065 
1066  const TGC *thist = dynamic_cast<const TGC*>(mysql.GetTechnology(tname));
1067  const std::size_t ncomp = (thist->materials).size();
1068 
1069  unsigned int gasGap{0};
1070  for (std::size_t i = 0; i < ncomp; ++i) {
1071  double newpos = -re->getZsize() / 2. + thist->positions[i] + thist->tck[i] / 2.;
1072 
1073  if ( thist->materials[i].find("TGCGas") != std::string::npos) {
1074  re->setPlaneZ(newpos, ++gasGap);
1075  }
1076  }
1077  }
1078 
1079  void MuonChamberLite::print() const {
1080  ATH_MSG_INFO("MuonChamberLite " << name << " :" );
1081  }
1082 } // namespace MuonGM
CscIdHelper.h
MuonGM::CbmComponent::lb_width
double lb_width
Definition: CbmComponent.h:16
MuonGM::CbmComponent::hole_pos1
double hole_pos1
Definition: CbmComponent.h:17
MuonGM::Station::hasMdts
bool hasMdts() const
Definition: Station.h:88
MuonIdHelper::stationNameIndex
int stationNameIndex(const std::string &name) const
Definition: MuonIdHelper.cxx:846
beamspotman.r
def r
Definition: beamspotman.py:674
MuonGM::RPC::bakeliteframesize
double bakeliteframesize
Definition: RPC_Technology.h:47
MuonGM::MYSQL::GetTechnology
Technology * GetTechnology(const std::string &name)
Definition: MYSQL.cxx:105
MdtReadoutElement.h
MuonGM::TGC::materials
std::vector< std::string > materials
Definition: TGC_Technology.h:20
MuonGM::StandardComponent::index
int index
Definition: StandardComponent.h:27
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
MuonGM::DetectorElement::name
std::string name
Definition: DetectorElement.h:17
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
MuonGM::MuonChamberLite::m_station
Station * m_station
Definition: MuonChamberLite.h:59
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
MuonGM::TgcComponent
Definition: TgcComponent.h:14
MuonGM::CSC::phireadoutpitch
double phireadoutpitch
Definition: CSC_Technology.h:38
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CscComponent.h
MuonGM::Station::GetExtraBottomThickness
double GetExtraBottomThickness() const
Definition: Station.cxx:155
MuonGM::MuonChamberLite::print
virtual void print() const override
Definition: MuonChamberLite.cxx:1079
MuonGM::CbmComponent
Definition: CbmComponent.h:12
MuonGM::MYSQL::allocPosFindSubtype
int allocPosFindSubtype(const std::string &statType, int fi, int zi) const
Definition: MYSQL.cxx:196
RPCON
#define RPCON
Definition: MuonChamberLite.cxx:60
MuonGM::TGC::frame_ab
double frame_ab
Definition: TGC_Technology.h:19
MuonGM::MuonChamberLite::longWidth
double longWidth
Definition: MuonChamberLite.h:37
TRTCalib_Extractor.det
det
Definition: TRTCalib_Extractor.py:36
TgcIdHelper
Definition: TgcIdHelper.h:50
MuonGM::Station::getAmdbOrigine_along_thickness
double getAmdbOrigine_along_thickness(const MYSQL &mysql) const
Definition: Station.cxx:558
MuonGM::StandardComponent::GetThickness
double GetThickness(const MYSQL &mysql) const
Definition: StandardComponent.cxx:27
hist_file_dump.d
d
Definition: hist_file_dump.py:142
MuonGM::TGC::tck
std::vector< double > tck
Definition: TGC_Technology.h:22
Rpc.h
Spacer.h
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
Muon::MuonStationIndex::stName
const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:104
MuonGM::Cutout::dx
double dx
Definition: Cutout.h:23
MuonGM::Station
Definition: Station.h:40
MuonGM::MuonChamberLite::width
double width
Definition: MuonChamberLite.h:34
MuonGM::MuonStation::setBlineFixedPointInAmdbLRS
void setBlineFixedPointInAmdbLRS(double s0, double z0, double t0)
Definition: MuonStation.cxx:65
createCablingJSON.doubletR
int doubletR
Definition: createCablingJSON.py:15
MuonGM::MDT::tubeEndPlugLength
double tubeEndPlugLength
Definition: MDT_Technology.h:22
MuonGM::RPC::stripPitchS
double stripPitchS
Definition: RPC_Technology.h:64
deg
#define deg
Definition: SbPolyhedron.cxx:17
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
MuonGM::MDT::numOfLayers
int numOfLayers
Definition: MDT_Technology.h:17
MuonGM::MuonChamberLite::m_keySet
std::set< std::string > * m_keySet
Definition: MuonChamberLite.h:63
MuonGM::MYSQL
Definition: MYSQL.h:43
MuonGM::CscComponent
Definition: CscComponent.h:11
MuonGM::RPC::NGasGaps_in_s
int NGasGaps_in_s
Definition: RPC_Technology.h:43
MuonGM::RpcReadoutElement
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/RpcReadoutElement.h:55
Csc.h
MuonGM::MDT::tubeWallThickness
double tubeWallThickness
Definition: MDT_Technology.h:23
MuonGM::MuonStation::updateBlineFixedPointInAmdbLRS
void updateBlineFixedPointInAmdbLRS()
Definition: MuonStation.cxx:86
MuonGM::CscReadoutElement
Definition: CscReadoutElement.h:56
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonGM::MYSQL::allocPosFindCutout
int allocPosFindCutout(const std::string &statType, int fi, int zi) const
Definition: MYSQL.cxx:201
RpcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
Definition: RpcIdHelper.cxx:931
MuonGM::LBI
Definition: LBI_Technology.h:13
MuonGM::MYSQL::GetStationPosition
Position GetStationPosition(const std::string &nameType, int fi, int zi) const
Definition: MYSQL.cxx:71
MuonGM::CSC::roxacellwith
double roxacellwith
Definition: CSC_Technology.h:29
RpcIdHelper
Definition: RpcIdHelper.h:51
MuonGM::DetectorElement
Definition: DetectorElement.h:15
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
MuonGM::StandardComponent
Definition: StandardComponent.h:15
RpcIdHelper.h
MuonGM::CbmComponent::lb_height
double lb_height
Definition: CbmComponent.h:15
Ded.h
Station.h
MuonGM::CSC
Definition: CSC_Technology.h:13
MuonGM::CSC::anocathodist
double anocathodist
Definition: CSC_Technology.h:23
MuonGM::CSC::nEtastrips
int nEtastrips
Definition: CSC_Technology.h:39
MuonGM::RPC::GasGapThickness
double GasGapThickness
Definition: RPC_Technology.h:45
MuonGM::MDT
Definition: MDT_Technology.h:15
MuonGM::MuonChamberLite::setCscReadoutGeom
void setCscReadoutGeom(const MYSQL &mysql, CscReadoutElement *re, const CscComponent *cc, const Position &p)
Definition: MuonChamberLite.cxx:847
TgcComponent.h
MuonGM::TGC::frame_h
double frame_h
Definition: TGC_Technology.h:18
MuonGM::MuonChamberLite::setRpcReadoutGeom
void setRpcReadoutGeom(const MYSQL &mysql, RpcReadoutElement *re, const RpcComponent *cc, const Position &p)
Definition: MuonChamberLite.cxx:943
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeoPrimitives.h
MuonGM::MdtComponent
Definition: MdtComponent.h:12
MuonGM::Component::dy
double dy
Definition: Component.h:21
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
python.BunchSpacingUtils.lb
lb
Definition: BunchSpacingUtils.py:86
useAssemblies
#define useAssemblies
Definition: MuonChamberLite.cxx:61
MuonGM::MuonChamberLite::addReadoutLayers
GeoVPhysVol * addReadoutLayers(const MYSQL &mysql, MuonDetectorManager *manager, int ieta, int iphi, bool is_mirrored, bool &isAssembly)
Definition: MuonChamberLite.cxx:106
MuonGM::Position
Definition: Position.h:11
MuonGM::MdtReadoutElement
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MdtReadoutElement.h:51
StandardComponent.h
CbmComponent.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
MuonGM::LbiComponent
Definition: LbiComponent.h:12
TGC
Definition: TgcBase.h:6
MuonGM::CbmComponent::hole_pos2
double hole_pos2
Definition: CbmComponent.h:18
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonGM::MDT::y
std::array< double, 4 > y
Definition: MDT_Technology.h:25
MuonGM::RpcComponent
Definition: RpcComponent.h:12
Cutout.h
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
RPC_Technology.h
MuonGM::MuonStation
Definition: MuonStation.h:51
MuonGM::Station::getAmdbOrigine_along_length
double getAmdbOrigine_along_length() const
Definition: Station.cxx:553
CscReadoutElement.h
MuonGM::TgcReadoutElement
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/TgcReadoutElement.h:42
BindingsTest.cut
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
Definition: BindingsTest.py:13
MuonGM::Cutout::dy
double dy
Definition: Cutout.h:24
MdtIdHelper
Definition: MdtIdHelper.h:61
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
MdtIdHelper.h
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
MuonGM::Station::GetExtraTopThickness
double GetExtraTopThickness() const
Definition: Station.cxx:151
SpacerBeam.h
MuonGM::CSC::cathreadoutpitch
double cathreadoutpitch
Definition: CSC_Technology.h:37
MuonGM::RPC::centralSupPanelThickness
double centralSupPanelThickness
Definition: RPC_Technology.h:28
MuonGM::MDT::innerRadius
double innerRadius
Definition: MDT_Technology.h:19
CSC_Technology.h
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
LBI_Technology.h
MYSQL.h
MuonGM::StandardComponent::posy
double posy
Definition: StandardComponent.h:20
MuonGM::TGC::positions
std::vector< double > positions
Definition: TGC_Technology.h:21
CscIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int chamberLayer, int wireLayer, int measuresPhi, int strip) const
Definition: CscIdHelper.cxx:706
MuonGM::MuonChamberLite::length
double length
Definition: MuonChamberLite.h:35
MdtIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
Definition: MdtIdHelper.cxx:659
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
MuonGM::MuonChamberLite::thickness
double thickness
Definition: MuonChamberLite.h:36
MuonGM::CSC::numOfLayers
int numOfLayers
Definition: CSC_Technology.h:16
LbiComponent.h
MuonGM::MDT::x
std::array< double, 4 > x
Definition: MDT_Technology.h:26
MuonGM::MuonStation::setPhysVol
void setPhysVol(const PVLink &vol)
Definition: MuonStation.cxx:397
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonDetectorManager.h
MuonGM::MuonStation::addMuonReadoutElementWithAlTransf
void addMuonReadoutElementWithAlTransf(MuonReadoutElement *a, GeoAlignableTransform *ptrsf, int jobIndex)
Definition: MuonStation.cxx:177
MDT_Technology.h
MuonGM::RPC::stripPitchZ
double stripPitchZ
Definition: RPC_Technology.h:65
MuonGM::Station::GetNrOfCutouts
int GetNrOfCutouts() const
Definition: Station.cxx:324
MuonGM::strtoint
int strtoint(std::string_view str, unsigned int istart, unsigned int length)
Definition: GlobalUtilities.cxx:37
Position.h
MuonGM::RPC::externalSupPanelThickness
double externalSupPanelThickness
Definition: RPC_Technology.h:19
Mdt.h
MuonChamberLite.h
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
MuonGM::Station::GetNrOfComponents
int GetNrOfComponents() const
Definition: Station.cxx:322
MuonGM::RPC::rpcLayerThickness
double rpcLayerThickness
Definition: RPC_Technology.h:34
CscIdHelper
Definition: CscIdHelper.h:52
MuonGM::MuonChamberLite::setMdtReadoutGeom
void setMdtReadoutGeom(const MYSQL &mysql, MdtReadoutElement *re, const MdtComponent *cc, const Position &p)
Definition: MuonChamberLite.cxx:883
MuonGM::RPC::stripPanelThickness
double stripPanelThickness
Definition: RPC_Technology.h:67
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:51
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
re
const boost::regex re(r_e)
MuonGM::MYSQL::GetATechnology
const Technology * GetATechnology(const std::string &name) const
Definition: MYSQL.cxx:162
MuonGM::RPC
Definition: RPC_Technology.h:14
MuonGM::stationPhiTGC
int stationPhiTGC(std::string_view stName, int fi, int zi_input)
Converts the AMDB phi index to the Identifier phi Index.
Definition: GlobalUtilities.cxx:44
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
MuonGM::Cutout::lengthY
double lengthY
Definition: Cutout.h:27
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
MuonGM::Station::GetCutout
Cutout * GetCutout(int i) const
Definition: Station.cxx:85
MuonGM::MYSQL::GetTgcRPars
GeoModel::TransientConstSharedPtr< TgcReadoutParams > GetTgcRPars(const std::string &name) const
Definition: MYSQL.cxx:88
createCablingJSON.doubletPhi
int doubletPhi
Definition: createCablingJSON.py:16
TgcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int gasGap, int isStrip, int channel) const
Definition: TgcIdHelper.cxx:583
TgcReadoutElement.h
TgcIdHelper.h
MuonGM::RPC::NstripPanels_in_s
int NstripPanels_in_s
Definition: RPC_Technology.h:60
python.Logging.manager
manager
Definition: PhysicsAnalysis/D3PDTools/AnaAlgorithm/python/Logging.py:92
RpcComponent.h
dqt_zlumi_alleff_HIST.tl
tl
Definition: dqt_zlumi_alleff_HIST.py:73
TGC_Technology.h
MdtComponent.h
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:23
rp
ReadCards * rp
Definition: IReadCards.cxx:26
MuonGM::MDT::pitch
double pitch
Definition: MDT_Technology.h:18
MuonGM::MuonStation::getBlineFixedPointInAmdbLRS
const Amg::Vector3D & getBlineFixedPointInAmdbLRS() const
Definition: MuonStation.cxx:81
MuonStation.h
MuonGM::Cutout
Definition: Cutout.h:14
MuonGM::buildString
std::string buildString(int i, int ncha)
Definition: GlobalUtilities.cxx:23
MuonGM::Station::GetComponent
Component * GetComponent(int i) const
Definition: Station.cxx:83
MuonGM::Station::GetName
const std::string & GetName() const
Definition: Station.cxx:110
MuonGM::Station::mdtHalfPitch
double mdtHalfPitch(const MYSQL &mysql) const
Definition: Station.cxx:343
MuonGM::RPC::stripSeparation
double stripSeparation
Definition: RPC_Technology.h:66
python.compressB64.c
def c
Definition: compressB64.py:93
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
MuonGM::LbiComponent::associated_CMIsubtype
std::string associated_CMIsubtype
Definition: LbiComponent.h:14
SupComponent.h
calibdata.tube
tube
Definition: calibdata.py:30
Tgc.h
MuonGM::MuonStation::setxAmdbCRO
void setxAmdbCRO(double xpos)
Definition: MuonStation.cxx:52
python.handimod.cc
int cc
Definition: handimod.py:522
MuonGM::MuonChamberLite::MuonChamberLite
MuonChamberLite(const MYSQL &mysql, Station *s, std::map< std::string, GeoFullPhysVol * > *mapFPV, std::map< std::string, GeoAlignableTransform * > *mapAXF)
Definition: MuonChamberLite.cxx:84
MuonGM::CSC::nPhistrips
int nPhistrips
Definition: CSC_Technology.h:40
MuonGM::MuonChamberLite::setTgcReadoutGeom
void setTgcReadoutGeom(const MYSQL &mysql, TgcReadoutElement *re, const TgcComponent *cc, const Position &p, const std::string &statname)
Definition: MuonChamberLite.cxx:1034
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
MuonGM::StandardComponent::posz
double posz
Definition: StandardComponent.h:21
RpcReadoutElement.h
Identifier
Definition: IdentifierFieldParser.cxx:14