Links

Content Skeleton

This Page

Previous topic

GDML from ROOT

Next topic

Geant4 Collada Export

GDML Export ImplementationΒΆ

Intend to borrow from here for Collada export, so need to know details of the exporter implementation.

Inverted inheritance chain structure:

G4GDMLWrite < ... < G4GDMLWriteStructure

Contary to expectations from the name G4GDMLWriteStructure is top dog inheriting from all the other G4GDMLWrite* classes including G4GDMLWrite at the base. Inheritance misused for categorisation.

$DYB/NuWa-trunk/lhcb/Sim/GaussTools/src/Components/GiGaRunActionGDML.cpp:

55    G4VPhysicalVolume* wpv = G4TransportationManager::GetTransportationManager()->
56       GetNavigatorForTracking()->GetWorldVolume();
57
58    G4String outFilePath("g4_00.gdml");
59    G4GDMLParser parser ;
60    if(wpv)
61    {
62        std::cout << "GiGaRunActionGDML::BeginOfRunAction writing to " << m_outFilePath << std::endl ;
63        parser.Write(outFilePath, wpv);
64    }

$DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLParser.cc:

37 G4GDMLParser::G4GDMLParser()
38   : ucode(false)
39 {
40   reader = new G4GDMLReadStructure;
41   writer = new G4GDMLWriteStructure;
42   xercesc::XMLPlatformUtils::Initialize();
43 }

$DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/include/G4GDMLParser.icc:

47 inline
48 void G4GDMLParser::Write(const G4String& filename,
49                          const G4VPhysicalVolume* const pvol,
50                                G4bool refs,
51                          const G4String& schemaLocation)
52 {
53   const G4int depth = 0;
54   G4LogicalVolume* lvol = 0;
55
56   if (!pvol)
57   {
58     G4VPhysicalVolume* worldPV = GetWorldVolume();
59     if (!worldPV)
60     {
61       G4Exception("G4DMLParser::Write()", "InvalidSetup", FatalException,
62                   "Detector-Construction needs to be registered first!");
63     }
64     lvol = worldPV->GetLogicalVolume();
65   }
66   else
67   {
68     lvol = pvol->GetLogicalVolume();
69   }
70   writer->Write(filename,lvol,schemaLocation,depth,refs);
71 }

$DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLWrite.cc:

107 G4Transform3D G4GDMLWrite::Write(const G4String& fname,
108                                  const G4LogicalVolume* const logvol,
109                                  const G4String& setSchemaLocation,
110                                  const G4int depth,
111                                        G4bool refs)
112 {
///
///    xercesc XML writer/doc setup
///
161    DefineWrite(gdml);         // open "define" element
162    MaterialsWrite(gdml);      // open "materials" element and clear materialsList, isotopeList
163    SolidsWrite(gdml);         // open "solids" element and clear solidsList
164    StructureWrite(gdml);      // open "structure" element
165    SetupWrite(gdml,logvol);   // open "setup" element and populate
166
167    G4Transform3D R = TraverseVolumeTree(logvol,depth);   // the meat, kicking off the recursive traverse
168
///
///    xercesc XML writing
///
216    return R;
217 }

$DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLWriteStructure.cc:

