ATLAS Offline Software
Loading...
Searching...
No Matches
StripDetectorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "StripDetectorTool.h"
5#include "StripGmxInterface.h"
6
9
11#include <GeoModelKernel/GeoPhysVol.h>
13#include <SGTools/DataProxy.h>
14#include "GeoModelRead/ReadGeoModel.h"
15
16
17namespace ITk
18{
19
21 const std::string &name,
22 const IInterface *parent)
23 : GeoModelXmlTool(type, name, parent)
24{
25}
26
27
29{
30 // retrieve the common stuff
32
33 GeoModelExperiment *theExpt = nullptr;
34 ATH_CHECK(detStore()->retrieve(theExpt, "ATLAS"));
35 const SCT_ID *idHelper = nullptr;
36 ATH_CHECK(detStore()->retrieve(idHelper, "SCT_ID"));
37
38 m_commonItems = std::make_unique<InDetDD::SiCommonItems>(idHelper);
39
40
41 // If we are not taking the geo from sqlite, check the availability of tables
42 // (or that we have a local geometry)
43 std::string node{"SCT"};
44 std::string table{"ITKXDD"};
45
46 GeoModelIO::ReadGeoModel* sqlreader = getSqliteReader();
47
48 if(!sqlreader){
49 if (!isAvailable(node, table)) {
50 ATH_MSG_INFO("Trying new " << m_detectorName.value() << " database location.");
51 node = "InnerDetector";
52 table = "StripXDD";
53 if (!isAvailable(node, table)) {
54 ATH_MSG_ERROR("No ITk Strip geometry found. ITk Strip can not be built.");
55 return StatusCode::FAILURE;
56 }
57 }
58 }
59 //
60 // Create the detector manager
61 //
62 // The * converts a ConstPVLink to a ref to a GeoVPhysVol
63 // The & takes the address of the GeoVPhysVol
64 GeoPhysVol *world = &*theExpt->getPhysVol();
67
69 // Load the geometry, create the volume,
70 // node,table are the location in the DB to look for the clob
71 // empty strings are the (optional) containing detector and envelope names
72 // allowed to pass a null sqlreader ptr - it will be used to steer the source of the geometry
73 const GeoVPhysVol* topVolume = createTopVolume(world, gmxInterface, node, table,"","",sqlreader);
74 // if we are using SQLite inputs,
75 if(sqlreader){
76 ATH_MSG_INFO("Building Strip Readout Geometry from SQLite using "<<m_geoDbTagSvc->getParamSvcName());
77 gmxInterface.buildReadoutGeometryFromSqlite(m_sqliteReadSvc.operator->(),sqlreader);
78 }
79
80 if (topVolume) { //see that a valid pointer is returned
81 manager->addTreeTop(topVolume);
83 manager->initNeighbours();
84 } else {
85 ATH_MSG_FATAL("Could not find the Top Volume!!!");
86 return StatusCode::FAILURE;
87 }
88
89 // set the manager
91
92 ATH_CHECK(detStore()->record(m_detManager, m_detManager->getName()));
93 theExpt->addManager(m_detManager);
94
95 return StatusCode::SUCCESS;
96}
97
98
100{
101 SG::DataProxy* proxy = detStore()->proxy(ClassID_traits<InDetDD::SCT_DetectorManager>::ID(),m_detManager->getName());
102 if (proxy) {
103 proxy->reset();
104 m_detManager = nullptr;
105 }
106 return StatusCode::SUCCESS;
107}
108
110{
111 ATH_MSG_INFO("\n\nSCT Numerology:\n===============\n\nNumber of parts is " << m_waferTree.nParts() << "\n");
113
114 bool barrelDone = false;
115 for (int b = -1; b <= 1; ++b) {
116 if (m_waferTree.count(b)) {
117 msg(MSG::DEBUG) << " Found barrel with index " << b << std::endl;
118 n.addBarrel(b);
119 if (!barrelDone) {
120 n.setNumLayers(m_waferTree[b].nLayers());
121 msg(MSG::DEBUG) << " Number of barrel layers = " << n.numLayers() << std::endl;
122 for (LayerDisk::iterator l = m_waferTree[b].begin(); l != m_waferTree[b].end(); ++l) {
123 n.setNumEtaModulesForLayer(l->first, l->second.nEtaModules());
124 // All staves within a layer are assumed identical, so we can just look at the first eta
125 n.setNumPhiModulesForLayer(l->first, l->second.begin()->second.nPhiModules());
126 msg(MSG::DEBUG) << " layer = " << l->first << " has " << n.numEtaModulesForLayer(l->first)
127 << " etaModules each with " << n.numPhiModulesForLayer(l->first) << " phi modules" << std::endl;
128 }
129 barrelDone = true;
130 }
131 }
132
133 }
134
135 bool endcapDone = false;
136 for (int ec = -2; ec <= 2; ec += 4) {
137 if (m_waferTree.count(ec)) {
138 msg(MSG::DEBUG) << " Found endcap with index " << ec << std::endl;
139 n.addEndcap(ec);
140 if (!endcapDone) {
141 n.setNumDisks(m_waferTree[ec].nLayers());
142 msg(MSG::DEBUG) << " Number of endcap wheels = " << n.numDisks() << std::endl;
143 for (LayerDisk::iterator l = m_waferTree[ec].begin(); l != m_waferTree[ec].end(); ++l) {
144 n.setNumRingsForDisk(l->first, l->second.nEtaModules());
145 msg(MSG::DEBUG) << " Wheel " << l->first << " has " << n.numRingsForDisk(l->first) << " rings" << std::endl;
146 for (EtaModule::iterator eta = l->second.begin(); eta != l->second.end(); ++eta) {
147 n.setNumPhiModulesForDiskRing(l->first, eta->first, eta->second.nPhiModules());
148 msg(MSG::DEBUG) << " Ring " << eta->first << " has "
149 << n.numPhiModulesForDiskRing(l->first, eta->first) << " phi modules" << std::endl;
150 }
151 }
152 endcapDone = true;
153 }
154 }
155 }
156
157 msg(MSG::INFO) << endmsg;
158
159 int totalWafers = 0;
160 for (BarrelEndcap::iterator bec = m_waferTree.begin(); bec != m_waferTree.end(); ++bec) {
161 for (LayerDisk::iterator ld = bec->second.begin(); ld != bec->second.end(); ++ld) {
162 for (EtaModule::iterator eta = ld->second.begin(); eta != ld->second.end(); ++eta) {
163 for (PhiModule::iterator phi = eta->second.begin(); phi != eta->second.end(); ++phi) {
164 for (Side::iterator side =phi->second.begin(); side != phi->second.end(); ++side) {
165 totalWafers++;
166 }
167 }
168 }
169 }
170 }
171 ATH_MSG_INFO("Total number of wafers added is " << totalWafers);
172 const SCT_ID *sctIdHelper = static_cast<const SCT_ID *> (m_commonItems->getIdHelper());
173 ATH_MSG_INFO("Total number of wafer identifiers is " << sctIdHelper->wafer_hash_max());
174 //
175 // Used in digitization to create one vector big enough to hold all strips, whichever detector is in consideration.
176 // Anyway they are common to pixels and strips! Pixels dominate the EtaCell count (which traditionally the SCT does not set)
177 //
178 n.setMaxNumEtaCells(1);
179 for (int d = 0; d < manager->numDesigns(); ++d) {
180 n.setMaxNumPhiCells(manager->getSCT_Design(d)->cells());
181 }
182 ATH_MSG_INFO("Max. eta cells is " << n.maxNumEtaCells());
183 ATH_MSG_INFO("Max. phi cells is " << n.maxNumPhiCells());
184 ATH_MSG_INFO("Max. no. strips is " << n.maxNumStrips());
185
186 manager->numerology() = std::move(n);
187
188 ATH_MSG_INFO("End of numerology\n");
189
190 //
191 // Alignment preparation
192 //
193 if (m_alignable) {
194 ATH_MSG_INFO("Set up alignment directories");
195 const std::string topFolder(m_alignmentFolderName);
196 const std::string barrelBase("/SCTB");
197 const std::string endcapBase("/SCTE");
198 std::string baseName("");
199
200 // Register the keys and the level corresponding to the key
201 // and whether it expects a global or local shift.
202 // level 0: sensor, level 1: module, level 2, layer/disc, level 3: whole barrel/enccap
203 //Before the type was determined from content; would be better to just set it explcitly if we only expect one
204 //Format for ITk strip. Set it to "static_run1" for the moment, since this is what exisits in the conditions
205 //but this should be revisited in future
207 manager->addAlignFolderType(alignFolderType);
208
209 switch (alignFolderType) {
211 manager->addChannel(topFolder + "/ID", 3, InDetDD::global);
212 manager->addChannel(topFolder + "/SCT",2, InDetDD::global);
213 for (BarrelEndcap::iterator bec = m_waferTree.begin(); bec != m_waferTree.end(); ++bec) {
214 switch (bec->first) {
215 case -2:
216 baseName = topFolder + endcapBase + "C";
217 break;
218 case 0:
219 baseName = topFolder + barrelBase;
220 break;
221 case 2:
222 baseName = topFolder + endcapBase + "A";
223 break;
224 default:
225 ATH_MSG_FATAL("Unknown SCT part with bec-ID " << bec->first << " encountered.");
226 throw std::runtime_error("Unknown ITkStrip part for alignment.");
227 }
228 for (LayerDisk::iterator ld = bec->second.begin(); ld != bec->second.end(); ++ld) {
229 std::ostringstream layer;
230 layer << ld->first + 1;
231 manager->addChannel(baseName + layer.str(), 1, InDetDD::local);
232 }
233 }
234 break;
235 // To be added: case InDetDD::timedependent_run2:, see SCT_GeoModel
236 default:
237 ATH_MSG_FATAL("Alignment requested for unknown alignment folder type in StripDetectorFactory.");
238 throw std::runtime_error("Wrong alignment folder type for StripDetectorFactory in StripGeoModelXml.");
239 }
240 }
241
242 return;
243}
244
245
246} // namespace ITk
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
GeoPhysVol * getPhysVol()
Destructor.
void addManager(const GeoVDetectorManager *)
virtual GeoVDetectorManager * manager()
ServiceHandle< IRDBAccessSvc > m_sqliteReadSvc
StatusCode createBaseTool()
bool isAvailable(const std::string &versionNode, const std::string &tableNode) const
GeoModelXmlTool(const std::string &type, const std::string &name, const IInterface *parent)
const GeoVPhysVol * createTopVolume(GeoPhysVol *worldVol, GmxInterface &interface, const std::string &versionNode, const std::string &tableNode, const std::string &containingDetector="", const std::string &envelopeName="", const GeoModelIO::ReadGeoModel *sqlreader=nullptr) const
Gaudi::Property< std::string > m_detectorName
ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc
GeoModelIO::ReadGeoModel * getSqliteReader() const
StripDetectorTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode clear() override final
const InDetDD::SCT_DetectorManager * m_detManager
Gaudi::Property< bool > m_alignable
Gaudi::Property< std::string > m_alignmentFolderName
virtual StatusCode create() override final
std::unique_ptr< InDetDD::SiCommonItems > m_commonItems
Gaudi::Property< bool > m_doEndcapEtaNeighbour
void doNumerology(InDetDD::SCT_DetectorManager *manager)
void buildReadoutGeometryFromSqlite(IRDBAccessSvc *rdbAccessSvc, GeoModelIO::ReadGeoModel *sqlreader)
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
Class to extract numerology for Pixel and SCT.
This is an Identifier helper class for the SCT subdetector.
Definition SCT_ID.h:68
size_type wafer_hash_max() const
Definition SCT_ID.cxx:621
Definition node.h:24
MsgStream & msg
Definition testRead.cxx:32