ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4GDMLReadStructure.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4GDMLReadStructure.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 G4GDMLReadStructure Implementation
28 //
29 // Original author: Zoltan Torzsok, November 2007
30 //
31 // --------------------------------------------------------------------
32 
33 #include "G4GDMLReadStructure.hh"
34 
35 #include "G4UnitsTable.hh"
36 #include "G4LogicalVolume.hh"
37 #include "G4VPhysicalVolume.hh"
38 #include "G4PVPlacement.hh"
39 #include "G4LogicalVolumeStore.hh"
40 #include "G4PhysicalVolumeStore.hh"
41 #include "G4AssemblyVolume.hh"
42 #include "G4ReflectionFactory.hh"
43 #include "G4PVDivisionFactory.hh"
45 #include "G4LogicalSkinSurface.hh"
46 #include "G4VisAttributes.hh"
47 
49  : G4GDMLReadParamvol(), pMotherLogical(0), strip(false)
50 {
51 }
52 
54 {
55 }
56 
57 
59 BorderSurfaceRead(const xercesc::DOMElement* const bordersurfaceElement)
60 {
61  G4String name;
62  G4VPhysicalVolume* pv1 = 0;
63  G4VPhysicalVolume* pv2 = 0;
64  G4SurfaceProperty* prop = 0;
65  G4int index = 0;
66 
67  const xercesc::DOMNamedNodeMap* const attributes
68  = bordersurfaceElement->getAttributes();
69  XMLSize_t attributeCount = attributes->getLength();
70 
71  for (XMLSize_t attribute_index=0;
72  attribute_index<attributeCount; attribute_index++)
73  {
74  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
75 
76  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
77  { continue; }
78 
79  const xercesc::DOMAttr* const attribute
80  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
81  if (!attribute)
82  {
83  G4Exception("G4GDMLReadStructure::BorderSurfaceRead()",
84  "InvalidRead", FatalException, "No attribute found!");
85  return;
86  }
87  const G4String attName = Transcode(attribute->getName());
88  const G4String attValue = Transcode(attribute->getValue());
89 
90  if (attName=="name")
91  { name = GenerateName(attValue); } else
92  if (attName=="surfaceproperty")
93  { prop = GetSurfaceProperty(GenerateName(attValue)); }
94  }
95 
96  for (xercesc::DOMNode* iter = bordersurfaceElement->getFirstChild();
97  iter != 0; iter = iter->getNextSibling())
98  {
99  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
100 
101  const xercesc::DOMElement* const child
102  = dynamic_cast<xercesc::DOMElement*>(iter);
103  if (!child)
104  {
105  G4Exception("G4GDMLReadStructure::BorderSurfaceRead()",
106  "InvalidRead", FatalException, "No child found!");
107  return;
108  }
109  const G4String tag = Transcode(child->getTagName());
110 
111  if (tag != "physvolref") { continue; }
112 
113  if (index==0)
114  { pv1 = GetPhysvol(GenerateName(RefRead(child))); index++; } else
115  if (index==1)
116  { pv2 = GetPhysvol(GenerateName(RefRead(child))); index++; } else
117  break;
118  }
119 
120  new G4LogicalBorderSurface(Strip(name),pv1,pv2,prop);
121 }
122 
124 DivisionvolRead(const xercesc::DOMElement* const divisionvolElement)
125 {
126  G4String name;
127  G4double unit = 1.0;
128  G4double width = 0.0;
129  G4double offset = 0.0;
130  G4int number = 0;
131  EAxis axis = kUndefined;
132  G4LogicalVolume* logvol = 0;
133 
134  const xercesc::DOMNamedNodeMap* const attributes
135  = divisionvolElement->getAttributes();
136  XMLSize_t attributeCount = attributes->getLength();
137  G4String unitname;
138 
139  for (XMLSize_t attribute_index=0;
140  attribute_index<attributeCount; attribute_index++)
141  {
142  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
143 
144  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
145  { continue; }
146 
147  const xercesc::DOMAttr* const attribute
148  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
149  if (!attribute)
150  {
151  G4Exception("G4GDMLReadStructure::DivisionvolRead()",
152  "InvalidRead", FatalException, "No attribute found!");
153  return;
154  }
155  const G4String attName = Transcode(attribute->getName());
156  const G4String attValue = Transcode(attribute->getValue());
157 
158  if (attName=="name") { name = attValue; } else
159  if (attName=="unit") { unit = G4UnitDefinition::GetValueOf(attValue);
160  unitname = G4UnitDefinition::GetCategory(attValue);
161  } else
162  if (attName=="width") { width = eval.Evaluate(attValue); } else
163  if (attName=="offset") { offset = eval.Evaluate(attValue); } else
164  if (attName=="number") { number = eval.EvaluateInteger(attValue); } else
165  if (attName=="axis")
166  {
167  if (attValue=="kXAxis") { axis = kXAxis; } else
168  if (attValue=="kYAxis") { axis = kYAxis; } else
169  if (attValue=="kZAxis") { axis = kZAxis; } else
170  if (attValue=="kRho") { axis = kRho; } else
171  if (attValue=="kPhi") { axis = kPhi; }
172  }
173  }
174 
175  if ( ((axis == kXAxis || axis == kYAxis || axis == kZAxis) && unitname!="Length") ||
176  ((axis == kRho || axis == kPhi) && unitname!="Angle")) {
177  G4Exception("G4GDMLReadStructure::DivisionvolRead()", "InvalidRead",
178  FatalException, "Invalid unit!"); }
179 
180  width *= unit;
181  offset *= unit;
182 
183  for (xercesc::DOMNode* iter = divisionvolElement->getFirstChild();
184  iter != 0;iter = iter->getNextSibling())
185  {
186  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
187 
188  const xercesc::DOMElement* const child
189  = dynamic_cast<xercesc::DOMElement*>(iter);
190  if (!child)
191  {
192  G4Exception("G4GDMLReadStructure::DivisionvolRead()",
193  "InvalidRead", FatalException, "No child found!");
194  return;
195  }
196  const G4String tag = Transcode(child->getTagName());
197 
198  if (tag=="volumeref") { logvol = GetVolume(GenerateName(RefRead(child))); }
199  }
200 
201  if (!logvol) { return; }
202 
205 
206  G4String pv_name = logvol->GetName() + "_div";
207  if ((number != 0) && (width == 0.0))
208  {
210  ->Divide(pv_name,logvol,pMotherLogical,axis,number,offset);
211  }
212  else if ((number == 0) && (width != 0.0))
213  {
215  ->Divide(pv_name,logvol,pMotherLogical,axis,width,offset);
216  }
217  else
218  {
220  ->Divide(pv_name,logvol,pMotherLogical,axis,number,width,offset);
221  }
222 
223  if (pair.first != 0) { GeneratePhysvolName(name,pair.first); }
224  if (pair.second != 0) { GeneratePhysvolName(name,pair.second); }
225 }
226 
228 FileRead(const xercesc::DOMElement* const fileElement)
229 {
230  G4String name;
231  G4String volname;
232 
233  const xercesc::DOMNamedNodeMap* const attributes
234  = fileElement->getAttributes();
235  XMLSize_t attributeCount = attributes->getLength();
236 
237  for (XMLSize_t attribute_index=0;
238  attribute_index<attributeCount; attribute_index++)
239  {
240  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
241 
242  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
243  { continue; }
244 
245  const xercesc::DOMAttr* const attribute
246  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
247  if (!attribute)
248  {
249  G4Exception("G4GDMLReadStructure::FileRead()",
250  "InvalidRead", FatalException, "No attribute found!");
251  return 0;
252  }
253  const G4String attName = Transcode(attribute->getName());
254  const G4String attValue = Transcode(attribute->getValue());
255 
256  if (attName=="name") { name = attValue; } else
257  if (attName=="volname") { volname = attValue; }
258  }
259 
260  const G4bool isModule = true;
261  G4GDMLReadStructure structure;
262  structure.Read(name,validate,isModule);
263 
264  // Register existing auxiliar information defined in child module
265  //
266  const G4GDMLAuxMapType* aux = structure.GetAuxMap();
267  if (!aux->empty())
268  {
269  G4GDMLAuxMapType::const_iterator pos;
270  for (pos = aux->begin(); pos != aux->end(); ++pos)
271  {
272  auxMap.insert(std::make_pair(pos->first,pos->second));
273  }
274  }
275 
276  // Return volume structure from child module
277  //
278  if (volname.empty())
279  {
280  return structure.GetVolume(structure.GetSetup("Default"));
281  }
282  else
283  {
284  return structure.GetVolume(structure.GenerateName(volname));
285  }
286 }
287 
289 PhysvolRead(const xercesc::DOMElement* const physvolElement,
290  G4AssemblyVolume* pAssembly)
291 {
292  G4String name;
293  G4LogicalVolume* logvol = 0;
294  G4AssemblyVolume* assembly = 0;
295  G4ThreeVector position(0.0,0.0,0.0);
296  G4ThreeVector rotation(0.0,0.0,0.0);
297  G4ThreeVector scale(1.0,1.0,1.0);
298  G4int copynumber = 0;
299 
300  const xercesc::DOMNamedNodeMap* const attributes
301  = physvolElement->getAttributes();
302  XMLSize_t attributeCount = attributes->getLength();
303 
304  for (XMLSize_t attribute_index=0;
305  attribute_index<attributeCount; attribute_index++)
306  {
307  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
308 
309  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
310  { continue; }
311 
312  const xercesc::DOMAttr* const attribute
313  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
314  if (!attribute)
315  {
316  G4Exception("G4GDMLReadStructure::PhysvolRead()",
317  "InvalidRead", FatalException, "No attribute found!");
318  return;
319  }
320  const G4String attName = Transcode(attribute->getName());
321  const G4String attValue = Transcode(attribute->getValue());
322 
323  if (attName=="name") { name = attValue; }
324  if (attName=="copynumber") { copynumber = eval.EvaluateInteger(attValue); }
325  }
326 
327  for (xercesc::DOMNode* iter = physvolElement->getFirstChild();
328  iter != 0; iter = iter->getNextSibling())
329  {
330  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
331 
332  const xercesc::DOMElement* const child
333  = dynamic_cast<xercesc::DOMElement*>(iter);
334  if (!child)
335  {
336  G4Exception("G4GDMLReadStructure::PhysvolRead()",
337  "InvalidRead", FatalException, "No child found!");
338  return;
339  }
340  const G4String tag = Transcode(child->getTagName());
341 
342  if (tag=="volumeref")
343  {
344  const G4String& child_name = GenerateName(RefRead(child));
345  assembly = GetAssembly(child_name);
346  if (!assembly) { logvol = GetVolume(child_name); }
347  }
348  else if (tag=="file")
349  { logvol = FileRead(child); }
350  else if (tag=="position")
351  { VectorRead(child,position); }
352  else if (tag=="rotation")
353  { VectorRead(child,rotation); }
354  else if (tag=="scale")
355  { VectorRead(child,scale); }
356  else if (tag=="positionref")
357  { position = GetPosition(GenerateName(RefRead(child))); }
358  else if (tag=="rotationref")
359  { rotation = GetRotation(GenerateName(RefRead(child))); }
360  else if (tag=="scaleref")
361  { scale = GetScale(GenerateName(RefRead(child))); }
362  else
363  {
364  G4String error_msg = "Unknown tag in physvol: " + tag;
365  G4Exception("G4GDMLReadStructure::PhysvolRead()", "ReadError",
366  FatalException, error_msg);
367  return;
368  }
369  }
370 
371  G4Transform3D transform(GetRotationMatrix(rotation).inverse(),position);
372  transform = transform*G4Scale3D(scale.x(),scale.y(),scale.z());
373 
374  if (pAssembly) // Fill assembly structure
375  {
376  if (assembly) // Case of recursive assemblies
377  {
378  pAssembly->AddPlacedAssembly(assembly, transform);
379  }
380  if (!logvol) { return; }
381  pAssembly->AddPlacedVolume(logvol, transform);
382  }
383  else // Generate physical volume tree or do assembly imprint
384  {
385  if (assembly)
386  {
387  assembly->MakeImprint(pMotherLogical, transform, 0, check);
388  }
389  else
390  {
391  if (!logvol) { return; }
392  G4String pv_name = logvol->GetName() + "_PV";
394  ->Place(transform,pv_name,logvol,pMotherLogical,false,copynumber,check);
395 
396  if (pair.first != 0) { GeneratePhysvolName(name,pair.first); }
397  if (pair.second != 0) { GeneratePhysvolName(name,pair.second); }
398  }
399  }
400 }
401 
403 ReplicavolRead(const xercesc::DOMElement* const replicavolElement, G4int number)
404 {
405  G4LogicalVolume* logvol = 0;
406  for (xercesc::DOMNode* iter = replicavolElement->getFirstChild();
407  iter != 0; iter = iter->getNextSibling())
408  {
409  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
410 
411  const xercesc::DOMElement* const child
412  = dynamic_cast<xercesc::DOMElement*>(iter);
413  if (!child)
414  {
415  G4Exception("G4GDMLReadStructure::ReplicavolRead()",
416  "InvalidRead", FatalException, "No child found!");
417  return;
418  }
419  const G4String tag = Transcode(child->getTagName());
420 
421  if (tag=="volumeref")
422  {
423  logvol = GetVolume(GenerateName(RefRead(child)));
424  }
425  else if (tag=="replicate_along_axis")
426  {
427  if (logvol) { ReplicaRead(child,logvol,number); }
428  }
429  else
430  {
431  G4String error_msg = "Unknown tag in ReplicavolRead: " + tag;
432  G4Exception("G4GDMLReadStructure::ReplicavolRead()",
433  "ReadError", FatalException, error_msg);
434  }
435  }
436 }
437 
439 ReplicaRead(const xercesc::DOMElement* const replicaElement,
440  G4LogicalVolume* logvol, G4int number)
441 {
442  G4double width = 0.0;
443  G4double offset = 0.0;
444  G4ThreeVector position(0.0,0.0,0.0);
445  G4ThreeVector rotation(0.0,0.0,0.0);
446  EAxis axis = kUndefined;
447  G4String name;
448 
449  for (xercesc::DOMNode* iter = replicaElement->getFirstChild();
450  iter != 0; iter = iter->getNextSibling())
451  {
452  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
453 
454  const xercesc::DOMElement* const child
455  = dynamic_cast<xercesc::DOMElement*>(iter);
456  if (!child)
457  {
458  G4Exception("G4GDMLReadStructure::ReplicaRead()",
459  "InvalidRead", FatalException, "No child found!");
460  return;
461  }
462  const G4String tag = Transcode(child->getTagName());
463 
464  if (tag=="position")
465  { VectorRead(child,position); } else
466  if (tag=="rotation")
467  { VectorRead(child,rotation); } else
468  if (tag=="positionref")
469  { position = GetPosition(GenerateName(RefRead(child))); } else
470  if (tag=="rotationref")
471  { rotation = GetRotation(GenerateName(RefRead(child))); } else
472  if (tag=="direction")
473  { axis=AxisRead(child); } else
474  if (tag=="width")
475  { width=QuantityRead(child); } else
476  if (tag=="offset")
477  { offset=QuantityRead(child); }
478  else
479  {
480  G4String error_msg = "Unknown tag in ReplicaRead: " + tag;
481  G4Exception("G4GDMLReadStructure::ReplicaRead()", "ReadError",
482  FatalException, error_msg);
483  }
484  }
485 
486  G4String pv_name = logvol->GetName() + "_PV";
488  ->Replicate(pv_name,logvol,pMotherLogical,axis,number,width,offset);
489 
490  if (pair.first != 0) { GeneratePhysvolName(name,pair.first); }
491  if (pair.second != 0) { GeneratePhysvolName(name,pair.second); }
492 
493 }
494 
496 AxisRead(const xercesc::DOMElement* const axisElement)
497 {
498  EAxis axis = kUndefined;
499 
500  const xercesc::DOMNamedNodeMap* const attributes
501  = axisElement->getAttributes();
502  XMLSize_t attributeCount = attributes->getLength();
503 
504  for (XMLSize_t attribute_index=0;
505  attribute_index<attributeCount; attribute_index++)
506  {
507  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
508 
509  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
510  { continue; }
511 
512  const xercesc::DOMAttr* const attribute
513  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
514  if (!attribute)
515  {
516  G4Exception("G4GDMLReadStructure::AxisRead()",
517  "InvalidRead", FatalException, "No attribute found!");
518  return axis;
519  }
520  const G4String attName = Transcode(attribute->getName());
521  const G4String attValue = Transcode(attribute->getValue());
522  if (attName=="x")
523  { if( eval.Evaluate(attValue)==1.) {axis=kXAxis;} }
524  else if (attName=="y")
525  { if( eval.Evaluate(attValue)==1.) {axis=kYAxis;} }
526  else if (attName=="z")
527  { if( eval.Evaluate(attValue)==1.) {axis=kZAxis;} }
528  else if (attName=="rho")
529  { if( eval.Evaluate(attValue)==1.) {axis=kRho;} }
530  else if (attName=="phi")
531  { if( eval.Evaluate(attValue)==1.) {axis=kPhi;} }
532  }
533 
534  return axis;
535 }
536 
538 QuantityRead(const xercesc::DOMElement* const readElement)
539 {
540  G4double value = 0.0;
541  G4double unit = 0.0;
542  const xercesc::DOMNamedNodeMap* const attributes
543  = readElement->getAttributes();
544  XMLSize_t attributeCount = attributes->getLength();
545 
546  for (XMLSize_t attribute_index=0;
547  attribute_index<attributeCount; attribute_index++)
548  {
549  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
550 
551  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
552  { continue; }
553  const xercesc::DOMAttr* const attribute
554  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
555  if (!attribute)
556  {
557  G4Exception("G4GDMLReadStructure::QuantityRead()",
558  "InvalidRead", FatalException, "No attribute found!");
559  return value;
560  }
561  const G4String attName = Transcode(attribute->getName());
562  const G4String attValue = Transcode(attribute->getValue());
563 
564  if (attName=="unit") { unit = G4UnitDefinition::GetValueOf(attValue);
565  if (G4UnitDefinition::GetCategory(attValue)!="Length" && G4UnitDefinition::GetCategory(attValue)!="Angle") {
566  G4Exception("G4GDMLReadStructure::QuantityRead()", "InvalidRead",
567  FatalException, "Invalid unit for lenght or angle (width, offset)!"); }
568  } else
569  if (attName=="value"){ value= eval.Evaluate(attValue); }
570  }
571 
572  return value*unit;
573 }
574 
576 VolumeRead(const xercesc::DOMElement* const volumeElement)
577 {
578  G4VSolid* solidPtr = 0;
579  G4Material* materialPtr = 0;
580  G4GDMLAuxListType auxList;
581 
582  XMLCh *name_attr = xercesc::XMLString::transcode("name");
583  const G4String name = Transcode(volumeElement->getAttribute(name_attr));
584  xercesc::XMLString::release(&name_attr);
585 
586  for (xercesc::DOMNode* iter = volumeElement->getFirstChild();
587  iter != 0; iter = iter->getNextSibling())
588  {
589  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
590 
591  const xercesc::DOMElement* const child
592  = dynamic_cast<xercesc::DOMElement*>(iter);
593  if (!child)
594  {
595  G4Exception("G4GDMLReadStructure::VolumeRead()",
596  "InvalidRead", FatalException, "No child found!");
597  return;
598  }
599  const G4String tag = Transcode(child->getTagName());
600 
601  if (tag=="auxiliary")
602  { auxList.push_back(AuxiliaryRead(child)); } else
603  if (tag=="materialref")
604  { materialPtr = GetMaterial(GenerateName(RefRead(child),true)); } else
605  if (tag=="solidref")
606  { solidPtr = GetSolid(GenerateName(RefRead(child))); }
607  }
608 
609  pMotherLogical = new G4LogicalVolume(solidPtr,materialPtr,
610  GenerateName(name),0,0,0);
611 
612  if (!auxList.empty()) { auxMap[pMotherLogical] = auxList; }
613 
614  Volume_contentRead(volumeElement);
615 }
616 
618 AssemblyRead(const xercesc::DOMElement* const assemblyElement)
619 {
620  XMLCh *name_attr = xercesc::XMLString::transcode("name");
621  const G4String name = Transcode(assemblyElement->getAttribute(name_attr));
622  xercesc::XMLString::release(&name_attr);
623 
624  G4AssemblyVolume* pAssembly = new G4AssemblyVolume();
625  assemblyMap.insert(std::make_pair(GenerateName(name), pAssembly));
626 
627  for (xercesc::DOMNode* iter = assemblyElement->getFirstChild();
628  iter != 0; iter = iter->getNextSibling())
629  {
630  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
631  const xercesc::DOMElement* const child
632  = dynamic_cast<xercesc::DOMElement*>(iter);
633  if (!child)
634  {
635  G4Exception("G4GDMLReadStructure::AssemblyRead()",
636  "InvalidRead", FatalException, "No child found!");
637  return;
638  }
639  const G4String tag = Transcode(child->getTagName());
640 
641  if (tag=="physvol")
642  {
643  PhysvolRead(child, pAssembly);
644  }
645  else
646  {
647  G4cout << "Unsupported GDML tag '" << tag
648  << "' for Geant4 assembly structure !" << G4endl;
649  }
650  }
651 }
652 
654 SkinSurfaceRead(const xercesc::DOMElement* const skinsurfaceElement)
655 {
656  G4String name;
657  G4LogicalVolume* logvol = 0;
658  G4SurfaceProperty* prop = 0;
659 
660  const xercesc::DOMNamedNodeMap* const attributes
661  = skinsurfaceElement->getAttributes();
662  XMLSize_t attributeCount = attributes->getLength();
663 
664  for (XMLSize_t attribute_index=0;
665  attribute_index<attributeCount; attribute_index++)
666  {
667  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
668 
669  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
670  { continue; }
671 
672  const xercesc::DOMAttr* const attribute
673  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
674  if (!attribute)
675  {
676  G4Exception("G4GDMLReadStructure::SkinsurfaceRead()",
677  "InvalidRead", FatalException, "No attribute found!");
678  return;
679  }
680  const G4String attName = Transcode(attribute->getName());
681  const G4String attValue = Transcode(attribute->getValue());
682 
683  if (attName=="name")
684  { name = GenerateName(attValue); } else
685  if (attName=="surfaceproperty")
686  { prop = GetSurfaceProperty(GenerateName(attValue)); }
687  }
688 
689  for (xercesc::DOMNode* iter = skinsurfaceElement->getFirstChild();
690  iter != 0; iter = iter->getNextSibling())
691  {
692  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
693 
694  const xercesc::DOMElement* const child
695  = dynamic_cast<xercesc::DOMElement*>(iter);
696  if (!child)
697  {
698  G4Exception("G4GDMLReadStructure::SkinsurfaceRead()",
699  "InvalidRead", FatalException, "No child found!");
700  return;
701  }
702  const G4String tag = Transcode(child->getTagName());
703 
704  if (tag=="volumeref")
705  {
706  logvol = GetVolume(GenerateName(RefRead(child)));
707  }
708  else
709  {
710  G4String error_msg = "Unknown tag in skinsurface: " + tag;
711  G4Exception("G4GDMLReadStructure::SkinsurfaceRead()", "ReadError",
712  FatalException, error_msg);
713  }
714  }
715 
716  new G4LogicalSkinSurface(Strip(name),logvol,prop);
717 }
718 
720 Volume_contentRead(const xercesc::DOMElement* const volumeElement)
721 {
722  for (xercesc::DOMNode* iter = volumeElement->getFirstChild();
723  iter != 0; iter = iter->getNextSibling())
724  {
725  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
726 
727  const xercesc::DOMElement* const child
728  = dynamic_cast<xercesc::DOMElement*>(iter);
729  if (!child)
730  {
731  G4Exception("G4GDMLReadStructure::Volume_contentRead()",
732  "InvalidRead", FatalException, "No child found!");
733  return;
734  }
735  const G4String tag = Transcode(child->getTagName());
736 
737  if ((tag=="auxiliary") || (tag=="materialref") || (tag=="solidref"))
738  {
739  // These are already processed in VolumeRead()
740  }
741  else if (tag=="paramvol")
742  {
744  }
745  else if (tag=="physvol")
746  {
747  PhysvolRead(child);
748  }
749  else if (tag=="replicavol")
750  {
751  G4int number = 1;
752  const xercesc::DOMNamedNodeMap* const attributes
753  = child->getAttributes();
754  XMLSize_t attributeCount = attributes->getLength();
755  for (XMLSize_t attribute_index=0;
756  attribute_index<attributeCount; attribute_index++)
757  {
758  xercesc::DOMNode* attribute_node
759  = attributes->item(attribute_index);
760  if (attribute_node->getNodeType()!=xercesc::DOMNode::ATTRIBUTE_NODE)
761  {
762  continue;
763  }
764  const xercesc::DOMAttr* const attribute
765  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
766  if (!attribute)
767  {
768  G4Exception("G4GDMLReadStructure::Volume_contentRead()",
769  "InvalidRead", FatalException, "No attribute found!");
770  return;
771  }
772  const G4String attName = Transcode(attribute->getName());
773  const G4String attValue = Transcode(attribute->getValue());
774  if (attName=="number")
775  {
776  number = eval.EvaluateInteger(attValue);
777  }
778  }
779  ReplicavolRead(child,number);
780  }
781  else if (tag=="divisionvol")
782  {
783  DivisionvolRead(child);
784  }
785  else if (tag=="loop")
786  {
788  }
789  else
790  {
791  G4cout << "Treating unknown GDML tag in volume '" << tag
792  << "' as GDML extension..." << G4endl;
793  }
794  }
795 }
796 
798 StructureRead(const xercesc::DOMElement* const structureElement)
799 {
800 #ifdef G4VERBOSE
801  G4cout << "G4GDML: Reading structure..." << G4endl;
802 #endif
803  for (xercesc::DOMNode* iter = structureElement->getFirstChild();
804  iter != 0; iter = iter->getNextSibling())
805  {
806  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
807 
808  const xercesc::DOMElement* const child
809  = dynamic_cast<xercesc::DOMElement*>(iter);
810  if (!child)
811  {
812  G4Exception("G4GDMLReadStructure::StructureRead()",
813  "InvalidRead", FatalException, "No child found!");
814  return;
815  }
816  const G4String tag = Transcode(child->getTagName());
817 
818  if (tag=="bordersurface") { BorderSurfaceRead(child); } else
819  if (tag=="skinsurface") { SkinSurfaceRead(child); } else
820  if (tag=="volume") { VolumeRead(child); } else
821  if (tag=="assembly") { AssemblyRead(child); } else
822  if (tag=="loop") { LoopRead(child,&G4GDMLRead::StructureRead); }
823  else
824  {
825  G4String error_msg = "Unknown tag in structure: " + tag;
826  G4Exception("G4GDMLReadStructure::StructureRead()",
827  "ReadError", FatalException, error_msg);
828  }
829  }
830 }
831 
833 GetPhysvol(const G4String& ref) const
834 {
835  G4VPhysicalVolume* physvolPtr =
837 
838  if (!physvolPtr)
839  {
840  G4String error_msg = "Referenced physvol '" + ref + "' was not found!";
841  G4Exception("G4GDMLReadStructure::GetPhysvol()", "ReadError",
842  FatalException, error_msg);
843  }
844 
845  return physvolPtr;
846 }
847 
849 GetVolume(const G4String& ref) const
850 {
851  G4LogicalVolume *volumePtr
853 
854  if (!volumePtr)
855  {
856  G4String error_msg = "Referenced volume '" + ref + "' was not found!";
857  G4Exception("G4GDMLReadStructure::GetVolume()", "ReadError",
858  FatalException, error_msg);
859  }
860 
861  return volumePtr;
862 }
863 
865 GetAssembly(const G4String& ref) const
866 {
867  G4GDMLAssemblyMapType::const_iterator pos = assemblyMap.find(ref);
868  if (pos != assemblyMap.end()) { return pos->second; }
869  return 0;
870 }
871 
874 {
875  G4GDMLAuxMapType::const_iterator pos = auxMap.find(logvol);
876  if (pos != auxMap.end()) { return pos->second; }
877  else { return G4GDMLAuxListType(); }
878 }
879 
881 GetWorldVolume(const G4String& setupName)
882 {
883  G4String sname = GetSetup(setupName);
884  if (sname == "") { return 0; }
885 
888 
889  G4VPhysicalVolume* pvWorld = 0;
890 
891  if(setuptoPV[setupName])
892  {
893  pvWorld = setuptoPV[setupName];
894  }
895  else
896  {
897  pvWorld = new G4PVPlacement(0,G4ThreeVector(0,0,0),volume,
898  volume->GetName()+"_PV",0,0,0);
899  setuptoPV[setupName] = pvWorld;
900  }
901  return pvWorld;
902 }
903 
905 {
906  eval.Clear();
907  setuptoPV.clear();
908  auxMap.clear();
909 }