ATLAS Offline Software
DBM_Module.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 
6 #include <utility>
7 
8 #include "DBM_Module.h"
9 
10 #include "GeoModelKernel/GeoTransform.h"
11 #include "GeoModelKernel/GeoAlignableTransform.h"
12 #include "GeoModelKernel/GeoNameTag.h"
13 #include "GeoModelKernel/GeoBox.h"
14 #include "GaudiKernel/SystemOfUnits.h"
15 
16 #include "Identifier/Identifier.h"
19 
22 #include "PixelGeoUtils.h"
23 using namespace InDetDD;
24 
27  GeoModelIO::ReadGeoModel* sqliteReader,
28  std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
29  std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
30  : GeoVPixelFactory (ddmgr, mgr, sqliteReader, std::move(mapFPV), std::move(mapAX))
31 {
32 
33  double thickness = 0.5;
34 
35  int circuitsPerPhi = 1;
36  int circuitsPerEta = 1;
37  int cellRowPerCirc = 80;
38  int cellColPerCirc = 336;
39  int rowsPerCircuit = 80;
40  int columnsPerCircuit = 336;
41  int readoutSide = 1;
42 
43  double pitchEtaLongEnd = 0.05;
44  double pitchEtaLong = 0.05;
45  double pitchPhi = 0.25;
46  double pitchEta = 0.05;
47 
48  constexpr auto readoutTechnology = InDetDD::PixelReadoutTechnology::FEI4;
52  readoutTechnology,
53  std::array<int,kNDirections>{circuitsPerPhi,circuitsPerEta}, // [0]=phi/row, [1]=eta/column
54  std::array<int,kNDirections>{rowsPerCircuit,columnsPerCircuit}, // [0]=phi/row, [1]=eta/column
55  std::array<std::array<double,kNDirections>,kNPixelLocations>{ // regular/central,longEnd/outer,long/inner
56  std::array<double,kNDirections>{pitchPhi,pitchEta},
57  std::array<double,kNDirections>{0.,pitchEtaLongEnd},
58  std::array<double,kNDirections>{0.,pitchEtaLong}});
59 
60  std::unique_ptr<PixelModuleDesign> p_dbmdesign = std::make_unique<PixelModuleDesign>(thickness,
61  circuitsPerPhi,
62  circuitsPerEta,
63  cellColPerCirc,
64  cellRowPerCirc,
65  columnsPerCircuit,
66  rowsPerCircuit,
67  std::move(diode_tree),
69  readoutSide,
70  false, /* 3D */
71  InDetDD::Undefined, /* detector type */
72  readoutTechnology);
73 
74 
75  m_design = m_DDmgr->addDesign(std::move(p_dbmdesign));
76 
77 
78 }
79 
80 GeoVPhysVol* DBM_Module::Build()
81 {
82  const PixelID * idHelper = m_gmt_mgr->getIdHelper();
83  int dbmdet = 4*m_gmt_mgr->GetSide();
84  Identifier idwafer;
85  idwafer = idHelper->wafer_id(dbmdet,m_gmt_mgr->GetLD(),m_gmt_mgr->Phi(),m_gmt_mgr->Eta());
86 
87  if(m_sqliteReader) {
88  std::string key ="DBMDiamond_" + std::to_string(dbmdet) +"_"+ std::to_string(m_gmt_mgr->GetLD()) +"_"+ std::to_string(m_gmt_mgr->Phi()) +"_"+ std::to_string(m_gmt_mgr->Eta());
90  // add the element to the manager
91  m_DDmgr->addDetectorElement(element);
92  m_DDmgr->addAlignableTransform(0, idwafer, (*m_mapAX)[key], (*m_mapFPV)[key]);
93  return nullptr;
94  }
95  else {
96  GeoIdentifierTag* diamondTag = new GeoIdentifierTag(400);
97 
98 
99  double safety = 0.003*Gaudi::Units::mm;
100 
101  //diamond dimension
102  double diamond_X = m_gmt_mgr->DBMDiamondX();
103  double diamond_Y = m_gmt_mgr->DBMDiamondY();
104  double diamond_Z = m_gmt_mgr->DBMDiamondZ();
105  double air_gap = m_gmt_mgr->DBMAirGap();
106 
107  //chip, FEI4 dimension
108  double chip_X = m_gmt_mgr->DBMFEI4X();
109  double chip_Y = m_gmt_mgr->DBMFEI4Y();
110  double chip_thick = m_gmt_mgr->DBMFEI4Z();
111 
112  //ceramic dimension
113  double substrate_X = m_gmt_mgr->DBMCeramicX();
114  double substrate_Y = m_gmt_mgr->DBMCeramicY();
115  double substrate_Z = m_gmt_mgr->DBMCeramicZ();
116 
117  //distances from bottom of the ceramic
118  //Hardcoded!
119  double bot2Chip = 0.0*Gaudi::Units::mm;
120  double bot2Diamond = 1.685*Gaudi::Units::mm;
121 
122 
123  //---------------------------------------------
124  // Get parameters for alignable Transform
125 
126  // Position of the corner closest to IP and beamline
127  // Hardcoded, so if change then change in GeoPixelEnvelope and DBM_Det too
128  double ZToIP = 887.002*Gaudi::Units::mm;
129  double RToBeam = 46.678*Gaudi::Units::mm;
130 
131  // layer spacing
132  double Zspacing = m_gmt_mgr->DBMSpacingZ();
133  double Rspacing = m_gmt_mgr->DBMSpacingRadial();
134  // gap between V-slide and first main plate
135  double layer1Space = m_gmt_mgr->DBMSpace();
136 
137  // parameters for rotating the 3-layer unit
138  double angle = m_gmt_mgr->DBMAngle(); // telescope tilting angle in degree
139  double bracketZ = m_gmt_mgr->DBMBracketZ(); // total thickness of the bracket unit,
140  double trapBackY = m_gmt_mgr->DBMTrapezBackY();
141  double trapBackShortZ = m_gmt_mgr->DBMTrapezBackShortZ();
142  double coolingSidePlateY = m_gmt_mgr->DBMCoolingSidePlateY();
143  double brcktLockZ = m_gmt_mgr->DBMBrcktLockZ();
144 
145  //double lyRadius = sqrt(layerUnitY*layerUnitY/4 + layerUnitZ*layerUnitZ/4);
146  //double lyAngle = atan(layerUnitY/layerUnitZ);
147  // position of the 3-layer unit's corner closest to the IP and beamline, which is the rotation point
148  double layerUnitPos_Y = (trapBackY/cos(angle) - coolingSidePlateY)*cos(angle);
149  double layerUnitPos_Z = coolingSidePlateY*sin(angle) + trapBackShortZ + bracketZ - brcktLockZ;
150  //---------------------------------------------
151 
152 
153 
154  const GeoMaterial* air = m_mat_mgr->getMaterial("std::Air");
155  //first try the Diamond
156  const GeoMaterial* diamond = m_mat_mgr->getMaterial("pix::Diamond");
157  if(diamond == nullptr)
158  {
159  diamond = m_mat_mgr->getMaterial("std::Carbon");
160  }
161 
162  const GeoMaterial* chip_mat = m_mat_mgr->getMaterial("pix::ChipBase");
163 
164  double max_thick = diamond_Z + air_gap + chip_thick + substrate_Z;
165 
166  //create a outer box to contain all volumes
167  const GeoBox* dbmModuleBox = new GeoBox(substrate_X/2.0 + safety, substrate_Y/2.0 + safety, max_thick/2.0 + safety);
168  const GeoLogVol* dbmModuleLog = new GeoLogVol("dbmModuleLog", dbmModuleBox, air);
169  GeoPhysVol* dbmModulePhys = new GeoPhysVol(dbmModuleLog);
170 
171  GeoTrf::Transform3D rm = GeoTrf::RotateZ3D(90.*Gaudi::Units::deg)*GeoTrf::RotateY3D(270.*Gaudi::Units::deg);
172 
173  //diamond
174  const GeoBox* dbmDiamondBox = new GeoBox(diamond_Z/2.0, diamond_X/2.0, diamond_Y/2.0 );
175  const GeoLogVol* dbmDiamondLog = new GeoLogVol("dbmDiamondLog", dbmDiamondBox, diamond);
176  GeoFullPhysVol* dbmDiamondPhys = new GeoFullPhysVol(dbmDiamondLog);
177 
178  SiDetectorElement* element= new SiDetectorElement(idwafer, m_design, dbmDiamondPhys, m_gmt_mgr->commonItems());
179  // add the element to the manager
180  m_DDmgr->addDetectorElement(element);
181 
182  GeoTrf::Translation3D dbmDiamondPos(0, bot2Diamond+diamond_Y/2.0-substrate_Y/2.0, diamond_Z/2.0-max_thick/2.0);
183  GeoTransform* xform = new GeoTransform(GeoTrf::Transform3D(dbmDiamondPos*rm));
184 
185  dbmModulePhys->add(diamondTag);
186  dbmModulePhys->add(xform);
187  dbmModulePhys->add(dbmDiamondPhys);
188 
189  //FEI4 chip
190  const GeoBox* dbmFEI4Box = new GeoBox(chip_thick/2.0, chip_X/2.0, chip_Y/2.0 );
191  const GeoLogVol* dbmFEI4Log = new GeoLogVol("dbmWallLogF4", dbmFEI4Box, chip_mat); //should this be "dbmdiamondLog"?
192  GeoPhysVol* dbmFEI4Phys = new GeoPhysVol(dbmFEI4Log);
193 
194  GeoTrf::Translation3D dbmFEI4Pos(0, bot2Chip+chip_Y/2.0-substrate_Y/2.0, max_thick/2.0-substrate_Z-chip_thick/2.0);
195  xform = new GeoTransform(GeoTrf::Transform3D(dbmFEI4Pos*rm));
196 
197  dbmModulePhys->add(xform);
198  dbmModulePhys->add(dbmFEI4Phys);
199 
200  //ceramic support
201  const GeoBox* dbmSubstBox = new GeoBox(substrate_X/2.0, substrate_Y/2.0, substrate_Z/2.0);
202  const GeoMaterial* aluminiumNitride = m_mat_mgr->getMaterialForVolume("pix::DBMCeramic", dbmSubstBox->volume());
203  const GeoLogVol* dbmSubstLog = new GeoLogVol("dbmWallLogCe", dbmSubstBox, aluminiumNitride);
204  GeoPhysVol* dbmSubstPhys = new GeoPhysVol(dbmSubstLog);
205 
206  GeoTrf::Translate3D dbmSubstPos(0, 0, max_thick/2.0-substrate_Z/2.0);
207  xform = new GeoTransform(dbmSubstPos);
208 
209  dbmModulePhys->add(xform);
210  dbmModulePhys->add(dbmSubstPhys);
211 
212  //-----------------------------------------------------
213  //Add to alignable transform
214  // DBM has only level 0 alignable transform.
215  // So, a transform w.r.t global position is created.
216  // This mean the alignable pos below should be
217  // the global position of the sensor
218 
219  int layer = m_gmt_mgr->GetLD();
220  double sensorPosInModuleCage_Z = layer1Space + layer*Zspacing - (substrate_Z + chip_thick + air_gap + diamond_Z/2.);
221  double sensorPosInModuleCage_Y = Rspacing + bot2Diamond + diamond_Y/2.;
222  double globPosZ = ZToIP + layerUnitPos_Z + (sensorPosInModuleCage_Z * cos(angle) - sensorPosInModuleCage_Y * sin(angle));
223  double globPosY = RToBeam + layerUnitPos_Y + (sensorPosInModuleCage_Z * sin(angle) + sensorPosInModuleCage_Y * cos(angle));
224 
225  GeoTrf::RotateX3D rmX10(-10.*Gaudi::Units::deg);
226  GeoTrf::Translation3D alignTransformPos(0, globPosY, globPosZ);
227  GeoAlignableTransform *xformAlign = new GeoAlignableTransform(GeoTrf::Transform3D(alignTransformPos*rmX10));
228  m_DDmgr->addAlignableTransform(0, idwafer, xformAlign, dbmDiamondPhys);
229  //-----------------------------------------------------
230 
231  return dbmModulePhys;
232  }
233 }
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
InDetDD::PixelDiodeTree
Tree structure to find the position, index or pitch of a pixel on a semi-regular grid The grid is con...
Definition: PixelDiodeTree.h:33
PixelGeometryManager::DBMBrcktLockZ
virtual double DBMBrcktLockZ()=0
PixelGeometryManager::DBMBracketZ
virtual double DBMBracketZ()=0
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
PixelGeometryManager::DBMDiamondZ
virtual double DBMDiamondZ()=0
PixelGeometryManager::DBMSpacingRadial
virtual double DBMSpacingRadial()=0
PixelGeometryManager
Definition: PixelGeometryManager.h:28
PixelGeometryManager::DBMDiamondX
virtual double DBMDiamondX()=0
InDetDD::detail::kNPixelLocations
@ kNPixelLocations
Definition: PixelGeoUtils.h:19
DBM_Module::DBM_Module
DBM_Module(InDetDD::PixelDetectorManager *ddmgr, PixelGeometryManager *mgr, GeoModelIO::ReadGeoModel *sqliteReader, std::shared_ptr< std::map< std::string, GeoFullPhysVol * >> mapFPV, std::shared_ptr< std::map< std::string, GeoAlignableTransform * >> mapAX)
Definition: DBM_Module.cxx:25
PixelGeometryManager::DBMCeramicY
virtual double DBMCeramicY()=0
PixelGeometryManager::DBMTrapezBackShortZ
virtual double DBMTrapezBackShortZ()=0
deg
#define deg
Definition: SbPolyhedron.cxx:17
InDetDD::SiDetectorManager::addDesign
const SiDetectorDesign * addDesign(std::unique_ptr< const SiDetectorDesign > &&)
Access to module design; returns an observer pointer.
Definition: SiDetectorManager.cxx:134
PixelGeometryManager::DBMSpace
virtual double DBMSpace()=0
PixelGeometryManager::GetSide
virtual int GetSide()=0
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
GeoVPixelFactory::m_mapAX
std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > m_mapAX
Definition: GeoVPixelFactory.h:48
GeoVPixelFactory::m_sqliteReader
GeoModelIO::ReadGeoModel * m_sqliteReader
Definition: GeoVPixelFactory.h:46
DBM_Module.h
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:360
GeoVPixelFactory::m_DDmgr
InDetDD::PixelDetectorManager * m_DDmgr
Definition: GeoVPixelFactory.h:45
PixelGeometryManager::DBMAirGap
virtual double DBMAirGap()=0
GeoVPixelFactory::m_gmt_mgr
PixelGeometryManager * m_gmt_mgr
Definition: GeoVPixelFactory.h:43
GeoVPixelFactory::m_mapFPV
std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > m_mapFPV
Definition: GeoVPixelFactory.h:47
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
PixelDetectorManager.h
PixelGeoUtils.h
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:71
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
PixelGeometryManager::Eta
virtual int Eta()=0
InDetMaterialManager::getMaterialForVolume
const GeoMaterial * getMaterialForVolume(const std::string &materialName, double volume, const std::string &newName="")
Create and get material with a density calculated to give weight in predefined weight table.
Definition: InDetMaterialManager.cxx:460
PixelGeometryManager::DBMAngle
virtual double DBMAngle()=0
PixelGeometryManager::DBMCoolingSidePlateY
virtual double DBMCoolingSidePlateY()=0
PixelGeometryManager::DBMSpacingZ
virtual double DBMSpacingZ()=0
PixelGeometryManager::DBMTrapezBackY
virtual double DBMTrapezBackY()=0
InDetDD::PixelDetectorManager::addAlignableTransform
virtual void addAlignableTransform(int level, const Identifier &id, GeoAlignableTransform *xf, const GeoVFullPhysVol *child)
Add alignable transforms.
Definition: PixelDetectorManager.cxx:274
PixelGeometryManager::DBMCeramicZ
virtual double DBMCeramicZ()=0
PixelGeometryManager::DBMCeramicX
virtual double DBMCeramicX()=0
InDetDD::PixelDetectorManager
Definition: PixelDetectorManager.h:47
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDetDD::PixelReadoutTechnology::FEI4
@ FEI4
GeoVPixelFactory::m_mat_mgr
InDetMaterialManager * m_mat_mgr
Definition: GeoVPixelFactory.h:44
SiDetectorElement.h
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
PixelModuleDesign.h
DBM_Module::m_design
const InDetDD::SiDetectorDesign * m_design
Definition: DBM_Module.h:38
PixelGeometryManager::DBMDiamondY
virtual double DBMDiamondY()=0
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
GeoVPixelFactory
This is the base class for all the pieces of the Pixel detector.
Definition: GeoVPixelFactory.h:31
PixelGeometryManager::DBMFEI4X
virtual double DBMFEI4X()=0
PixelGeometryManager::getIdHelper
virtual const PixelID * getIdHelper()=0
InDetDD::Undefined
@ Undefined
Definition: DetectorDesign.h:46
PixelGeometryManager::commonItems
virtual InDetDD::SiCommonItems * commonItems()=0
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
InDetDD::detail::kNDirections
@ kNDirections
Definition: PixelGeoUtils.h:20
InDetMaterialManager::getMaterial
const GeoMaterial * getMaterial(const std::string &materialName)
Get material. First looks for locally defined material and if not found looks in GeoModel material ma...
Definition: InDetMaterialManager.cxx:96
InDetDD::detail::makePixelDiodeTree
PixelDiodeTree makePixelDiodeTree(T_MsgParent *gmt_mgr, InDetDD::PixelReadoutTechnology readoutTechnology, const std::array< int, kNDirections > &circuits, const std::array< int, kNDirections > &dimPerCircuit, const std::array< std::array< double, kNDirections >, kNPixelLocations > &pitch)
Definition: PixelGeoUtils.h:46
PixelID
Definition: PixelID.h:67
PixelGeometryManager::DBMFEI4Z
virtual double DBMFEI4Z()=0
DBM_Module::Build
virtual GeoVPhysVol * Build() override
Definition: DBM_Module.cxx:80
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
InDetDD::PixelDetectorManager::addDetectorElement
virtual void addDetectorElement(SiDetectorElement *element) override
Add elememts.
Definition: PixelDetectorManager.cxx:128
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
PixelGeometryManager::DBMFEI4Y
virtual double DBMFEI4Y()=0
PixelGeometryManager::GetLD
virtual int GetLD()=0
PixelGeometryManager::Phi
virtual int Phi()=0
Identifier
Definition: IdentifierFieldParser.cxx:14