ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_FwdSensor.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 "SCT_FwdSensor.h"
6
9
11
12#include "SCT_Identifier.h"
13
14#include "GeoModelRead/ReadGeoModel.h"
15#include "GeoModelKernel/GeoTrd.h"
16#include "GeoModelKernel/GeoShape.h"
17#include "GeoModelKernel/GeoLogVol.h"
18#include "GeoModelKernel/GeoShapeShift.h"
19#include "GeoModelKernel/GeoShapeUnion.h"
20#include "GeoModelKernel/GeoPhysVol.h"
21#include "GeoModelKernel/GeoFullPhysVol.h"
22#include "GeoModelKernel/GeoNameTag.h"
23#include "GeoModelKernel/GeoTransform.h"
24#include "GeoModelKernel/GeoAlignableTransform.h"
25#include "GeoModelKernel/GeoMaterial.h"
26#include "GaudiKernel/SystemOfUnits.h"
27
28#include "GeoModelKernel/GeoDefinitions.h"
29
35
36#include <cmath>
37#include <utility>
38
39using namespace InDetDD;
40
41
42SCT_FwdSensor::SCT_FwdSensor(const std::string & name,
43 int ringType,
44 InDetDD::SCT_DetectorManager* detectorManager,
45 SCT_GeometryManager* geometryManager,
46 SCT_MaterialManager* materials,
47 GeoModelIO::ReadGeoModel* sqliteReader,
48 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
49 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
50 : SCT_UniqueComponentFactory(name, detectorManager, geometryManager, materials, sqliteReader, std::move(mapFPV), std::move(mapAX)),
53{
56
57}
58
60
61void
63{
64 const SCT_ForwardModuleParameters * parameters = m_geometryManager->forwardModuleParameters();
65
66 if(!m_sqliteReader){
67 m_materialSensor = m_materials->getMaterial(parameters->fwdSensorMaterialFar(m_ringType));
68
69 m_materialGlass = nullptr;
70 if (m_ringType == 2) { // Only need to define glass if its a Truncated middle module.
71 m_materialGlass = m_materials->getMaterial(parameters->fwdSensorMaterialNear(m_ringType));
72 }
73 }
74
75 m_thicknessN = m_thicknessF = parameters->fwdSensorThickness(m_ringType);
76
77 m_innerWidthF = parameters->fwdSensorInnerWidthFar(m_ringType);
78 m_outerWidthF = parameters->fwdSensorOuterWidthFar(m_ringType);
79 m_lengthF = parameters->fwdSensorLengthFar(m_ringType);
80 m_radiusF = parameters->fwdSensorRadiusFar(m_ringType);
81
82 m_innerWidthN = parameters->fwdSensorInnerWidthNear(m_ringType);
83 m_outerWidthN = parameters->fwdSensorOuterWidthNear(m_ringType);
84 m_lengthN = parameters->fwdSensorLengthNear(m_ringType);
85 m_radiusN = parameters->fwdSensorRadiusNear(m_ringType);
86
87 if (m_ringType == 3) {
88 // For Inner Module only use number for far sensor.
91 } else {
94 }
97
98 m_activeHalfLengthFar = parameters->fwdSensorActiveHalfLengthFar(m_ringType);
99 m_activeHalfLengthNear = parameters->fwdSensorActiveHalfLengthNear(m_ringType);
100
101 if (m_ringType == 3) { // Inner
103 } else {
106 }
107
108 // For truncated middle the sensor is offset from what it would be if it was a full middle.
109 m_sensorOffset = 0;
110 if (m_ringType == 2) { // truncated middle
112 }
113
114 // The thickness of the two are the same, but to be pedantic.
116}
117
118const GeoLogVol * SCT_FwdSensor::preBuild()
119{
120 const GeoLogVol * sensorLog=nullptr;
121 if(!m_sqliteReader){
122
123 const GeoTrd * sensorShapeF = new GeoTrd(0.5 * m_thicknessF, 0.5 * m_thicknessF,
124 0.5 * m_innerWidthF, 0.5 * m_outerWidthF,
125 0.5 * m_lengthF);
126
127
128 const GeoTrd * sensorShapeN= nullptr;
129 if (m_ringType != 3) {
130 sensorShapeN= new GeoTrd(0.5 * m_thicknessN, 0.5 * m_thicknessN,
131 0.5 * m_innerWidthN, 0.5 * m_outerWidthN,
132 0.5 * m_lengthN);
133 }
134
135
136 const GeoShape * sensorShape = nullptr;
137 if ((m_ringType == 2) || (m_ringType == 3)) {
138 // For truncated middle and inner there is only one wafer.
139 sensorShape = sensorShapeF;
140 } else {
141 // For outer and middle there are two wafers. We
142 // define the sensor as a boolean volume of the two wafers.
143 // relative position of near sensor
144 double positionNearZ = m_radiusN - m_sensorRadius;
145 const GeoShape & sensorPosN = (*sensorShapeN<< GeoTrf::TranslateZ3D(positionNearZ)) ;
146 // relative position of near sensor
147 double positionFarZ = m_radiusF - m_sensorRadius;
148 const GeoShape & sensorPosF = (*sensorShapeF<< GeoTrf::TranslateZ3D(positionFarZ) );
149 sensorShape = &(sensorPosF.add(sensorPosN));
150 }
151
152 sensorLog = new GeoLogVol(getName(), sensorShape, m_materialSensor);
153
154
155 if (m_ringType == 2) {
156 // Make inactive glass sensor.
157 double positionZ = m_radiusN - m_sensorRadius;
158 const GeoShape & sensorPosN = (*sensorShapeN<< GeoTrf::TranslateZ3D(positionZ) );
159 GeoLogVol * inactiveLog = new GeoLogVol(getName()+"Glass", &sensorPosN, m_materialGlass);
160 m_inactive = new GeoPhysVol(inactiveLog);
161 }
162 }
163
164 // Make the moduleside design for this sensor
165 makeDesign();
166
167 return sensorLog;
168}
169
171{
172
173 // The designs require a name when put in the collection
174 // but usually the design is accessed through SiDetectorElement
175 // and so is not generally acessesed through the DesignCollection.
176
177 // Design names are no longer used/needed, but might be used in the future for
178 // information purposes.
179 /*
180 std::string designName;
181 switch (m_ringType) {
182 case 0: // Outer
183 designName = "SCT:ForwardRing1G3";
184 break;
185 case 1: // Middle
186 designName = "SCT:ForwardRing2G3";
187 break;
188 case 2: // Truncated Middle
189 designName = "SCT:ForwardRing3G3";
190 break;
191 case 3: // Inner
192 designName = "SCT:ForwardRing4G3";
193 break;
194 default:
195 break;
196 }
197 */
198
199 // These can no longer be user defined and are ignored.
200 //SiDetectorDesign::Axis etaAxis = SiDetectorDesign::zAxis;
201 //SiDetectorDesign::Axis phiAxis = SiDetectorDesign::yAxis;
202 //SiDetectorDesign::Axis depthAxis = SiDetectorDesign::xAxis;
203
204
205 // SCT_ForwardModuleSideDesign Constructor with parameters:
206 // local axis corresponding to eta direction
207 // local axis corresponding to phi direction
208 // local axis corresponding to depth direction
209 // thickness of silicon sensor
210 // number of crystals within module side
211 // number of diodes within crystal
212 // number of cells within module side
213 // index of diode connected to cell with index 0
214 // radius from inner crystal center to beam
215 // inner crystal half height
216 // radius from outer crystal (if present) center to beam
217 // outer crystal (if present) half height
218 // strip step in angle (same for both crystals)
219 // eta coordinate of crystal center
220 // phi coordinate of crystal center
221
222 const SCT_ForwardModuleParameters * parameters = m_geometryManager->forwardModuleParameters();
223
224 double radius1=0;
225 double radius2=0;
226 double halfHeight1=0;
227 double halfHeight2=0;
228 int crystals=0;
229
230 switch (m_ringType) {
231 case 0: // Outer Module
232 case 1: // Full Middle module
233 crystals = 2;
234 radius1 = m_radiusN;
235 radius2 = m_radiusF;
236 halfHeight1 = m_activeHalfLengthNear;
237 halfHeight2 = m_activeHalfLengthFar;
238 break;
239 case 2: // Truncated Middle Module
240 case 3: // Inner Module
241 crystals = 1;
242 radius1 = m_radiusF;
243 radius2 = 0.;
244 halfHeight1 = m_activeHalfLengthFar;
245 halfHeight2 = 0.;
246 break;
247 default:
248 std::cout << "ERROR!!!! SCT_FwdSensor: Invalid ring type" << std::endl;
249 }
250
251 double etaCenter = 0;
252 double phiCenter = 0;
253
254 //int cells = parameters->fwdSensorNumReadoutStrips();
255 //int diodes = parameters->fwdSensorNumStrips();
256 //int shift = parameters->fwdSensorStripShift();
257 // For consistency with older version we keep shift = 0.
258 int cells = parameters->fwdSensorNumReadoutStrips(m_ringType);
259 int diodes = cells;
260 int shift = 0;
261
262 double step = parameters->fwdSensorAngularPitch(m_ringType);
263
264 // Readout direction is same direction as local phi direction for outer module
265 // and the opposite direction for inner and middle module.
266 bool swapStripReadout = (m_ringType != 0); // ie false for outer module only.
267
268 // The readout side is at the +ve depth direction
269 int readoutSide = +1;
270
271 // m_design will be owned and deleted by SCT_DetectorManager
272 std::unique_ptr<SCT_ForwardModuleSideDesign> design = std::make_unique<SCT_ForwardModuleSideDesign>(m_thicknessN,
273 crystals,
274 diodes,
275 cells,
276 shift,
277 swapStripReadout,
279 radius1,
280 halfHeight1,
281 radius2,
282 halfHeight2,
283 step,
284 etaCenter,
285 phiCenter,
286 readoutSide);
287 m_design = m_detectorManager->addDesign(std::move(design));
288
289 //
290 // Flags to signal if axis can be swapped.
291 // For trapezoid z axis (xEta) cannot be swapped.
292 // This is the default and no action is required.
293 // Can force axes not to be swapped by setting to false.
294 //
295 // bool phiSyGaudi::Units::mmetric = true;
296 // bool etaSyGaudi::Units::mmetric = false;
297 // bool depthSyGaudi::Units::mmetric = true;
298 // m_design->setSyGaudi::Units::mmetry(phiSyGaudi::Units::mmetric, etaSyGaudi::Units::mmetric, depthSyGaudi::Units::mmetric,
299 //
300
301}
302
304{
305
306 GeoFullPhysVol * sensor=nullptr;
307 if (m_sqliteReader)
308 {
309
310 std::string key="FwdSensor_Side#"+std::to_string(id.getSide())+"_"+std::to_string(id.getBarrelEC())+"_"+std::to_string(id.getLayerDisk())+"_"+std::to_string(id.getEtaModule())+"_"+std::to_string(id.getPhiModule());
311
312 sensor = (*m_mapFPV)[key];
313 } else
314 sensor= new GeoFullPhysVol(m_logVolume);
315
316 // Make detector element and add to collection
317 // Only do so if we have a valid id helper.
318 //id.print(); // for debugging only
319
320 const SiCommonItems* commonItems = m_geometryManager->commonItems();
321
322 if (commonItems->getIdHelper()) {
323
324 // detElement will be owned by SCT_DetectorManager
325 // and will be deleted in destructor of SiDetectorElementCollection in SCT_DetectorManager
326 SiDetectorElement * detElement = new SiDetectorElement(id.getWaferId(),
327 m_design,
328 sensor,
329 commonItems);
330
331 // Add the detector element.
332 m_detectorManager->addDetectorElement(detElement);
333
334 } else {
335 if (m_noElementWarning) {
336 std::cout << "WARNING!!!!: No SCT id helper and so no elements being produced." << std::endl;
337 m_noElementWarning = false;
338 }
339 }
340
341 return sensor;
342}
343
344
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
Helper class to concentrate common items, such as the pointer to the IdHelper, the lorentzAngle tool ...
const AtlasDetectorID * getIdHelper() const
Class to hold geometrical description of a silicon detector element.
const std::string & getName() const
InDetDD::SCT_DetectorManager * m_detectorManager
SCT_GeometryManager * m_geometryManager
SCT_MaterialManager * m_materials
double m_innerWidth
double m_innerRadius
virtual const GeoLogVol * preBuild()
double m_sensorOffset
int ringType() const
double m_sensorRadius
virtual GeoVPhysVol * build(SCT_Identifier id)
const GeoMaterial * m_materialGlass
double m_activeHalfLengthFar
std::atomic_bool m_noElementWarning
double m_innerWidthN
GeoIntrusivePtr< GeoPhysVol > m_inactive
SCT_FwdSensor(const std::string &name, int ringType, 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)
const InDetDD::SiDetectorDesign * m_design
double m_outerWidthN
double m_outerWidth
double m_activeHalfLengthNear
double m_outerRadius
const GeoMaterial * m_materialSensor
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)
GeoModelIO::ReadGeoModel * m_sqliteReader
Message Stream Member.
STL namespace.