ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_FwdModule.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// Simulation for the COMBINED TESTBEAM 2004 //
7// //
8// Zdenka.Broklova@matfyz.cz //
9// Carlos.Escobar@ific.uv.es //
10// Peter.Kodys@ific.uv.es //
11// January 23, 2004 //
13
14#include "SCT_FwdModule.h"
15#include "SCT_GeometryManager.h"
16#include "SCT_MaterialManager.h"
17
20#include "SCT_Identifier.h"
21
23#include "SCT_FwdSpine.h"
24#include "SCT_FwdSubSpine.h"
25#include "SCT_FwdHybrid.h"
26
28
29#include "GeoModelRead/ReadGeoModel.h"
30#include "GeoModelKernel/GeoTrd.h"
31#include "GeoModelKernel/GeoShapeShift.h"
32#include "GeoModelKernel/GeoShape.h"
33#include "GeoModelKernel/GeoLogVol.h"
34#include "GeoModelKernel/GeoPhysVol.h"
35#include "GeoModelKernel/GeoFullPhysVol.h"
36#include "GeoModelKernel/GeoNameTag.h"
37#include "GeoModelKernel/GeoIdentifierTag.h"
38#include "GeoModelKernel/GeoTransform.h"
39#include "GeoModelKernel/GeoAlignableTransform.h"
40#include "GeoModelKernel/GeoMaterial.h"
41#include "GeoModelKernel/GeoDefinitions.h"
42#include "GaudiKernel/SystemOfUnits.h"
43
44#include <cmath>
45#include <sstream>
46#include <utility>
47
48inline double sqr(double x) {return x*x;}
49
50SCT_FwdModule::SCT_FwdModule(const std::string & name, int ringType,
51 InDetDD::SCT_DetectorManager* detectorManager,
52 SCT_GeometryManager* geometryManager,
53 SCT_MaterialManager* materials,
54 GeoModelIO::ReadGeoModel* sqliteReader,
55 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
56 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
57 : SCT_UniqueComponentFactory(name, detectorManager, geometryManager, materials, sqliteReader, std::move(mapFPV), std::move(mapAX)),
59{
62 {
63 m_hybrid = std::make_unique<SCT_FwdHybrid>("SCT_FwdHybrid"+intToString(ringType), m_ringType, m_detectorManager, m_geometryManager, materials);
64 m_spine = std::make_unique<SCT_FwdSpine>("SCT_FwdSpine"+intToString(ringType), m_ringType, m_detectorManager, m_geometryManager, materials);
65 m_subspineL = std::make_unique<SCT_FwdSubSpine>("SCT_FwdSubSpineL"+intToString(ringType), m_ringType, SUBSPINE_LEFT,
67 m_subspineR = std::make_unique<SCT_FwdSubSpine>("SCT_FwdSubSpineR"+intToString(ringType), m_ringType, SUBSPINE_RIGHT,
70 m_connector = std::make_unique<SCT_FwdModuleConnector>("SCT_FwdModuleConnector"+intToString(ringType), m_ringType,
72 }
73 }
74 m_sensor = std::make_unique<SCT_FwdSensor>("ECSensor"+intToString(ringType), m_ringType,
77
78}
79
83
84
85void
87{
88 const SCT_ForwardModuleParameters * parameters = m_geometryManager->forwardModuleParameters();
89 m_upperSide = parameters->fwdModuleUpperSideNumber(m_ringType);
91 {
92 m_glueThickness = parameters->fwdModuleGlueThickness(m_ringType);
93 m_distBtwMountPoints = parameters->fwdModuleDistBtwMountPoints(m_ringType);
94 m_mountPointToCenter = parameters->fwdModuleMountPoint(m_ringType);
95 m_hybridIsOnInnerEdge = parameters->fwdHybridIsOnInnerEdge(m_ringType);
96 m_stereoAngle = parameters->fwdModuleStereoAngle(m_ringType);
97 m_connectorPresent = parameters->fwdModuleConnectorPresent();
98
99 }
100
101}
102
103
104const GeoLogVol * SCT_FwdModule::preBuild()
105{
106 // module volume preparing
107
108 if(m_sqliteReader) return nullptr;
109
110 const SCT_GeneralParameters * generalParameters = m_geometryManager->generalParameters();
111 double safety = generalParameters->safety();
112 double safetyTmp = safety * Gaudi::Units::cm; // For compatibility with minor bug in older version - safety already in CLHEP units;
113
114 // module_length = (zhyb->hyby - zhyb->hybysh + zsmi[m_ringType].mountd2 + 0.33 ) * Gaudi::Units::cm + safety;
115 // Distance from outer bybrid edge to outer spine edge.
116 // FIXME: The 1.05Gaudi::Units::mm is not needed
117 double moduleLength = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter + m_spine->moduleCenterToEnd() + 1.05 * Gaudi::Units::mm;
118 m_length = moduleLength + safety; // We add a bit of safety for the envelope
119
120 // module_thickness = (zhyb->hybz0 * 2 + safety) * Gaudi::Units::cm;
121 double sensorEnvelopeThickness = 2 * m_sensor->thickness() + m_spine->thickness() + 2 * m_glueThickness;
122 m_thickness = std::max(sensorEnvelopeThickness, m_hybrid->thickness());
123
124 // module_widthInner = ((zsmo->subdq + zssp[m_ringType].ssp0l + 0.325) * 2.+ 0.7 + safety)*Gaudi::Units::cm; // upto to NOVA_760
125 // module_widthOuter = ((zsmo->subdq + zssp[m_ringType].ssp2l + 0.325) * 2.+ 0.7 + safety)*Gaudi::Units::cm; // upto to NOVA_760
126
127 //module_widthInner = ((zsmo->subdq + zssp[m_ringType].ssp0l) * 2.+ 0.7 + safety)*Gaudi::Units::cm;
128 //module_widthOuter = ((zsmo->subdq + zssp[m_ringType].ssp2l) * 2.+ 0.7 + safety)*Gaudi::Units::cm;
129
130 m_widthInner = (m_spine->width() + 2 * m_subspineL->innerWidth() + 0.7*Gaudi::Units::cm) + safetyTmp;
131 m_widthOuter = (m_spine->width() + 2 * m_subspineL->outerWidth() + 0.7*Gaudi::Units::cm) + safetyTmp;
132
133 if (m_ringType == 3 ) {
134 // module_widthOuter = (( zsmo->subdq + zssp[m_ringType].ssp2l + 0.325) * 2.+ 1.6 + safety)*Gaudi::Units::cm; // upto to NOVA_760
135 // module_widthOuter = (( zsmo->subdq + zssp[m_ringType].ssp2l) * 2.+ 1.6 + safety)*Gaudi::Units::cm;
136 m_widthOuter = m_spine->width() + 2 * m_subspineL->outerWidth() + 1.6*Gaudi::Units::cm + safetyTmp;
137 }
138
139 // Calculate module shift. Distance between module physics center and center of envelope.
140 int hybridSign = m_hybridIsOnInnerEdge ? +1: -1;
141 //module_shift = (zhyb->hyby - zhyb->hybysh + zsmi[m_ringType].mountd + 0.05)*Gaudi::Units::cm;
142 //module_shift = hybrid * (module_length / 2. - module_shift);
143
144 double moduleCenterToHybridOuterEdge = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter + 0.5*Gaudi::Units::mm;
145 //FIXME: Should be: (ie don't need the 0.5Gaudi::Units::mm)
146 // double moduleCenterToHybridOuterEdge = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter ;
147 m_moduleShift = hybridSign * (0.5 * m_length - moduleCenterToHybridOuterEdge);
148
149 // Envelope inner/outer radius
150 m_innerRadius = m_sensor->centerRadius() + m_moduleShift - 0.5*m_length;
151 m_outerRadius = m_sensor->centerRadius() + m_moduleShift + 0.5*m_length;
152
153 // Radial location of mount points (ignoring streo rotation)
154 m_mainMountPoint = m_sensor->centerRadius() - hybridSign * m_mountPointToCenter;
156 m_endLocator = m_sensor->centerRadius() + hybridSign * m_spine->moduleCenterToEnd();
157
158 // Outer module the hybrid is on inner edge.
159 // For the rest its in the outer edge.
160 // TODO Check this.
161 m_powerTapeStart = m_sensor->centerRadius() - hybridSign * moduleCenterToHybridOuterEdge;
162
163
164 const GeoTrd * moduleEnvelopeShape = new GeoTrd(0.5 * m_thickness, 0.5 * m_thickness,
165 0.5 * m_widthInner, 0.5 * m_widthOuter,
166 0.5 * m_length);
167 const GeoShapeShift & moduleEnvelope = (*moduleEnvelopeShape << GeoTrf::TranslateZ3D(m_moduleShift) );
168
169 GeoLogVol * moduleLog = new GeoLogVol(getName(), &moduleEnvelope, m_materials->gasMaterial());
170
171 return moduleLog;
172
173}
174
176{
177
178 // build method for creating module parent physical volume
179 // and puting all components into it
180 // - relative position of component is part of its shape
181 GeoFullPhysVol * module=nullptr;
182
183 if(!m_sqliteReader){
184
185 module= new GeoFullPhysVol(m_logVolume);
186
187 if (m_connector != nullptr) module->add(m_connector->getVolume());
188 module->add(m_hybrid->getVolume());
189 module->add(m_spine->getVolume());
190 module->add(m_subspineL->getVolume());
191 module->add(m_subspineR->getVolume());
192
193
194 // name tags are not final
195
196
197 // Position bottom (x<0)sensor
198 double positionX;
199 double positionZ = m_sensor->sensorOffset(); // For truncated middle the sensor is offset.
200 double rotation;
201 positionX =-(0.5*m_spine->thickness() + m_glueThickness + 0.5*m_sensor->thickness());
202 rotation = 0.5 * m_stereoAngle;
203 GeoTrf::Translation3D vecB(positionX,0,0);
204 // Rotate so that X axis goes from backside to implant side
205 GeoTrf::Transform3D rotB = GeoTrf::RotateX3D(rotation)*GeoTrf::RotateZ3D(180*Gaudi::Units::degree);
206 // First translate in z (only non-zero for truncated middle)
207 // Then rotate and then translate in x.
208 GeoAlignableTransform *bottomTransform
209 = new GeoAlignableTransform(GeoTrf::Transform3D(vecB*rotB)*GeoTrf::TranslateZ3D(positionZ));
210
211 int bottomSideNumber = (m_upperSide) ? 0 : 1;
212 id.setSide(bottomSideNumber);
213 module->add(new GeoNameTag("Sensor_Side#"+intToString(bottomSideNumber)));
214 module->add(new GeoIdentifierTag(600+bottomSideNumber));
215 module->add(bottomTransform);
216 GeoVPhysVol * bottomSensorPV = m_sensor->build(id);
217 module->add(bottomSensorPV);
218
219 // Store transform
220 m_detectorManager->addAlignableTransform(0, id.getWaferId(), bottomTransform, bottomSensorPV);
221
222
223 if (m_ringType == 2) { // Place glass pieces in place of sensor
224 module->add(new GeoTransform(GeoTrf::Transform3D(vecB*rotB)));
225 module->add(m_sensor->getInactive());
226 }
227
228 // Position top (x>0) sensor
229 positionX=-positionX;
230 rotation=-rotation;
231 GeoTrf::RotateX3D rotT(rotation);
232 //rotT.rotateZ(180*Gaudi::Units::degree); // Rotate so that X axis goes from implant side to backside
233 GeoTrf::Translation3D vecT(positionX,0,0);
234 // First translate in z (only non-zero for truncated middle)
235 // Then rotate and then translate in x.
236 GeoAlignableTransform *topTransform
237 = new GeoAlignableTransform(GeoTrf::Transform3D(vecT*rotT)*GeoTrf::TranslateZ3D(positionZ));
238
239 int topSideNumber = m_upperSide;
240 id.setSide(topSideNumber);
241 module->add(new GeoNameTag("Sensor_Side#"+intToString(topSideNumber)));
242 module->add(new GeoIdentifierTag(600+topSideNumber));
243 module->add(topTransform);
244 GeoVPhysVol * topSensorPV = m_sensor->build(id);
245 module->add(topSensorPV);
246
247 // Store transform
248 m_detectorManager->addAlignableTransform(0, id.getWaferId(), topTransform, topSensorPV);
249
250 if (m_ringType == 2) { // Place glass pieces in place of sensor
251 module->add(new GeoTransform(GeoTrf::Transform3D(vecT*rotT)));
252 module->add(m_sensor->getInactive());
253 };
254 }
255 else{
256
257 int bottomSideNumber = (m_upperSide) ? 0 : 1;
258 id.setSide(bottomSideNumber);
259 m_sensor->build(id);
260
261 // Store transform
262 std::string key="FwdSensor_Side#"+std::to_string(bottomSideNumber)+"_"+std::to_string(id.getBarrelEC())+"_"+std::to_string(id.getLayerDisk())+"_"+std::to_string(id.getEtaModule())+"_"+std::to_string(id.getPhiModule());
263 m_detectorManager->addAlignableTransform(0, id.getWaferId(), (*m_mapAX)[key], (*m_mapFPV)[key]);
264
265 int topSideNumber = m_upperSide;
266 id.setSide(topSideNumber);
267
268 m_sensor->build(id);
269
270 key="FwdSensor_Side#"+std::to_string(topSideNumber)+"_"+std::to_string(id.getBarrelEC())+"_"+std::to_string(id.getLayerDisk())+"_"+std::to_string(id.getEtaModule())+"_"+std::to_string(id.getPhiModule());
271
272 // Store transform
273 m_detectorManager->addAlignableTransform(0, id.getWaferId(), (*m_mapAX)[key], (*m_mapFPV)[key]);
274
275 }
276 return module;
277
278}
#define sqr(t)
#define SUBSPINE_RIGHT
#define SUBSPINE_LEFT
#define x
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
const std::string & getName() const
std::string intToString(int i) const
InDetDD::SCT_DetectorManager * m_detectorManager
SCT_GeometryManager * m_geometryManager
SCT_MaterialManager * m_materials
double m_widthInner
int ringType() const
double m_outerRadius
std::unique_ptr< SCT_FwdSensor > m_sensor
std::unique_ptr< SCT_FwdModuleConnector > m_connector
virtual GeoVPhysVol * build(SCT_Identifier id)
double m_mountPointToCenter
double m_distBtwMountPoints
double m_secMountPoint
double m_stereoAngle
double m_glueThickness
double m_mainMountPoint
double m_powerTapeStart
std::unique_ptr< SCT_FwdSubSpine > m_subspineR
double m_innerRadius
std::unique_ptr< SCT_FwdSpine > m_spine
bool m_connectorPresent
virtual const GeoLogVol * preBuild()
double m_endLocator
double m_moduleShift
std::unique_ptr< SCT_FwdHybrid > m_hybrid
double m_widthOuter
std::unique_ptr< SCT_FwdSubSpine > m_subspineL
SCT_FwdModule(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)
bool m_hybridIsOnInnerEdge
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.