ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_FwdCylinderServices.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
12
13#include "GeoModelKernel/GeoCons.h"
14#include "GeoModelKernel/GeoTube.h"
15#include "GeoModelKernel/GeoTubs.h"
16#include "GeoModelKernel/GeoLogVol.h"
17#include "GeoModelKernel/GeoPhysVol.h"
18#include "GeoModelKernel/GeoTransform.h"
19#include "GeoModelKernel/GeoMaterial.h"
20#include "GeoModelKernel/GeoDefinitions.h"
21#include "GaudiKernel/SystemOfUnits.h"
22
23#include <sstream>
24#include <cmath>
25
27 double rmin,
28 double rmax,
29 double length,
30 InDetDD::SCT_DetectorManager* detectorManager,
31 SCT_GeometryManager* geometryManager,
32 SCT_MaterialManager* materials)
33 : SCT_SharedComponentFactory(name, detectorManager, geometryManager, materials),
35{
38
39}
40
44
45void
47{
48 const SCT_ForwardParameters * parameters = m_geometryManager->forwardParameters();
49
50 // Retrieve parameters for each service
51 for (int iType = 0; iType < parameters->fwdNumCylinderServiceTypes(); iType++) {
52 if (parameters->fwdCylinderServiceName(iType) == "CoolingPipe") {
53 m_coolingDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
54 m_coolingRPhi = parameters->fwdCylinderServiceRPhi(iType);
55 m_coolingMaterialName = parameters->fwdCylinderServiceMaterial(iType);
56 }
57 if (parameters->fwdCylinderServiceName(iType) == "LMT") {
58 m_lmtDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
59 m_lmtRPhi = parameters->fwdCylinderServiceRPhi(iType);
60 m_lmtMaterialName = parameters->fwdCylinderServiceMaterial(iType);
61 }
62 if (parameters->fwdCylinderServiceName(iType) == "LMTCooling") {
63 m_lmtCoolingDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
64 m_lmtCoolingRPhi = parameters->fwdCylinderServiceRPhi(iType);
65 m_lmtCoolingMaterialName = parameters->fwdCylinderServiceMaterial(iType);
66 }
67 if (parameters->fwdCylinderServiceName(iType) == "Fibres") {
68 m_fibreDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
69 m_fibreRPhi = parameters->fwdCylinderServiceRPhi(iType);
70 m_fibreMaterialName = parameters->fwdCylinderServiceMaterial(iType);
71 }
72 if (parameters->fwdCylinderServiceName(iType) == "NPipe") {
73 m_nPipeDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
74 m_nPipeRPhi = parameters->fwdCylinderServiceRPhi(iType);
75 m_nPipeMaterialName = parameters->fwdCylinderServiceMaterial(iType);
76 }
77 if (parameters->fwdCylinderServiceName(iType) == "Rail") {
78 m_railDeltaR = parameters->fwdCylinderServiceDeltaR(iType);
79 m_railRPhi = parameters->fwdCylinderServiceRPhi(iType);
80 m_railMaterialName = parameters->fwdCylinderServiceMaterial(iType);
81 }
82 }
83
84 // Retrieve angles for each service
85 for (int iLoc = 0; iLoc < parameters->fwdNumCylinderServiceLocs(); iLoc++) {
86 if (parameters->fwdCylinderServiceLocName(iLoc) == "CoolingPipe") {
87 m_coolingLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
88 }
89 if (parameters->fwdCylinderServiceLocName(iLoc) == "LMT") {
90 m_lmtLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
91 }
92 if (parameters->fwdCylinderServiceLocName(iLoc) == "LMTCooling") {
93 m_lmtCoolingLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
94 }
95 if (parameters->fwdCylinderServiceLocName(iLoc) == "Fibres") {
96 m_fibreLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
97 }
98 if (parameters->fwdCylinderServiceLocName(iLoc) == "NPipe") {
99 m_nPipeLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
100 }
101 if (parameters->fwdCylinderServiceLocName(iLoc) == "Rail") {
102 m_railLocAngle.push_back(parameters->fwdCylinderServiceLocAngle(iLoc));
103 }
104 }
105
106 // Starting position for LMT Cooling is midpoint between wheels 1 and 2
107 double lmtCoolingZStart = 0.5 * (parameters->fwdWheelZPosition(1) + parameters->fwdWheelZPosition(2));
108 m_lmtCoolingZOffset = 0.5 * (lmtCoolingZStart - parameters->fwdSupportFrameZMin());
109
110}
111
112GeoVPhysVol *
114{
115
116 // Make envelope for the services
117 const GeoTube * cylinderShape = new GeoTube(m_innerRadius, m_outerRadius, 0.5 * m_length);
118 const GeoLogVol * cylinderLog = new GeoLogVol(getName(), cylinderShape, m_materials->gasMaterial());
119 GeoPhysVol * cylinder = new GeoPhysVol(cylinderLog);
120
121 // Create All Services
122 // All except LMT Cooling run complete length of cylinder
123 // LMT Cooling starts midway between wheels 1 and 2
124 // CoolingPipe, LMT and Fibres build up in z and are modelled as cone sections
125 // LMT Cooling, N2 Pipes and Rails are uniform in z and modelled as tube sections
126 // Cooling pipe, LMT, fibres and N2 pipe are placed at same radius
127 // LMT Cooling is outside LMT
128 // Rails are outside Cooling and N2 pipes
129
130 // Cooling pipe
131 double coolingRmin = m_innerRadius;
132 double coolingRmax1 = coolingRmin + 0.2 * m_coolingDeltaR;
133 double coolingRmax2 = coolingRmin + 1.8 * m_coolingDeltaR;
134 double coolingDPhi = m_coolingRPhi / coolingRmin;
135 const GeoCons* coolingShape = new GeoCons(coolingRmin, coolingRmin, coolingRmax1, coolingRmax2,
136 0.5 * m_length,
137 -0.5 * coolingDPhi * Gaudi::Units::radian, coolingDPhi * Gaudi::Units::radian);
138 const GeoLogVol * coolingLog = new GeoLogVol("CoolingPipe", coolingShape, m_materials->getMaterialForVolume(m_coolingMaterialName, coolingShape->volume()));
139 GeoPhysVol * coolingPipe = new GeoPhysVol(coolingLog);
140
141 // Low Mass Tapes
142 double lmtRmin = m_innerRadius;
143 double lmtRmax1 = lmtRmin + 0.2 * m_lmtDeltaR;
144 double lmtRmax2 = lmtRmin + 1.8 * m_lmtDeltaR;
145 double lmtDPhi = m_lmtRPhi / lmtRmin;
146 const GeoCons* lmtShape = new GeoCons(lmtRmin, lmtRmin, lmtRmax1, lmtRmax2, 0.5 * m_length,
147 -0.5 * lmtDPhi * Gaudi::Units::radian, lmtDPhi * Gaudi::Units::radian);
148 const GeoLogVol * lmtLog = new GeoLogVol("LMT", lmtShape, m_materials->getMaterialForVolume(m_lmtMaterialName,lmtShape->volume()));
149 GeoPhysVol * lmt = new GeoPhysVol(lmtLog);
150
151 // LMT Cooling: must be outside LMTs
152 double lmtCoolingRmin = lmtRmax2;
153 double lmtCoolingRmax = lmtCoolingRmin + m_lmtCoolingDeltaR;
154 double lmtCoolingDPhi = m_lmtCoolingRPhi / lmtCoolingRmin;
155 double lmtLength = m_length - 2. * m_lmtCoolingZOffset;
156 const GeoTubs* lmtCoolingShape = new GeoTubs(lmtCoolingRmin, lmtCoolingRmax, 0.5 * lmtLength,
157 -0.5 * lmtCoolingDPhi * Gaudi::Units::radian, lmtCoolingDPhi * Gaudi::Units::radian);
158 const GeoLogVol * lmtCoolingLog = new GeoLogVol("LMTCooling", lmtCoolingShape, m_materials->getMaterialForVolume(m_lmtCoolingMaterialName,lmtCoolingShape->volume()));
159 GeoPhysVol * lmtCooling = new GeoPhysVol(lmtCoolingLog);
160
161 // Fibres
162 double fibreRmin = m_innerRadius;
163 double fibreRmax1 = fibreRmin + 0.2 * m_fibreDeltaR;
164 double fibreRmax2 = fibreRmin + 1.8 * m_fibreDeltaR;
165 double fibreDPhi = m_fibreRPhi / fibreRmin;
166 const GeoCons* fibreShape = new GeoCons(fibreRmin, fibreRmin, fibreRmax1, fibreRmax2, 0.5 * m_length,
167 -0.5 * fibreDPhi * Gaudi::Units::radian, fibreDPhi * Gaudi::Units::radian);
168 const GeoLogVol * fibreLog = new GeoLogVol("Fibres", fibreShape, m_materials->getMaterialForVolume(m_fibreMaterialName,fibreShape->volume()));
169 GeoPhysVol * fibres = new GeoPhysVol(fibreLog);
170
171 // N2 Pipe
172 double nPipeRmin = m_innerRadius;
173 double nPipeRmax = nPipeRmin + m_nPipeDeltaR;
174 double nPipeDPhi = m_nPipeRPhi / nPipeRmin;
175 const GeoTubs* nPipeShape = new GeoTubs(nPipeRmin, nPipeRmax, 0.5 * m_length,
176 -0.5 * nPipeDPhi * Gaudi::Units::radian, nPipeDPhi * Gaudi::Units::radian);
177 const GeoLogVol * nPipeLog = new GeoLogVol("NPipe", nPipeShape, m_materials->getMaterialForVolume(m_nPipeMaterialName,nPipeShape->volume()));
178 GeoPhysVol * nPipe = new GeoPhysVol(nPipeLog);
179
180 // Rails: must be outside Cooling and N2 Pipes
181 double railRmin = std::max(coolingRmax2, nPipeRmax);
182 double railRmax = railRmin + m_railDeltaR;
183 double railDPhi = m_railRPhi / railRmin;
184 const GeoTubs* railShape = new GeoTubs(railRmin, railRmax,
185 0.5 * m_length, -0.5 * railDPhi * Gaudi::Units::radian, railDPhi * Gaudi::Units::radian);
186 const GeoLogVol * railLog = new GeoLogVol("Rail", railShape, m_materials->getMaterialForVolume(m_railMaterialName,railShape->volume()));
187 GeoPhysVol * rail = new GeoPhysVol(railLog);
188
189 // Services are repeated for each quadrant
190 for (int iquad = 0; iquad < 4; iquad++) {
191
192 // Cooling pipe
193 for (unsigned int iLoc = 0; iLoc < m_coolingLocAngle.size(); iLoc++) {
194 double coolingAngle = m_coolingLocAngle[iLoc] + iquad * 90*Gaudi::Units::degree;
195 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(coolingAngle)));
196 cylinder->add(coolingPipe);
197 }
198
199 // Low Mass Tapes and LMT Cooling are at same phi positions
200 for (unsigned int iLoc = 0; iLoc < m_lmtLocAngle.size(); iLoc++) {
201 double lmtAngle = m_lmtLocAngle[iLoc] + iquad * 90*Gaudi::Units::degree;
202 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(lmtAngle)));
203 cylinder->add(lmt);
204 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(lmtAngle)*GeoTrf::TranslateZ3D(m_lmtCoolingZOffset)));
205 cylinder->add(lmtCooling);
206 }
207
208 // Fibres are between pairs of LMTs
209 for (unsigned int iLoc = 0; iLoc < m_fibreLocAngle.size(); iLoc++) {
210 double fibreAngle = m_fibreLocAngle[iLoc] + iquad * 90*Gaudi::Units::degree;
211 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(fibreAngle)));
212 cylinder->add(fibres);
213 }
214
215 // N2 Pipes
216 for (unsigned int iLoc = 0; iLoc < m_nPipeLocAngle.size(); iLoc++) {
217 double nPipeAngle = m_nPipeLocAngle[iLoc] + iquad * 90*Gaudi::Units::degree;
218 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(nPipeAngle)));
219 cylinder->add(nPipe);
220 }
221
222 // Rails
223 for (unsigned int iLoc = 0; iLoc < m_railLocAngle.size(); iLoc++) {
224 double railAngle = m_railLocAngle[iLoc] + iquad * 90*Gaudi::Units::degree;
225 cylinder->add(new GeoTransform(GeoTrf::RotateZ3D(railAngle)));
226 cylinder->add(rail);
227 }
228
229 } // end loop over quadrants
230
231 return cylinder;
232
233}
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
const std::string & getName() const
SCT_GeometryManager * m_geometryManager
SCT_MaterialManager * m_materials
std::vector< double > m_fibreLocAngle
std::vector< double > m_coolingLocAngle
SCT_FwdCylinderServices(const std::string &name, double rmin, double rmax, double length, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials)
std::vector< double > m_lmtCoolingLocAngle
std::vector< double > m_railLocAngle
std::vector< double > m_nPipeLocAngle
std::vector< double > m_lmtLocAngle
SCT_SharedComponentFactory(const std::string &name, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials=nullptr)