ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_FwdModule.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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{
61 if(!m_sqliteReader) {
62 m_hybrid = std::make_unique<SCT_FwdHybrid>(std::format("SCT_FwdHybrid{}",ringType), m_ringType, m_detectorManager, m_geometryManager, materials);
63 m_spine = std::make_unique<SCT_FwdSpine>(std::format("SCT_FwdSpine{}",ringType), m_ringType, m_detectorManager, m_geometryManager, materials);
64 m_subspineL = std::make_unique<SCT_FwdSubSpine>(std::format("SCT_FwdSubSpineL{}",ringType), m_ringType, SUBSPINE_LEFT,
66 m_subspineR = std::make_unique<SCT_FwdSubSpine>(std::format("SCT_FwdSubSpineR{}",ringType), m_ringType, SUBSPINE_RIGHT,
69 m_connector = std::make_unique<SCT_FwdModuleConnector>(std::format("SCT_FwdModuleConnector{}",ringType), m_ringType,
71 }
72 }
73 m_sensor = std::make_unique<SCT_FwdSensor>(std::format("ECSensor{}",ringType), m_ringType,
76
77}
78
80
81void
83{
84 const SCT_ForwardModuleParameters * parameters = m_geometryManager->forwardModuleParameters();
85 m_upperSide = parameters->fwdModuleUpperSideNumber(m_ringType);
87 {
88 m_glueThickness = parameters->fwdModuleGlueThickness(m_ringType);
89 m_distBtwMountPoints = parameters->fwdModuleDistBtwMountPoints(m_ringType);
90 m_mountPointToCenter = parameters->fwdModuleMountPoint(m_ringType);
91 m_hybridIsOnInnerEdge = parameters->fwdHybridIsOnInnerEdge(m_ringType);
92 m_stereoAngle = parameters->fwdModuleStereoAngle(m_ringType);
93 m_connectorPresent = parameters->fwdModuleConnectorPresent();
94
95 }
96
97}
98
99
100const GeoLogVol * SCT_FwdModule::preBuild()
101{
102 // module volume preparing
103
104 if(m_sqliteReader) return nullptr;
105
106 const SCT_GeneralParameters * generalParameters = m_geometryManager->generalParameters();
107 double safety = generalParameters->safety();
108 double safetyTmp = safety * Gaudi::Units::cm; // For compatibility with minor bug in older version - safety already in CLHEP units;
109
110 // module_length = (zhyb->hyby - zhyb->hybysh + zsmi[m_ringType].mountd2 + 0.33 ) * Gaudi::Units::cm + safety;
111 // Distance from outer bybrid edge to outer spine edge.
112 // FIXME: The 1.05Gaudi::Units::mm is not needed
113 double moduleLength = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter + m_spine->moduleCenterToEnd() + 1.05 * Gaudi::Units::mm;
114 m_length = moduleLength + safety; // We add a bit of safety for the envelope
115
116 // module_thickness = (zhyb->hybz0 * 2 + safety) * Gaudi::Units::cm;
117 double sensorEnvelopeThickness = 2 * m_sensor->thickness() + m_spine->thickness() + 2 * m_glueThickness;
118 m_thickness = std::max(sensorEnvelopeThickness, m_hybrid->thickness());
119
120 // module_widthInner = ((zsmo->subdq + zssp[m_ringType].ssp0l + 0.325) * 2.+ 0.7 + safety)*Gaudi::Units::cm; // upto to NOVA_760
121 // module_widthOuter = ((zsmo->subdq + zssp[m_ringType].ssp2l + 0.325) * 2.+ 0.7 + safety)*Gaudi::Units::cm; // upto to NOVA_760
122
123 //module_widthInner = ((zsmo->subdq + zssp[m_ringType].ssp0l) * 2.+ 0.7 + safety)*Gaudi::Units::cm;
124 //module_widthOuter = ((zsmo->subdq + zssp[m_ringType].ssp2l) * 2.+ 0.7 + safety)*Gaudi::Units::cm;
125
126 m_widthInner = (m_spine->width() + 2 * m_subspineL->innerWidth() + 0.7*Gaudi::Units::cm) + safetyTmp;
127 m_widthOuter = (m_spine->width() + 2 * m_subspineL->outerWidth() + 0.7*Gaudi::Units::cm) + safetyTmp;
128
129 if (m_ringType == 3 ) {
130 // module_widthOuter = (( zsmo->subdq + zssp[m_ringType].ssp2l + 0.325) * 2.+ 1.6 + safety)*Gaudi::Units::cm; // upto to NOVA_760
131 // module_widthOuter = (( zsmo->subdq + zssp[m_ringType].ssp2l) * 2.+ 1.6 + safety)*Gaudi::Units::cm;
132 m_widthOuter = m_spine->width() + 2 * m_subspineL->outerWidth() + 1.6*Gaudi::Units::cm + safetyTmp;
133 }
134
135 // Calculate module shift. Distance between module physics center and center of envelope.
136 int hybridSign = m_hybridIsOnInnerEdge ? +1: -1;
137 //module_shift = (zhyb->hyby - zhyb->hybysh + zsmi[m_ringType].mountd + 0.05)*Gaudi::Units::cm;
138 //module_shift = hybrid * (module_length / 2. - module_shift);
139
140 double moduleCenterToHybridOuterEdge = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter + 0.5*Gaudi::Units::mm;
141 //FIXME: Should be: (ie don't need the 0.5Gaudi::Units::mm)
142 // double moduleCenterToHybridOuterEdge = m_hybrid->mountPointToOuterEdge() + m_mountPointToCenter ;
143 m_moduleShift = hybridSign * (0.5 * m_length - moduleCenterToHybridOuterEdge);
144
145 // Envelope inner/outer radius
146 m_innerRadius = m_sensor->centerRadius() + m_moduleShift - 0.5*m_length;
147 m_outerRadius = m_sensor->centerRadius() + m_moduleShift + 0.5*m_length;
148
149 // Radial location of mount points (ignoring streo rotation)
150 m_mainMountPoint = m_sensor->centerRadius() - hybridSign * m_mountPointToCenter;
152 m_endLocator = m_sensor->centerRadius() + hybridSign * m_spine->moduleCenterToEnd();
153
154 // Outer module the hybrid is on inner edge.
155 // For the rest its in the outer edge.
156 // TODO Check this.
157 m_powerTapeStart = m_sensor->centerRadius() - hybridSign * moduleCenterToHybridOuterEdge;
158
159
160 const GeoTrd * moduleEnvelopeShape = new GeoTrd(0.5 * m_thickness, 0.5 * m_thickness,
161 0.5 * m_widthInner, 0.5 * m_widthOuter,
162 0.5 * m_length);
163 const GeoShapeShift & moduleEnvelope = (*moduleEnvelopeShape << GeoTrf::TranslateZ3D(m_moduleShift) );
164
165 GeoLogVol * moduleLog = new GeoLogVol(getName(), &moduleEnvelope, m_materials->gasMaterial());
166
167 return moduleLog;
168
169}
170
172{
173
174 // build method for creating module parent physical volume
175 // and puting all components into it
176 // - relative position of component is part of its shape
177 GeoFullPhysVol * module=nullptr;
178
179 if(!m_sqliteReader){
180
181 module= new GeoFullPhysVol(m_logVolume);
182
183 if (m_connector != nullptr) module->add(m_connector->getVolume());
184 module->add(m_hybrid->getVolume());
185 module->add(m_spine->getVolume());
186 module->add(m_subspineL->getVolume());
187 module->add(m_subspineR->getVolume());
188
189
190 // name tags are not final
191
192
193 // Position bottom (x<0)sensor
194 double positionX;
195 double positionZ = m_sensor->sensorOffset(); // For truncated middle the sensor is offset.
196 double rotation;
197 positionX =-(0.5*m_spine->thickness() + m_glueThickness + 0.5*m_sensor->thickness());
198 rotation = 0.5 * m_stereoAngle;
199 GeoTrf::Translation3D vecB(positionX,0,0);
200 // Rotate so that X axis goes from backside to implant side
201 GeoTrf::Transform3D rotB = GeoTrf::RotateX3D(rotation)*GeoTrf::RotateZ3D(180*Gaudi::Units::degree);
202 // First translate in z (only non-zero for truncated middle)
203 // Then rotate and then translate in x.
204 GeoAlignableTransform *bottomTransform
205 = new GeoAlignableTransform(GeoTrf::Transform3D(vecB*rotB)*GeoTrf::TranslateZ3D(positionZ));
206
207 int bottomSideNumber = (m_upperSide) ? 0 : 1;
208 id.setSide(bottomSideNumber);
209 module->add(new GeoNameTag(std::format("Sensor_Side#{}",bottomSideNumber)));
210 module->add(new GeoIdentifierTag(600+bottomSideNumber));
211 module->add(bottomTransform);
212 GeoVPhysVol * bottomSensorPV = m_sensor->build(id);
213 module->add(bottomSensorPV);
214
215 // Store transform
216 m_detectorManager->addAlignableTransform(0, id.getWaferId(), bottomTransform, bottomSensorPV);
217
218
219 if (m_ringType == 2) { // Place glass pieces in place of sensor
220 module->add(new GeoTransform(GeoTrf::Transform3D(vecB*rotB)));
221 module->add(m_sensor->getInactive());
222 }
223
224 // Position top (x>0) sensor
225 positionX=-positionX;
226 rotation=-rotation;
227 GeoTrf::RotateX3D rotT(rotation);
228 //rotT.rotateZ(180*Gaudi::Units::degree); // Rotate so that X axis goes from implant side to backside
229 GeoTrf::Translation3D vecT(positionX,0,0);
230 // First translate in z (only non-zero for truncated middle)
231 // Then rotate and then translate in x.
232 GeoAlignableTransform *topTransform
233 = new GeoAlignableTransform(GeoTrf::Transform3D(vecT*rotT)*GeoTrf::TranslateZ3D(positionZ));
234
235 int topSideNumber = m_upperSide;
236 id.setSide(topSideNumber);
237 module->add(new GeoNameTag(std::format("Sensor_Side#{}",topSideNumber)));
238 module->add(new GeoIdentifierTag(600+topSideNumber));
239 module->add(topTransform);
240 GeoVPhysVol * topSensorPV = m_sensor->build(id);
241 module->add(topSensorPV);
242
243 // Store transform
244 m_detectorManager->addAlignableTransform(0, id.getWaferId(), topTransform, topSensorPV);
245
246 if (m_ringType == 2) { // Place glass pieces in place of sensor
247 module->add(new GeoTransform(GeoTrf::Transform3D(vecT*rotT)));
248 module->add(m_sensor->getInactive());
249 };
250 }
251 else {
252 int bottomSideNumber = (m_upperSide) ? 0 : 1;
253 id.setSide(bottomSideNumber);
254 m_sensor->build(id);
255
256 // Store transform
257 std::string key=std::format("FwdSensor_Side#{}_{}_{}_{}_{}",bottomSideNumber,id.getBarrelEC(),id.getLayerDisk(),id.getEtaModule(),id.getPhiModule());
258 m_detectorManager->addAlignableTransform(0, id.getWaferId(), (*m_mapAX)[key], (*m_mapFPV)[key]);
259
260 int topSideNumber = m_upperSide;
261 id.setSide(topSideNumber);
262
263 m_sensor->build(id);
264
265 // Store transform
266 key=std::format("FwdSensor_Side#{}_{}_{}_{}_{}",topSideNumber,id.getBarrelEC(),id.getLayerDisk(),id.getEtaModule(),id.getPhiModule());
267 m_detectorManager->addAlignableTransform(0, id.getWaferId(), (*m_mapAX)[key], (*m_mapFPV)[key]);
268 }
269 return module;
270
271}
#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
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.