ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4GDMLRead.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4GDMLRead.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // class G4GDMLRead Implementation
28 //
29 // History:
30 // - Created. Zoltan Torzsok, November 2007
31 // -------------------------------------------------------------------------
32 
33 #include "globals.hh"
34 
35 #include "G4GDMLRead.hh"
36 
37 #include "G4UnitsTable.hh"
38 #include "G4Element.hh"
39 #include "G4Material.hh"
40 #include "G4SolidStore.hh"
41 #include "G4LogicalVolumeStore.hh"
42 #include "G4PhysicalVolumeStore.hh"
43 
45  : validate(true), check(false), dostrip(true), inLoop(0), loopCount(0)
46 {
47  // Make sure units are defined.
49 }
50 
52 {
53 }
54 
55 G4String G4GDMLRead::Transcode(const XMLCh* const toTranscode)
56 {
57  char* char_str = xercesc::XMLString::transcode(toTranscode);
58  G4String my_str(char_str);
59  xercesc::XMLString::release(&char_str);
60  return my_str;
61 }
62 
64 {
65  check = flag;
66 }
67 
69 {
70  G4String nameOut(nameIn);
71 
72  if (inLoop>0)
73  {
74  nameOut = eval.SolveBrackets(nameOut);
75  }
76  if (strip) { StripName(nameOut); }
77 
78  return nameOut;
79 }
80 
82  G4VPhysicalVolume* physvol)
83 {
84  G4String nameOut(nameIn);
85 
86  if (nameIn.empty())
87  {
88  std::stringstream stream;
89  stream << physvol->GetLogicalVolume()->GetName() << "_PV";
90  nameOut = stream.str();
91  }
92  nameOut = eval.SolveBrackets(nameOut);
93 
94  physvol->SetName(nameOut);
95 }
96 
98 {
99  G4String sname(name);
100  return sname.remove(sname.find("0x"));
101 }
102 
104 {
105  name.remove(name.find("0x"));
106 }
107 
109 {
110  // Strips off names of volumes, solids elements and materials from possible
111  // reference pointers or IDs attached to their original identifiers.
112 
118 
119  G4cout << "Stripping off GDML names of materials, solids and volumes ..."
120  << G4endl;
121 
122  G4String sname;
123  size_t i;
124 
125  // Solids...
126  //
127  for (i=0; i<solids->size(); ++i)
128  {
129  G4VSolid* psol = (*solids)[i];
130  sname = psol->GetName();
131  StripName(sname);
132  psol->SetName(sname);
133  }
134 
135  // Logical volumes...
136  //
137  for (i=0; i<lvols->size(); ++i)
138  {
139  G4LogicalVolume* lvol = (*lvols)[i];
140  sname = lvol->GetName();
141  StripName(sname);
142  lvol->SetName(sname);
143  }
144 
145  // Physical volumes...
146  //
147  for (i=0; i<pvols->size(); ++i)
148  {
149  G4VPhysicalVolume* pvol = (*pvols)[i];
150  sname = pvol->GetName();
151  StripName(sname);
152  pvol->SetName(sname);
153  }
154 
155  // Materials...
156  //
157  for (i=0; i<materials->size(); ++i)
158  {
159  G4Material* pmat = (*materials)[i];
160  sname = pmat->GetName();
161  StripName(sname);
162  pmat->SetName(sname);
163  }
164 
165  // Elements...
166  //
167  for (i=0; i<elements->size(); ++i)
168  {
169  G4Element* pelm = (*elements)[i];
170  sname = pelm->GetName();
171  StripName(sname);
172  pelm->SetName(sname);
173  }
174 }
175 
176 void G4GDMLRead::LoopRead(const xercesc::DOMElement* const element,
177  void(G4GDMLRead::*func)(const xercesc::DOMElement* const))
178 {
179  G4String var;
180  G4String from;
181  G4String to;
182  G4String step;
183 
184  const xercesc::DOMNamedNodeMap* const attributes = element->getAttributes();
185  XMLSize_t attributeCount = attributes->getLength();
186 
187  for (XMLSize_t attribute_index=0;
188  attribute_index<attributeCount;attribute_index++)
189  {
190  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
191 
192  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
193  { continue; }
194 
195  const xercesc::DOMAttr* const attribute
196  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
197  if (!attribute)
198  {
199  G4Exception("G4GDMLRead::LoopRead()", "InvalidRead",
200  FatalException, "No attribute found!");
201  return;
202  }
203  const G4String attribute_name = Transcode(attribute->getName());
204  const G4String attribute_value = Transcode(attribute->getValue());
205 
206  if (attribute_name=="for") { var = attribute_value; } else
207  if (attribute_name=="from") { from = attribute_value; } else
208  if (attribute_name=="to") { to = attribute_value; } else
209  if (attribute_name=="step") { step = attribute_value; }
210  }
211 
212  if (var.empty())
213  {
214  G4Exception("G4GDMLRead::loopRead()", "InvalidRead",
215  FatalException, "No variable is determined for loop!");
216  }
217 
218  if (!eval.IsVariable(var))
219  {
220  G4Exception("G4GDMLRead::loopRead()", "InvalidRead",
221  FatalException, "Variable is not defined in loop!");
222  }
223 
224  G4int _var = eval.EvaluateInteger(var);
225  G4int _from = eval.EvaluateInteger(from);
226  G4int _to = eval.EvaluateInteger(to);
227  G4int _step = eval.EvaluateInteger(step);
228 
229  if (!from.empty()) { _var = _from; }
230 
231  if ((_from < _to) && (_step <= 0))
232  {
233  G4Exception("G4GDMLRead::loopRead()", "InvalidRead",
234  FatalException, "Infinite loop!");
235  }
236  if ((_from > _to) && (_step >= 0))
237  {
238  G4Exception("G4GDMLRead::loopRead()", "InvalidRead",
239  FatalException, "Infinite loop!");
240  }
241 
242  inLoop++;
243 
244  while (_var <= _to)
245  {
246  eval.SetVariable(var,_var);
247  (this->*func)(element);
248  _var += _step;
249  loopCount++;
250  }
251 
252  inLoop--;
253  if (!inLoop) { loopCount = 0; }
254 }
255 
257 AuxiliaryRead(const xercesc::DOMElement* const auxiliaryElement)
258 {
259  G4GDMLAuxStructType auxstruct = {"","","",0};
260  G4GDMLAuxListType* auxList=0;
261 
262  const xercesc::DOMNamedNodeMap* const attributes
263  = auxiliaryElement->getAttributes();
264  XMLSize_t attributeCount = attributes->getLength();
265 
266  for (XMLSize_t attribute_index=0;
267  attribute_index<attributeCount; attribute_index++)
268  {
269  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
270 
271  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
272  { continue; }
273 
274  const xercesc::DOMAttr* const attribute
275  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
276  if (!attribute)
277  {
278  G4Exception("G4GDMLRead::AuxiliaryRead()",
279  "InvalidRead", FatalException, "No attribute found!");
280  return auxstruct;
281  }
282  const G4String attName = Transcode(attribute->getName());
283  const G4String attValue = Transcode(attribute->getValue());
284 
285  if (attName=="auxtype") { auxstruct.type = attValue; } else
286  if (attName=="auxvalue") { auxstruct.value = attValue; } else
287  if (attName=="auxunit") { auxstruct.unit = attValue; }
288  }
289 
290  for (xercesc::DOMNode* iter = auxiliaryElement->getFirstChild();
291  iter != 0; iter = iter->getNextSibling())
292  {
293  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
294 
295  const xercesc::DOMElement* const child
296  = dynamic_cast<xercesc::DOMElement*>(iter);
297  if (!child)
298  {
299  G4Exception("G4GDMLRead::AuxiliaryRead()",
300  "InvalidRead", FatalException, "No child found!");
301  break;
302  }
303  const G4String tag = Transcode(child->getTagName());
304 
305  if (tag=="auxiliary")
306  {
307  if(!auxList) { auxList = new G4GDMLAuxListType; }
308  auxList->push_back(AuxiliaryRead(child));
309  }
310  }
311 
312  if (auxList) { auxstruct.auxList = auxList; }
313 
314  return auxstruct;
315 }
316 
317 void G4GDMLRead::UserinfoRead(const xercesc::DOMElement* const userinfoElement)
318 {
319 #ifdef G4VERBOSE
320  G4cout << "G4GDML: Reading userinfo..." << G4endl;
321 #endif
322  for (xercesc::DOMNode* iter = userinfoElement->getFirstChild();
323  iter != 0; iter = iter->getNextSibling())
324  {
325  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
326 
327  const xercesc::DOMElement* const child
328  = dynamic_cast<xercesc::DOMElement*>(iter);
329  if (!child)
330  {
331  G4Exception("G4GDMLRead::UserinfoRead()",
332  "InvalidRead", FatalException, "No child found!");
333  return;
334  }
335  const G4String tag = Transcode(child->getTagName());
336 
337  if (tag=="auxiliary")
338  {
339  auxGlobalList.push_back(AuxiliaryRead(child));
340  }
341  else
342  {
343  G4String error_msg = "Unknown tag in structure: " + tag;
344  G4Exception("G4GDMLRead::UserinfoRead()",
345  "ReadError", FatalException, error_msg);
346  }
347  }
348 }
349 
350 void G4GDMLRead::ExtensionRead(const xercesc::DOMElement* const)
351 {
352  G4String error_msg = "No handle to user-code for parsing extensions!";
353  G4Exception("G4GDMLRead::ExtensionRead()",
354  "NotImplemented", JustWarning, error_msg);
355 }
356 
357 void G4GDMLRead::Read(const G4String& fileName,
358  G4bool validation,
359  G4bool isModule,
360  G4bool strip)
361 {
362  dostrip = strip;
363 #ifdef G4VERBOSE
364  if (isModule)
365  {
366  G4cout << "G4GDML: Reading module '" << fileName << "'..." << G4endl;
367  }
368  else
369  {
370  G4cout << "G4GDML: Reading '" << fileName << "'..." << G4endl;
371  }
372 #endif
373  inLoop = 0;
374  validate = validation;
375 
376  xercesc::ErrorHandler* handler = new G4GDMLErrorHandler(!validate);
377  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
378 
379  if (validate)
380  {
381  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
382  }
383  parser->setValidationSchemaFullChecking(validate);
384  parser->setCreateEntityReferenceNodes(false);
385  // Entities will be automatically resolved by Xerces
386 
387  parser->setDoNamespaces(true);
388  parser->setDoSchema(validate);
389  parser->setErrorHandler(handler);
390 
391  try { parser->parse(fileName.c_str()); }
392  catch (const xercesc::XMLException &e)
393  { G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl; }
394  catch (const xercesc::DOMException &e)
395  { G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl; }
396 
397  xercesc::DOMDocument* doc = parser->getDocument();
398 
399  if (!doc)
400  {
401  G4String error_msg = "Unable to open document: " + fileName;
402  G4Exception("G4GDMLRead::Read()", "InvalidRead",
403  FatalException, error_msg);
404  return;
405  }
406  xercesc::DOMElement* element = doc->getDocumentElement();
407 
408  if (!element)
409  {
410  std::ostringstream message;
411  message << "ERROR - Empty document or unable to validate schema!" << G4endl
412  << " Check Internet connection is ON in case of schema"
413  << G4endl
414  << " validation enabled and location defined as URL in"
415  << G4endl
416  << " the GDML file - " << fileName << " - being imported!"
417  << G4endl
418  << " Otherwise, verify GDML schema server is reachable!";
419  G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException, message);
420  return;
421  }
422 
423  for (xercesc::DOMNode* iter = element->getFirstChild();
424  iter != 0; iter = iter->getNextSibling())
425  {
426  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
427 
428  const xercesc::DOMElement* const child
429  = dynamic_cast<xercesc::DOMElement*>(iter);
430  if (!child)
431  {
432  G4Exception("G4GDMLRead::Read()", "InvalidRead",
433  FatalException, "No child found!");
434  return;
435  }
436  const G4String tag = Transcode(child->getTagName());
437 
438  if (tag=="define") { DefineRead(child); } else
439  if (tag=="materials") { MaterialsRead(child); } else
440  if (tag=="solids") { SolidsRead(child); } else
441  if (tag=="setup") { SetupRead(child); } else
442  if (tag=="structure") { StructureRead(child); } else
443  if (tag=="userinfo") { UserinfoRead(child); } else
444  if (tag=="extension") { ExtensionRead(child); }
445  else
446  {
447  G4String error_msg = "Unknown tag in gdml: " + tag;
448  G4Exception("G4GDMLRead::Read()", "InvalidRead",
449  FatalException, error_msg);
450  }
451  }
452 
453  delete parser;
454  delete handler;
455 
456  if (isModule)
457  {
458 #ifdef G4VERBOSE
459  G4cout << "G4GDML: Reading module '" << fileName << "' done!" << G4endl;
460 #endif
461  }
462  else
463  {
464  G4cout << "G4GDML: Reading '" << fileName << "' done!" << G4endl;
465  if (strip) { StripNames(); }
466  }
467 }
468 
470 {
471  return &auxGlobalList;
472 }