ATLAS Offline Software
DumpGeo.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Initial version:
6 // - 2017, Sep -- Riccardo Maria BIANCHI
7 // <riccardo.maria.bianchi@cern.ch>
8 // Main updates:
9 // - 2024, Feb -- Riccardo Maria BIANCHI
10 // <riccardo.maria.bianchi@cern.ch>
11 // Moved configuration to ComponentAccumulator (CA)
12 // - 2024, Mar -- Riccardo Maria BIANCHI
13 // <riccardo.maria.bianchi@cern.ch>
14 // Removed GeoExporter, moved all to DumpGeo
15 // - 2024, Apr -- Added missing sub-systems: Cavern, HGTD, FWD detectors, ...
16 
17 #include "DumpGeo/DumpGeo.h"
18 
19 // Athena includes
23 
24 // From GeoModel in Externals
25 #include "GeoModelDBManager/GMDBManager.h"
26 #include "GeoModelKernel/GeoBox.h"
27 #include "GeoModelKernel/GeoVDetectorManager.h"
28 #include "GeoModelKernel/GeoVolumeCursor.h"
29 #include "GeoModelWrite/WriteGeoModel.h"
30 // #include "GeoModelHelpers/defineWorld.h" // not available in 24.0...
31 
32 // C++ includes
33 #include <cstdlib> //For setenv
34 #include <iomanip>
35 #include <iostream>
36 #include <stdexcept>
37 #include <vector>
38 
39 // Units
40 #include "GeoModelKernel/Units.h"
41 #define UNITS GeoModelKernelUnits // so we can use, e.g., 'UNITS::cm'
42 
43 // TODO: replace this with GeoModelHelpers/defineWorld.h
44 //_____________________________________________________________________________________
45 GeoPhysVol* createTheWorld() {
46 // Define the units
47 #define gr UNITS::gram
48 #define mole UNITS::mole
49 #define cm3 UNITS::cm3
50 
51  // Define the chemical elements
52  GeoElement* Nitrogen =
53  new GeoElement("Nitrogen", "N", 7.0, 14.0067 * gr / mole);
54  GeoElement* Oxygen = new GeoElement("Oxygen", "O", 8.0, 15.9995 * gr / mole);
55  GeoElement* Argon = new GeoElement("Argon", "Ar", 18.0, 39.948 * gr / mole);
56  GeoElement* Hydrogen =
57  new GeoElement("Hydrogen", "H", 1.0, 1.00797 * gr / mole);
58 
59  // Define the materials
60  double densityOfAir = 0.001214 * gr / cm3;
61  GeoMaterial* air = new GeoMaterial("Air", densityOfAir);
62  air->add(Nitrogen, 0.7494);
63  air->add(Oxygen, 0.2369);
64  air->add(Argon, 0.0129);
65  air->add(Hydrogen, 0.0008);
66  air->lock();
67 
68  //-----------------------------------------------------------------------------------//
69  // create the world volume container and
70  // get the 'world' volume, i.e. the root volume of the GeoModel tree
71  const GeoBox* worldBox =
72  new GeoBox(1000 * UNITS::cm, 1000 * UNITS::cm, 1000 * UNITS::cm);
73  const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air);
74  GeoPhysVol* world = new GeoPhysVol(worldLog);
75  return world;
76 }
77 
78 //____________________________________________________________________
79 DumpGeo::DumpGeo(const std::string& name, ISvcLocator* svcLocator)
80  : AthAlgorithm(name, svcLocator) {}
81 
82 //____________________________________________________________________
84  ATH_MSG_DEBUG("in initialize()");
85 
86  ATH_MSG_INFO("===================================================");
87  ATH_MSG_INFO("\t\tLaunching DumpGeo");
88  ATH_MSG_INFO("===================================================");
89 
90  ATH_MSG_INFO("Accessing the ATLAS geometry...");
91  const GeoModelExperiment* theExpt = nullptr;
92  ATH_CHECK(detStore()->retrieve(theExpt, "ATLAS"));
93 
94  // Get the ATLAS GEOMETRY 'World' volume
95  PVConstLink world(theExpt->getPhysVol());
96 
98  "User filter DetectorManagers: " << m_user_filterDetManagersList);
99 
100  ServiceHandle<IGeoDbTagSvc> geoDbTag("GeoDbTagSvc", name());
101  ATH_CHECK(geoDbTag.retrieve());
102  ATH_MSG_INFO(
103  "This is the Geometry TAG we are dumping: " << geoDbTag->atlasVersion());
104 
105  GeoPhysVol* volTop = createTheWorld();
106 
107  // Get list of managers
108  // We fill a set from the output vector,
109  // so we can use its built-in 'count' method later,
110  // to search for DetManagers
111  ATH_MSG_INFO("Dumping the GeoModel tree...");
112  std::set<std::string> managersList{};
113  {
114  std::vector<std::string> blub = theExpt->getListOfManagers();
115  managersList.insert(blub.begin(), blub.end());
116  }
117  if (msgLvl(MSG::INFO)) {
118  ATH_MSG_INFO("List of the GeoModel Detector Managers that are being dumped: ");
119  for (auto const& man : managersList) {
120  // get the DetectorManager
121  const GeoVDetectorManager* manager = theExpt->getManager(man);
122  unsigned int nTreetops = manager->getNumTreeTops();
123  std::cout << "\t" << man << " [contains " << nTreetops << " treetops]"
124  << std::endl;
125  for (unsigned int i = 0; i < nTreetops; ++i) {
126  PVConstLink treetop(manager->getTreeTop(i));
127  // get treetop's volume
128  const GeoVPhysVol* vol = treetop;
129  // get treetop's logvol's name
130  std::string volName = vol->getLogVol()->getName();
131  std::cout << "\t\t treetop: " << volName << std::endl;
132  }
133  }
134  }
135 
136  if (!(m_user_filterDetManagersList.empty())) {
137  // Convert the list of det managers passed by the user into a set
138  std::set<std::string> user_managersList{};
139  {
140  user_managersList.insert(m_user_filterDetManagersList.begin(),
142  }
143  // safety check:
144  // check that all DetManagers requested by the user are in the list
145  // If not, print an error message to warn the user and return
146  for (auto& userDet : user_managersList) {
147  if (!managersList.count(userDet)) {
149  "This Detector Manager you requested to dump is not in the list of "
150  "DetectorManagers for the geometry tag you are using: "
151  << userDet);
152  throw GaudiException(
153  "The Detector Manager you requested to dump is not in the list of "
154  "DetectorManagers.",
155  "DumpGeo", StatusCode::FAILURE);
156  }
157  }
158 
159  if (!(managersList.empty())) {
160  for (auto const& mm : managersList) {
161  // get the DetectorManager
162  const GeoVDetectorManager* manager = theExpt->getManager(mm);
163 
164  // get the name of the DetectorManager
165  std::string detManName = manager->getName();
166  ATH_MSG_INFO("\tDetectorManager: " << detManName);
167 
168  // get the DetManager's TreeTops
169  unsigned int nTreetops = manager->getNumTreeTops();
170  ATH_MSG_INFO("\t" << mm << " - # TreeTops: " << nTreetops);
171 
172  if ((nTreetops > 0) && user_managersList.count(detManName)) {
173 
174  for (unsigned int i = 0; i < nTreetops; ++i) {
175 
176  PVConstLink treetop(manager->getTreeTop(i));
177 
178  // get treetop's volume
179  const GeoVPhysVol* vol = treetop;
180 
181  // get volume's transform
182  // NOTE: we use getDefX() to get the transform without any alignment
183  GeoTransform* volXf = new GeoTransform(vol->getDefX());
184 
185  // get volume's logvol's name
186  std::string volName = vol->getLogVol()->getName();
187  ATH_MSG_INFO("\t* treetop " << i << ": " << volName);
188 
189  // Add to the main volume a GeoNameTag with the name of the
190  // DetectorManager
191  volTop->add(new GeoNameTag(detManName));
192  // add Transform and Volume to the main PhysVol
193  volTop->add(volXf);
194  volTop->add(const_cast<GeoVPhysVol*>(vol));
195 
196  if (m_showTreetopContent) {
197  ATH_MSG_INFO("You enabled the option 'showTreetopContent', so we now print the content of the first layers of child volumes of the Treetops...");
198  unsigned v1{0};
199  GeoVolumeCursor av(treetop);
200  while (!av.atEnd()) {
201  ++v1;
202  if(1==v1) ATH_MSG_INFO("first level of child volumes:");
203  ATH_MSG_INFO("\t\t- child's name: " << av.getName());
204  ATH_MSG_INFO("\t\t- child's n. sub-nodes: " << av.getVolume()->getNChildNodes());
205  ATH_MSG_INFO("\t\t- child's n. sub-volumes: " << av.getVolume()->getNChildVols());
206 
207 
208  unsigned v2{0};
209  GeoVolumeCursor av2(av.getVolume());
210  while (!av2.atEnd()) {
211  ++v2;
212  if(1==v2) ATH_MSG_INFO("second level of child volumes:");
213  ATH_MSG_INFO("\t\t\t- child's logvol's name: " << av2.getVolume()->getLogVol()->getName());
214 
215  unsigned v3{0};
216  GeoVolumeCursor av3(av2.getVolume());
217  while (!av3.atEnd()) {
218  ++v3;
219  if(1==v3) ATH_MSG_INFO("third level of child volumes:");
220  ATH_MSG_INFO("\t\t\t\t- child's logvol's name: " << av3.getVolume()->getLogVol()->getName());
221  av3.next(); // increment volume cursor.
222  } // end while
223 
224  av2.next(); // increment volume cursor.
225  } // end while
226 
227  av.next(); // increment volume cursor.
228  } // end while
229  }
230  }
231  }
232  }
233  }
234  }
235 
236  // DEBUG inspection
237  if (msgLvl(MSG::DEBUG)) {
239  "Looping over top volumes in the GeoModel tree (children of the "
240  "'World' volume)...");
241  GeoVolumeCursor av(world);
242  while (!av.atEnd()) {
243  std::string volname = av.getName();
244  ATH_MSG_DEBUG("\t* relevant NameTag:" << volname);
245  av.next(); // increment volume cursor.
246  }
247  }
248 
249  ATH_MSG_INFO("Creating the SQLite DB file...");
250  if (m_outFileName.empty()) {
251  ATH_MSG_FATAL("The name of the output SQLite file is not set!");
252  throw GaudiException("The name of the output SQLite file is not set!",
253  "DumpGeo", StatusCode::FAILURE);
254  }
255  ATH_MSG_INFO("Output file name: " << m_outFileName);
256 
257  // open the DB connection
258  GMDBManager db(m_outFileName);
259 
260  // check the DB connection
261  if (db.checkIsDBOpen())
262  ATH_MSG_INFO("OK! Database is open!");
263  else {
264  ATH_MSG_ERROR(" ***** Database ERROR!! Exiting...");
265  throw GaudiException(
266  "The GeoModel SQLite .db file could not be opened successfully.",
267  "DumpGeo", StatusCode::FAILURE);
268  }
269 
270  ATH_MSG_INFO("Traversing the GeoModel tree...");
271  // Dump the tree volumes into a DB
272  // 1. init the GeoModel node action
273  GeoModelIO::WriteGeoModel dumpGeoModelGraph(db);
274  // 2. visit all GeoModel nodes
275  if (!(m_user_filterDetManagersList.empty())) {
276  volTop->exec(&dumpGeoModelGraph);
277  } else {
278  world->exec(&dumpGeoModelGraph);
279  }
280  ATH_MSG_INFO("Saving the GeoModel tree to the DB...");
281  // 3. save it to an SQLite file
282  dumpGeoModelGraph.saveToDB();
283  ATH_MSG_ALWAYS("DONE. Geometry saved to " << m_outFileName);
284 
285  // Quick test if DEBUG
286  if (msgLvl(MSG::DEBUG)) {
288  "Test - list of all the GeoMaterial nodes in the persistified "
289  "geometry:");
290  db.printAllMaterials();
292  "Test - list of all the GeoElement nodes in the persistified "
293  "geometry:");
294  db.printAllElements();
295  }
296 
297  ATH_MSG_DEBUG("End of DumpGeo::init().");
298  return StatusCode::SUCCESS;
299 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
GeoModelExperiment::getPhysVol
GeoPhysVol * getPhysVol()
Destructor.
Definition: GeoModelExperiment.cxx:21
DumpGeo::m_outFileName
Gaudi::Property< std::string > m_outFileName
Definition: DumpGeo.h:48
DumpGeo::initialize
StatusCode initialize()
Definition: DumpGeo.cxx:83
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
createTheWorld
GeoPhysVol * createTheWorld()
Definition: DumpGeo.cxx:45
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthMsgStreamMacros.h
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:43
DumpGeo::DumpGeo
DumpGeo(const std::string &name, ISvcLocator *pSvcLocator) ATLAS_CTORDTOR_NOT_THREAD_SAFE
Definition: DumpGeo.cxx:79
cm3
#define cm3
GeoModelExperiment
Definition: GeoModelExperiment.h:32
AthCommonMsg< Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
gr
#define gr
DumpGeo::m_user_filterDetManagersList
Gaudi::Property< std::vector< std::string > > m_user_filterDetManagersList
Definition: DumpGeo.h:50
GeoModelExperiment::getListOfManagers
std::vector< std::string > getListOfManagers() const
Definition: GeoModelExperiment.cxx:64
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
GeoModelExperiment.h
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
DumpGeo::m_showTreetopContent
Gaudi::Property< bool > m_showTreetopContent
Definition: DumpGeo.h:51
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
GeoModelExperiment::getManager
const GeoVDetectorManager * getManager(const std::string &name) const
Definition: GeoModelExperiment.cxx:52
ATH_MSG_ALWAYS
#define ATH_MSG_ALWAYS(x)
Definition: AthMsgStreamMacros.h:35
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AthAlgorithm
Definition: AthAlgorithm.h:47
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
DumpGeo.h
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
DEBUG
#define DEBUG
Definition: page_access.h:11
mole
#define mole
python.Logging.manager
manager
Definition: PhysicsAnalysis/D3PDTools/AnaAlgorithm/python/Logging.py:92
IGeoDbTagSvc.h
ServiceHandle< IGeoDbTagSvc >