ATLAS Offline Software
Loading...
Searching...
No Matches
sTGC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MuonGeoModel/sTGC.h"
6
11#include "GeoModelKernel/GeoFullPhysVol.h"
12#include "GeoModelKernel/GeoIdentifierTag.h"
13#include "GeoModelKernel/GeoLogVol.h"
14#include "GeoModelKernel/GeoNameTag.h"
15#include "GeoModelKernel/GeoPhysVol.h"
16#include "GeoModelKernel/GeoSerialIdentifier.h"
17#include "GeoModelKernel/GeoShapeShift.h"
18#include "GeoModelKernel/GeoShapeSubtraction.h"
19#include "GeoModelKernel/GeoSimplePolygonBrep.h"
20#include "GeoModelKernel/GeoTransform.h"
21#include "GeoModelKernel/GeoTrd.h"
27
28#include <GaudiKernel/IMessageSvc.h>
29#include <GaudiKernel/MsgStream.h>
30#include <GeoModelKernel/GeoDefinitions.h>
31#include <GeoModelKernel/GeoShape.h>
32#include <cmath>
33#include <string>
34
35class GeoMaterial;
36
37namespace MuonGM {
38
39 // Get sTGC components for the trapezoidal shape of the quadruplet
41 sTGCComponent *s = static_cast<sTGCComponent *>(ss);
42 m_component = s;
43 width = s->dx1;
44 longWidth = s->dx2;
45 yCutout = s->yCutout;
46 yCutoutCathode = s->yCutoutCathode;
47 length = s->dy;
48 name = s->name;
49 index = s->index;
50 }
51
52 GeoFullPhysVol *sTGC::build(StoredMaterialManager& matManager,
53 int minimalgeo) {
54 std::vector<Cutout *> vcutdef;
55 int cutoutson = 0;
56 return build(matManager, minimalgeo, cutoutson, vcutdef);
57 }
58
59 // Start building the physical volume of the quadruplet
60 GeoFullPhysVol *sTGC::build(StoredMaterialManager& matManager,
61 int minimalgeo, int,
62 const std::vector<Cutout *>&) {
63 sTGCDetectorHelper stgcHelper;
65 AGDDDetectorStore& ds = c->GetDetectorStore();
66 sTGCDetectorDescription *stgc_descr = stgcHelper.Get_sTGCDetectorSubType(m_component->subType);
67
68 sTGC_Technology *t = static_cast<sTGC_Technology *>(ds.GetTechnology(name));
69 thickness = t->Thickness();
70 double gasTck = t->gasThickness;
71 // Defining PCB thickness based on quadruplet type
72 bool isQS1 = (m_component->subType == "QS1P" || m_component->subType == "QS1C");
73 bool isQL1 = (m_component->subType == "QL1P" || m_component->subType == "QL1C");
74 double pcbTck = (isQS1 || isQL1) ? t->pcbThickness150 : t->pcbThickness200;
75 // Resolves backward compatibility issues where pcbTck150 and pcbTck200
76 // Are not defined in previous XML versions
77 if(pcbTck == 0)
78 pcbTck = t->pcbThickness;
79
80 double coverTck = t->coverThickness;
81 double f4 = stgc_descr->ylFrame();
82 double f5 = stgc_descr->ysFrame();
83 double f6 = stgc_descr->xFrame();
84
85 // Evaluate honeycomb thickness
86 double chamberTck = gasTck + pcbTck; // Note: pcbTck is the xml value and is the combined thickness of 2 pcbs.
87 double honeycombTck = (thickness - 4 * chamberTck - 2 * coverTck) / 5;
88 double pcbActualTck = pcbTck / 2;
89
90 minimalgeo = t->geoLevel;
91
92 // Build sTGC mother volume out of honeycomb material
93 GeoSimplePolygonBrep *solid;
94 solid = new GeoSimplePolygonBrep(thickness / 2.);
95 solid->addVertex(longWidth / 2., length / 2.);
96 solid->addVertex(-longWidth / 2., length / 2.);
97 if (yCutout)
98 solid->addVertex(-longWidth / 2., length / 2. - yCutout);
99 solid->addVertex(-width / 2., -length / 2.);
100 solid->addVertex(width / 2., -length / 2.);
101 if (yCutout)
102 solid->addVertex(longWidth / 2., length / 2. - yCutout);
103
104 // Transform the mother volume to the correct position
105 GeoTrf::Transform3D rot = GeoTrf::RotateZ3D(M_PI / 2.) * GeoTrf::RotateX3D(M_PI / 2.);
106 const GeoShape *strd = new GeoShapeShift(solid, rot);
107
109 if (!(m_component->subType).empty())
110 logVolName += ("-" + m_component->subType);
111 const GeoMaterial *mtrd = matManager.getMaterial("muo::Honeycomb");
112 GeoLogVol *ltrd = new GeoLogVol(logVolName, strd, mtrd);
113 GeoFullPhysVol *ptrd = new GeoFullPhysVol(ltrd);
114
115 if (!minimalgeo)
116 return ptrd;
117
118 double newpos = -thickness / 2.;
119 ptrd->add(new GeoSerialIdentifier(0));
120
121 int igl = 0;
122
123 // Loop over sTGC layers
124 for (int i = 0; i < t->nlayers; i++) {
125 double widthActive;
126 double longWidthActive;
127 double lengthActive;
128
129 igl++;
130 ptrd->add(new GeoIdentifierTag(igl));
131
132 widthActive = width;
133 longWidthActive = longWidth;
134 lengthActive = length;
135
136 double newXPos;
137 double pcbpos;
138 if (i == 0)
139 newXPos = newpos + chamberTck / 2 + honeycombTck + coverTck;
140 else
141 newXPos = newpos + chamberTck + honeycombTck;
142
143 // Build chamber volume (gas + pcb) out of gas
144 GeoSimplePolygonBrep *sGasVolume = new GeoSimplePolygonBrep(chamberTck / 2.);
145 sGasVolume->addVertex(longWidthActive / 2., lengthActive / 2.);
146 sGasVolume->addVertex(-longWidthActive / 2., lengthActive / 2.);
147 if (yCutout)
148 sGasVolume->addVertex(-longWidthActive / 2., lengthActive / 2. - yCutout);
149 sGasVolume->addVertex(-widthActive / 2., -lengthActive / 2.);
150 sGasVolume->addVertex(widthActive / 2., -lengthActive / 2.);
151 if (yCutout)
152 sGasVolume->addVertex(longWidthActive / 2., lengthActive / 2. - yCutout);
153
154 // Transform gas volume
155 GeoTrf::Transform3D rot = GeoTrf::RotateZ3D(M_PI / 2.) * GeoTrf::RotateX3D(M_PI / 2.);
156 const GeoShape *sGasVolume1 = new GeoShapeShift(sGasVolume, rot);
157 GeoLogVol *ltrdgas = new GeoLogVol("sTGC_Sensitive", sGasVolume1, matManager.getMaterial("muo::TGCGas"));
158 GeoPhysVol *ptrdgas = new GeoPhysVol(ltrdgas);
159 GeoNameTag *gastag = new GeoNameTag(name + "muo::TGCGas");
160 GeoTransform *chamberpos = new GeoTransform(GeoTrf::TranslateX3D(newXPos));
161
162 // Build two pcb volumes and add them to the gas at -chamberTck/2 and at +chamberTck/2
163 for (int i = 0; i < 2; i++) {
164 if (i == 0) {
165 // This becomes the zero reference point for the pcb at -chamberTck/2
166 pcbpos = -chamberTck / 2 + pcbActualTck / 2;
167 } else {
168 // This becomes the zero reference point for the pcb at +chamberTck/2. Alternatively,
169 // we can say pcbpos = +chamberTck/2 - pcbActualTck/2 ???
170 pcbpos = -chamberTck / 2 + pcbActualTck + gasTck + pcbActualTck / 2;
171 }
172
173 // Build pcb volume out of G10 material
174 GeoSimplePolygonBrep *sPcbVolume = new GeoSimplePolygonBrep(pcbActualTck / 2.);
175 sPcbVolume->addVertex(longWidthActive / 2., lengthActive / 2.);
176 sPcbVolume->addVertex(-longWidthActive / 2., lengthActive / 2.);
177 if (yCutout)
178 sPcbVolume->addVertex(-longWidthActive / 2., lengthActive / 2. - yCutout);
179 sPcbVolume->addVertex(-widthActive / 2., -lengthActive / 2.);
180 sPcbVolume->addVertex(widthActive / 2., -lengthActive / 2.);
181 if (yCutout)
182 sPcbVolume->addVertex(longWidthActive / 2., lengthActive / 2. - yCutout);
183
184 // Transform PCB volume
185 GeoTrf::Transform3D rott = GeoTrf::RotateZ3D(M_PI / 2.) * GeoTrf::RotateX3D(M_PI / 2.);
186 const GeoShape *sPcbVolume1 = new GeoShapeShift(sPcbVolume, rott);
187
188 const GeoMaterial *mtrdC = matManager.getMaterial("std::G10");
189 GeoLogVol *ltrdC = new GeoLogVol(logVolName, sPcbVolume1, mtrdC);
190 GeoPhysVol *ptrdPcb = new GeoPhysVol(ltrdC);
191 GeoNameTag *ntrdtmpC = new GeoNameTag(name + "std::G10");
192
193 GeoTransform *ttrdtmpC = new GeoTransform(GeoTrf::TranslateX3D(pcbpos));
194
195 // Place pcb volume inside chamber volume
196 ptrdgas->add(ntrdtmpC); // nametag
197 ptrdgas->add(ttrdtmpC); // shift
198 ptrdgas->add(ptrdPcb); // volume
199 } // Close loop on pcb volumes
200
201 // Place chamber volume inside the mother volume (honeycomb volume)
202 ptrd->add(gastag);
203 ptrd->add(chamberpos);
204 ptrd->add(ptrdgas);
205
206 // Cutouts
207 if (!yCutout) {
208 double lW = longWidth / 2. - ((longWidth - width) / 2.) * f4 / length;
209 double W = width / 2. + ((longWidth - width) / 2.) * f5 / length;
210 const GeoShape *trd1 = new GeoTrd(gasTck / 2, gasTck / 2, width / 2, longWidth / 2, length / 2);
211 const GeoShape *trd2 = new GeoTrd(gasTck, gasTck, W - f6, lW - f6, length / 2 - (f4 + f5) / 2.);
212 GeoTrf::Translate3D c(0, 0, (f5 - f4) / 2.);
213 trd1 = &(trd1->subtract((*trd2) << c));
214 GeoLogVol *ltrdframe = new GeoLogVol("sTGC_Frame", trd1, matManager.getMaterial("std::Aluminium"));
215 GeoPhysVol *ptrdframe = new GeoPhysVol(ltrdframe);
216
217 ptrdgas->add(ptrdframe);
218 } else {
219 double W = width / 2. + ((longWidth - width) / 2.) * f5 / (length);
220 // This describes the active area
221 GeoSimplePolygonBrep *sGasV = new GeoSimplePolygonBrep(gasTck / 2.);
222 sGasV->addVertex(longWidthActive / 2. - f6, lengthActive / 2. - f4);
223 sGasV->addVertex(-longWidthActive / 2. + f6, lengthActive / 2. - f4);
224 sGasV->addVertex(-longWidthActive / 2. + f6, lengthActive / 2. - f4 - yCutoutCathode);
225 sGasV->addVertex(-W + f6, -lengthActive / 2. + f5);
226 sGasV->addVertex(W - f6, -lengthActive / 2. + f5);
227 sGasV->addVertex(longWidthActive / 2. - f6, lengthActive / 2. - f4 - yCutoutCathode);
228
229 // This describes the enveloppe (active area + frames)
230 GeoSimplePolygonBrep *sGasV2 = new GeoSimplePolygonBrep(gasTck / 2.);
231 sGasV2->addVertex(longWidth / 2., length / 2.);
232 sGasV2->addVertex(-longWidth / 2., length / 2.);
233 sGasV2->addVertex(-longWidth / 2., length / 2. - yCutout);
234 sGasV2->addVertex(-width / 2., -length / 2.);
235 sGasV2->addVertex(width / 2., -length / 2.);
236 sGasV2->addVertex(longWidth / 2., length / 2. - yCutout);
237
238 // define the final geo shapes
239 const GeoShape *sGasV1 = new GeoShapeShift(sGasV, rot);
240 const GeoShape *sGasV3 = new GeoShapeShift(sGasV2, rot);
241 // Remove active from active+frames to only get frames
242 sGasV3 = &(sGasV3->subtract((*sGasV1)));
243
244 GeoLogVol *ltrdframe = new GeoLogVol("sTGC_Frame", sGasV3, matManager.getMaterial("std::Aluminium"));
245 GeoPhysVol *ptrdframe = new GeoPhysVol(ltrdframe);
246
247 // Add frame volume to QL3
248 ptrdgas->add(ptrdframe);
249 }
250
251 newpos = newXPos;
252 } // Loop over stgc layers
253
254 return ptrd;
255 }
256
257 void sTGC::print() const {
258 MsgStream log(Athena::getMessageSvc(), "MuGM::sTGC");
259 log << MSG::INFO << " sTGC " << name << " :" << endmsg;
260 }
261
262} // namespace MuonGM
#define M_PI
#define endmsg
static Double_t ss
static std::map< double, LArWheelSliceSolid * > solid
CxxUtils::LockedPointer< AGDDController > LockedController
DetectorElement(const std::string &n)
virtual void print() const override
Definition sTGC.cxx:257
double yCutoutCathode
Definition sTGC.h:28
double width
Definition sTGC.h:23
double longWidth
Definition sTGC.h:26
GeoFullPhysVol * build(StoredMaterialManager &matManager, int minimalgeo)
Definition sTGC.cxx:52
sTGC(Component *s)
Definition sTGC.cxx:40
double yCutout
Definition sTGC.h:27
sTGCComponent * m_component
Definition sTGC.h:40
double thickness
Definition sTGC.h:25
double length
Definition sTGC.h:24
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
IAGDDtoGeoSvc::LockedController Get_Controller()
sTGCDetectorDescription * Get_sTGCDetectorSubType(const std::string &type)
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
Definition index.py:1