ATLAS Offline Software
Loading...
Searching...
No Matches
StripDetectorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 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 // Create a symLink to the SiDetectorManager base class so it can be accessed as either SiDetectorManager or
96 // SCT_DetectorManager
97 const InDetDD::SiDetectorManager *siDetManager = m_detManager;
98 ATH_CHECK(detStore()->symLink(m_detManager, siDetManager));
99
100 return StatusCode::SUCCESS;
101}
102
103
105{
106 SG::DataProxy* proxy = detStore()->proxy(ClassID_traits<InDetDD::SCT_DetectorManager>::ID(),m_detManager->getName());
107 if (proxy) {
108 proxy->reset();
109 m_detManager = nullptr;
110 }
111 return StatusCode::SUCCESS;
112}
113
115{
116 ATH_MSG_INFO("\n\nSCT Numerology:\n===============\n\nNumber of parts is " << m_waferTree.nParts() << "\n");
118
119 bool barrelDone = false;
120 for (int b = -1; b <= 1; ++b) {
121 if (m_waferTree.count(b)) {
122 msg(MSG::INFO) << " Found barrel with index " << b << std::endl;
123 n.addBarrel(b);
124 if (!barrelDone) {
125 n.setNumLayers(m_waferTree[b].nLayers());
126 msg(MSG::INFO) << " Number of barrel layers = " << n.numLayers() << std::endl;
127 for (LayerDisk::iterator l = m_waferTree[b].begin(); l != m_waferTree[b].end(); ++l) {
128 n.setNumEtaModulesForLayer(l->first, l->second.nEtaModules());
129 // All staves within a layer are assumed identical, so we can just look at the first eta
130 n.setNumPhiModulesForLayer(l->first, l->second.begin()->second.nPhiModules());
131 msg(MSG::INFO) << " layer = " << l->first << " has " << n.numEtaModulesForLayer(l->first)
132 << " etaModules each with " << n.numPhiModulesForLayer(l->first) << " phi modules" << std::endl;
133 }
134 barrelDone = true;
135 }
136 }
137
138 }
139
140 bool endcapDone = false;
141 for (int ec = -2; ec <= 2; ec += 4) {
142 if (m_waferTree.count(ec)) {
143 msg(MSG::INFO) << " Found endcap with index " << ec << std::endl;
144 n.addEndcap(ec);
145 if (!endcapDone) {
146 n.setNumDisks(m_waferTree[ec].nLayers());
147 msg(MSG::INFO) << " Number of endcap wheels = " << n.numDisks() << std::endl;
148 for (LayerDisk::iterator l = m_waferTree[ec].begin(); l != m_waferTree[ec].end(); ++l) {
149 n.setNumRingsForDisk(l->first, l->second.nEtaModules());
150 msg(MSG::INFO) << " Wheel " << l->first << " has " << n.numRingsForDisk(l->first) << " rings" << std::endl;
151 for (EtaModule::iterator eta = l->second.begin(); eta != l->second.end(); ++eta) {
152 n.setNumPhiModulesForDiskRing(l->first, eta->first, eta->second.nPhiModules());
153 msg(MSG::INFO) << " Ring " << eta->first << " has "
154 << n.numPhiModulesForDiskRing(l->first, eta->first) << " phi modules" << std::endl;
155 }
156 }
157 endcapDone = true;
158 }
159 }
160 }
161
162 msg(MSG::INFO) << endmsg;
163
164 int totalWafers = 0;
165 for (BarrelEndcap::iterator bec = m_waferTree.begin(); bec != m_waferTree.end(); ++bec) {
166 for (LayerDisk::iterator ld = bec->second.begin(); ld != bec->second.end(); ++ld) {
167 for (EtaModule::iterator eta = ld->second.begin(); eta != ld->second.end(); ++eta) {
168 for (PhiModule::iterator phi = eta->second.begin(); phi != eta->second.end(); ++phi) {
169 for (Side::iterator side =phi->second.begin(); side != phi->second.end(); ++side) {
170 totalWafers++;
171 }
172 }
173 }
174 }
175 }
176 ATH_MSG_INFO("Total number of wafers added is " << totalWafers);
177 const SCT_ID *sctIdHelper = dynamic_cast<const SCT_ID *> (m_commonItems->getIdHelper());
178 ATH_MSG_INFO("Total number of wafer identifiers is " << sctIdHelper->wafer_hash_max());
179 //
180 // Used in digitization to create one vector big enough to hold all strips, whichever detector is in consideration.
181 // Anyway they are common to pixels and strips! Pixels dominate the EtaCell count (which traditionally the SCT does not set)
182 //
183 n.setMaxNumEtaCells(1);
184 for (int d = 0; d < manager->numDesigns(); ++d) {
185 n.setMaxNumPhiCells(manager->getSCT_Design(d)->cells());
186 }
187 ATH_MSG_INFO("Max. eta cells is " << n.maxNumEtaCells());
188 ATH_MSG_INFO("Max. phi cells is " << n.maxNumPhiCells());
189 ATH_MSG_INFO("Max. no. strips is " << n.maxNumStrips());
190
191 manager->numerology() = n;
192
193 ATH_MSG_INFO("End of numerology\n");
194
195 //
196 // Alignment preparation
197 //
198 if (m_alignable) {
199 ATH_MSG_INFO("Set up alignment directories");
200 const std::string topFolder(m_alignmentFolderName);
201 const std::string barrelBase("/SCTB");
202 const std::string endcapBase("/SCTE");
203 std::string baseName("");
204
205 // Register the keys and the level corresponding to the key
206 // and whether it expects a global or local shift.
207 // level 0: sensor, level 1: module, level 2, layer/disc, level 3: whole barrel/enccap
208 //Before the type was determined from content; would be better to just set it explcitly if we only expect one
209 //Format for ITk strip. Set it to "static_run1" for the moment, since this is what exisits in the conditions
210 //but this should be revisited in future
212 manager->addAlignFolderType(alignFolderType);
213
214 switch (alignFolderType) {
216 manager->addChannel(topFolder + "/ID", 3, InDetDD::global);
217 manager->addChannel(topFolder + "/SCT",2, InDetDD::global);
218 for (BarrelEndcap::iterator bec = m_waferTree.begin(); bec != m_waferTree.end(); ++bec) {
219 switch (bec->first) {
220 case -2:
221 baseName = topFolder + endcapBase + "C";
222 break;
223 case 0:
224 baseName = topFolder + barrelBase;
225 break;
226 case 2:
227 baseName = topFolder + endcapBase + "A";
228 break;
229 default:
230 ATH_MSG_FATAL("Unknown SCT part with bec-ID " << bec->first << " encountered.");
231 throw std::runtime_error("Unknown ITkStrip part for alignment.");
232 }
233 for (LayerDisk::iterator ld = bec->second.begin(); ld != bec->second.end(); ++ld) {
234 std::ostringstream layer;
235 layer << ld->first + 1;
236 manager->addChannel(baseName + layer.str(), 1, InDetDD::local);
237 }
238 }
239 break;
240 // To be added: case InDetDD::timedependent_run2:, see SCT_GeoModel
241 default:
242 ATH_MSG_FATAL("Alignment requested for unknown alignment folder type in StripDetectorFactory.");
243 throw std::runtime_error("Wrong alignment folder type for StripDetectorFactory in StripGeoModelXml.");
244 }
245 }
246
247 return;
248}
249
250
251} // 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_FATAL(x)
#define ATH_MSG_INFO(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...
Base class for Pixel and SCT Detector managers.
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