ATLAS Offline Software
GeoModelXmlTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <GeoModelKernel/GeoPhysVol.h>
9 #include <GeoModelXml/Gmx2Geo.h>
10 #include <GeoModelXml/GmxInterface.h>
11 #include <GeoModelRead/ReadGeoModel.h>
15 
16 #include <fstream>
17 #include <utility>
18 
20  const std::string &name,
21  const IInterface *parent)
23 {
24 }
25 
27 {
28  ATH_CHECK(m_geoDbTagSvc.retrieve());
29  ATH_CHECK(m_rdbAccessSvc.retrieve());
30  ATH_CHECK(m_sqliteReadSvc.retrieve());
31 
32  return StatusCode::SUCCESS;
33 }
34 
35 const GeoVPhysVol* GeoModelXmlTool::createTopVolume(GeoPhysVol* world, GmxInterface& gmxInterface, const std::string& vNode, const std::string& tableName, const std::string& containingDetector, const std::string& envelopeName, const GeoModelIO::ReadGeoModel* sqlreader) const
36 {
37  //If we have a valid sqlreader pointer, it means the volume should already exist,
38  // so we don't need to create it
39  if(!sqlreader) createVolume(world, gmxInterface, vNode, tableName);
40  else ATH_MSG_INFO("Using geometry from .sqlite file for"<<m_detectorName);
41 
42  unsigned int nChildren = world->getNChildVols();
43 
44  const GeoVPhysVol * envVol = nullptr;
45  const GeoVPhysVol * topVol = nullptr;
46 
47  bool foundEnvelope = false;
48  bool foundContainingDetector = false;
49  // find the appropriate volume in the hierarchy, to allow it to be set as the topVolume in
50  // our detectorManager
51  std::string detectorName = m_detectorName;
52  //if a containingDetector is set, which the detector we are dealing with will sit inside, look for that first.
53  // Otherwise its just the name of the detector we are dealing with we look for
54  if(containingDetector!="") detectorName = containingDetector;
55 
56  for (int iChild = nChildren - 1; iChild>=0; --iChild) {
57  if (world->getNameOfChildVol(iChild) == detectorName) {
58  // The * converts from a ConstPVLink to a reference to a GeoVPhysVol;
59  // the & takes its address.
60  envVol = &*world->getChildVol(iChild);
61  foundContainingDetector = true;
62  if(envelopeName=="") {topVol = envVol;break;}
63  unsigned int nGrandchildren = envVol->getNChildVols();
64  for (int iGchild = nGrandchildren - 1; iGchild>=0; --iGchild) {
65  if (envVol->getNameOfChildVol(iGchild) == envelopeName) {
66  topVol = &*(envVol->getChildVol(iGchild));
67  foundEnvelope = true;
68  break;
69  }
70  }
71  }
72  }
73  if(containingDetector!="" && !foundContainingDetector) ATH_MSG_ERROR("Couldn't find the containing detector "<<containingDetector<<" in the world hierarchy!");
74  else if(envelopeName!="" && !foundEnvelope) ATH_MSG_ERROR("Couldn't find the envelope volume "<<envelopeName<<" in the world hierarchy!");
75  return topVol;
76 }
77 
78 bool GeoModelXmlTool::isAvailable(const std::string& vNode, const std::string& tableName) const
79 {
80  if (m_gmxFilename.empty()) {
81  DecodeVersionKey versionKey(&*m_geoDbTagSvc, vNode);
82  const std::string& versionTag = versionKey.tag();
83  const std::string& versionNode = versionKey.node();
84  const std::string version = m_rdbAccessSvc->getChildTag(tableName, versionTag, versionNode);
85  if (version.empty()) {
86  return false;
87  }
88  ATH_MSG_INFO("Using " << version << " from " << versionNode << " tag " << versionTag);
89  }
90 
91  return true;
92 }
93 
94 std::string GeoModelXmlTool::getBlob(const std::string& vNode, const std::string& tableName) const
95 {
96  DecodeVersionKey versionKey(&*m_geoDbTagSvc, vNode);
97  const IRDBRecordset_ptr recordSet = m_rdbAccessSvc->getRecordsetPtr(tableName, versionKey.tag(), versionKey.node());
98  if (!recordSet || recordSet->size() == 0) {
99  ATH_MSG_FATAL("Unable to obtain " << vNode << " recordSet");
100  throw std::runtime_error("Unable to obtain recordSet");
101  }
102  const IRDBRecord *record = (*recordSet)[0];
103  std::string clobString = record->getString("XMLCLOB");
104  return clobString;
105 }
106 
107 void GeoModelXmlTool::createVolume(GeoPhysVol* world, GmxInterface& gmxInterface, const std::string& vNode, const std::string& tableName) const {
108  int flags{};
109  std::string gmxInput;
110 
111  if (m_gmxFilename.empty()) {
112  ATH_MSG_INFO("Getting " << m_detectorName.value() << " GeoModelXml description from the geometry database");
113  flags = 0x1; // Lowest bit ==> string; next bit implies gzip'd but we decided not to gzip
114  // how to propagate these to here best...?
115  gmxInput = getBlob(vNode,tableName);
116  if (gmxInput.empty()) { // Invalid blob?
117  std::string errMessage("GeoModelXmlTool::createTopVolume: Empty response received from the database.");
118  throw std::runtime_error(errMessage);
119  }
120  } else {
121  flags = 0;
122  gmxInput = PathResolver::find_file(m_gmxFilename, "DATAPATH");
123  ATH_MSG_INFO("Getting " << m_detectorName.value() << " GeoModelXml description from file "<<gmxInput);
124  if (gmxInput.empty()) { // File not found
125  std::string errMessage("GeoModelXmlTool::createTopVolume: Unable to find file " + m_gmxFilename +
126  " with PathResolver; check filename and DATAPATH environment variable");
127  throw std::runtime_error(errMessage);
128  }
129  }
130 
131  // Use the DTD from GeoModel
132  if (m_gmxFilename.empty()) {
133  std::string replacementName = "GeoModelXml/";
134  //now, work out the specific dtd version in the input .gmx
135  std::string startdelim = "SYSTEM \"";
136  std::string enddelim = "\" [";
137  unsigned startpos = gmxInput.find(startdelim) + startdelim.length();
138  unsigned endpos = gmxInput.find(enddelim);
139  std::string searchName = gmxInput.substr(startpos,(endpos - startpos));
140  if(searchName=="geomodel.dtd") replacementName+="geomodel_v0.dtd"; //used in xml for initial geometry tags - special case
141  else replacementName+=searchName;
142  ATH_MSG_DEBUG("Searching for "<<searchName<<" and replacing it with "<<replacementName);
143  size_t chars = searchName.length();
144  size_t index = gmxInput.find(searchName);
145  if(m_dtdName!="") replacementName=m_dtdName; //allow overriding of dtd version
146  if (index != std::string::npos) {
147  std::string dtdFile = PathResolver::find_file(replacementName, "DATAPATH");
148  ATH_MSG_DEBUG("dtdFile = " << dtdFile);
149  gmxInput.replace(index,chars, dtdFile);
150  } else {
151  throw std::runtime_error("GeoModelXmlTool::createTopVolume: Did not find valid .dtd in the gmx input string.");
152  }
153  }
154 
155  // optionally dump to local file for examination
156  if (m_clobOutputFileName != "") {
157  std::ofstream out(m_clobOutputFileName);
158  if (m_gmxFilename.empty()) {
159  out << gmxInput;
160  } else {
161  std::ifstream in(gmxInput);
162  out << in.rdbuf();
163  }
164  out.close();
165  }
166  gmxInterface.enableLogVolDeDuplication(m_deduplicateLogVol);
167  gmxInterface.enablePhysVolDeDuplication(m_deduplicatePhysVol);
168  gmxInterface.enableShapeDeDuplication(m_deduplicateShape);
169  gmxInterface.enableTransformDeDuplication(m_deduplicateTransf);
170 
171  Gmx2Geo gmx2Geo(gmxInput, world, gmxInterface, flags);
172 }
173 
174 GeoModelIO::ReadGeoModel* GeoModelXmlTool::getSqliteReader() const{
175  return m_geoDbTagSvc->getSqliteReader();
176 }
GeoModelXmlTool::m_rdbAccessSvc
ServiceHandle< IRDBAccessSvc > m_rdbAccessSvc
Definition: GeoModelXmlTool.h:43
GeoModelXmlTool::createBaseTool
StatusCode createBaseTool()
Definition: GeoModelXmlTool.cxx:26
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
index
Definition: index.py:1
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
IRDBRecord::getString
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
GeoModelXmlTool::m_clobOutputFileName
Gaudi::Property< std::string > m_clobOutputFileName
Definition: GeoModelXmlTool.h:60
GeoModelXmlTool::isAvailable
bool isAvailable(const std::string &versionNode, const std::string &tableNode) const
Definition: GeoModelXmlTool.cxx:78
DecodeVersionKey::node
const std::string & node() const
Return the version node.
Definition: DecodeVersionKey.cxx:97
GeoModelXmlTool::createTopVolume
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
Definition: GeoModelXmlTool.cxx:35
GeoModelXmlTool::m_detectorName
Gaudi::Property< std::string > m_detectorName
Definition: GeoModelXmlTool.h:42
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
GeoModelXmlTool::getSqliteReader
GeoModelIO::ReadGeoModel * getSqliteReader() const
Definition: GeoModelXmlTool.cxx:174
GeoModelXmlTool::m_gmxFilename
Gaudi::Property< std::string > m_gmxFilename
Definition: GeoModelXmlTool.h:41
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
DecodeVersionKey
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
Definition: DecodeVersionKey.h:18
test_pyathena.parent
parent
Definition: test_pyathena.py:15
DecodeVersionKey::tag
const std::string & tag() const
Return version tag.
Definition: DecodeVersionKey.cxx:91
GeoModelTool
Definition: GeoModelTool.h:17
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
GeoModelXmlTool::createVolume
void createVolume(GeoPhysVol *worldVol, GmxInterface &interface, const std::string &versionNode, const std::string &tableNode) const
Definition: GeoModelXmlTool.cxx:107
GeoModelXmlTool::m_dtdName
Gaudi::Property< std::string > m_dtdName
Definition: GeoModelXmlTool.h:46
GeoModelXmlTool::m_deduplicatePhysVol
Gaudi::Property< bool > m_deduplicatePhysVol
Definition: GeoModelXmlTool.h:50
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
GeoModelXmlTool::m_deduplicateShape
Gaudi::Property< bool > m_deduplicateShape
Definition: GeoModelXmlTool.h:52
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
DecodeVersionKey.h
get_generator_info.version
version
Definition: get_generator_info.py:33
GeoModelXmlTool::getBlob
std::string getBlob(const std::string &versionNode, const std::string &tableNode) const
Definition: GeoModelXmlTool.cxx:94
GeoModelXmlTool::m_deduplicateLogVol
Gaudi::Property< bool > m_deduplicateLogVol
Definition: GeoModelXmlTool.h:48
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
GeoModelXmlTool::m_geoDbTagSvc
ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc
Definition: GeoModelXmlTool.h:45
IRDBRecord
IRDBRecord is one record in the IRDBRecordset object.
Definition: IRDBRecord.h:27
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
GeoModelXmlTool.h
GeoModelXmlTool::m_sqliteReadSvc
ServiceHandle< IRDBAccessSvc > m_sqliteReadSvc
Definition: GeoModelXmlTool.h:44
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
GeoModelXmlTool::m_deduplicateTransf
Gaudi::Property< bool > m_deduplicateTransf
Definition: GeoModelXmlTool.h:54
GeoModelXmlTool::GeoModelXmlTool
GeoModelXmlTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: GeoModelXmlTool.cxx:19