ATLAS Offline Software
RpcLayer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
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/GeoShapeSubtraction.h" // for cutouts
16 #include "GeoModelKernel/GeoTransform.h"
17 #include "GeoModelKernel/GeoTrd.h"
18 #include "MuonGeoModel/Cutout.h"
19 #include "MuonGeoModel/MYSQL.h"
21 #include "MuonGeoModel/Rpc.h"
23 
24 #include <TString.h> // for Form
25 #include <iomanip>
26 #include <utility>
27 
28 namespace {
29  constexpr double const rpc3GapLayerThickness = 11.8; // gas vol. + ( bakelite + graphite + PET )x2
30  constexpr double const rpc3GapStrPanThickness = 3.5;
31  constexpr double const rpc3GapStrPanCopThickness = 0.3;
32  constexpr double const rpc3GapBakelThickness = 1.2;
33  constexpr double const rpc3GapGThickness = 1.0;
34  constexpr double const rpc3GapTotAirThickness = 0.52; // corresponds to PET+glue, which are not simulated?
35 } // namespace
36 
37 namespace MuonGM {
38 
39  RpcLayer::RpcLayer(const std::string& s, Rpc *t) : DetectorElement(s) { m = t; }
40 
41  GeoVPhysVol *RpcLayer::build(StoredMaterialManager& matManager,
42  const MYSQL& mysql) {
43  std::vector<Cutout *> vcutdef;
44  int cutoutson = 0;
45  return build(matManager, mysql, cutoutson, vcutdef);
46  }
47 
48  GeoVPhysVol *RpcLayer::build(StoredMaterialManager& matManager,
49  const MYSQL& mysql,
50  int cutoutson,
51  const std::vector<Cutout *>& vcutdef) {
52  MsgStream log(Athena::getMessageSvc(), "MuGM::GeoVPhysVol::build");
53 
54  double eps = 0.000001;
55  double tol = 1.e-6;
56 
57  const RPC *r = dynamic_cast<const RPC*>(mysql.GetTechnology(name));
58 
59  if (m->nGasGaps() == 3 && r->NstripPanels_in_s != 1)
60  throw std::runtime_error(Form("File: %s, Line: %d\nRpcLayer::build() - NstripPanels_in_s = %d for BI RPC, not possible", __FILE__, __LINE__, r->NstripPanels_in_s));
61 
62  double thickness = r->rpcLayerThickness - tol;
63  if (m->nGasGaps() == 3)
64  thickness = rpc3GapLayerThickness - tol; // for BI RPCs
65  double length = m->length;
66  double width = m->width;
67 
68  if (RPCprint) {
69  log << MSG::VERBOSE << " RpcLayer: building an RPC layer with width = " << width << " length = " << length << " and thickness = " << thickness << endmsg;
70  }
71 
72  const GeoShape *srpcl = new GeoTrd(thickness / 2, thickness / 2, width / 2, width / 2, length / 2);
73  const GeoMaterial *mrpcl = matManager.getMaterial("std::Air");
74  GeoLogVol *lrpcl = new GeoLogVol("Rpclayer", srpcl, mrpcl);
75  GeoPhysVol *prpcl = new GeoPhysVol(lrpcl);
76 
77  double newpos = -thickness / 2.;
78 
79  // phi strip panel(s)
80  double strpanThickness = r->stripPanelThickness - tol;
81  double strpanCopperThickness = r->stripPanelCopperSkinThickness;
82  if (m->nGasGaps() == 3) { // for BI RPCs
83  strpanThickness = rpc3GapStrPanThickness - tol;
84  strpanCopperThickness = rpc3GapStrPanCopThickness;
85  }
86  double strpanLength = length / r->NstripPanels_in_z;
87  double strpanWidth = width / r->NstripPanels_in_s - eps;
88  if (RPCprint) {
89  log << MSG::VERBOSE << " RpcLayer:: Building a strip panel:: div_s, div_z = " << r->NstripPanels_in_s << " " << r->NstripPanels_in_z << endmsg;
90  }
91  if (RPCprint) {
92  log << MSG::VERBOSE << " RpcLayer:: Building a strip panel:: w,l,t = " << strpanWidth << " " << strpanLength << " " << strpanThickness << endmsg;
93  }
94  GeoTrd *sstrpan = new GeoTrd(strpanThickness / 2., strpanThickness / 2., strpanWidth / 2., strpanWidth / 2., strpanLength / 2.);
95 
96  GeoTrd *sfoamstrpan = new GeoTrd(strpanThickness / 2. - strpanCopperThickness, strpanThickness / 2. - strpanCopperThickness, strpanWidth / 2. - strpanCopperThickness,
97  strpanWidth / 2. - strpanCopperThickness, strpanLength / 2. - strpanCopperThickness);
98  const GeoShape *scustrpan = sstrpan;
99 
100  const auto *stripMaterial = matManager.getMaterial("muo::RpcFoam");
101  if (m->nGasGaps() == 3) { // for BI RPCs
102  stripMaterial = matManager.getMaterial("muo::Forex");
103  }
104 
105  GeoLogVol *lcustrpan = new GeoLogVol("RPC_StripPanelCuSkin", scustrpan, matManager.getMaterial("std::Copper"));
106  GeoLogVol *lfoamstrpan = new GeoLogVol("RPC_StripPanelFoam", sfoamstrpan, stripMaterial);
107 
108  newpos += strpanThickness / 2. + tol / 2.;
109  GeoPhysVol *pcustrpan11 = new GeoPhysVol(lcustrpan);
110  GeoPhysVol *pfoamstrpan11 = new GeoPhysVol(lfoamstrpan);
111  GeoTransform *tx = new GeoTransform(GeoTrf::TranslateX3D(newpos));
112  GeoTransform *ty1;
113  GeoTransform *ty2;
114 
115  if (r->NstripPanels_in_s == 2) {
116  if (RPCprint) {
117  log << MSG::VERBOSE << " RpcLayer::NstripPanels_in_s == 2 " << endmsg;
118  }
119  GeoPhysVol *pcustrpan12 = new GeoPhysVol(lcustrpan);
120  GeoPhysVol *pfoamstrpan12 = new GeoPhysVol(lfoamstrpan);
121  ty1 = new GeoTransform(GeoTrf::TranslateY3D(-width / 4.));
122  ty2 = new GeoTransform(GeoTrf::TranslateY3D(width / 4.));
123  prpcl->add(tx);
124  prpcl->add(ty1);
125  if (RPCprint) {
126  log << MSG::VERBOSE << "RpcLayer:: Locating the 1st phi strip panel at x, y " << newpos << " " << -width / 4. << " of width =" << strpanWidth
127  << " in a box of width =" << width << endmsg;
128  }
129  prpcl->add(pcustrpan11);
130  pcustrpan11->add(pfoamstrpan11);
131  prpcl->add(tx);
132  prpcl->add(ty2);
133  if (RPCprint) {
134  log << MSG::VERBOSE << "RpcLayer:: Locating the 2nd phi strip panel at x, y " << newpos << " " << width / 4. << " of width =" << strpanWidth
135  << " in a box of width =" << width << endmsg;
136  }
137  prpcl->add(pcustrpan12);
138  pcustrpan12->add(pfoamstrpan12);
139 
140  } else if (r->NstripPanels_in_s == 1) {
141  if (RPCprint) {
142  log << MSG::VERBOSE << " RpcLayer::NstripPanels_in_s == 1 " << endmsg;
143  }
144  prpcl->add(tx);
145  prpcl->add(pcustrpan11);
146  pcustrpan11->add(pfoamstrpan11);
147  if (RPCprint) {
148  log << MSG::VERBOSE << " RpcLayer:: Locating a single phi strip panel at x, y " << newpos << " 0 "
149  << " of width = " << strpanWidth << " in a box of width = " << width << endmsg;
150  }
151  }
152 
153  newpos += strpanThickness / 2.;
154  double bakelThickness = r->bakeliteThickness;
155  double gThickness = r->gasThickness;
156  double totAirThickness = r->totalAirThickness;
157  if (m->nGasGaps() == 3) { // for BI RPCs
158  bakelThickness = rpc3GapBakelThickness;
159  gThickness = rpc3GapGThickness;
160  totAirThickness = rpc3GapTotAirThickness;
161  }
162 
163  double ggThickness = 2. * bakelThickness + gThickness + totAirThickness;
164  newpos += ggThickness / 2.;
165  // this brings to the center of the gas gap
166 
167  double ggLength = length;
168  double ggWidth = width / r->NGasGaps_in_s - eps;
169  double gasLength = ggLength - 2. * r->bakeliteframesize;
170  double gasWidth = ggWidth - 2. * r->bakeliteframesize;
171 
172  if (m->nGasGaps() == 3) { // for BI RPCs
173  if (name == "RPC26") { // big RPC7
174  gasLength = ggLength - 93.25; // ggLength - deadframesizeEta
175  gasWidth = ggWidth - 109.52; // ggWidth - deadframesizePhi
176  } else if (name == "RPC27") { // small RPC7
177  gasLength = ggLength - 93.12; // ggLength - deadframesizeEta
178  gasWidth = ggWidth - 109.52; // ggWidth - deadframesizePhi
179  } else if (name == "RPC28") { // big RPC8
180  gasLength = ggLength - 93.04; // ggLength - deadframesizeEta
181  gasWidth = ggWidth - 109.52; // ggWidth - deadframesizePhi
182  } else if (name == "RPC29") { // small RPC8
183  gasLength = ggLength - 93.04; // ggLength - deadframesizeEta
184  gasWidth = ggWidth - 109.2; // ggWidth - deadframesizePhi
185  }
186  }
187 
188  if (RPCprint) {
189  log << MSG::VERBOSE << "RpcLayer:: Building the gasgap:: " << r->NGasGaps_in_s << " in s direction" << endmsg;
190  log << MSG::VERBOSE << "RpcLayer:: Building the gasgap:: w,l,t " << ggWidth << " " << ggLength << " " << ggThickness << endmsg;
191  log << MSG::VERBOSE << "RpcLayer:: Building the gas:: w,l,t " << gasWidth << " " << gasLength << " " << gThickness << endmsg;
192  }
193  GeoTrd *sgg = new GeoTrd(ggThickness / 2., ggThickness / 2., ggWidth / 2., ggWidth / 2., ggLength / 2.);
194  GeoTrd *sgas = new GeoTrd(gThickness / 2., gThickness / 2., gasWidth / 2., gasWidth / 2., gasLength / 2.);
195  const GeoShape *sbak = sgg;
196  GeoLogVol *lbak = new GeoLogVol("gas volume:" + MuonGM::buildString(r->NGasGaps_in_s, 0) + "gg_in_s_" + MuonGM::buildString(r->NstripPanels_in_s, 0) + "sp_in_s", sbak,
197  matManager.getMaterial("std::Bakelite"));
198  GeoLogVol *lgas = new GeoLogVol("gazGap", sgas, matManager.getMaterial("muo::RPCgas"));
199  GeoPhysVol *pbak1 = new GeoPhysVol(lbak);
200  GeoPhysVol *pgas1 = new GeoPhysVol(lgas);
201  tx = new GeoTransform(GeoTrf::TranslateX3D(newpos));
202 
203  if (r->NGasGaps_in_s == 2) {
204  GeoPhysVol *pbak2 = new GeoPhysVol(lbak);
205  GeoPhysVol *pgas2 = new GeoPhysVol(lgas);
206  ty1 = new GeoTransform(GeoTrf::TranslateY3D(-width / 4.));
207  ty2 = new GeoTransform(GeoTrf::TranslateY3D(width / 4.));
208  prpcl->add(tx);
209  prpcl->add(ty1);
210  if (RPCprint) {
211  log << MSG::VERBOSE << "RpcLayer:: put 1st gas gap centre at depth, s " << newpos << " " << -width / 4. << endmsg;
212  }
213  prpcl->add(new GeoIdentifierTag(0));
214  prpcl->add(pbak1);
215  pbak1->add(new GeoIdentifierTag(1));
216  pbak1->add(pgas1);
217  prpcl->add(tx);
218  prpcl->add(ty2);
219  if (RPCprint) {
220  log << MSG::VERBOSE << "RpcLayer:: put 2nd gas gap centre at depth, s " << newpos << " " << width / 4. << endmsg;
221  }
222  prpcl->add(new GeoIdentifierTag(10));
223  prpcl->add(pbak2);
224  pbak2->add(new GeoIdentifierTag(1));
225  pbak2->add(pgas2);
226  } else if (r->NGasGaps_in_s == 1) {
227  prpcl->add(tx);
228  if (m->nGasGaps() == 3) { // for BI RPCs
229  GeoTransform *ty = new GeoTransform(GeoTrf::TranslateY3D(m->y_translation));
230  GeoTransform *tz = new GeoTransform(GeoTrf::TranslateZ3D(m->z_translation));
231  prpcl->add(ty);
232  prpcl->add(tz);
233  }
234  prpcl->add(new GeoIdentifierTag(0));
235  prpcl->add(pbak1);
236  if (RPCprint) {
237  log << MSG::VERBOSE << "RpcLayer:: put a single gas gap at depth, s " << newpos << " 0 " << endmsg;
238  }
239  pbak1->add(new GeoIdentifierTag(1));
240  pbak1->add(pgas1);
241  }
242 
243  newpos += ggThickness / 2.;
244 
245  // now eta strip panel
246  newpos += strpanThickness / 2.;
247 
248  GeoPhysVol *pcustrpan21 = new GeoPhysVol(lcustrpan);
249  GeoPhysVol *pfoamstrpan21 = new GeoPhysVol(lfoamstrpan);
250  tx = new GeoTransform(GeoTrf::TranslateX3D(newpos));
251 
252  if (r->NstripPanels_in_s == 2) {
253  GeoPhysVol *pcustrpan22 = new GeoPhysVol(lcustrpan);
254  GeoPhysVol *pfoamstrpan22 = new GeoPhysVol(lfoamstrpan);
255  ty1 = new GeoTransform(GeoTrf::TranslateY3D(-width / 4.));
256  ty2 = new GeoTransform(GeoTrf::TranslateY3D(width / 4.));
257  prpcl->add(tx);
258  prpcl->add(ty1);
259  if (RPCprint) {
260  log << MSG::VERBOSE << "RpcLayer:: Locating the 1st eta panel at x, y " << newpos << " " << -width / 4. << " of width =" << strpanWidth
261  << " in a box of width =" << width << endmsg;
262  }
263  prpcl->add(pcustrpan21);
264  pcustrpan21->add(pfoamstrpan21);
265  prpcl->add(tx);
266  prpcl->add(ty2);
267  if (RPCprint) {
268  log << MSG::VERBOSE << "RpcLayer:: Locating the 2nd eta panel at x, y " << newpos << " " << width / 4. << " of width =" << strpanWidth
269  << " in a box of width =" << width << endmsg;
270  }
271  prpcl->add(pcustrpan22);
272  pcustrpan22->add(pfoamstrpan22);
273  } else if (r->NstripPanels_in_s == 1) {
274  prpcl->add(tx);
275  if (RPCprint) {
276  log << MSG::VERBOSE << "RpcLayer:: Locating a single eta panel at x, y " << newpos << " 0 " << endmsg;
277  }
278  prpcl->add(pcustrpan21);
279  pcustrpan21->add(pfoamstrpan21);
280  }
281 
282  // Apply cutouts
283  if (cutoutson && !vcutdef.empty()) {
284  GeoPhysVol *tempPhys = nullptr;
285  Cutout *cut = nullptr;
286  GeoShape *cutoutShape = nullptr;
287  GeoTrf::Transform3D cutTrans{GeoTrf::Transform3D::Identity()};
288 
289  for (unsigned i = 0; i < vcutdef.size(); i++) {
290  cut = vcutdef[i];
291  cutoutShape = new GeoTrd(thickness / 2. + 1., thickness / 2. + 1., cut->widthXs / 2. + 0.5, cut->widthXl / 2. + 0.5, cut->lengthY / 2. + tol);
292  cutTrans = GeoTrf::Translate3D(0.0, cut->dx, -length / 2 + cut->dy + cut->lengthY / 2.);
293 
294  GeoIntrusivePtr<GeoVPhysVol> volToCut{prpcl};
295  GeoCutVolAction cutAction(*cutoutShape, cutTrans);
296  volToCut->apply(&cutAction);
297  tempPhys = cutAction.getPV();
298  prpcl = tempPhys;
299  }
300  }
301 
302  return prpcl;
303  }
304 
305  void RpcLayer::print() const {
306  MsgStream log(Athena::getMessageSvc(), "MuGM::GeoVPhysVol");
307  log << MSG::INFO << " Rpc Layer " << name + "Layer"
308  << " :" << endmsg;
309  }
310 
311 } // namespace MuonGM
beamspotman.r
def r
Definition: beamspotman.py:676
MuonGM::MYSQL::GetTechnology
Technology * GetTechnology(const std::string &name)
Definition: MYSQL.cxx:105
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
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
MuonGM::Rpc::width
double width
Definition: Rpc.h:24
MuonGM::Rpc::y_translation
float y_translation
Definition: Rpc.h:30
MuonGM::RpcLayer::RpcLayer
RpcLayer(const std::string &s, Rpc *t)
Definition: RpcLayer.cxx:39
Rpc.h
MuonGM::Rpc::nGasGaps
unsigned int nGasGaps() const
Definition: Rpc.h:49
MuonGM::MYSQL
Definition: MYSQL.h:43
MuonGM::Rpc::z_translation
float z_translation
Definition: Rpc.h:31
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
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
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
Cutout.h
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
MuonGM::RpcLayer::thickness
double thickness
Definition: RpcLayer.h:27
GlobalUtilities.h
MYSQL.h
RpcLayer.h
MuonGM::RpcLayer::print
virtual void print() const override
Definition: RpcLayer.cxx:305
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
MuonGM::RpcLayer::m
Rpc * m
Definition: RpcLayer.h:30
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
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
MuonGM::Cutout
Definition: Cutout.h:14
MuonGM::Rpc
Definition: Rpc.h:21
MuonGM::buildString
std::string buildString(int i, int ncha)
Definition: GlobalUtilities.cxx:23
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
TileDCSDataPlotter.tx
tx
Definition: TileDCSDataPlotter.py:878
MuonGM::Rpc::length
double length
Definition: Rpc.h:25