ATLAS Offline Software
Loading...
Searching...
No Matches
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
28namespace {
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
37namespace 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
#define endmsg
#define RPCprint
Definition DBReader.h:106
double length(const pvec &v)
const double width
DetectorElement(const std::string &n)
Technology * GetTechnology(const std::string &name)
Definition MYSQL.cxx:105
virtual void print() const override
Definition RpcLayer.cxx:303
RpcLayer(const std::string &s, Rpc *t)
Definition RpcLayer.cxx:39
double thickness
Definition RpcLayer.h:27
PVLink build(StoredMaterialManager &matManager, const MYSQL &mysql)
Definition RpcLayer.cxx:41
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
singleton-like access to IMessageSvc via open function and helper
int r
Definition globals.cxx:22
IMessageSvc * getMessageSvc(bool quiet=false)
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
std::string buildString(int i, int ncha)