ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_Forward.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SCT_Forward.h"
6
8
12
13#include "SCT_FwdWheel.h"
14#include "SCT_FwdModule.h"
15#include "SCT_FwdRing.h"
16#include "SCT_FwdSupportFrame.h"
17#include "SCT_FwdCoolingPipe.h"
18#include "SCT_FwdPowerTape.h"
21
23
25
26#include "GeoModelRead/ReadGeoModel.h"
27#include "GeoModelKernel/GeoTube.h"
28#include "GeoModelKernel/GeoLogVol.h"
29#include "GeoModelKernel/GeoFullPhysVol.h"
30#include "GeoModelKernel/GeoNameTag.h"
31#include "GeoModelKernel/GeoIdentifierTag.h"
32#include "GeoModelKernel/GeoTransform.h"
33#include "GeoModelKernel/GeoAlignableTransform.h"
34#include "GeoModelKernel/GeoMaterial.h"
35#include "GaudiKernel/SystemOfUnits.h"
36
37#include <cmath>
38#include <utility>
39
40SCT_Forward::SCT_Forward(const std::string & name,
41 int ec,
42 InDetDD::SCT_DetectorManager* detectorManager,
43 SCT_GeometryManager* geometryManager,
44 SCT_MaterialManager* materials,
45 GeoModelIO::ReadGeoModel* sqliteReader,
46 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
47 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
49 detectorManager,
50 geometryManager,
51 materials,
52 sqliteReader,
53 std::move(mapFPV),
54 std::move(mapAX)),
55 m_endcap(ec)
56{
59}
60
62
63void
65{
66 const SCT_ForwardParameters * parameters = m_geometryManager->forwardParameters();
67 const SCT_ForwardModuleParameters * moduleParameters = m_geometryManager->forwardModuleParameters();
68
69 //m_numRingTypes = parameters->fwdNumRingTypes();
70 m_numModuleTypes = moduleParameters->fwdModuleNumTypes();
71 m_numWheels = parameters->fwdNumWheels();
72 m_innerRadius = parameters->fwdInnerRadius();
73 m_outerRadius = parameters->fwdOuterRadius();
74 m_zMin = parameters->fwdZMin();
75 m_zMax = parameters->fwdZMax();
76 m_trtGapPos = parameters->fwdTrtGapPos();
77 m_coolingPipeRadius = parameters->fwdCoolingPipeRadius();
78 m_numThermalShieldElements = parameters->fwdNumThermalShieldElements();
79 m_cylinderServicesPresent = parameters->fwdCylinderServicePresent();
80
81 // Outer radius of cylinder services is given by inner radius of OTE
83 for (int iElement = 0; iElement < m_numThermalShieldElements; iElement++){
84 if(parameters->fwdThermalShieldMaterial(iElement) == "sct::FwdOTE") {
85 m_outerRadiusCylinderServices = parameters->fwdThermalShieldInnerRadius(iElement);
86 }
87 }
88 }
89
90 // Length of forward envelope
92
93
94 // Set numerology
95 m_detectorManager->numerology().setNumDisks(m_numWheels);
96
97
98}
99
100
101
102const GeoLogVol *
104{
105 // Create the elements we need for the forward
106 // We make all the module types here. There is a outer, middle, truncated middle and inner type module.
107 std::vector<SCT_FwdModule*> modules;
108 for (int iModuleType = 0; iModuleType < m_numModuleTypes; iModuleType++){
109
110 std::unique_ptr<SCT_FwdModule> module = std::make_unique<SCT_FwdModule>(std::format("FwdModule{}",iModuleType), iModuleType,
112 modules.push_back(module.get());
113 m_modules.push_back(std::move(module));
114 }
115
116 for (int iWheel = 0; iWheel < m_numWheels; iWheel++){
117 // Build Wheels
118 std::string name = std::format("Wheel{}{}",iWheel,((m_endcap > 0) ? "A" : "C"));
119 m_wheels.push_back(std::make_unique<SCT_FwdWheel>(name, iWheel, modules, m_endcap,
121 }
122
123 if(m_sqliteReader) return nullptr;
124
125 // Make one end of the Forward tracker
126 // Tube envelope containing the forward
127 const GeoTube * forwardEnvelopeShape = new GeoTube(m_innerRadius, m_outerRadius, 0.5 * m_length);
128 const GeoLogVol * forwardLog =
129 new GeoLogVol(getName(), forwardEnvelopeShape, m_materials->gasMaterial());
130
131 return forwardLog;
132}
133
134GeoVPhysVol *
136{
137 GeoFullPhysVol * forward=nullptr;
138 if(!m_sqliteReader)
139 {
140 forward = new GeoFullPhysVol(m_logVolume);
141
142 for (int iWheel = 0; iWheel < m_numWheels; iWheel++){
143
144 SCT_FwdWheel * wheel = m_wheels[iWheel].get();
145 double zpos = wheel->zPosition() - zCenter();
146 forward->add(new GeoNameTag(std::format("Wheel#{}",iWheel)));
147 forward->add(new GeoIdentifierTag(iWheel));
148 GeoAlignableTransform * transform = new GeoAlignableTransform(GeoTrf::TranslateZ3D(zpos));
149 forward->add(transform);
150 id.setLayerDisk(iWheel);
151 GeoVPhysVol * wheelPV = wheel->build(id);
152 forward->add(wheelPV);
153
154 // Store the alignable transform
155 m_detectorManager->addAlignableTransform(2, id.getWaferId(), transform, wheelPV);
156 }
157
158 //
159 // Place SupportFrame
160 //
162 double supportFrameZPos = supportFrame.zPosition() - zCenter();
163 forward->add(new GeoTransform(GeoTrf::TranslateZ3D(supportFrameZPos)));
164 forward->add(supportFrame.getVolume());
165
166 // Make and Place Cylinder Services
167
169
170 // New phi-dependent services
171 SCT_FwdCylinderServices cylinderServices("CylinderServices",
172 supportFrame.outerRadius(),
174 supportFrame.length(),
176 forward->add(new GeoTransform(GeoTrf::TranslateZ3D(supportFrameZPos)));
177 forward->add(cylinderServices.getVolume());
178
179 } else {
180
181 // Old cylindrical services
182 //
183 // Make cooling pipes. These extend from the wheel to the TRT Gap.
184 //
185 {
186 // End position of the pipes.
187 double endPos = m_trtGapPos;
188
189 // Calculate radius to start placing cooling pipes. This is equal to the
190 // outer radius of the support frame + the pipe radius (The pipe radius is to just
191 // give a small gap - it is not really necessary)
192 double innerRadiusCooling = supportFrame.outerRadius() + m_coolingPipeRadius;
193
194 // Inner radius of cylinder representing pipes. Gets incremented for each wheel.
195 double rStart = innerRadiusCooling;
196
197 for (int iWheel = 0; iWheel < m_numWheels; iWheel++){
198 // Start position of the pipes.
199 double startPos = m_wheels[iWheel]->zPosition();
200
201 // Assume one cooling circuit per quadrant of each ring. ie 8 pipes per ring.
202 int numPipes = 8 * m_wheels[iWheel]->numRings();
203
204 // Label Cooling pipe with W# at end of string
205 SCT_FwdCoolingPipe coolingPipe(std::format("OffDiskCoolingPipeW{}",iWheel),
206 numPipes, rStart, startPos, endPos,
208
209 // Place the cooling pipes
210 double coolingPipeZPos = coolingPipe.zPosition() - zCenter();
211 forward->add(new GeoTransform(GeoTrf::TranslateZ3D(coolingPipeZPos)));
212 forward->add(coolingPipe.getVolume());
213
214 // Set rStart for next cooling pipe equal to outer radius of this cooling pipe.
215 rStart = coolingPipe.outerRadius();
216
217 }
218 }
219
220 //
221 // Make Power Tapes. These extend from the wheel to the TRT Gap.
222 //
223 {
224
225 // End position of the power tapes.
226 double endPos = m_trtGapPos;
227
228 // Calculate radius to start placing power tapes. This is half way bewteen outer radius
229 // of support fram and outer radius of forward envelope.
230 // The -1 mm is to avoid a clash with the thermal shield.
231 double innerRadiusPowerTapes = 0.5*(supportFrame.outerRadius() + m_outerRadius) - 1*Gaudi::Units::mm;
232
233 // Inner radius of cylinder representing power tapes. Gets incremented for each wheel.
234 double rStart = innerRadiusPowerTapes;
235
236 for (int iWheel = 0; iWheel < m_numWheels; iWheel++){
237
238 // Start position of the power tapes.
239 double startPos = m_wheels[iWheel]->zPosition();
240
241 // Get total number of modules in wheel
242 int numModules = m_wheels[iWheel]->totalModules();
243
244 // Label power tape with W# at end of string
245 SCT_FwdPowerTape powerTape(std::format("OffDiskPowerTapeW{}",iWheel),
246 numModules, rStart, startPos, endPos,
248
249 // Place Power Tapes
250 double powerTapeZPos = powerTape.zPosition() - zCenter();
251 forward->add(new GeoTransform(GeoTrf::TranslateZ3D(powerTapeZPos)));
252 forward->add(powerTape.getVolume());
253
254 // Set rStart for next power tape equal to outer radius of this power tape.
255 rStart = powerTape.outerRadius();
256 } // end loop over wheels
257 }
258 }
259
260 //
261 // Place Thermal Shield Elements
262 //
263 for (int iElement = 0; iElement < m_numThermalShieldElements; iElement++){
264 SCT_FwdThermalShieldElement thermalShieldElement(std::format("FwdThermalShieldElement{}",iElement),
266 double elementZPos = thermalShieldElement.zPosition() - zCenter();
267 forward->add(new GeoTransform(GeoTrf::TranslateZ3D(elementZPos)));
268 forward->add(thermalShieldElement.getVolume());
269 }
270
271 // Extra Material
272 InDetDD::ExtraMaterial xMat(m_geometryManager->distortedMatManager());
273 xMat.add(forward, "SCTEndcap", zCenter());
274 if (m_endcap > 0) {
275 xMat.add(forward, "SCTEndcapA", zCenter());
276 } else {
277 xMat.add(forward, "SCTEndcapC", zCenter());
278 }
279
280 }
281 else {
282 for (int iWheel = 0; iWheel < m_numWheels; iWheel++){
283 SCT_FwdWheel * wheel = m_wheels[iWheel].get();
284 id.setLayerDisk(iWheel);
285 wheel->build(id);
286
287 // Store the alignable transform
288 std::string key = std::format("Wheel#{}_{}",iWheel,id.getBarrelEC());
289 m_detectorManager->addAlignableTransform(2, id.getWaferId(), (*m_mapAX)[key], (*m_mapFPV)[key]);
290 }
291 if (m_endcap > 0) {
292 forward= (*m_mapFPV)["SCTEndcapA"];
293 } else {
294 forward= (*m_mapFPV)["SCTEndcapC"];
295 }
296
297 }
298 return forward;
299}
void add(GeoPhysVol *parent, const std::string &parentName, double zPos=0)
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
const std::string & getName() const
InDetDD::SCT_DetectorManager * m_detectorManager
SCT_GeometryManager * m_geometryManager
SCT_MaterialManager * m_materials
double m_zMax
Definition SCT_Forward.h:66
std::vector< std::unique_ptr< SCT_FwdWheel > > m_wheels
Definition SCT_Forward.h:77
double m_trtGapPos
Definition SCT_Forward.h:67
void getParameters()
double m_outerRadius
Definition SCT_Forward.h:64
bool m_cylinderServicesPresent
Definition SCT_Forward.h:70
virtual GeoVPhysVol * build(SCT_Identifier id)
virtual const GeoLogVol * preBuild()
double zCenter() const
Definition SCT_Forward.h:49
double m_length
Definition SCT_Forward.h:73
int m_numThermalShieldElements
Definition SCT_Forward.h:69
SCT_Forward(const std::string &name, int ec, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials, GeoModelIO::ReadGeoModel *sqliteReader, std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > mapFPV, std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > mapAX)
std::vector< std::unique_ptr< SCT_FwdModule > > m_modules
Definition SCT_Forward.h:79
double m_outerRadiusCylinderServices
Definition SCT_Forward.h:74
int m_numModuleTypes
Definition SCT_Forward.h:61
double m_zMin
Definition SCT_Forward.h:65
double m_coolingPipeRadius
Definition SCT_Forward.h:68
double m_innerRadius
Definition SCT_Forward.h:63
double outerRadius() const
double zPosition() const
double outerRadius() const
double zPosition() const
virtual GeoVPhysVol * build(SCT_Identifier id)
double zPosition() const
SCT_UniqueComponentFactory(const std::string &name, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials=nullptr, GeoModelIO::ReadGeoModel *sqliteReader=nullptr, std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > mapFPV=nullptr, std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > mapAX=nullptr)
std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > m_mapFPV
std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > m_mapAX
GeoModelIO::ReadGeoModel * m_sqliteReader
STL namespace.