ATLAS Offline Software
sTGC.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 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"
25 #include "MuonGeoModel/Component.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 
35 class GeoMaterial;
36 
37 namespace MuonGM {
38 
39  // Get sTGC components for the trapezoidal shape of the quadruplet
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();
67 
68  sTGC_Technology *t = (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 
108  logVolName = name;
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
AGDDController.h
MuonGM::sTGC::longWidth
double longWidth
Definition: sTGC.h:26
AGDDDetectorStore.h
MuonGM::DetectorElement::name
std::string name
Definition: DetectorElement.h:17
checkxAOD.ds
ds
Definition: Tools/PyUtils/bin/checkxAOD.py:257
sTGCComponent.h
sTGCDetectorDescription::ylFrame
void ylFrame(double y)
Definition: sTGCDetectorDescription.h:96
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
CxxUtils::LockedPointer
A pointer together with a movable lock.
Definition: LockedPointer.h:35
sTGC_Technology.h
index
Definition: index.py:1
JetTiledMap::W
@ W
Definition: TiledEtaPhiMap.h:44
MuonGM::sTGC::width
double width
Definition: sTGC.h:23
MuonGM::sTGC::build
GeoFullPhysVol * build(StoredMaterialManager &matManager, int minimalgeo)
Definition: sTGC.cxx:52
M_PI
#define M_PI
Definition: ActiveFraction.h:11
sTGCDetectorHelper::Get_Controller
IAGDDtoGeoSvc::LockedController Get_Controller()
Definition: sTGCDetectorHelper.cxx:135
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
sTGCDetectorHelper::Get_sTGCDetectorSubType
sTGCDetectorDescription * Get_sTGCDetectorSubType(const std::string &type)
Definition: sTGCDetectorHelper.cxx:113
MuonGM::sTGCComponent
Definition: sTGCComponent.h:15
MuonGM::DetectorElement
Definition: DetectorElement.h:15
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
sTGCDetectorDescription
Definition: sTGCDetectorDescription.h:51
sTGCDetectorDescription.h
MuonGM::sTGC_Technology
Definition: MuonAGDDDescription/MuonAGDDDescription/sTGC_Technology.h:16
MuonGM::sTGC::print
virtual void print() const override
Definition: sTGC.cxx:257
MuonGM::Component
Definition: Component.h:11
lumiFormat.i
int i
Definition: lumiFormat.py:92
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
MuonGM::sTGCComponent::subType
std::string subType
Definition: sTGCComponent.h:23
sTGCDetectorDescription::ysFrame
void ysFrame(double y)
Definition: sTGCDetectorDescription.h:93
sTGCDetectorHelper.h
Component.h
MuonGM::sTGC::length
double length
Definition: sTGC.h:24
MuonGM::sTGC::sTGC
sTGC(Component *s)
Definition: sTGC.cxx:40
sTGCDetectorDescription::xFrame
void xFrame(double y)
Definition: sTGCDetectorDescription.h:90
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
StoredMaterialManager.h
AGDDDetectorStore
Definition: AGDDDetectorStore.h:18
MuonGM::sTGC::m_component
sTGCComponent * m_component
Definition: sTGC.h:40
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
MuonGM::sTGC::yCutout
double yCutout
Definition: sTGC.h:27
sTGC.h
python.compressB64.c
def c
Definition: compressB64.py:93
sTGCDetectorHelper
Definition: sTGCDetectorHelper.h:24
MuonGM::sTGC::yCutoutCathode
double yCutoutCathode
Definition: sTGC.h:28
MuonGM::sTGC::thickness
double thickness
Definition: sTGC.h:25