189 G4Transform3D G4GDMLWriteStructure::
190 TraverseVolumeTree(const G4LogicalVolume* const volumePtr, const G4int depth)
191 {
192    if (VolumeMap().find(volumePtr) != VolumeMap().end())
193    {
194      return VolumeMap()[volumePtr]; // Volume is already processed
195    }
196
197    G4VSolid* solidPtr = volumePtr->GetSolid();
198    G4Transform3D R,invR;
///
///    reflected solid handling skipped
///
235    const G4String name
236          = GenerateName(volumePtr->GetName(),volumePtr);      // lvName
237    const G4String materialref
238          = GenerateName(volumePtr->GetMaterial()->GetName(),
239                         volumePtr->GetMaterial());
240    const G4String solidref
241          = GenerateName(solidPtr->GetName(),solidPtr);
...
...    prep the volumeElement using name/materialref/solidref but dont append to structure yet
...
...    2181     <volume name="/dd/Geometry/RPC/lvRPCGasgap140xb7491f8">
...    2182       <materialref ref="/dd/Materials/Air0xb830740"/>
...    2183       <solidref ref="RPCGasgap140xbad5938"/>
...
...
232    if (reflected>0) { invR = R.inverse(); }
233      // Only compute the inverse when necessary!
...
252    const G4int daughterCount = volumePtr->GetNoDaughters();
253
254    for (G4int i=0;i<daughterCount;i++)   // Traverse all the children!
255    {
256       const G4VPhysicalVolume* const physvol = volumePtr->GetDaughter(i);
257       const G4String ModuleName = Modularize(physvol,depth);
258
259       G4Transform3D daughterR;
260
261       if (ModuleName.empty())   // Check if subtree requested to be
262       {                         // a separate module!
263          daughterR = TraverseVolumeTree(physvol->GetLogicalVolume(),depth+1);
...
...   Q: hmm, how come not getting a deeper GDML structure then ?
...   A: because no matter what depth of the recursion the resulting volumeElement with 0 or more child physvol
...      are appended to the fixed structureElement gdml/structure/
...
264       }
265       else
266       {
267          G4GDMLWriteStructure writer;
268          daughterR = writer.Write(ModuleName,physvol->GetLogicalVolume(),
269                                   SchemaLocation,depth+1);
270       }
...
272       if (const G4PVDivision* const divisionvol
273          = dynamic_cast<const G4PVDivision*>(physvol)) // Is it division?
274       {
///
///              divisional/replica/parameterized skipped
///
309       else   // Is it a physvol?
310       {
311          G4RotationMatrix rot;
312
313          if (physvol->GetFrameRotation() != 0)
314          {
315            rot = *(physvol->GetFrameRotation());
316          }
317          G4Transform3D P(rot,physvol->GetObjectTranslation());           // placement transform of daughter pv wrt mother
318          PhysvolWrite(volumeElement,physvol,invR*P*daughterR,ModuleName);
...
...             R, invR are identity transforms when not dealing with reflections.. ?
...
319       }
320    }
321
322    structureElement->appendChild(volumeElement);
323      // Append the volume AFTER traversing the children so that
324      // the order of volumes will be correct!
325
326    VolumeMap()[volumePtr] = R;
327
328    G4GDMLWriteMaterials::AddMaterial(volumePtr->GetMaterial());
329      // Add the involved materials and solids!
330
331    G4GDMLWriteSolids::AddSolid(solidPtr);
332
333    return R;
334 }
76 void G4GDMLWriteStructure::PhysvolWrite(xercesc::DOMElement* volumeElement,
77                                         const G4VPhysicalVolume* const physvol,
78                                         const G4Transform3D& T,
79                                         const G4String& ModuleName)
80 {
81    HepGeom::Scale3D scale;
82    HepGeom::Rotate3D rotate;
83    HepGeom::Translate3D translate;
84
85    T.getDecomposition(scale,rotate,translate);
86
87    const G4ThreeVector scl(scale(0,0),scale(1,1),scale(2,2));
88    const G4ThreeVector rot = GetAngles(rotate.getRotation());
89    const G4ThreeVector pos = T.getTranslation();
90
91    const G4String name = GenerateName(physvol->GetName(),physvol);
92
93    xercesc::DOMElement* physvolElement = NewElement("physvol");
94    physvolElement->setAttributeNode(NewAttribute("name",name));
95    volumeElement->appendChild(physvolElement);
96
97    const G4String volumeref
98          = GenerateName(physvol->GetLogicalVolume()->GetName(),
99                         physvol->GetLogicalVolume());
100
101    if (ModuleName.empty())
102    {
103       xercesc::DOMElement* volumerefElement = NewElement("volumeref");
104       volumerefElement->setAttributeNode(NewAttribute("ref",volumeref));
105       physvolElement->appendChild(volumerefElement);
106    }
...
...       physvol are the children of the mother lv.
...       volumeref/@ref point to the lv of the child physvol
...
...       2181     <volume name="/dd/Geometry/RPC/lvRPCGasgap140xb7491f8">
...       2182       <materialref ref="/dd/Materials/Air0xb830740"/>
...       2183       <solidref ref="RPCGasgap140xbad5938"/>
...       2184       <physvol name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930">
...       2185         <volumeref ref="/dd/Geometry/RPC/lvRPCStrip0xb839910"/>
...       2186         <position name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930_pos" unit="mm" x="-910" y="0" z="0"/>
...       2187         <rotation name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930_rot" unit="deg" x="0" y="0" z="-90"/>
...       2188       </physvol>
...
...
107    else
108    {
109       xercesc::DOMElement* fileElement = NewElement("file");
110       fileElement->setAttributeNode(NewAttribute("name",ModuleName));
111       fileElement->setAttributeNode(NewAttribute("volname",volumeref));
112       physvolElement->appendChild(fileElement);
113    }
114
115    if (std::fabs(pos.x()) > kLinearPrecision
116     || std::fabs(pos.y()) > kLinearPrecision
117     || std::fabs(pos.z()) > kLinearPrecision)
118    {
119      PositionWrite(physvolElement,name+"_pos",pos);
120    }
121    if (std::fabs(rot.x()) > kAngularPrecision
122     || std::fabs(rot.y()) > kAngularPrecision
123     || std::fabs(rot.z()) > kAngularPrecision)
124    {
125      RotationWrite(physvolElement,name+"_rot",rot);
126    }
127    if (std::fabs(scl.x()-1.0) > kRelativePrecision
128     || std::fabs(scl.y()-1.0) > kRelativePrecision
129     || std::fabs(scl.z()-1.0) > kRelativePrecision)
130    {
131      ScaleWrite(physvolElement,name+"_scl",scl);
132    }
133 }

$LOCAL_BASE/env/geant4/geometry/gdml/g4_01.gdml:

...
...     structure only goes to two levels ?  structure/volume/physvol/volumeref
...     presumably depth heirarchy being repesented via the volumeref linking up multiple such relations
...
...     Logical volumes with @name are pointed to by physvol/volumeref/@ref
...
2172   <structure>
2173     <volume name="/dd/Geometry/PoolDetails/lvNearTopCover0xbad46a0">
2174       <materialref ref="/dd/Materials/PPE0xb8310e0"/>
2175       <solidref ref="near_top_cover_box0xbad4490"/>
2176     </volume>
2177     <volume name="/dd/Geometry/RPC/lvRPCStrip0xb839910">
2178       <materialref ref="/dd/Materials/MixGas0xbad5d28"/>
2179       <solidref ref="RPCStrip0xb751cc0"/>
2180     </volume>
2181     <volume name="/dd/Geometry/RPC/lvRPCGasgap140xb7491f8">
2182       <materialref ref="/dd/Materials/Air0xb830740"/>
2183       <solidref ref="RPCGasgap140xbad5938"/>
2184       <physvol name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930">
2185         <volumeref ref="/dd/Geometry/RPC/lvRPCStrip0xb839910"/>
2186         <position name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930_pos" unit="mm" x="-910" y="0" z="0"/>
2187         <rotation name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:1#pvStrip14Unit0xbc1e930_rot" unit="deg" x="0" y="0" z="-90"/>
2188       </physvol>
2189       <physvol name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:2#pvStrip14Unit0xbc1f8b8">
2190         <volumeref ref="/dd/Geometry/RPC/lvRPCStrip0xb839910"/>
2191         <position name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:2#pvStrip14Unit0xbc1f8b8_pos" unit="mm" x="-650" y="0" z="0"/>
2192         <rotation name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:2#pvStrip14Unit0xbc1f8b8_rot" unit="deg" x="0" y="0" z="-90"/>
2193       </physvol>
....
2219       <physvol name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:8#pvStrip14Unit0xbc1feb0">
2220         <volumeref ref="/dd/Geometry/RPC/lvRPCStrip0xb839910"/>
2221         <position name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:8#pvStrip14Unit0xbc1feb0_pos" unit="mm" x="910" y="0" z="0"/>
2222         <rotation name="/dd/Geometry/RPC/lvRPCGasgap14#pvStrip14Array#pvStrip14ArrayOne:8#pvStrip14Unit0xbc1feb0_rot" unit="deg" x="0" y="0" z="-90"/>
2223       </physvol>
2224     </volume>
2225     <volume name="/dd/Geometry/RPC/lvRPCBarCham140xbad5978">
2226       <materialref ref="/dd/Materials/Bakelite0xb830008"/>
2227       <solidref ref="RPCBarCham140xbd59170"/>
2228       <physvol name="/dd/Geometry/RPC/lvRPCBarCham14#pvRPCGasgap140xbc1f360">
2229         <volumeref ref="/dd/Geometry/RPC/lvRPCGasgap140xb7491f8"/>
2230       </physvol>
2231     </volume>
....
30919     <volume name="/dd/Geometry/Sites/lvNearSiteRock0xb82e578">
30920       <materialref ref="/dd/Materials/Rock0xb849090"/>
30921       <solidref ref="near_rock0xb8499c8"/>
30922       <physvol name="/dd/Geometry/Sites/lvNearSiteRock#pvNearHallTop0xb7dd068">
30923         <volumeref ref="/dd/Geometry/Sites/lvNearHallTop0xb745f10"/>
30924         <position name="/dd/Geometry/Sites/lvNearSiteRock#pvNearHallTop0xb7dd068_pos" unit="mm" x="2500" y="-500" z="7500"/>
30925       </physvol>
30926       <physvol name="/dd/Geometry/Sites/lvNearSiteRock#pvNearHallBot0xc5065d0">
30927         <volumeref ref="/dd/Geometry/Sites/lvNearHallBot0xb7dd4a8"/>
30928         <position name="/dd/Geometry/Sites/lvNearSiteRock#pvNearHallBot0xc5065d0_pos" unit="mm" x="0" y="0" z="-5150"/>
30929       </physvol>
30930     </volume>
30931     <volume name="World0xc6337a8">
30932       <materialref ref="/dd/Materials/Vacuum0xbaff828"/>
30933       <solidref ref="WorldBox0xc6328f0"/>
30934       <physvol name="/dd/Structure/Sites/db-rock0xc633af8">
30935         <volumeref ref="/dd/Geometry/Sites/lvNearSiteRock0xb82e578"/>
30936         <position name="/dd/Structure/Sites/db-rock0xc633af8_pos" unit="mm" x="-16519.9999999999" y="-802110" z="-2110"/>
30937         <rotation name="/dd/Structure/Sites/db-rock0xc633af8_rot" unit="deg" x="0" y="0" z="-122.9"/>
30938       </physvol>
30939     </volume>
30940   </structure>

$LOCAL_BASE/env/geant4/geometry/gdml/g4_01.gdml:

1 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2 <gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd">
3
4   <define/>
5
6   <materials>
7     <element Z="6" name="/dd/Materials/Carbon0xbad48f8">
8       <atom unit="g/mole" value="12.0109936803044"/>
9     </element>
10     <element Z="1" name="/dd/Materials/Hydrogen0xbad34d0">
11       <atom unit="g/mole" value="1.00793946966331"/>
12     </element>
13     <material name="/dd/Materials/PPE0xb8310e0" state="solid">
14       <P unit="pascal" value="101324.946686941"/>
15       <D unit="g/cm3" value="0.919999515933733"/>
16       <fraction n="0.798874855998063" ref="/dd/Materials/Carbon0xbad48f8"/>
17       <fraction n="0.201125144001937" ref="/dd/Materials/Hydrogen0xbad34d0"/>
18     </material>
..
401   <solids>
402     <box lunit="mm" name="near_top_cover0xbb2aa88" x="16000" y="10000" z="44"/>
403     <box lunit="mm" name="near_top_cover_sub00xbad4c78" x="4249.00272282321" y="4249.00272282321" z="54"/>
404     <subtraction name="near_top_cover-ChildFornear_top_cover_box0xbad6708">
405       <first ref="near_top_cover0xbb2aa88"/>
406       <second ref="near_top_cover_sub00xbad4c78"/>
407       <position name="near_top_cover-ChildFornear_top_cover_box0xbad6708_pos" unit="mm" x="8000" y="5000" z="0"/>
408       <rotation name="near_top_cover-ChildFornear_top_cover_box0xbad6708_rot" unit="deg" x="0" y="0" z="45"/>
409     </subtraction>
...
2172   <structure>
....
....     dealt with above
....
30940   </structure>
30941
30942   <setup name="Default" version="1.0">
30943     <world ref="World0xc6337a8"/>
30944   </setup>
30945
30946 </gdml>