26 #include <TInterpreter.h>
27 #include <TGeoElement.h>
28 #include <TGeoManager.h>
29 #include <TGDMLParse.h>
30 #include <TGDMLWrite.h>
44 static long gdml_parse(
Detector& description,
int argc,
char** argv) {
48 for(
int i = 0; i < argc && argv[i]; ++i) {
49 if ( 0 == ::strncmp(
"-input",argv[i],2) )
51 else if ( 0 == ::strncmp(
"-path", argv[i],2) )
53 else if ( 0 == ::strncmp(
"-world", argv[i],2) )
56 if ( input.empty() || (path.empty() && !wrld) ) {
58 "Usage: -plugin <name> -arg [-arg] \n"
59 " name: factory name DD4hep_ROOTGDMLParse \n"
60 " -input <string> Input file name. \n"
61 " -path <string> Path to parent detector element to attach \n"
62 " top volume from GDML file. \n"
63 " -world <string> Name of the world object if to be imported from gdml.\n"
64 " Note: -path and -world options are exclusive. \n"
65 "\tArguments given: " << arguments(argc,argv) << endl << flush;
68 printout(INFO,
"ROOTGDMLParse",
"+++ Read geometry from GDML file file:%s",input.c_str());
70 if ( !wrld && !elements.empty() ) {
73 for(
size_t i=0; i < elements.size(); ++i) {
74 const auto& e = elements[i];
75 if ( e == world.
name() )
77 child = parent.
child(e,
false);
78 if ( child.isValid() ) {
85 if ( i == elements.size()-1 ) {
87 TUri uri(input.c_str());
88 input = uri.GetRelativePart();
93 child.setPlacement(pv);
94 if (parent == world) description.
add(child);
95 else parent.
add(child);
96 printout(INFO,
"ROOTGDMLParse",
"+++ Attach GDML volume %s to Element path:%s",
97 vol.
name(), path.c_str());
100 except(
"ROOTGDMLParse",
"+++ Failed to parse GDML file:%s for path:%s",
101 input.c_str(),path.c_str());
104 child.setPlacement(pv);
105 if (parent == world) description.
add(child);
106 else parent.
add(child);
111 TUri uri(input.c_str());
112 input = uri.GetRelativePart();
116 description.
manager().SetTopVolume(vol.
ptr());
119 printout(INFO,
"ROOTGDMLParse",
"+++ Attach GDML volume %s", vol.
name());
122 except(
"ROOTGDMLParse",
"+++ Failed to parse GDML file:%s for path:%s",
123 input.c_str(),path.c_str());
126 except(
"ROOTGDMLParse",
"+++ Invalid DetElement path given: %s", path.c_str());
128 except(
"ROOTGDMLParse",
"+++ No input file name given.");
142 static long gdml_extract(
Detector& description,
int argc,
char** argv) {
144 bool detector =
true, volpath =
false;
147 for(
int i = 0; i < argc && argv[i]; ++i) {
148 if ( 0 == ::strncmp(
"-output",argv[i],2) )
150 else if ( 0 == ::strncmp(
"-path", argv[i],4) )
152 else if ( 0 == ::strncmp(
"-volpath", argv[i],7) )
153 volpath =
true, detector =
false;
154 else if ( 0 == ::strncmp(
"-volname", argv[i],7) )
155 volpath =
false, detector =
false;
156 else if ( 0 == ::strncmp(
"-detector", argv[i],8) )
157 volpath =
false, detector =
true;
158 else if ( 0 == ::strncmp(
"-precision", argv[i],5) )
159 precision = ::atol(argv[++i]);
161 if ( output.empty() || path.empty() ) {
163 "Usage: -plugin <name> -arg [-arg] \n"
164 " name: factory name DD4hep_ROOTGDMLExtract \n"
165 " -output <string> Output file name. \n"
166 " -path <string> Path to parent detector element to extract \n"
167 " top volume to GDML file. \n"
168 " -detector Indicate that the path is a DetElement path \n"
169 " -volpath Indicate that the path is a volume path \n"
170 " -volname Indicate that the path is a volume name prefix \n"
171 " -precision <number> GDML output floating point precision \n"
172 "\tArguments given: " << arguments(argc,argv) << endl << flush;
176 printout(INFO,
"ROOTGDMLExtract",
"+++ Write geometry %s to GDML file file:%s",
177 path.c_str(), output.c_str());
181 TUri uri(output.c_str());
182 description.
manager().SetExportPrecision(precision);
183 #if ROOT_VERSION_CODE > ROOT_VERSION(6,27,1)
184 extract.SetIgnoreDummyMaterial(
true);
185 extract.SetNamingSpeed(TGDMLWrite::kfastButUglySufix);
186 extract.WriteGDMLfile(&description.
manager(), de.
placement().
ptr(), uri.GetRelativePart());
188 extract.WriteGDMLfile(&description.
manager(), de.
placement().
ptr(), uri.GetRelativePart());
192 except(
"ROOTGDMLExtract",
"+++ Invalid DetElement path given: %s", path.c_str());
199 Actor(
const string& p,
bool vp) : _volpath(vp), _path(p) {}
200 void scan(TGeoNode* n,
const std::string& p=
"") {
205 if ( _volpath && nam.find(_path) == 0 ) {
208 for (Int_t idau = 0, ndau = n->GetNdaughters(); _node == 0 && idau < ndau; ++idau)
209 scan(n->GetDaughter(idau), p);
213 if ( nam.find(_path) == 0 ) {
215 printout(ALWAYS,
"Check",
"+++ Found required volume: %s",_path.c_str());
216 printout(ALWAYS,
"Check",
"+++ -> %s",nam.c_str());
219 for (Int_t idau = 0, ndau = n->GetNdaughters(); _node == 0 && idau < ndau; ++idau)
220 scan(n->GetDaughter(idau),nam);
224 TObjArray* ents = top->GetNodes();
225 Actor a(path, volpath ?
true :
false);
226 for (Int_t i = 0, n = ents->GetEntries(); i < n && a._node == 0; ++i) {
227 TGeoNode* node = (TGeoNode*)ents->At(i);
228 a.scan(node, node->GetName());
232 TUri uri(output.c_str());
233 description.
manager().SetExportPrecision(precision);
234 #if ROOT_VERSION_CODE > ROOT_VERSION(6,27,1)
235 extract.SetIgnoreDummyMaterial(
true);
236 extract.SetNamingSpeed(TGDMLWrite::kfastButUglySufix);
237 extract.WriteGDMLfile(&description.
manager(), a._node, uri.GetRelativePart());
239 extract.WriteGDMLfile(&description.
manager(), a._node, uri.GetRelativePart());
243 except(
"ROOTGDMLExtract",
"+++ Invalid volume path/name given: %s", path.c_str());
246 except(
"ROOTGDMLExtract",
"+++ No output file name given.");
254 string output = argv[0];
255 if ( output.substr(0,5) ==
"file:" ) output = output.substr(6);
256 const char* av[] = {
"DD4hepGeometry2GDML",
"-output", output.c_str(),
"-path",
"/world", 0};
257 if ( 1 == gdml_extract(description, 5, (
char**)av) ) {
258 printout(INFO,
"Geometry2GDML",
"+++ Successfully extracted GDML to %s",output.c_str());
261 except(
"Geometry2GDML",
"+++ FAILED to extract GDML file %s.",output.c_str());
263 except(
"Geometry2GDML",
"+++ No output file name given.");
272 int id = x_det.
hasAttr(
_U(
id)) ? x_det.id() : 0;
277 string name = x_det.nameStr();
278 string par_nam = x_par.nameStr();
279 string gdml = x_gdml.attr<
string>(
_U(ref));
280 string gdml_physvol = dd4hep::getAttrOrDefault<string>(x_gdml,
_Unicode(physvol),
"");
283 if ( !gdml.empty() && gdml[0] ==
'/' ) {
284 TUri uri(gdml.c_str());
285 gdml = uri.GetRelativePart();
289 TUri uri(path.c_str());
290 gdml = uri.GetRelativePart();
293 except(name,
"+++ Cannot access detector parent: %s",par_nam.c_str());
298 except(
"ROOTGDMLParse",
"+++ Failed to parse GDML file:%s",gdml.c_str());
301 printout(INFO,
"ROOTGDMLParse",
"+++ Attach GDML volume %s", volume.
name());
305 if ( !gdml_physvol.empty() ) {
306 PlacedVolume node = volume->FindNode(gdml_physvol.c_str());
308 printout(ERROR,
"ROOTGDMLParse",
"+++ Invalid gdml placed volume %s", gdml_physvol.c_str());
309 printout(ERROR,
"ROOTGDMLParse",
"+++ Valid top-level nodes are:");
310 volume->PrintNodes();
311 except(
"ROOTGDMLParse",
"+++ Failed to parse GDML file:%s for node:%s",
312 gdml.c_str(), gdml_physvol.c_str());
317 if ( x_pos && x_rot ) {
334 volume.
setLimitSet(description, x_det.limitsStr());
335 volume.
setRegion(description, x_det.regionStr());
339 sdet.setPlacement(pv);