Files
geant4/source/persistency/gdml/src/G4GDMLReadStructure.cc
T
2022-05-25 15:50:57 +02:00

1168 lines
32 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4GDMLReadStructure implementation
//
// Author: Zoltan Torzsok, November 2007
// --------------------------------------------------------------------
#include "G4GDMLReadStructure.hh"
#include "G4UnitsTable.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4AssemblyVolume.hh"
#include "G4ReflectionFactory.hh"
#include "G4PVDivisionFactory.hh"
#include "G4LogicalBorderSurface.hh"
#include "G4LogicalSkinSurface.hh"
#include "G4VisAttributes.hh"
// --------------------------------------------------------------------
G4GDMLReadStructure::G4GDMLReadStructure()
: G4GDMLReadParamvol()
{
}
// --------------------------------------------------------------------
G4GDMLReadStructure::~G4GDMLReadStructure()
{
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::BorderSurfaceRead(
const xercesc::DOMElement* const bordersurfaceElement)
{
G4String name;
G4VPhysicalVolume* pv1 = nullptr;
G4VPhysicalVolume* pv2 = nullptr;
G4SurfaceProperty* prop = nullptr;
G4int index = 0;
const xercesc::DOMNamedNodeMap* const attributes =
bordersurfaceElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::BorderSurfaceRead()", "InvalidRead",
FatalException, "No attribute found!");
return;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "name")
{
name = GenerateName(attValue);
}
else if(attName == "surfaceproperty")
{
prop = GetSurfaceProperty(GenerateName(attValue));
}
}
for(xercesc::DOMNode* iter = bordersurfaceElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::BorderSurfaceRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag != "physvolref")
{
continue;
}
if(index == 0)
{
pv1 = GetPhysvol(GenerateName(RefRead(child)));
++index;
}
else if(index == 1)
{
pv2 = GetPhysvol(GenerateName(RefRead(child)));
++index;
}
else
break;
}
new G4LogicalBorderSurface(Strip(name), pv1, pv2, prop);
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::DivisionvolRead(
const xercesc::DOMElement* const divisionvolElement)
{
G4String name;
G4double unit = 1.0;
G4double width = 0.0;
G4double offset = 0.0;
G4int number = 0;
EAxis axis = kUndefined;
G4LogicalVolume* logvol = nullptr;
const xercesc::DOMNamedNodeMap* const attributes =
divisionvolElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
G4String unitname;
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::DivisionvolRead()", "InvalidRead",
FatalException, "No attribute found!");
return;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "name")
{
name = attValue;
}
else if(attName == "unit")
{
unit = G4UnitDefinition::GetValueOf(attValue);
unitname = G4UnitDefinition::GetCategory(attValue);
}
else if(attName == "width")
{
width = eval.Evaluate(attValue);
}
else if(attName == "offset")
{
offset = eval.Evaluate(attValue);
}
else if(attName == "number")
{
number = eval.EvaluateInteger(attValue);
}
else if(attName == "axis")
{
if(attValue == "kXAxis")
{
axis = kXAxis;
}
else if(attValue == "kYAxis")
{
axis = kYAxis;
}
else if(attValue == "kZAxis")
{
axis = kZAxis;
}
else if(attValue == "kRho")
{
axis = kRho;
}
else if(attValue == "kPhi")
{
axis = kPhi;
}
}
}
if(((axis == kXAxis || axis == kYAxis || axis == kZAxis) &&
unitname != "Length") ||
((axis == kRho || axis == kPhi) && unitname != "Angle"))
{
G4Exception("G4GDMLReadStructure::DivisionvolRead()", "InvalidRead",
FatalException, "Invalid unit!");
}
width *= unit;
offset *= unit;
for(xercesc::DOMNode* iter = divisionvolElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::DivisionvolRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "volumeref")
{
logvol = GetVolume(GenerateName(RefRead(child)));
}
}
if(logvol == nullptr)
{
return;
}
G4PVDivisionFactory::GetInstance();
G4PhysicalVolumesPair pair;
G4String pv_name = logvol->GetName() + "_div";
if((number != 0) && (width == 0.0))
{
pair = G4ReflectionFactory::Instance()->Divide(
pv_name, logvol, pMotherLogical, axis, number, offset);
}
else if((number == 0) && (width != 0.0))
{
pair = G4ReflectionFactory::Instance()->Divide(
pv_name, logvol, pMotherLogical, axis, width, offset);
}
else
{
pair = G4ReflectionFactory::Instance()->Divide(
pv_name, logvol, pMotherLogical, axis, number, width, offset);
}
if(pair.first != nullptr)
{
GeneratePhysvolName(name, pair.first);
}
if(pair.second != nullptr)
{
GeneratePhysvolName(name, pair.second);
}
}
// --------------------------------------------------------------------
G4LogicalVolume* G4GDMLReadStructure::FileRead(
const xercesc::DOMElement* const fileElement)
{
G4String name;
G4String volname;
const xercesc::DOMNamedNodeMap* const attributes =
fileElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::FileRead()", "InvalidRead",
FatalException, "No attribute found!");
return nullptr;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "name")
{
name = attValue;
}
else if(attName == "volname")
{
volname = attValue;
}
}
const G4bool isModule = true;
G4GDMLReadStructure structure;
structure.Read(name, validate, isModule);
// Register existing auxiliar information defined in child module
//
const G4GDMLAuxMapType* aux = structure.GetAuxMap();
if(!aux->empty())
{
for(auto pos = aux->cbegin(); pos != aux->cend(); ++pos)
{
auxMap.insert(std::make_pair(pos->first, pos->second));
}
}
// Return volume structure from child module
//
if(volname.empty())
{
return structure.GetVolume(structure.GetSetup("Default"));
}
else
{
return structure.GetVolume(structure.GenerateName(volname));
}
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::PhysvolRead(
const xercesc::DOMElement* const physvolElement, G4AssemblyVolume* pAssembly)
{
G4String name;
G4LogicalVolume* logvol = nullptr;
G4AssemblyVolume* assembly = nullptr;
G4ThreeVector position(0.0, 0.0, 0.0);
G4ThreeVector rotation(0.0, 0.0, 0.0);
G4ThreeVector scale(1.0, 1.0, 1.0);
G4int copynumber = 0;
const xercesc::DOMNamedNodeMap* const attributes =
physvolElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::PhysvolRead()", "InvalidRead",
FatalException, "No attribute found!");
return;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "name")
{
name = attValue;
}
if(attName == "copynumber")
{
copynumber = eval.EvaluateInteger(attValue);
}
}
for(xercesc::DOMNode* iter = physvolElement->getFirstChild(); iter != nullptr;
iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::PhysvolRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "volumeref")
{
const G4String& child_name = GenerateName(RefRead(child));
assembly = GetAssembly(child_name);
if(assembly == nullptr)
{
logvol = GetVolume(child_name);
}
}
else if(tag == "file")
{
logvol = FileRead(child);
}
else if(tag == "position")
{
VectorRead(child, position);
}
else if(tag == "rotation")
{
VectorRead(child, rotation);
}
else if(tag == "scale")
{
VectorRead(child, scale);
}
else if(tag == "positionref")
{
position = GetPosition(GenerateName(RefRead(child)));
}
else if(tag == "rotationref")
{
rotation = GetRotation(GenerateName(RefRead(child)));
}
else if(tag == "scaleref")
{
scale = GetScale(GenerateName(RefRead(child)));
}
else
{
G4String error_msg = "Unknown tag in physvol: " + tag;
G4Exception("G4GDMLReadStructure::PhysvolRead()", "ReadError",
FatalException, error_msg);
return;
}
}
G4Transform3D transform(GetRotationMatrix(rotation).inverse(), position);
transform = transform * G4Scale3D(scale.x(), scale.y(), scale.z());
if(pAssembly != nullptr) // Fill assembly structure
{
if(assembly != nullptr) // Case of recursive assemblies
{
pAssembly->AddPlacedAssembly(assembly, transform);
}
if(logvol == nullptr)
{
return;
}
pAssembly->AddPlacedVolume(logvol, transform);
}
else // Generate physical volume tree or do assembly imprint
{
if(assembly != nullptr)
{
assembly->MakeImprint(pMotherLogical, transform, 0, check);
}
else
{
if(logvol == nullptr)
{
return;
}
G4String pv_name = logvol->GetName() + "_PV";
G4PhysicalVolumesPair pair = G4ReflectionFactory::Instance()->Place(
transform, pv_name, logvol, pMotherLogical, false, copynumber, check);
if(pair.first != nullptr)
{
GeneratePhysvolName(name, pair.first);
}
if(pair.second != nullptr)
{
GeneratePhysvolName(name, pair.second);
}
}
}
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::ReplicavolRead(
const xercesc::DOMElement* const replicavolElement, G4int number)
{
G4LogicalVolume* logvol = nullptr;
for(xercesc::DOMNode* iter = replicavolElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::ReplicavolRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "volumeref")
{
logvol = GetVolume(GenerateName(RefRead(child)));
}
else if(tag == "replicate_along_axis")
{
if(logvol)
{
ReplicaRead(child, logvol, number);
}
}
else
{
G4String error_msg = "Unknown tag in ReplicavolRead: " + tag;
G4Exception("G4GDMLReadStructure::ReplicavolRead()", "ReadError",
FatalException, error_msg);
}
}
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::ReplicaRead(
const xercesc::DOMElement* const replicaElement, G4LogicalVolume* logvol,
G4int number)
{
G4double width = 0.0;
G4double offset = 0.0;
G4ThreeVector position(0.0, 0.0, 0.0);
G4ThreeVector rotation(0.0, 0.0, 0.0);
EAxis axis = kUndefined;
G4String name;
for(xercesc::DOMNode* iter = replicaElement->getFirstChild(); iter != nullptr;
iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::ReplicaRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "position")
{
VectorRead(child, position);
}
else if(tag == "rotation")
{
VectorRead(child, rotation);
}
else if(tag == "positionref")
{
position = GetPosition(GenerateName(RefRead(child)));
}
else if(tag == "rotationref")
{
rotation = GetRotation(GenerateName(RefRead(child)));
}
else if(tag == "direction")
{
axis = AxisRead(child);
}
else if(tag == "width")
{
width = QuantityRead(child);
}
else if(tag == "offset")
{
offset = QuantityRead(child);
}
else
{
G4String error_msg = "Unknown tag in ReplicaRead: " + tag;
G4Exception("G4GDMLReadStructure::ReplicaRead()", "ReadError",
FatalException, error_msg);
}
}
G4String pv_name = logvol->GetName() + "_PV";
G4PhysicalVolumesPair pair = G4ReflectionFactory::Instance()->Replicate(
pv_name, logvol, pMotherLogical, axis, number, width, offset);
if(pair.first != nullptr)
{
GeneratePhysvolName(name, pair.first);
}
if(pair.second != nullptr)
{
GeneratePhysvolName(name, pair.second);
}
}
// --------------------------------------------------------------------
EAxis G4GDMLReadStructure::AxisRead(
const xercesc::DOMElement* const axisElement)
{
EAxis axis = kUndefined;
const xercesc::DOMNamedNodeMap* const attributes =
axisElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::AxisRead()", "InvalidRead",
FatalException, "No attribute found!");
return axis;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "x")
{
if(eval.Evaluate(attValue) == 1.)
{
axis = kXAxis;
}
}
else if(attName == "y")
{
if(eval.Evaluate(attValue) == 1.)
{
axis = kYAxis;
}
}
else if(attName == "z")
{
if(eval.Evaluate(attValue) == 1.)
{
axis = kZAxis;
}
}
else if(attName == "rho")
{
if(eval.Evaluate(attValue) == 1.)
{
axis = kRho;
}
}
else if(attName == "phi")
{
if(eval.Evaluate(attValue) == 1.)
{
axis = kPhi;
}
}
}
return axis;
}
// --------------------------------------------------------------------
G4double G4GDMLReadStructure::QuantityRead(
const xercesc::DOMElement* const readElement)
{
G4double value = 0.0;
G4double unit = 0.0;
const xercesc::DOMNamedNodeMap* const attributes =
readElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::QuantityRead()", "InvalidRead",
FatalException, "No attribute found!");
return value;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "unit")
{
unit = G4UnitDefinition::GetValueOf(attValue);
if(G4UnitDefinition::GetCategory(attValue) != "Length" &&
G4UnitDefinition::GetCategory(attValue) != "Angle")
{
G4Exception("G4GDMLReadStructure::QuantityRead()", "InvalidRead",
FatalException,
"Invalid unit for length or angle (width, offset)!");
}
}
else if(attName == "value")
{
value = eval.Evaluate(attValue);
}
}
return value * unit;
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::VolumeRead(
const xercesc::DOMElement* const volumeElement)
{
G4VSolid* solidPtr = nullptr;
G4Material* materialPtr = nullptr;
G4GDMLAuxListType auxList;
XMLCh* name_attr = xercesc::XMLString::transcode("name");
const G4String name = Transcode(volumeElement->getAttribute(name_attr));
xercesc::XMLString::release(&name_attr);
for(xercesc::DOMNode* iter = volumeElement->getFirstChild(); iter != nullptr;
iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::VolumeRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "auxiliary")
{
auxList.push_back(AuxiliaryRead(child));
}
else if(tag == "materialref")
{
materialPtr = GetMaterial(GenerateName(RefRead(child), true));
}
else if(tag == "solidref")
{
solidPtr = GetSolid(GenerateName(RefRead(child)));
}
}
pMotherLogical =
new G4LogicalVolume(solidPtr, materialPtr, GenerateName(name), 0, 0, 0);
if(!auxList.empty())
{
auxMap[pMotherLogical] = auxList;
}
Volume_contentRead(volumeElement);
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::AssemblyRead(
const xercesc::DOMElement* const assemblyElement)
{
XMLCh* name_attr = xercesc::XMLString::transcode("name");
const G4String name = Transcode(assemblyElement->getAttribute(name_attr));
xercesc::XMLString::release(&name_attr);
G4AssemblyVolume* pAssembly = new G4AssemblyVolume();
auto aName = GenerateName(name);
if(reverseSearch)
{
assemblyMap.insert_or_assign(aName, pAssembly);
}
else
{
assemblyMap.insert(std::make_pair(aName, pAssembly));
}
for(xercesc::DOMNode* iter = assemblyElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::AssemblyRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "physvol")
{
PhysvolRead(child, pAssembly);
}
else
{
G4cout << "Unsupported GDML tag '" << tag
<< "' for Geant4 assembly structure !" << G4endl;
}
}
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::SkinSurfaceRead(
const xercesc::DOMElement* const skinsurfaceElement)
{
G4String name;
G4LogicalVolume* logvol = nullptr;
G4SurfaceProperty* prop = nullptr;
const xercesc::DOMNamedNodeMap* const attributes =
skinsurfaceElement->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::SkinsurfaceRead()", "InvalidRead",
FatalException, "No attribute found!");
return;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "name")
{
name = GenerateName(attValue);
}
else if(attName == "surfaceproperty")
{
prop = GetSurfaceProperty(GenerateName(attValue));
}
}
for(xercesc::DOMNode* iter = skinsurfaceElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::SkinsurfaceRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "volumeref")
{
logvol = GetVolume(GenerateName(RefRead(child)));
}
else
{
G4String error_msg = "Unknown tag in skinsurface: " + tag;
G4Exception("G4GDMLReadStructure::SkinsurfaceRead()", "ReadError",
FatalException, error_msg);
}
}
new G4LogicalSkinSurface(Strip(name), logvol, prop);
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::Volume_contentRead(
const xercesc::DOMElement* const volumeElement)
{
for(xercesc::DOMNode* iter = volumeElement->getFirstChild(); iter != nullptr;
iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::Volume_contentRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if((tag == "auxiliary") || (tag == "materialref") || (tag == "solidref"))
{
// These are already processed in VolumeRead()
}
else if(tag == "paramvol")
{
ParamvolRead(child, pMotherLogical);
}
else if(tag == "physvol")
{
PhysvolRead(child);
}
else if(tag == "replicavol")
{
G4int number = 1;
const xercesc::DOMNamedNodeMap* const attributes = child->getAttributes();
XMLSize_t attributeCount = attributes->getLength();
for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
++attribute_index)
{
xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
{
continue;
}
const xercesc::DOMAttr* const attribute =
dynamic_cast<xercesc::DOMAttr*>(attribute_node);
if(attribute == nullptr)
{
G4Exception("G4GDMLReadStructure::Volume_contentRead()",
"InvalidRead", FatalException, "No attribute found!");
return;
}
const G4String attName = Transcode(attribute->getName());
const G4String attValue = Transcode(attribute->getValue());
if(attName == "number")
{
number = eval.EvaluateInteger(attValue);
}
}
ReplicavolRead(child, number);
}
else if(tag == "divisionvol")
{
DivisionvolRead(child);
}
else if(tag == "loop")
{
LoopRead(child, &G4GDMLRead::Volume_contentRead);
}
else
{
G4cout << "Treating unknown GDML tag in volume '" << tag
<< "' as GDML extension..." << G4endl;
}
}
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::StructureRead(
const xercesc::DOMElement* const structureElement)
{
#ifdef G4VERBOSE
G4cout << "G4GDML: Reading structure..." << G4endl;
#endif
for(xercesc::DOMNode* iter = structureElement->getFirstChild();
iter != nullptr; iter = iter->getNextSibling())
{
if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
{
continue;
}
const xercesc::DOMElement* const child =
dynamic_cast<xercesc::DOMElement*>(iter);
if(child == nullptr)
{
G4Exception("G4GDMLReadStructure::StructureRead()", "InvalidRead",
FatalException, "No child found!");
return;
}
const G4String tag = Transcode(child->getTagName());
if(tag == "bordersurface")
{
BorderSurfaceRead(child);
}
else if(tag == "skinsurface")
{
SkinSurfaceRead(child);
}
else if(tag == "volume")
{
VolumeRead(child);
}
else if(tag == "assembly")
{
AssemblyRead(child);
}
else if(tag == "loop")
{
LoopRead(child, &G4GDMLRead::StructureRead);
}
else
{
G4String error_msg = "Unknown tag in structure: " + tag;
G4Exception("G4GDMLReadStructure::StructureRead()", "ReadError",
FatalException, error_msg);
}
}
}
// --------------------------------------------------------------------
G4VPhysicalVolume* G4GDMLReadStructure::GetPhysvol(const G4String& ref) const
{
G4VPhysicalVolume* physvolPtr
= G4PhysicalVolumeStore::GetInstance()->GetVolume(ref,false,reverseSearch);
if(physvolPtr == nullptr)
{
G4String error_msg = "Referenced physvol '" + ref + "' was not found!";
G4Exception("G4GDMLReadStructure::GetPhysvol()", "ReadError",
FatalException, error_msg);
}
return physvolPtr;
}
// --------------------------------------------------------------------
G4LogicalVolume* G4GDMLReadStructure::GetVolume(const G4String& ref) const
{
G4LogicalVolume* volumePtr
= G4LogicalVolumeStore::GetInstance()->GetVolume(ref,false,reverseSearch);
if(volumePtr == nullptr)
{
G4String error_msg = "Referenced volume '" + ref + "' was not found!";
G4Exception("G4GDMLReadStructure::GetVolume()", "ReadError", FatalException,
error_msg);
}
return volumePtr;
}
// --------------------------------------------------------------------
G4AssemblyVolume* G4GDMLReadStructure::GetAssembly(const G4String& ref) const
{
auto pos = assemblyMap.find(ref);
if(pos != assemblyMap.cend())
{
return pos->second;
}
return nullptr;
}
// --------------------------------------------------------------------
G4GDMLAuxListType G4GDMLReadStructure::GetVolumeAuxiliaryInformation(
G4LogicalVolume* logvol) const
{
auto pos = auxMap.find(logvol);
if(pos != auxMap.cend())
{
return pos->second;
}
else
{
return G4GDMLAuxListType();
}
}
// --------------------------------------------------------------------
G4VPhysicalVolume* G4GDMLReadStructure::GetWorldVolume(
const G4String& setupName)
{
G4String sname = GetSetup(setupName);
if(sname == "")
{
return nullptr;
}
G4LogicalVolume* volume = GetVolume(GenerateName(sname, dostrip));
volume->SetVisAttributes(G4VisAttributes::GetInvisible());
G4VPhysicalVolume* pvWorld = nullptr;
if(setuptoPV[setupName])
{
pvWorld = setuptoPV[setupName];
}
else
{
pvWorld = new G4PVPlacement(nullptr, G4ThreeVector(0, 0, 0), volume,
volume->GetName() + "_PV", 0, 0, 0);
setuptoPV[setupName] = pvWorld;
}
return pvWorld;
}
// --------------------------------------------------------------------
void G4GDMLReadStructure::Clear()
{
eval.Clear();
setuptoPV.clear();
auxMap.clear();
}