1479 lines
44 KiB
C++
1479 lines
44 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. *
|
|
// ********************************************************************
|
|
//
|
|
// G4tgbGeometryDumper implementation
|
|
//
|
|
// Author: P.Arce, CIEMAT (November 2007)
|
|
// --------------------------------------------------------------------
|
|
|
|
#include "G4tgbGeometryDumper.hh"
|
|
|
|
#include "G4tgrMessenger.hh"
|
|
|
|
#include "G4UIcommand.hh"
|
|
#include "G4Material.hh"
|
|
#include "G4Element.hh"
|
|
#include "G4VSolid.hh"
|
|
#include "G4Box.hh"
|
|
#include "G4Tubs.hh"
|
|
#include "G4Cons.hh"
|
|
#include "G4Trap.hh"
|
|
#include "G4Sphere.hh"
|
|
#include "G4Orb.hh"
|
|
#include "G4Trd.hh"
|
|
#include "G4Para.hh"
|
|
#include "G4Torus.hh"
|
|
#include "G4Hype.hh"
|
|
#include "G4Polycone.hh"
|
|
#include "G4GenericPolycone.hh"
|
|
#include "G4Polyhedra.hh"
|
|
#include "G4EllipticalTube.hh"
|
|
#include "G4Ellipsoid.hh"
|
|
#include "G4EllipticalCone.hh"
|
|
#include "G4Hype.hh"
|
|
#include "G4Tet.hh"
|
|
#include "G4TwistedBox.hh"
|
|
#include "G4TwistedTrap.hh"
|
|
#include "G4TwistedTrd.hh"
|
|
#include "G4TwistedTubs.hh"
|
|
#include "G4MultiUnion.hh"
|
|
#include "G4ScaledSolid.hh"
|
|
#include "G4PVPlacement.hh"
|
|
#include "G4PVParameterised.hh"
|
|
#include "G4PVReplica.hh"
|
|
#include "G4BooleanSolid.hh"
|
|
#include "G4ReflectionFactory.hh"
|
|
#include "G4ReflectedSolid.hh"
|
|
#include "G4LogicalVolumeStore.hh"
|
|
#include "G4PhysicalVolumeStore.hh"
|
|
#include "G4GeometryTolerance.hh"
|
|
#include "G4VPVParameterisation.hh"
|
|
#include "G4SystemOfUnits.hh"
|
|
#include <iomanip>
|
|
|
|
// --------------------------------------------------------------------
|
|
G4ThreadLocal G4tgbGeometryDumper* G4tgbGeometryDumper::theInstance = nullptr;
|
|
|
|
// --------------------------------------------------------------------
|
|
G4tgbGeometryDumper::G4tgbGeometryDumper()
|
|
{
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4tgbGeometryDumper* G4tgbGeometryDumper::GetInstance()
|
|
{
|
|
if(theInstance == nullptr)
|
|
{
|
|
theInstance = new G4tgbGeometryDumper;
|
|
}
|
|
return theInstance;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpGeometry(const G4String& fname)
|
|
{
|
|
theFile = new std::ofstream(fname);
|
|
|
|
G4VPhysicalVolume* pv = GetTopPhysVol();
|
|
DumpPhysVol(pv); // dump volume and recursively it will dump all hierarchy
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4VPhysicalVolume* G4tgbGeometryDumper::GetTopPhysVol()
|
|
{
|
|
G4PhysicalVolumeStore* pvstore = G4PhysicalVolumeStore::GetInstance();
|
|
G4VPhysicalVolume* pv = *(pvstore->cbegin());
|
|
for(;;)
|
|
{
|
|
G4LogicalVolume* lv = pv->GetMotherLogical();
|
|
if(lv == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//----- look for one PV of this LV
|
|
for(auto ite = pvstore->cbegin(); ite != pvstore->cend(); ++ite)
|
|
{
|
|
pv = (*ite);
|
|
if(pv->GetLogicalVolume() == lv)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pv;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4tgbGeometryDumper::~G4tgbGeometryDumper()
|
|
{
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpPhysVol(G4VPhysicalVolume* pv)
|
|
{
|
|
//--- Dump logical volume first
|
|
G4LogicalVolume* lv = pv->GetLogicalVolume();
|
|
|
|
G4ReflectionFactory* reffact = G4ReflectionFactory::Instance();
|
|
|
|
//--- It is not needed to dump _refl volumes created when parent is reflected
|
|
// !!WARNING : it must be avoided to reflect a volume hierarchy if children
|
|
// has also been reflected, as both will have same name
|
|
|
|
if(reffact->IsReflected(lv) && reffact->IsReflected(pv->GetMotherLogical()))
|
|
{
|
|
return;
|
|
}
|
|
|
|
G4bool bVolExists = CheckIfLogVolExists(lv->GetName(), lv);
|
|
|
|
//---- Construct this PV
|
|
if(pv->GetMotherLogical() != nullptr) // not WORLD volume
|
|
{
|
|
if(!pv->IsReplicated())
|
|
{
|
|
G4String lvName = lv->GetName();
|
|
if(!bVolExists)
|
|
{
|
|
lvName = DumpLogVol(lv);
|
|
}
|
|
DumpPVPlacement(pv, lvName);
|
|
}
|
|
else if(pv->IsParameterised())
|
|
{
|
|
G4PVParameterised* pvparam = (G4PVParameterised*) (pv);
|
|
DumpPVParameterised(pvparam);
|
|
}
|
|
else
|
|
{
|
|
G4String lvName = lv->GetName();
|
|
if(!bVolExists)
|
|
{
|
|
lvName = DumpLogVol(lv);
|
|
}
|
|
G4PVReplica* pvrepl = (G4PVReplica*) (pv);
|
|
DumpPVReplica(pvrepl, lvName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DumpLogVol(lv);
|
|
}
|
|
|
|
if(!bVolExists)
|
|
{
|
|
//---- Construct PV's who has this LV as mother
|
|
std::vector<G4VPhysicalVolume*> pvChildren = GetPVChildren(lv);
|
|
for(auto ite = pvChildren.cbegin(); ite != pvChildren.cend(); ++ite)
|
|
{
|
|
DumpPhysVol(*ite);
|
|
}
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpPVPlacement(G4VPhysicalVolume* pv,
|
|
const G4String& lvName, G4int copyNo)
|
|
{
|
|
G4String pvName = pv->GetName();
|
|
|
|
G4RotationMatrix* rotMat = pv->GetRotation();
|
|
if(rotMat == nullptr)
|
|
rotMat = new G4RotationMatrix();
|
|
|
|
//---- Check if it is reflected
|
|
G4ReflectionFactory* reffact = G4ReflectionFactory::Instance();
|
|
G4LogicalVolume* lv = pv->GetLogicalVolume();
|
|
if(reffact->IsReflected(lv))
|
|
{
|
|
#ifdef G4VERBOSE
|
|
if(G4tgrMessenger::GetVerboseLevel() >= 1)
|
|
{
|
|
G4cout << " G4tgbGeometryDumper::DumpPVPlacement() - Reflected volume: "
|
|
<< pv->GetName() << G4endl;
|
|
}
|
|
#endif
|
|
G4ThreeVector colx = rotMat->colX();
|
|
G4ThreeVector coly = rotMat->colY();
|
|
G4ThreeVector colz = rotMat->colZ();
|
|
// apply a Z reflection (reflection matrix is decomposed in new
|
|
// reflection-free rotation + z-reflection)
|
|
colz *= -1.;
|
|
G4Rep3x3 rottemp(colx.x(), coly.x(), colz.x(), colx.y(), coly.y(), colz.y(),
|
|
colx.z(), coly.z(), colz.z());
|
|
// matrix representation (inverted)
|
|
*rotMat = G4RotationMatrix(rottemp);
|
|
*rotMat = (*rotMat).inverse();
|
|
pvName += "_refl";
|
|
}
|
|
const G4String& rotName = DumpRotationMatrix(rotMat);
|
|
G4ThreeVector pos = pv->GetTranslation();
|
|
|
|
if(copyNo == -999) // for parameterisations copy number is provided
|
|
{
|
|
copyNo = pv->GetCopyNo();
|
|
}
|
|
|
|
const G4String& fullname = pvName + "#" + G4UIcommand::ConvertToString(copyNo)
|
|
+ "/" + pv->GetMotherLogical()->GetName();
|
|
|
|
if(!CheckIfPhysVolExists(fullname, pv))
|
|
{
|
|
(*theFile) << ":PLACE " << SubstituteRefl(AddQuotes(lvName)) << " "
|
|
<< copyNo << " "
|
|
<< SubstituteRefl(AddQuotes(pv->GetMotherLogical()->GetName()))
|
|
<< " " << AddQuotes(rotName) << " " << pos.x() << " " << pos.y()
|
|
<< " " << pos.z() << G4endl;
|
|
|
|
thePhysVols[fullname] = pv;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpPVParameterised(G4PVParameterised* pv)
|
|
{
|
|
G4String pvName = pv->GetName();
|
|
|
|
EAxis axis;
|
|
G4int nReplicas;
|
|
G4double width;
|
|
G4double offset;
|
|
G4bool consuming;
|
|
pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
|
|
|
|
G4VPVParameterisation* param = pv->GetParameterisation();
|
|
|
|
G4LogicalVolume* lv = pv->GetLogicalVolume();
|
|
G4VSolid* solid1st = param->ComputeSolid(0, pv);
|
|
G4Material* mate1st = param->ComputeMaterial(0, pv);
|
|
std::vector<G4double> params1st = GetSolidParams(solid1st);
|
|
std::vector<G4double> newParams;
|
|
G4VSolid* newSolid = solid1st;
|
|
G4String lvName;
|
|
|
|
for(G4int ii = 0; ii < nReplicas; ++ii)
|
|
{
|
|
G4Material* newMate = param->ComputeMaterial(ii, pv);
|
|
if(solid1st->GetEntityType() == "G4Box")
|
|
{
|
|
G4Box* box = (G4Box*) (solid1st);
|
|
param->ComputeDimensions(*box, ii, pv);
|
|
newParams = GetSolidParams(box);
|
|
newSolid = (G4VSolid*) box;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Tubs")
|
|
{
|
|
G4Tubs* tubs = (G4Tubs*) (solid1st);
|
|
param->ComputeDimensions(*tubs, ii, pv);
|
|
newParams = GetSolidParams(tubs);
|
|
newSolid = (G4VSolid*) tubs;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Trd")
|
|
{
|
|
G4Trd* trd = (G4Trd*) (solid1st);
|
|
param->ComputeDimensions(*trd, ii, pv);
|
|
newParams = GetSolidParams(trd);
|
|
newSolid = (G4VSolid*) trd;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Trap")
|
|
{
|
|
G4Trap* trap = (G4Trap*) (solid1st);
|
|
param->ComputeDimensions(*trap, ii, pv);
|
|
newParams = GetSolidParams(trap);
|
|
newSolid = (G4VSolid*) trap;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Cons")
|
|
{
|
|
G4Cons* cons = (G4Cons*) (solid1st);
|
|
param->ComputeDimensions(*cons, ii, pv);
|
|
newParams = GetSolidParams(cons);
|
|
newSolid = (G4VSolid*) cons;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Sphere")
|
|
{
|
|
G4Sphere* sphere = (G4Sphere*) (solid1st);
|
|
param->ComputeDimensions(*sphere, ii, pv);
|
|
newParams = GetSolidParams(sphere);
|
|
newSolid = (G4VSolid*) sphere;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Orb")
|
|
{
|
|
G4Orb* orb = (G4Orb*) (solid1st);
|
|
param->ComputeDimensions(*orb, ii, pv);
|
|
newParams = GetSolidParams(orb);
|
|
newSolid = (G4VSolid*) orb;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Torus")
|
|
{
|
|
G4Torus* torus = (G4Torus*) (solid1st);
|
|
param->ComputeDimensions(*torus, ii, pv);
|
|
newParams = GetSolidParams(torus);
|
|
newSolid = (G4VSolid*) torus;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Para")
|
|
{
|
|
G4Para* para = (G4Para*) (solid1st);
|
|
param->ComputeDimensions(*para, ii, pv);
|
|
newParams = GetSolidParams(para);
|
|
newSolid = (G4VSolid*) para;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Polycone")
|
|
{
|
|
G4Polycone* polycone = (G4Polycone*) (solid1st);
|
|
param->ComputeDimensions(*polycone, ii, pv);
|
|
newParams = GetSolidParams(polycone);
|
|
newSolid = (G4VSolid*) polycone;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Polyhedra")
|
|
{
|
|
G4Polyhedra* polyhedra = (G4Polyhedra*) (solid1st);
|
|
param->ComputeDimensions(*polyhedra, ii, pv);
|
|
newParams = GetSolidParams(polyhedra);
|
|
newSolid = (G4VSolid*) polyhedra;
|
|
}
|
|
else if(solid1st->GetEntityType() == "G4Hype")
|
|
{
|
|
G4Hype* hype = (G4Hype*) (solid1st);
|
|
param->ComputeDimensions(*hype, ii, pv);
|
|
newParams = GetSolidParams(hype);
|
|
newSolid = (G4VSolid*) hype;
|
|
}
|
|
if(ii == 0 || mate1st != newMate || params1st[0] != newParams[0])
|
|
{
|
|
G4String extraName = "";
|
|
if(ii != 0)
|
|
{
|
|
extraName = "#" + G4UIcommand::ConvertToString(ii) + "/" +
|
|
pv->GetMotherLogical()->GetName();
|
|
}
|
|
lvName = DumpLogVol(lv, extraName, newSolid, newMate);
|
|
}
|
|
|
|
param->ComputeTransformation(ii, pv);
|
|
DumpPVPlacement(pv, lvName, ii);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpPVReplica(G4PVReplica* pv, const G4String& lvName)
|
|
{
|
|
EAxis axis;
|
|
G4int nReplicas;
|
|
G4double width;
|
|
G4double offset;
|
|
G4bool consuming;
|
|
pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
|
|
G4String axisName;
|
|
switch(axis)
|
|
{
|
|
case kXAxis:
|
|
axisName = "X";
|
|
break;
|
|
case kYAxis:
|
|
axisName = "Y";
|
|
break;
|
|
case kZAxis:
|
|
axisName = "Z";
|
|
break;
|
|
case kRho:
|
|
axisName = "R";
|
|
break;
|
|
case kPhi:
|
|
axisName = "PHI";
|
|
break;
|
|
case kRadial3D:
|
|
case kUndefined:
|
|
G4String ErrMessage =
|
|
"Unknown axis of replication for volume" + pv->GetName();
|
|
G4Exception("G4tgbGeometryDumper::DumpPVReplica", "Wrong axis ",
|
|
FatalException, ErrMessage);
|
|
break;
|
|
}
|
|
|
|
const G4String& fullname = lvName + "/" + pv->GetMotherLogical()->GetName();
|
|
|
|
if(!CheckIfPhysVolExists(fullname, pv))
|
|
{
|
|
(*theFile) << ":REPL " << SubstituteRefl(AddQuotes(lvName)) << " "
|
|
<< SubstituteRefl(AddQuotes(pv->GetMotherLogical()->GetName()))
|
|
<< " " << axisName << " " << nReplicas;
|
|
if(axis != kPhi)
|
|
{
|
|
(*theFile) << " " << width << " " << offset << G4endl;
|
|
}
|
|
else
|
|
{
|
|
(*theFile) << " " << width / deg << "*deg"
|
|
<< " " << offset / deg << "*deg" << G4endl;
|
|
}
|
|
|
|
thePhysVols[fullname] = pv;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::DumpLogVol(G4LogicalVolume* lv,
|
|
const G4String& extraName,
|
|
G4VSolid* solid,
|
|
G4Material* mate)
|
|
{
|
|
G4String lvName;
|
|
|
|
if(extraName == "") //--- take out the '_refl' in the name
|
|
{
|
|
lvName = GetObjectName(lv, theLogVols);
|
|
}
|
|
else
|
|
{
|
|
lvName = lv->GetName() + extraName;
|
|
}
|
|
|
|
if(theLogVols.find(lvName) != theLogVols.cend()) // alredy dumped
|
|
{
|
|
return lvName;
|
|
}
|
|
|
|
if(solid == nullptr)
|
|
{
|
|
solid = lv->GetSolid();
|
|
}
|
|
|
|
//---- Dump solid
|
|
const G4String& solidName = DumpSolid(solid, extraName);
|
|
|
|
//---- Dump material
|
|
if(mate == nullptr)
|
|
{
|
|
mate = lv->GetMaterial();
|
|
}
|
|
const G4String& mateName = DumpMaterial(mate);
|
|
|
|
//---- Dump logical volume (solid + material)
|
|
(*theFile) << ":VOLU " << SubstituteRefl(AddQuotes(lvName)) << " "
|
|
<< SupressRefl(AddQuotes(solidName)) << " " << AddQuotes(mateName)
|
|
<< G4endl;
|
|
|
|
theLogVols[lvName] = lv;
|
|
|
|
return lvName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::DumpMaterial(G4Material* mat)
|
|
{
|
|
const G4String& mateName = GetObjectName(mat, theMaterials);
|
|
if(theMaterials.find(mateName) != theMaterials.cend()) // alredy dumped
|
|
{
|
|
return mateName;
|
|
}
|
|
|
|
std::size_t numElements = mat->GetNumberOfElements();
|
|
G4double density = mat->GetDensity() / g * cm3;
|
|
|
|
// start tag
|
|
//
|
|
if(numElements == 1)
|
|
{
|
|
(*theFile) << ":MATE " << AddQuotes(mateName) << " " << mat->GetZ() << " "
|
|
<< mat->GetA() / (g / mole) << " " << density << G4endl;
|
|
}
|
|
else
|
|
{
|
|
const G4ElementVector* elems = mat->GetElementVector();
|
|
const G4double* fractions = mat->GetFractionVector();
|
|
for(std::size_t ii = 0; ii < numElements; ++ii)
|
|
{
|
|
DumpElement(const_cast<G4Element*>((*elems)[ii]));
|
|
}
|
|
|
|
(*theFile) << ":MIXT " << AddQuotes(mateName) << " " << density << " "
|
|
<< numElements << G4endl;
|
|
// close start element tag and get ready to do composit "parts"
|
|
for(std::size_t ii = 0; ii < numElements; ++ii)
|
|
{
|
|
(*theFile) << " " << AddQuotes(GetObjectName(const_cast<G4Element*>((*elems)[ii]), theElements))
|
|
<< " " << fractions[ii] << G4endl;
|
|
}
|
|
}
|
|
|
|
(*theFile) << ":MATE_MEE " << AddQuotes(mateName) << " "
|
|
<< mat->GetIonisation()->GetMeanExcitationEnergy() / eV << "*eV"
|
|
<< G4endl;
|
|
|
|
(*theFile) << ":MATE_TEMPERATURE " << AddQuotes(mateName) << " "
|
|
<< mat->GetTemperature() / kelvin << "*kelvin" << G4endl;
|
|
|
|
(*theFile) << ":MATE_PRESSURE " << AddQuotes(mateName) << " "
|
|
<< mat->GetPressure() / atmosphere << "*atmosphere" << G4endl;
|
|
|
|
G4State state = mat->GetState();
|
|
G4String stateStr;
|
|
switch(state)
|
|
{
|
|
case kStateUndefined:
|
|
stateStr = "Undefined";
|
|
break;
|
|
case kStateSolid:
|
|
stateStr = "Solid";
|
|
break;
|
|
case kStateLiquid:
|
|
stateStr = "Liquid";
|
|
break;
|
|
case kStateGas:
|
|
stateStr = "Gas";
|
|
break;
|
|
}
|
|
|
|
(*theFile) << ":MATE_STATE " << AddQuotes(mateName) << " " << stateStr
|
|
<< G4endl;
|
|
|
|
theMaterials[mateName] = mat;
|
|
|
|
return mateName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpElement(G4Element* ele)
|
|
{
|
|
const G4String& elemName = GetObjectName(ele, theElements);
|
|
|
|
if(theElements.find(elemName) != theElements.cend()) // alredy dumped
|
|
{
|
|
return;
|
|
}
|
|
|
|
//--- Add symbol name: Material mixtures store the components as elements
|
|
// (even if the input are materials), but without symbol
|
|
//
|
|
G4String symbol = ele->GetSymbol();
|
|
if(symbol == "" || symbol == " ")
|
|
{
|
|
symbol = elemName;
|
|
}
|
|
|
|
if(ele->GetNumberOfIsotopes() == 0)
|
|
{
|
|
(*theFile) << ":ELEM " << AddQuotes(elemName) << " " << AddQuotes(symbol)
|
|
<< " " << ele->GetZ() << " " << ele->GetA() / (g / mole) << " "
|
|
<< G4endl;
|
|
}
|
|
else
|
|
{
|
|
const G4IsotopeVector* isots = ele->GetIsotopeVector();
|
|
for(std::size_t ii = 0; ii < ele->GetNumberOfIsotopes(); ++ii)
|
|
{
|
|
DumpIsotope((*isots)[ii]);
|
|
}
|
|
|
|
(*theFile) << ":ELEM_FROM_ISOT " << AddQuotes(elemName) << " "
|
|
<< AddQuotes(symbol) << " " << ele->GetNumberOfIsotopes()
|
|
<< G4endl;
|
|
const G4double* fractions = ele->GetRelativeAbundanceVector();
|
|
for(std::size_t ii = 0; ii < ele->GetNumberOfIsotopes(); ++ii)
|
|
{
|
|
(*theFile) << " " << AddQuotes(GetObjectName((*isots)[ii], theIsotopes))
|
|
<< " " << fractions[ii] << G4endl;
|
|
}
|
|
}
|
|
theElements[elemName] = ele;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpIsotope(G4Isotope* isot)
|
|
{
|
|
const G4String& isotName = GetObjectName(isot, theIsotopes);
|
|
if(theIsotopes.find(isotName) != theIsotopes.cend()) // alredy dumped
|
|
{
|
|
return;
|
|
}
|
|
|
|
(*theFile) << ":ISOT " << AddQuotes(isotName) << " " << isot->GetZ() << " "
|
|
<< isot->GetN() << " " << isot->GetA() / (g / mole) << " "
|
|
<< G4endl;
|
|
|
|
theIsotopes[isotName] = isot;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::DumpSolid(G4VSolid* solid,
|
|
const G4String& extraName)
|
|
{
|
|
G4String solidName;
|
|
if(extraName == "")
|
|
{
|
|
solidName = GetObjectName(solid, theSolids);
|
|
}
|
|
else
|
|
{
|
|
solidName = solid->GetName() + extraName;
|
|
}
|
|
|
|
if(theSolids.find(solidName) != theSolids.cend()) // alredy dumped
|
|
{
|
|
return solidName;
|
|
}
|
|
|
|
G4String solidType = solid->GetEntityType();
|
|
solidType = GetTGSolidType(solidType);
|
|
|
|
if(solidType == "UNIONSOLID")
|
|
{
|
|
DumpBooleanVolume("UNION", solid);
|
|
}
|
|
else if(solidType == "SUBTRACTIONSOLID")
|
|
{
|
|
DumpBooleanVolume("SUBTRACTION", solid);
|
|
}
|
|
else if(solidType == "INTERSECTIONSOLID")
|
|
{
|
|
DumpBooleanVolume("INTERSECTION", solid);
|
|
}
|
|
else if(solidType == "REFLECTEDSOLID")
|
|
{
|
|
G4ReflectedSolid* solidrefl = dynamic_cast<G4ReflectedSolid*>(solid);
|
|
if(solidrefl == nullptr)
|
|
{
|
|
G4Exception("G4tgbGeometryDumper::DumpSolid()", "InvalidType",
|
|
FatalException, "Invalid reflected solid!");
|
|
return solidName;
|
|
}
|
|
G4VSolid* solidori = solidrefl->GetConstituentMovedSolid();
|
|
DumpSolid(solidori);
|
|
}
|
|
else if(solidType == "MULTIUNION")
|
|
{
|
|
DumpMultiUnionVolume(solid);
|
|
}
|
|
else if(solidType == "SCALEDSOLID")
|
|
{
|
|
DumpScaledVolume(solid);
|
|
}
|
|
else
|
|
{
|
|
(*theFile) << ":SOLID " << AddQuotes(solidName) << " ";
|
|
(*theFile) << AddQuotes(solidType) << " ";
|
|
DumpSolidParams( solid );
|
|
theSolids[solidName] = solid;
|
|
}
|
|
|
|
return solidName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpBooleanVolume(const G4String& solidType,
|
|
G4VSolid* so)
|
|
{
|
|
G4BooleanSolid* bso = dynamic_cast<G4BooleanSolid*>(so);
|
|
if(bso == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
G4VSolid* solid0 = bso->GetConstituentSolid(0);
|
|
G4VSolid* solid1 = bso->GetConstituentSolid(1);
|
|
G4DisplacedSolid* solid1Disp = nullptr;
|
|
G4bool displaced = dynamic_cast<G4DisplacedSolid*>(solid1);
|
|
if(displaced)
|
|
{
|
|
solid1Disp = dynamic_cast<G4DisplacedSolid*>(solid1);
|
|
if(solid1Disp != nullptr)
|
|
{
|
|
solid1 = solid1Disp->GetConstituentMovedSolid();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
DumpSolid(solid0);
|
|
DumpSolid(solid1);
|
|
|
|
G4String rotName;
|
|
G4ThreeVector pos;
|
|
if(displaced)
|
|
{
|
|
pos = solid1Disp->GetObjectTranslation(); // translation is of mother frame
|
|
rotName = DumpRotationMatrix(new G4RotationMatrix(
|
|
(solid1Disp->GetTransform().NetRotation()).inverse()));
|
|
}
|
|
else // no displacement
|
|
{
|
|
rotName = DumpRotationMatrix(new G4RotationMatrix);
|
|
pos = G4ThreeVector();
|
|
}
|
|
|
|
const G4String& bsoName = GetObjectName(so, theSolids);
|
|
if(theSolids.find(bsoName) != theSolids.cend()) return; // alredy dumped
|
|
const G4String& solid0Name = FindSolidName(solid0);
|
|
const G4String& solid1Name = FindSolidName(solid1);
|
|
|
|
(*theFile) << ":SOLID " << AddQuotes(bsoName) << " " << AddQuotes(solidType)
|
|
<< " " << AddQuotes(solid0Name) << " " << AddQuotes(solid1Name)
|
|
<< " " << AddQuotes(rotName) << " " << approxTo0(pos.x()) << " "
|
|
<< approxTo0(pos.y()) << " " << approxTo0(pos.z()) << " "
|
|
<< G4endl;
|
|
|
|
theSolids[bsoName] = bso;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpMultiUnionVolume( G4VSolid* so)
|
|
{
|
|
const G4MultiUnion* muun = dynamic_cast<const G4MultiUnion*>(so);
|
|
if(muun != nullptr)
|
|
{
|
|
G4int nSolids = muun->GetNumberOfSolids();
|
|
std::vector<G4String> rotList;
|
|
for( G4int iso = 0; iso < nSolids; iso++ ) {
|
|
G4Transform3D trans = muun->GetTransformation(iso);
|
|
const G4String& rotName = DumpRotationMatrix( new G4RotationMatrix(trans.getRotation()));
|
|
rotList.push_back(rotName);
|
|
G4VSolid* solN = muun->GetSolid(iso);
|
|
DumpSolid(solN);
|
|
}
|
|
const G4String& bsoName = GetObjectName(const_cast<G4VSolid*>(so), theSolids);
|
|
(*theFile) << ":SOLID " << AddQuotes(bsoName) << " MULTIUNION "
|
|
<< nSolids;
|
|
|
|
for( G4int iso = 0; iso < nSolids; ++iso ) {
|
|
G4VSolid* solN = muun->GetSolid(iso);
|
|
G4Transform3D trans = muun->GetTransformation(iso);
|
|
G4ThreeVector pos = trans.getTranslation(); // translation is of mother frame
|
|
(*theFile) << " " << solN->GetName()
|
|
<< " " << " " << rotList[iso]
|
|
<< " " << approxTo0(pos.x())
|
|
<< " " << approxTo0(pos.y())
|
|
<< " " << approxTo0(pos.z());
|
|
}
|
|
(*theFile) << G4endl;
|
|
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpScaledVolume( G4VSolid* so)
|
|
{
|
|
const G4ScaledSolid* ssol = dynamic_cast<const G4ScaledSolid*>(so);
|
|
if(ssol != nullptr)
|
|
{
|
|
G4VSolid* unscaledSolid = ssol->GetUnscaledSolid();
|
|
G4Scale3D scaleTransf = ssol->GetScaleTransform();
|
|
G4String bsoName = GetObjectName(const_cast<G4VSolid*>(so), theSolids);
|
|
(*theFile) << ":SOLID " << AddQuotes(bsoName) << " SCALED "
|
|
<< unscaledSolid->GetName() << " "
|
|
<< scaleTransf.xx() << " "
|
|
<< scaleTransf.yy() << " "
|
|
<< scaleTransf.zz() << G4endl;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
void G4tgbGeometryDumper::DumpSolidParams(G4VSolid* so)
|
|
{
|
|
std::vector<G4double> params = GetSolidParams(so);
|
|
for(std::size_t ii = 0; ii < params.size(); ++ii)
|
|
{
|
|
(*theFile) << params[ii] << " ";
|
|
}
|
|
(*theFile) << G4endl;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
std::vector<G4double> G4tgbGeometryDumper::GetSolidParams(const G4VSolid* so)
|
|
{
|
|
std::vector<G4double> params;
|
|
|
|
G4String solidType = so->GetEntityType();
|
|
solidType = GetTGSolidType(solidType);
|
|
|
|
if(solidType == "BOX")
|
|
{
|
|
const G4Box* sb = dynamic_cast<const G4Box*>(so);
|
|
if(sb != nullptr)
|
|
{
|
|
params.push_back(sb->GetXHalfLength());
|
|
params.push_back(sb->GetYHalfLength());
|
|
params.push_back(sb->GetZHalfLength());
|
|
}
|
|
}
|
|
else if(solidType == "TUBS")
|
|
{
|
|
const G4Tubs* tu = dynamic_cast<const G4Tubs*>(so);
|
|
if(tu != nullptr)
|
|
{
|
|
params.push_back(tu->GetInnerRadius());
|
|
params.push_back(tu->GetOuterRadius());
|
|
params.push_back(tu->GetZHalfLength());
|
|
params.push_back(tu->GetStartPhiAngle() / deg);
|
|
params.push_back(tu->GetDeltaPhiAngle() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "TRAP")
|
|
{
|
|
const G4Trap* trp = dynamic_cast<const G4Trap*>(so);
|
|
if(trp != nullptr)
|
|
{
|
|
G4ThreeVector symAxis(trp->GetSymAxis());
|
|
params.push_back(trp->GetZHalfLength());
|
|
params.push_back(symAxis.theta() / deg);
|
|
params.push_back(symAxis.phi() / deg);
|
|
params.push_back(trp->GetYHalfLength1());
|
|
params.push_back(trp->GetXHalfLength1());
|
|
params.push_back(trp->GetXHalfLength2());
|
|
params.push_back(std::atan(trp->GetTanAlpha1()) / deg);
|
|
params.push_back(trp->GetYHalfLength2());
|
|
params.push_back(trp->GetXHalfLength3());
|
|
params.push_back(trp->GetXHalfLength4());
|
|
params.push_back(std::atan(trp->GetTanAlpha2()) / deg);
|
|
}
|
|
}
|
|
else if(solidType == "TRD")
|
|
{
|
|
const G4Trd* tr = dynamic_cast<const G4Trd*>(so);
|
|
if(tr != nullptr)
|
|
{
|
|
params.push_back(tr->GetXHalfLength1());
|
|
params.push_back(tr->GetXHalfLength2());
|
|
params.push_back(tr->GetYHalfLength1());
|
|
params.push_back(tr->GetYHalfLength2());
|
|
params.push_back(tr->GetZHalfLength());
|
|
}
|
|
}
|
|
else if(solidType == "PARA")
|
|
{
|
|
const G4Para* para = dynamic_cast<const G4Para*>(so);
|
|
if(para != nullptr)
|
|
{
|
|
G4ThreeVector symAxis(para->GetSymAxis());
|
|
params.push_back(para->GetXHalfLength());
|
|
params.push_back(para->GetYHalfLength());
|
|
params.push_back(para->GetZHalfLength());
|
|
params.push_back(std::atan(para->GetTanAlpha()) / deg);
|
|
params.push_back(symAxis.theta() / deg);
|
|
params.push_back(symAxis.phi() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "CONS")
|
|
{
|
|
const G4Cons* cn = dynamic_cast<const G4Cons*>(so);
|
|
if(cn != nullptr)
|
|
{
|
|
params.push_back(cn->GetInnerRadiusMinusZ());
|
|
params.push_back(cn->GetOuterRadiusMinusZ());
|
|
params.push_back(cn->GetInnerRadiusPlusZ());
|
|
params.push_back(cn->GetOuterRadiusPlusZ());
|
|
params.push_back(cn->GetZHalfLength());
|
|
params.push_back(cn->GetStartPhiAngle() / deg);
|
|
params.push_back(cn->GetDeltaPhiAngle() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "SPHERE")
|
|
{
|
|
const G4Sphere* sphere = dynamic_cast<const G4Sphere*>(so);
|
|
if(sphere != nullptr)
|
|
{
|
|
params.push_back(sphere->GetInnerRadius());
|
|
params.push_back(sphere->GetOuterRadius());
|
|
params.push_back(sphere->GetStartPhiAngle() / deg);
|
|
params.push_back(sphere->GetDeltaPhiAngle() / deg);
|
|
params.push_back(sphere->GetStartThetaAngle() / deg);
|
|
params.push_back(sphere->GetDeltaThetaAngle() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "ORB")
|
|
{
|
|
const G4Orb* orb = dynamic_cast<const G4Orb*>(so);
|
|
if(orb != nullptr)
|
|
{
|
|
params.push_back(orb->GetRadius());
|
|
}
|
|
}
|
|
else if(solidType == "TORUS")
|
|
{
|
|
const G4Torus* torus = dynamic_cast<const G4Torus*>(so);
|
|
if(torus != nullptr)
|
|
{
|
|
params.push_back(torus->GetRmin());
|
|
params.push_back(torus->GetRmax());
|
|
params.push_back(torus->GetRtor());
|
|
params.push_back(torus->GetSPhi() / deg);
|
|
params.push_back(torus->GetDPhi() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "POLYCONE")
|
|
{
|
|
//--- Dump RZ corners, as original parameters will not be present
|
|
// if it was build from RZ corners
|
|
const G4Polycone* plc = dynamic_cast<const G4Polycone*>(so);
|
|
if(plc != nullptr)
|
|
{
|
|
G4double angphi = plc->GetStartPhi() / deg;
|
|
if(angphi > 180 * deg)
|
|
{
|
|
angphi -= 360 * deg;
|
|
}
|
|
G4double endphi = plc->GetEndPhi() / deg;
|
|
if(endphi > 180 * deg)
|
|
{
|
|
endphi -= 360 * deg;
|
|
}
|
|
params.push_back(angphi);
|
|
params.push_back(endphi - angphi);
|
|
// params.push_back(plc->GetOriginalParameters()->Opening_angle / deg);
|
|
G4int ncor = plc->GetNumRZCorner();
|
|
params.push_back(ncor);
|
|
|
|
for(G4int ii = 0; ii < ncor; ++ii)
|
|
{
|
|
params.push_back(plc->GetCorner(ii).r);
|
|
params.push_back(plc->GetCorner(ii).z);
|
|
}
|
|
}
|
|
}
|
|
else if(solidType == "GENERICPOLYCONE")
|
|
{
|
|
//--- Dump RZ corners
|
|
const G4GenericPolycone* plc = dynamic_cast<const G4GenericPolycone*>(so);
|
|
if(plc != nullptr)
|
|
{
|
|
G4double angphi = plc->GetStartPhi() / deg;
|
|
if(angphi > 180 * deg)
|
|
{
|
|
angphi -= 360 * deg;
|
|
}
|
|
G4double endphi = plc->GetEndPhi() / deg;
|
|
if(endphi > 180 * deg)
|
|
{
|
|
endphi -= 360 * deg;
|
|
}
|
|
params.push_back(angphi);
|
|
params.push_back(endphi - angphi);
|
|
G4int ncor = plc->GetNumRZCorner();
|
|
params.push_back(ncor);
|
|
|
|
for(G4int ii = 0; ii < ncor; ++ii)
|
|
{
|
|
params.push_back(plc->GetCorner(ii).r);
|
|
params.push_back(plc->GetCorner(ii).z);
|
|
}
|
|
}
|
|
}
|
|
else if(solidType == "POLYHEDRA")
|
|
{
|
|
//--- Dump RZ corners, as original parameters will not be present
|
|
// if it was build from RZ corners
|
|
const G4Polyhedra* ph = (dynamic_cast<const G4Polyhedra*>(so));
|
|
if(ph != nullptr)
|
|
{
|
|
G4double angphi = ph->GetStartPhi() / deg;
|
|
if(angphi > 180 * deg)
|
|
angphi -= 360 * deg;
|
|
|
|
G4int ncor = ph->GetNumRZCorner();
|
|
|
|
params.push_back(angphi);
|
|
params.push_back(ph->GetOriginalParameters()->Opening_angle / deg);
|
|
params.push_back(ph->GetNumSide());
|
|
params.push_back(ncor);
|
|
|
|
for(G4int ii = 0; ii < ncor; ++ii)
|
|
{
|
|
params.push_back(ph->GetCorner(ii).r);
|
|
params.push_back(ph->GetCorner(ii).z);
|
|
}
|
|
}
|
|
}
|
|
else if(solidType == "ELLIPTICALTUBE")
|
|
{
|
|
const G4EllipticalTube* eltu = dynamic_cast<const G4EllipticalTube*>(so);
|
|
if(eltu != nullptr)
|
|
{
|
|
params.push_back(eltu->GetDx());
|
|
params.push_back(eltu->GetDy());
|
|
params.push_back(eltu->GetDz());
|
|
}
|
|
}
|
|
else if(solidType == "ELLIPSOID")
|
|
{
|
|
const G4Ellipsoid* dso = dynamic_cast<const G4Ellipsoid*>(so);
|
|
if(dso != nullptr)
|
|
{
|
|
params.push_back(dso->GetSemiAxisMax(0));
|
|
params.push_back(dso->GetSemiAxisMax(1));
|
|
params.push_back(dso->GetSemiAxisMax(2));
|
|
params.push_back(dso->GetZBottomCut());
|
|
params.push_back(dso->GetZTopCut());
|
|
}
|
|
}
|
|
else if(solidType == "ELLIPTICAL_CONE")
|
|
{
|
|
const G4EllipticalCone* elco = dynamic_cast<const G4EllipticalCone*>(so);
|
|
if(elco != nullptr)
|
|
{
|
|
params.push_back(elco->GetSemiAxisX());
|
|
params.push_back(elco->GetSemiAxisY());
|
|
params.push_back(elco->GetZMax());
|
|
params.push_back(elco->GetZTopCut());
|
|
}
|
|
}
|
|
else if(solidType == "HYPE")
|
|
{
|
|
const G4Hype* hype = dynamic_cast<const G4Hype*>(so);
|
|
if(hype != nullptr)
|
|
{
|
|
params.push_back(hype->GetInnerRadius());
|
|
params.push_back(hype->GetOuterRadius());
|
|
params.push_back(hype->GetInnerStereo() / deg);
|
|
params.push_back(hype->GetOuterStereo() / deg);
|
|
params.push_back(2 * hype->GetZHalfLength());
|
|
}
|
|
// } else if( solidType == "TET" ) {
|
|
}
|
|
else if(solidType == "TWISTEDBOX")
|
|
{
|
|
const G4TwistedBox* tbox = dynamic_cast<const G4TwistedBox*>(so);
|
|
if(tbox != nullptr)
|
|
{
|
|
params.push_back(tbox->GetPhiTwist() / deg);
|
|
params.push_back(tbox->GetXHalfLength());
|
|
params.push_back(tbox->GetYHalfLength());
|
|
params.push_back(tbox->GetZHalfLength());
|
|
}
|
|
}
|
|
else if(solidType == "TWISTEDTRAP")
|
|
{
|
|
const G4TwistedTrap* ttrap = dynamic_cast<const G4TwistedTrap*>(so);
|
|
if(ttrap != nullptr)
|
|
{
|
|
params.push_back(ttrap->GetPhiTwist() / deg);
|
|
params.push_back(ttrap->GetZHalfLength());
|
|
params.push_back(ttrap->GetPolarAngleTheta() / deg);
|
|
params.push_back(ttrap->GetAzimuthalAnglePhi() / deg);
|
|
params.push_back(ttrap->GetY1HalfLength());
|
|
params.push_back(ttrap->GetX1HalfLength());
|
|
params.push_back(ttrap->GetX2HalfLength());
|
|
params.push_back(ttrap->GetY2HalfLength());
|
|
params.push_back(ttrap->GetX3HalfLength());
|
|
params.push_back(ttrap->GetX4HalfLength());
|
|
params.push_back(ttrap->GetTiltAngleAlpha() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "TWISTEDTRD")
|
|
{
|
|
const G4TwistedTrd* ttrd = dynamic_cast<const G4TwistedTrd*>(so);
|
|
if(ttrd != nullptr)
|
|
{
|
|
params.push_back(ttrd->GetX1HalfLength());
|
|
params.push_back(ttrd->GetX2HalfLength());
|
|
params.push_back(ttrd->GetY1HalfLength());
|
|
params.push_back(ttrd->GetY2HalfLength());
|
|
params.push_back(ttrd->GetZHalfLength());
|
|
params.push_back(ttrd->GetPhiTwist() / deg);
|
|
}
|
|
}
|
|
else if(solidType == "TWISTEDTUBS")
|
|
{
|
|
const G4TwistedTubs* ttub = dynamic_cast<const G4TwistedTubs*>(so);
|
|
if(ttub != nullptr)
|
|
{
|
|
params.push_back(ttub->GetInnerRadius());
|
|
params.push_back(ttub->GetOuterRadius());
|
|
params.push_back(ttub->GetZHalfLength());
|
|
params.push_back(ttub->GetDPhi() / deg);
|
|
params.push_back(ttub->GetPhiTwist() / deg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const G4String& ErrMessage = "Solid type not supported, sorry... " + solidType;
|
|
G4Exception("G4tgbGeometryDumper::DumpSolidParams()", "NotImplemented",
|
|
FatalException, ErrMessage);
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::DumpRotationMatrix(G4RotationMatrix* rotm)
|
|
{
|
|
if(rotm == nullptr)
|
|
{
|
|
rotm = new G4RotationMatrix();
|
|
}
|
|
|
|
G4double de = MatDeterminant(rotm);
|
|
G4String rotName = LookForExistingRotation(rotm);
|
|
if(rotName != "")
|
|
{
|
|
return rotName;
|
|
}
|
|
|
|
G4ThreeVector v(1., 1., 1.);
|
|
if(de < -0.9) // a reflection ....
|
|
{
|
|
(*theFile) << ":ROTM ";
|
|
rotName = "RRM";
|
|
rotName += G4UIcommand::ConvertToString(theRotationNumber++);
|
|
|
|
(*theFile) << AddQuotes(rotName) << std::setprecision(9) << " "
|
|
<< approxTo0(rotm->xx()) << " " << approxTo0(rotm->yx()) << " "
|
|
<< approxTo0(rotm->zx()) << " " << approxTo0(rotm->xy()) << " "
|
|
<< approxTo0(rotm->yy()) << " " << approxTo0(rotm->zy()) << " "
|
|
<< approxTo0(rotm->xz()) << " " << approxTo0(rotm->yz()) << " "
|
|
<< approxTo0(rotm->zz()) << G4endl;
|
|
}
|
|
else if(de > 0.9) // a rotation ....
|
|
{
|
|
(*theFile) << ":ROTM ";
|
|
rotName = "RM";
|
|
rotName += G4UIcommand::ConvertToString(theRotationNumber++);
|
|
|
|
(*theFile) << AddQuotes(rotName) << " " << approxTo0(rotm->thetaX() / deg)
|
|
<< " " << approxTo0(rotm->phiX() / deg) << " "
|
|
<< approxTo0(rotm->thetaY() / deg) << " "
|
|
<< approxTo0(rotm->phiY() / deg) << " "
|
|
<< approxTo0(rotm->thetaZ() / deg) << " "
|
|
<< approxTo0(rotm->phiZ() / deg) << G4endl;
|
|
}
|
|
|
|
theRotMats[rotName] = rotm;
|
|
|
|
return rotName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
std::vector<G4VPhysicalVolume*>
|
|
G4tgbGeometryDumper::GetPVChildren(G4LogicalVolume* lv)
|
|
{
|
|
G4PhysicalVolumeStore* pvstore = G4PhysicalVolumeStore::GetInstance();
|
|
std::vector<G4VPhysicalVolume*> children;
|
|
for(auto ite = pvstore->cbegin(); ite != pvstore->cend(); ++ite)
|
|
{
|
|
if((*ite)->GetMotherLogical() == lv)
|
|
{
|
|
children.push_back(*ite);
|
|
#ifdef G4VERBOSE
|
|
if(G4tgrMessenger::GetVerboseLevel() >= 1)
|
|
{
|
|
G4cout << " G4tgbGeometryDumper::GetPVChildren() - adding children: "
|
|
<< (*ite)->GetName() << " of " << lv->GetName() << G4endl;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return children;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::GetTGSolidType(const G4String& solidType)
|
|
{
|
|
G4String newsolidType = solidType.substr(2, solidType.length());
|
|
for(G4int ii = 0; ii < (G4int)newsolidType.length(); ++ii)
|
|
{
|
|
newsolidType[ii] = (char)std::toupper(newsolidType[ii]);
|
|
}
|
|
return newsolidType;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4double G4tgbGeometryDumper::MatDeterminant(G4RotationMatrix* ro)
|
|
{
|
|
G4Rep3x3 r = ro->rep3x3();
|
|
return r.xx_ * (r.yy_ * r.zz_ - r.zy_ * r.yz_) -
|
|
r.yx_ * (r.xy_ * r.zz_ - r.zy_ * r.xz_) +
|
|
r.zx_ * (r.xy_ * r.yz_ - r.yy_ * r.xz_);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4double G4tgbGeometryDumper::approxTo0(G4double val)
|
|
{
|
|
G4double precision =
|
|
G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
|
|
|
|
if(std::fabs(val) < precision)
|
|
{
|
|
val = 0.0;
|
|
}
|
|
return val;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::AddQuotes(const G4String& str)
|
|
{
|
|
//--- look if there is a separating blank
|
|
|
|
G4bool bBlank = FALSE;
|
|
std::size_t siz = str.length();
|
|
for(std::size_t ii = 0; ii < siz; ++ii)
|
|
{
|
|
if(str.substr(ii, 1) == " ")
|
|
{
|
|
bBlank = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
G4String str2 = str;
|
|
if(bBlank)
|
|
{
|
|
str2 = G4String("\"") + str2 + G4String("\"");
|
|
}
|
|
return str2;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::SupressRefl(G4String name)
|
|
{
|
|
std::size_t irefl = name.rfind("_refl");
|
|
if(irefl != G4String::npos)
|
|
{
|
|
name = name.substr(0, irefl);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::SubstituteRefl(G4String name)
|
|
{
|
|
std::size_t irefl = name.rfind("_refl");
|
|
if(irefl != G4String::npos)
|
|
{
|
|
name = name.substr(0, irefl) + "_REFL";
|
|
}
|
|
return name;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String G4tgbGeometryDumper::GetIsotopeName(G4Isotope* isot)
|
|
{
|
|
G4String isotName = isot->GetName();
|
|
// first look if this is isotope is already dumped,
|
|
// with original isotope name or new one
|
|
//
|
|
std::map<G4String, G4Isotope*>::const_iterator ite;
|
|
for(ite = theIsotopes.cbegin(); ite != theIsotopes.cend(); ++ite)
|
|
{
|
|
if(isot == (*ite).second)
|
|
{
|
|
return (*ite).first;
|
|
}
|
|
}
|
|
|
|
// Now look if there is another isotope dumped with same name,
|
|
// and if found add _N to the name
|
|
//
|
|
ite = theIsotopes.find(isotName);
|
|
if(ite != theIsotopes.cend()) // Isotope found with same name
|
|
{
|
|
G4Isotope* isotold = (*ite).second;
|
|
if(isot != isotold) // new isotope it is not the really
|
|
{ // the same one as isotope found
|
|
if(!Same2G4Isotopes(isot, isotold))
|
|
{ // if the two have same data, use the old one
|
|
G4int ii = 2; // G4Nist does names isotopes of same element
|
|
// with same name
|
|
for(;; ++ii)
|
|
{
|
|
const G4String& newIsotName =
|
|
isotName + "_" + G4UIcommand::ConvertToString(ii);
|
|
std::map<G4String, G4Isotope*>::const_iterator ite2 =
|
|
theIsotopes.find(newIsotName);
|
|
if(ite2 == theIsotopes.cend())
|
|
{
|
|
isotName = newIsotName;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(Same2G4Isotopes(isot, (*ite2).second))
|
|
{
|
|
isotName = newIsotName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return isotName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
template <class TYP>
|
|
G4String G4tgbGeometryDumper::GetObjectName(
|
|
TYP* obj, std::map<G4String, TYP*> objectsDumped)
|
|
{
|
|
G4String objName = obj->GetName();
|
|
|
|
// first look if this is objecy is already dumped,
|
|
// with original object name or new one
|
|
//
|
|
typename std::map<G4String, TYP*>::const_iterator ite;
|
|
for(ite = objectsDumped.cbegin(); ite != objectsDumped.cend(); ++ite)
|
|
{
|
|
if(obj == (*ite).second)
|
|
{
|
|
return (*ite).first;
|
|
}
|
|
}
|
|
|
|
// Now look if there is another object dumped with same name,
|
|
// and if found add _N to the name
|
|
//
|
|
ite = objectsDumped.find(objName);
|
|
|
|
if(ite != objectsDumped.cend()) // Object found with same name
|
|
{
|
|
TYP* objold = (*ite).second;
|
|
if(obj != objold) // new object it is not the really
|
|
{ // the same one as object found
|
|
G4int ii = 2;
|
|
for(;; ++ii)
|
|
{
|
|
const G4String& newObjName = objName + "_" + G4UIcommand::ConvertToString(ii);
|
|
typename std::map<G4String, TYP*>::const_iterator ite2 =
|
|
objectsDumped.find(newObjName);
|
|
if(ite2 == objectsDumped.cend())
|
|
{
|
|
objName = newObjName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return objName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4bool G4tgbGeometryDumper::CheckIfLogVolExists(const G4String& name,
|
|
G4LogicalVolume* pt)
|
|
{
|
|
if(theLogVols.find(name) != theLogVols.cend())
|
|
{
|
|
G4LogicalVolume* lvnew = (*(theLogVols.find(name))).second;
|
|
if(lvnew != pt)
|
|
{
|
|
/*
|
|
//---- Reflected volumes are repeated
|
|
|
|
G4ReflectionFactory* reffact = G4ReflectionFactory::Instance();
|
|
if( !reffact->IsReflected( pt ) && !reffact->IsReflected( lvnew ) )
|
|
{
|
|
G4String ErrMessage = "LogVol found but not same as before: " + name;
|
|
G4Exception("G4tgbGeometryDumper::CheckIfLogVolExists()",
|
|
"InvalidSetup", FatalException, ErrMessage);
|
|
}
|
|
*/
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4bool G4tgbGeometryDumper::CheckIfPhysVolExists(const G4String& name,
|
|
G4VPhysicalVolume* pt)
|
|
{
|
|
#ifdef G4VERBOSE
|
|
if(G4tgrMessenger::GetVerboseLevel() >= 1)
|
|
{
|
|
G4cout << " G4tgbGeometryDumper::CheckIfPhysVolExists() - " << name
|
|
<< G4endl;
|
|
}
|
|
#endif
|
|
if(thePhysVols.find(name) != thePhysVols.cend())
|
|
{
|
|
if((*(thePhysVols.find(name))).second != pt)
|
|
{
|
|
// G4String ErrMessage = "Placement found but not same as before: "
|
|
// + name;
|
|
// G4Exception("G4tgbGeometryDumper::CheckIfPhysVolExists()",
|
|
// "InvalidSetup", FatalException, ErrMessage);
|
|
G4cerr << " G4tgbGeometryDumper::CheckIfPhysVolExists () -"
|
|
<< " Placement found but not same as before : " << name << G4endl;
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4String
|
|
G4tgbGeometryDumper::LookForExistingRotation(const G4RotationMatrix* rotm)
|
|
{
|
|
G4String rmName = "";
|
|
|
|
for(auto ite = theRotMats.cbegin(); ite != theRotMats.cend(); ++ite)
|
|
{
|
|
if((*ite).second->isNear(*rotm))
|
|
{
|
|
rmName = (*ite).first;
|
|
break;
|
|
}
|
|
}
|
|
return rmName;
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
G4bool G4tgbGeometryDumper::Same2G4Isotopes(G4Isotope* isot1, G4Isotope* isot2)
|
|
{
|
|
if((isot1->GetZ() != isot2->GetZ()) || (isot1->GetN() != isot2->GetN()) ||
|
|
(isot1->GetA() != isot2->GetA()))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
const G4String& G4tgbGeometryDumper::FindSolidName(G4VSolid* solid)
|
|
{
|
|
std::map<G4String, G4VSolid*>::const_iterator ite;
|
|
for(ite = theSolids.cbegin(); ite != theSolids.cend(); ++ite)
|
|
{
|
|
if(solid == (*ite).second)
|
|
{
|
|
return (*ite).first;
|
|
}
|
|
}
|
|
|
|
if(ite == theSolids.cend())
|
|
{
|
|
G4Exception("G4tgbGeometryDumper::FindSolidName()", "ReadError",
|
|
FatalException, "Programming error.");
|
|
}
|
|
return (*ite).first;
|
|
}
|