ATLAS Offline Software
Rpc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MuonGeoModel/Rpc.h"
6 
7 #include "GaudiKernel/SystemOfUnits.h"
8 #include "GeoModelKernel/GeoCutVolAction.h"
9 #include "GeoModelKernel/GeoDefinitions.h"
10 #include "GeoModelKernel/GeoIdentifierTag.h"
11 #include "GeoModelKernel/GeoLogVol.h"
12 #include "GeoModelKernel/GeoMaterial.h"
13 #include "GeoModelKernel/GeoNameTag.h"
14 #include "GeoModelKernel/GeoPhysVol.h"
15 #include "GeoModelKernel/GeoShapeIntersection.h"
16 #include "GeoModelKernel/GeoShapeShift.h"
17 #include "GeoModelKernel/GeoShapeSubtraction.h"
18 #include "GeoModelKernel/GeoTransform.h"
19 #include "GeoModelKernel/GeoTrd.h"
20 #include "GeoModelKernel/GeoVFullPhysVol.h"
22 #include "MuonGeoModel/MYSQL.h"
24 #include "MuonGeoModel/RpcLayer.h"
26 
27 #include <cassert>
28 #include <iomanip>
29 
30 #define skip_rpc false
31 
32 namespace {
33  // make a const array holding all amdb RPC names corresponding to BI RPCs
34  const std::array<std::string, 7> biRpcs = {"RPC26", "RPC27", "RPC28", "RPC29", "RPC30", "RPC31", "RPC32"};
35  constexpr double const &rpc3GapLayerThickness = 11.8; // gas vol. + ( bakelite + graphite + PET )x2
36  constexpr double const &rpc3GapMaxThickness = 36.0; // min 35.4 (11.8x3) - max 40.0 mm (tolerance from design)
37 } // namespace
38 
39 namespace MuonGM {
40 
42 
44  double tol = 1.e-3;
46  width = s->dx1;
47  longWidth = s->dx2;
48  thickness = s->GetThickness(mysql);
49  length = s->dy - tol;
50  m_component = s;
51  idiv = s->ndivy;
52  jdiv = s->ndivz;
53  y_translation = 0;
54  z_translation = 0;
55  m_nlayers = 2;
56  // the BI RPCs are the only ones with 3 gas gaps
57  if (std::find(std::begin(biRpcs), std::end(biRpcs), ss->name) != std::end(biRpcs))
58  m_nlayers = 3;
59  }
60 
61  GeoFullPhysVol *Rpc::build(StoredMaterialManager& matManager,
62  const MYSQL& mysql,
63  int minimalgeo) {
64  std::vector<Cutout *> vcutdef;
65  int cutoutson = 0;
66  return build(matManager, mysql, minimalgeo, cutoutson, vcutdef);
67  }
68 
69  GeoFullPhysVol *Rpc::build(StoredMaterialManager& matManager,
70  const MYSQL& mysql,
71  int minimalgeo, int cutoutson,
72  const std::vector<Cutout *>& vcutdef) {
73  MsgStream log(Athena::getMessageSvc(), "MuonGM::Rpc::build");
74 
75  std::string geometry_version = mysql.getGeometryVersion();
76  const RPC *r = dynamic_cast<const RPC*>(mysql.GetTechnology(name));
77 
78  // Retrieve geometrical information, these are for middle and outer alyers ("standard" RPCs)
79  double thickness = r->maxThickness;
80  width = width / idiv;
82  length = length / jdiv;
83 
84  double extSupThick = r->externalSupPanelThickness;
85  double extAlSupThick = r->externalAlSupPanelThickness;
86  double rpcLayerThickness = r->rpcLayerThickness;
87  double centSupThick = r->centralSupPanelThickness;
88  double centAlSupThick = r->centralAlSupPanelThickness;
89 
90  // Geometrical information to be overwritten for BI chambers (having 3 gas gaps)
91  if (m_nlayers == 3) {
92  // width, longWidth, length are taken from geometry DB
93  thickness = rpc3GapMaxThickness;
94  rpcLayerThickness = rpc3GapLayerThickness;
95  }
96 
97  if (RPCprint) {
98  log << MSG::VERBOSE << " RPC build: " << name << " has thickness = " << thickness << " long width = " << longWidth << " width = " << width << " length = " << length
99  << endmsg;
100  }
101 
102  const GeoShape *srpc = new GeoTrd(thickness / 2, thickness / 2, width / 2, longWidth / 2, length / 2);
103  // Apply cutouts to mother volume
104 
105  if (cutoutson && !vcutdef.empty()) {
106  Cutout *cut = nullptr;
107  GeoShape *cutoutShape = nullptr;
108  GeoTrf::Transform3D cutTrans{GeoTrf::Transform3D::Identity()};
109  for (unsigned i = 0; i < vcutdef.size(); i++) {
110  cut = vcutdef[i];
111  cutoutShape = new GeoTrd(thickness / 2. + 1., thickness / 2. + 1., cut->widthXs / 2., cut->widthXl / 2., cut->lengthY / 2.);
112  cutTrans = GeoTrf::Translate3D(0.0, cut->dx, -length / 2 + cut->dy + cut->lengthY / 2.);
113  srpc = &(srpc->subtract((*cutoutShape) << cutTrans));
114  }
115  }
116 
117  const GeoMaterial *mrpc = matManager.getMaterial("std::Air");
118  GeoLogVol *lrpc = new GeoLogVol(logVolName, srpc, mrpc);
119  GeoFullPhysVol *prpc = new GeoFullPhysVol(lrpc);
120 
121  if (minimalgeo == 1)
122  return prpc;
123 
124  if (geometry_version.compare(0, 1,"M") != 0) {
125  // here layout P and following (hopefully!)
126  if (idiv * jdiv != 1)
127  assert(0);
128 
129  // Note: the standard RPC (iswap != -1) has DED at the top:
130  // from bottom to top it consists of the external support panel
131  // and then the RPC doublet
132 
133  double newpos = -thickness / 2.;
134 
135  // here the bottom/external/pre-bent support panel
136  // shape of the al skin of the support panel
137  GeoTrd *slpan = new GeoTrd(extSupThick / 2, extSupThick / 2, width / 2, longWidth / 2, length / 2);
138  GeoTrd *sholpan =
139  new GeoTrd(extSupThick / 2 - extAlSupThick, extSupThick / 2 - extAlSupThick, width / 2 - extAlSupThick, longWidth / 2 - extAlSupThick, length / 2 - extAlSupThick);
140  const GeoShape *sallpan = slpan;
141  const GeoShape *sholpan2 = sholpan;
142  const GeoMaterial *mallpan = matManager.getMaterial("std::Aluminium");
143  GeoLogVol *lallpan = new GeoLogVol("RPC_AL_extsuppanel", sallpan, mallpan);
144  PVRef pallpan = PVRef (new GeoPhysVol(lallpan));
145  const GeoMaterial *mholpan = matManager.getMaterial("muo::RpcAlHonC");
146  GeoLogVol *lholpan = new GeoLogVol("RPC_honeyc_extsuppanel", sholpan2, mholpan);
147  GeoPhysVol *pholpan = new GeoPhysVol(lholpan);
148  pallpan->add(pholpan); // this way the honeycomb is a child of its al skin
149 
150  // Apply cutouts
151  if (cutoutson && !vcutdef.empty()) {
152  Cutout *cut = nullptr;
153  GeoTrf::Transform3D cutTrans{GeoTrf::Transform3D::Identity()};
154  for (unsigned i = 0; i < vcutdef.size(); i++) {
155  cut = vcutdef[i];
156  GeoRef<GeoTrd> cutoutShape (new GeoTrd (thickness / 2. + 1., thickness / 2. + 1., cut->widthXs / 2., cut->widthXl / 2., cut->lengthY / 2.));
157  cutTrans = GeoTrf::Translate3D(0.0, cut->dx, -length / 2 + cut->dy + cut->lengthY / 2.);
158 
159  GeoCutVolAction cutAction(*cutoutShape, cutTrans);
160  pallpan->apply(&cutAction);
161  pallpan = PVRef (cutAction.getPV());
162  }
163  }
164 
165  if (m_nlayers == 2) { // only to be done for standard (non-BI) RPCs
166  newpos += extSupThick / 2.;
167  GeoTransform *tlpan = new GeoTransform(GeoTrf::TranslateX3D(newpos));
168  if (RPCprint) {
169  log << MSG::VERBOSE << " Rpc:: put ext.sup panel at " << newpos << " from centre" << endmsg;
170  }
171  if (!skip_rpc) {
172  prpc->add(tlpan);
173  prpc->add(pallpan);
174  }
175 
176  // The first layer is support for RPCs with 2 gaps, is a layer for 3 gaps (BI chambers, no supports)
177  newpos += extSupThick / 2.;
178  }
179 
180  // bottom RpcLayer
181  std::unique_ptr<RpcLayer> rl = std::make_unique<RpcLayer>(name, this);
182  GeoVPhysVol *plowergg;
183  if (cutoutson && !vcutdef.empty()) {
184  plowergg = rl->build(matManager, mysql, cutoutson, vcutdef);
185  } else {
186  plowergg = rl->build(matManager, mysql);
187  }
188 
189  newpos += rpcLayerThickness / 2.;
190  GeoTransform *tlgg = new GeoTransform(GeoTrf::TranslateX3D(newpos));
191  if (RPCprint) {
192  log << MSG::VERBOSE << " Rpc:: put lower RPC layer at " << newpos << " from centre " << endmsg;
193  }
194  if (!skip_rpc) {
195  prpc->add(new GeoIdentifierTag(1));
196  prpc->add(tlgg);
197  prpc->add(plowergg);
198  }
199 
200  // central support panel
201  newpos += rpcLayerThickness / 2.;
202  GeoTrd *scpan = new GeoTrd(centSupThick / 2, centSupThick / 2, width / 2, longWidth / 2, length / 2);
203  GeoTrd *shocpan = new GeoTrd(centSupThick / 2 - centAlSupThick, centSupThick / 2 - centAlSupThick, width / 2 - centAlSupThick, longWidth / 2 - centAlSupThick,
204  length / 2 - centAlSupThick);
205 
206  const GeoShape *salcpan = scpan;
207  const GeoShape *shocpan2 = shocpan;
208  GeoLogVol *lalcpan = new GeoLogVol("RPC_AL_midsuppanel", salcpan, mallpan);
209  PVRef palcpan = PVRef (new GeoPhysVol(lalcpan));
210  const GeoMaterial *mhocpan = matManager.getMaterial("muo::RpcPapHonC");
211  GeoLogVol *lhocpan = new GeoLogVol("RPC_honeyc_midsuppanel", shocpan2, mhocpan);
212  GeoPhysVol *phocpan = new GeoPhysVol(lhocpan);
213  palcpan->add(phocpan); // this way the honeycomb is a child of its al skin
214 
215  // Apply cutouts
216  if (cutoutson && !vcutdef.empty()) {
217  Cutout *cut = nullptr;
218  GeoTrf::Transform3D cutTrans{GeoTrf::Transform3D::Identity()};
219  for (unsigned i = 0; i < vcutdef.size(); i++) {
220  cut = vcutdef[i];
221  GeoRef<GeoTrd> cutoutShape (new GeoTrd (thickness / 2. + 1., thickness / 2. + 1., cut->widthXs / 2., cut->widthXl / 2., cut->lengthY / 2.));
222  cutTrans = GeoTrf::Translate3D(0.0, cut->dx, -length / 2 + cut->dy + cut->lengthY / 2.);
223 
224  GeoCutVolAction cutAction(*cutoutShape, cutTrans);
225  palcpan->apply(&cutAction);
226  palcpan = PVRef (cutAction.getPV());
227  }
228  }
229 
230  if (m_nlayers == 2) { // only to be done for standard (non-BI) RPCs
231  newpos += centSupThick / 2.;
232  GeoTransform *tcpan = new GeoTransform(GeoTrf::TranslateX3D(newpos));
233  if (RPCprint) {
234  log << MSG::VERBOSE << " Rpc:: put central sup panel at " << newpos << " from centre" << endmsg;
235  }
236  if (!skip_rpc) {
237  prpc->add(tcpan);
238  prpc->add(palcpan);
239  }
240  newpos += centSupThick / 2.;
241  }
242 
243  // top RpcLayer
244  std::unique_ptr<RpcLayer> ru = std::make_unique<RpcLayer>(name, this);
245  GeoVPhysVol *puppergg;
246  if (cutoutson && !vcutdef.empty()) {
247  // This code required to take into account the various
248  // 180 degree rotations of RPC panels in BMS chambers
249  int subtype = 0;
250  int ijob = 0;
251  for (unsigned int i = 0; i < vcutdef.size(); i++) {
252  subtype = vcutdef[i]->subtype;
253  ijob = vcutdef[i]->ijob;
254 
255  // For BMS2, BMS13
256  if (name == "RPC06" && ijob == 3) {
257  if (subtype == 2) {
258  vcutdef[i]->dy = 0;
259  } else if (subtype == 13) {
260  vcutdef[i]->dy = this->length - vcutdef[i]->lengthY;
261  }
262  }
263 
264  // For BMS5, BMS9
265  if (name == "RPC07") {
266  if (subtype == 5) { // BMS5
267  if (ijob == 24)
268  vcutdef[i]->dy = this->length - vcutdef[i]->lengthY;
269  if (ijob == 32)
270  vcutdef[i]->dy = 0.;
271  } else if (subtype == 9) { // BMS9
272  if (ijob == 32)
273  vcutdef[i]->dy = this->length - vcutdef[i]->lengthY;
274  if (ijob == 24)
275  vcutdef[i]->dy = 0.;
276  }
277  }
278 
279  // For BMS6, BMS11
280  if (subtype == 6) {
281  if (ijob == 29 && name == "RPC07")
282  vcutdef[i]->dy = this->length - vcutdef[i]->lengthY;
283  if (ijob == 21 && name == "RPC08")
284  vcutdef[i]->dy = 0;
285  } else if (subtype == 11) {
286  if (ijob == 29 && name == "RPC07")
287  vcutdef[i]->dy = 0;
288  if (ijob == 21 && name == "RPC08")
289  vcutdef[i]->dy = this->length - vcutdef[i]->lengthY - vcutdef[i]->dy;
290  }
291  }
292 
293  puppergg = ru->build(matManager, mysql, cutoutson, vcutdef);
294  } else {
295  puppergg = ru->build(matManager, mysql);
296  }
297 
298  newpos += rpcLayerThickness / 2.;
299  GeoTransform *tugg = new GeoTransform(GeoTrf::TranslateX3D(newpos));
300  if (RPCprint) {
301  log << MSG::VERBOSE << " Rpc:: put upper RPC layer at " << newpos << " from centre " << endmsg;
302  }
303  if (!skip_rpc) {
304  prpc->add(new GeoIdentifierTag(2));
305  prpc->add(tugg);
306  if (m_nlayers == 2) {
307  GeoTransform *rugg = new GeoTransform(GeoTrf::RotateY3D(180 * Gaudi::Units::deg));
308  prpc->add(rugg); // only to be done for standard (non-BI) RPCs
309  }
310  prpc->add(puppergg);
311  }
312 
313  // additional RpcLayer for BI (3 gaps)
314  if (m_nlayers == 3) {
315  newpos += rpcLayerThickness / 2.;
316  RpcLayer rthird (name, this);
317  GeoVPhysVol *pthirdgg;
318  if (cutoutson && !vcutdef.empty()) {
319  pthirdgg = rthird.build(matManager, mysql, cutoutson, vcutdef);
320  } else {
321  pthirdgg = rthird.build(matManager, mysql);
322  }
323 
324  newpos += rpcLayerThickness / 2.;
325  GeoTransform *tthirdgg = new GeoTransform(GeoTrf::TranslateX3D(newpos));
326  if (RPCprint)
327  log << MSG::VERBOSE << " Rpc:: put upper RPC layer at " << newpos << " from centre " << endmsg;
328  if (!skip_rpc) {
329  prpc->add(new GeoIdentifierTag(3));
330  prpc->add(tthirdgg);
331  prpc->add(pthirdgg);
332  }
333  }
334  }
335  return prpc;
336  }
337 
338  void Rpc::print() const {
339  MsgStream log(Athena::getMessageSvc(), "MuonGM::Rpc::build");
340  log << MSG::INFO << "Rpc " << name.c_str() << " :" << endmsg;
341  }
342 
343 } // namespace MuonGM
MuonGM::Rpc::build
GeoVFullPhysVol * build()
beamspotman.r
def r
Definition: beamspotman.py:676
MuonGM::MYSQL::GetTechnology
Technology * GetTechnology(const std::string &name)
Definition: MYSQL.cxx:105
MuonGM::MYSQL::getGeometryVersion
std::string getGeometryVersion() const
Definition: MYSQL.cxx:258
MuonGM::DetectorElement::name
std::string name
Definition: DetectorElement.h:17
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
GeoRef.h
Simple smart-pointer class for GeoModel objects.
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
MuonGM::Rpc::m_component
RpcComponent * m_component
Definition: Rpc.h:46
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
MuonGM::Rpc::thickness
double thickness
Definition: Rpc.h:26
MuonGM::Rpc::width
double width
Definition: Rpc.h:24
MuonGM::Rpc::y_translation
float y_translation
Definition: Rpc.h:30
MuonGM::Rpc::jdiv
double jdiv
Definition: Rpc.h:29
Rpc.h
MuonGM::Rpc::Rpc
Rpc(const MYSQL &mysql, Component *s)
Definition: Rpc.cxx:43
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skip_rpc
#define skip_rpc
Definition: Rpc.cxx:30
deg
#define deg
Definition: SbPolyhedron.cxx:17
MuonGM::RpcLayer
Definition: RpcLayer.h:22
MuonGM::MYSQL
Definition: MYSQL.h:43
MuonGM::Rpc::z_translation
float z_translation
Definition: Rpc.h:31
MuonGM::RpcLayer::build
GeoVPhysVol * build(StoredMaterialManager &matManager, const MYSQL &mysql)
Definition: RpcLayer.cxx:41
MuonGM::DetectorElement
Definition: DetectorElement.h:15
RPCprint
#define RPCprint
Definition: DBReader.h:106
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
MuonGM::Component
Definition: Component.h:11
lumiFormat.i
int i
Definition: lumiFormat.py:92
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
MuonGM::RpcComponent
Definition: RpcComponent.h:12
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
RPC_Technology.h
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
MYSQL.h
MuonGM::Rpc::idiv
double idiv
Definition: Rpc.h:28
RpcLayer.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
MuonGM::Rpc::m_nlayers
unsigned int m_nlayers
Definition: Rpc.h:47
PlotCalibFromCool.rl
rl
Definition: PlotCalibFromCool.py:529
MuonGM::RPC
Definition: RPC_Technology.h:14
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
StoredMaterialManager
This class holds one or more material managers and makes them storeable, under StoreGate.
Definition: StoredMaterialManager.h:28
MuonGM::DetectorElement::logVolName
std::string logVolName
Definition: DetectorElement.h:18
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
MuonGM::Rpc::longWidth
double longWidth
Definition: Rpc.h:27
MuonGM::Cutout
Definition: Cutout.h:14
MuonGM::PVRef
GeoRef< GeoPhysVol > PVRef
Definition: Rpc.cxx:41
MuonGM::Rpc::print
virtual void print() const override
Definition: Rpc.cxx:338
subproc.subtype
string subtype
Definition: subproc.py:19
GeoRef
GeoIntrusivePtr< T > GeoRef
Definition: GeoRef.h:20
MuonGM::Rpc::length
double length
Definition: Rpc.h:25