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