Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
@@ -42,6 +42,8 @@
#include "G4Transform3D.hh"
#include "G4GeometryTolerance.hh"
#include <cmath>
G4ArrowModel::~G4ArrowModel ()
{
delete fpHeadPolyhedron;
@@ -77,26 +79,33 @@ G4ArrowModel::G4ArrowModel
// Make a cylinder slightly shorter than the arrow length so that it
// doesn't stick out of the head.
const G4double tolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
G4double shaftLength = std::sqrt
(std::pow(x2-x1,2)+std::pow(y2-y1,2)+std::pow(z2-z1,2));
if (shaftLength < tolerance) shaftLength = tolerance;
G4double shaftRadius = width/2.;
if (shaftRadius > shaftLength/100.) shaftRadius = shaftLength/100.;
if (shaftRadius < tolerance) shaftRadius = tolerance;
const G4double halfShaftLength = shaftLength/2.;
const G4double halfReduction = 4.*shaftRadius;
G4double halfLength = halfShaftLength - halfReduction;
if (halfLength < tolerance) halfLength = tolerance;
const G4Tubs shaft("shaft",0.,shaftRadius,halfLength,0.,twopi);
G4double totalLength = std::hypot(x2-x1, y2-y1, z2-z1);
if (totalLength < tolerance)
{totalLength = tolerance;}
G4double shaftRadius = width/6.;
if (shaftRadius < tolerance)
{shaftRadius = tolerance;}
// case 1 - arrow length >> width -> arrow head is width and 1.5x width tall
// case 2 - arrow length < width -> arrow head is made to be 0.5x length
G4double arrowLength = std::min(1.5*width, 0.5*totalLength);
G4double shaftLength = totalLength - arrowLength;
if (shaftLength < 2*tolerance)
{shaftLength = 2*tolerance;}
const G4Tubs shaft("shaft",0.,shaftRadius,0.5*shaftLength,0.,twopi);
fpShaftPolyhedron = shaft.CreatePolyhedron();
// Move it a little so that the tail is at z = -halfShaftLength.
// translate the polyhedron down w.r.t. the centre of the whole arrow
if (fpShaftPolyhedron)
fpShaftPolyhedron->Transform(G4Translate3D(0,0,-halfReduction));
{fpShaftPolyhedron->Transform(G4Translate3D(0,0,-0.5*arrowLength));}
// Locate the head at +halfShaftLength.
const G4double zHi = halfShaftLength;
const G4double zLow = halfShaftLength - 12.*shaftRadius;
const G4double rExt = 8. * shaftRadius;
const G4double zHi = 0.5*totalLength;
const G4double zLow = zHi - arrowLength;
const G4double rExt = 0.5*width;
const G4double xExt = std::sqrt(3.)*rExt/2.;
const G4Tet head("head",
G4ThreeVector(0.,0.,zHi),
@@ -40,7 +40,6 @@ G4BoundingExtentScene::G4BoundingExtentScene (G4VModel* pModel)
G4BoundingExtentScene::~G4BoundingExtentScene () {}
void G4BoundingExtentScene::ProcessVolume(const G4VSolid& solid)
{
G4VisExtent newExtent = solid.GetExtent ();
@@ -1,110 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// John Allison 7th June 1997
// An artificial scene to reuse G4VScene code to calculate a bounding sphere.
#include "G4BoundingSphereScene.hh"
#include "G4VSolid.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4Vector3D.hh"
G4BoundingSphereScene::G4BoundingSphereScene (G4VModel* pModel)
:fpModel(pModel)
,fRadius(-1.)
{}
G4BoundingSphereScene::~G4BoundingSphereScene () {}
G4VisExtent G4BoundingSphereScene::GetBoundingSphereExtent () {
return G4VisExtent (fCentre, fRadius);
}
void G4BoundingSphereScene::ProcessVolume(const G4VSolid& solid)
{
const G4VisExtent& newExtent = solid.GetExtent ();
G4Point3D newCentre = newExtent.GetExtentCentre ();
if (fpCurrentObjectTransformation) {
newCentre.transform (*fpCurrentObjectTransformation);
}
const G4double newRadius = newExtent.GetExtentRadius ();
AccrueBoundingSphere (newCentre, newRadius);
// Curtail descent - can assume daughters are contained within mother...
G4PhysicalVolumeModel* pPVM = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVM) pPVM->CurtailDescent();
}
void G4BoundingSphereScene::ResetBoundingSphere () {
fCentre = G4Point3D ();
fRadius = -1.;
fpCurrentObjectTransformation = 0;
}
void G4BoundingSphereScene::AccrueBoundingSphere
(const G4Point3D& newCentre,
G4double newRadius) {
if (fRadius < 0 ) { // First time.
fCentre = newCentre;
fRadius = newRadius;
}
else {
G4Vector3D join = newCentre - fCentre;
if (join == G4Vector3D (0., 0., 0.)) { // Centres coincide.
if (fRadius < newRadius) fRadius = newRadius;
}
else if (join.mag () + newRadius <= fRadius) { // Inside accrued sphere.
// Do nothing.
}
else {
G4Vector3D unitJoin = join.unit ();
G4Point3D oldExtremity1 = fCentre - fRadius * unitJoin;
G4Point3D newExtremity1 = newCentre - newRadius * unitJoin;
G4Point3D oldExtremity2 = fCentre + fRadius * unitJoin;
G4Point3D newExtremity2 = newCentre + newRadius * unitJoin;
G4Point3D extremity1;
if (oldExtremity1 * unitJoin < newExtremity1 * unitJoin) {
extremity1 = oldExtremity1;
}
else {
extremity1 = newExtremity1;
}
G4Point3D extremity2;
if (oldExtremity2 * unitJoin > newExtremity2 * unitJoin) {
extremity2 = oldExtremity2;
}
else {
extremity2 = newExtremity2;
}
fCentre = 0.5 * (extremity2 + extremity1);
fRadius = 0.5 * (extremity2 - extremity1).mag ();
}
}
}
+104 -49
View File
@@ -28,11 +28,33 @@
//
// John Allison May 2021
//
// G4Mesh encapsulates and validates a nested parameterisation, which we
// call a "mesh". If a valid mesh cannot be created out of this
// G4VPhysicalVolume* (which will probably be most common), it will
// have a type "invalid". Then, usually, it may simply be destroyed.
// The overhead of an invalid attempt is expected to be small.
// G4Mesh captures and validates a parameterisation, which we
// call a "mesh". This is typically intended for meshes with
// a large number of parameterisations, such as a medical phantom.
//
// G4Mesh is used by G4PhysicalVolumeModel if and only if
// G4ModelingParameters::fSpecialMeshRendering is set and if the
// name matches one in G4ModelingParameters::fSpecialMeshVolumes,
// if any. Then, if a valid mesh is found it calls the overriding
// implementation of G4VGraphicsScene::AddCompound(const G4Mesh&).
//
// To set the above parameters use the following commands in the
// standard Geant4 Visualisation System:
// /vis/viewer/set/specialMeshRendering
// /vis/viewer/set/specialMeshRenderingOption
// /vis/viewer/set/specialMeshVolumes
// See guidance on the above commmands for more detail.
//
// Note that if no special mesh volumes are specified,
// G4PhysicalVolumeModel will test all volumes, and therefore
// it will capture *all* parameterisations. This is not usually
// a problem, since there is usually only one, but to be
// selective you have to /vis/viewer/set/specialMeshVolumes.
//
// The specified G4VPhysicalVolume is searched for a
// parameterisation. If none is found it will have a type "invalid"
// and it should simply be destroyed (as in G4PhysicalVolumeModel).
// The overhead of an invalid attempt is small.
#include "G4Mesh.hh"
@@ -43,71 +65,92 @@
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4Sphere.hh"
#include "G4Tet.hh"
std::map<G4int,G4String> G4Mesh::fEnumMap;
std::map<G4int,G4String> G4Mesh::fEnumMap = {
{invalid,"invalid"},
{rectangle,"rectangle"},
{nested3DRectangular,"nested3Drectangular"},
{cylinder,"cylinder"},
{sphere,"sphere"},
{tetrahedron,"tetrahedron"}
};
G4Mesh::G4Mesh (G4VPhysicalVolume* containerVolume,const G4Transform3D& transform)
: fpContainerVolume(containerVolume)
, fpParameterisedVolume(nullptr)
, fMeshType(invalid)
, fMeshDepth(0)
, fTransform(transform)
{
if (fpContainerVolume == nullptr) return;
G4VPhysicalVolume* pv0 = fpContainerVolume;
G4VPhysicalVolume* pv1 = nullptr;
G4VPhysicalVolume* pv2 = nullptr;
G4VPhysicalVolume* pv3 = nullptr;
G4LogicalVolume* lv0 = pv0->GetLogicalVolume();
G4LogicalVolume* lv1 = nullptr;
G4LogicalVolume* lv2 = nullptr;
static G4bool first = true;
if (first) {
first = false;
fEnumMap[invalid] = "invalid";
fEnumMap[rectangle] = "rectangle";
fEnumMap[cylinder] = "cylinder";
fEnumMap[sphere] = "sphere";
}
const G4LogicalVolume* pLV = fpContainerVolume->GetLogicalVolume();
// check if this is a container for a nested parameterisation
// Check if this is a container for a parameterisation
G4bool isContainer = false;
if (pLV->GetNoDaughters()) {
if (lv0->GetNoDaughters()) {
fMeshDepth++;
const auto d0 = pLV->GetDaughter(0);
const auto d0LV = d0->GetLogicalVolume();
if (d0LV->GetNoDaughters()) {
pv1 = lv0->GetDaughter(0);
lv1 = pv1->GetLogicalVolume();
if (dynamic_cast<G4PVParameterised*>(pv1)) {
isContainer = true;
fpParameterisedVolume = pv1;
} else if (lv1->GetNoDaughters()) {
fMeshDepth++;
const auto d00 = d0LV->GetDaughter(0);
const auto pvParam00 = dynamic_cast<G4PVParameterised*>(d00);
if (pvParam00) {
const auto param00 = pvParam00->GetParameterisation();
const auto nestedParam00 = dynamic_cast<G4VNestedParameterisation*>(param00);
if (nestedParam00) { // 2-deep mesh
isContainer = true;
}
} else {
const auto d00LV = d00->GetLogicalVolume();
if (d00LV->GetNoDaughters()) {
fMeshDepth++;
const auto d000 = d00LV->GetDaughter(0);
const auto pvParam000 = dynamic_cast<G4PVParameterised*>(d000);
if (pvParam000) {
const auto param000 = pvParam000->GetParameterisation();
const auto nestedParam000 = dynamic_cast<G4VNestedParameterisation*>(param000);
if (nestedParam000) { // 3-deep mesh
isContainer = true;
}
}
}
pv2 = lv1->GetDaughter(0);
lv2 = pv2->GetLogicalVolume();
if (dynamic_cast<G4PVParameterised*>(pv2)) {
isContainer = true;
fpParameterisedVolume = pv2;
} else if (lv2->GetNoDaughters()) {
fMeshDepth++;
pv3 = lv2->GetDaughter(0);
if (dynamic_cast<G4PVParameterised*>(pv3)) {
isContainer = true;
fpParameterisedVolume = pv3;
}
}
}
}
if (isContainer) {
// Get type
G4VSolid* pSol = pLV -> GetSolid ();
if (dynamic_cast<G4Box*>(pSol)) {
G4VSolid* pEndSol = fpParameterisedVolume->GetLogicalVolume()->GetSolid ();
if (dynamic_cast<G4Box*>(pEndSol)) {
fMeshType = rectangle;
} else if (dynamic_cast<G4Tubs*>(pSol)) {
auto pBox = static_cast<G4Box*>(pEndSol);
f3DRPs.fHalfX = pBox->GetXHalfLength();
f3DRPs.fHalfY = pBox->GetYHalfLength();
f3DRPs.fHalfZ = pBox->GetZHalfLength();
} else if (dynamic_cast<G4Tet*>(pEndSol)) {
fMeshType = tetrahedron;
} else if (dynamic_cast<G4Tubs*>(pEndSol)) {
fMeshType = cylinder;
} else if (dynamic_cast<G4Sphere*>(pSol)) {
} else if (dynamic_cast<G4Sphere*>(pEndSol)) {
fMeshType = sphere;
}
// Special case for rectangular nested paramaterisation - extra information
if (fMeshDepth == 3 && fMeshType == rectangle) {
auto nestedParam3 = dynamic_cast<G4VNestedParameterisation*>(pv3);
if (nestedParam3) {
fMeshType = nested3DRectangular;
pv1->GetReplicationData
(f3DRPs.fAxis1,f3DRPs.fNreplica1,f3DRPs.fWidth1,f3DRPs.fOffset1,f3DRPs.fConsuming1);
pv2->GetReplicationData
(f3DRPs.fAxis2,f3DRPs.fNreplica2,f3DRPs.fWidth2,f3DRPs.fOffset2,f3DRPs.fConsuming2);
pv3->GetReplicationData
(f3DRPs.fAxis3,f3DRPs.fNreplica3,f3DRPs.fWidth3,f3DRPs.fOffset3,f3DRPs.fConsuming3);
}
}
}
}
@@ -116,9 +159,21 @@ G4Mesh::~G4Mesh () {}
std::ostream& operator << (std::ostream& os, const G4Mesh& mesh) {
os << "G4Mesh: ";
os << "\nContainer: " << mesh.GetContainerVolume()->GetName();
os << "\nType: " << mesh.GetEnumMap().find(mesh.GetMeshType())->second;
const auto& map = mesh.GetEnumMap();
const auto& typeEntry = map.find(mesh.GetMeshType());
G4String type;
if (typeEntry != map.end()) {
type = typeEntry->second;
} else {
type = "unrecognised";
}
os << "\nType: " << type;
os << "\nDepth: " << mesh.GetMeshDepth();
os << "\nTranslation: " << mesh.GetTransform().getTranslation();
os << "\nRotation: " << mesh.GetTransform().getRotation();
if (mesh.GetMeshType() == G4Mesh::rectangle &&
mesh.GetMeshDepth() == 3) {
// Print ThreeDRectangleParameters
}
return os;
}
@@ -42,7 +42,6 @@
#include "G4Material.hh"
#include "G4VisAttributes.hh"
#include "G4BoundingExtentScene.hh"
#include "G4PhysicalVolumeSearchScene.hh"
#include "G4TransportationManager.hh"
#include "G4Polyhedron.hh"
#include "HepPolyhedronProcessor.h"
@@ -162,6 +161,7 @@ void G4PhysicalVolumeModel::CalculateExtent ()
0., // Density (not relevant if density culling false).
true, // Cull daughters of opaque mothers.
24); // No of sides (not relevant for this operation).
mParams.SetSpecialMeshRendering(true); // Avoids traversing parameterisations
fpMP = &mParams;
DescribeYourselfTo (beScene);
fExtent = beScene.GetBoundingExtent();
@@ -555,42 +555,47 @@ void G4PhysicalVolumeModel::DescribeAndDescend
// Check for special mesh rendering
if (fpMP->IsSpecialMeshRendering()) {
G4bool potentialG4Mesh = false;
if (fpMP->GetSpecialMeshVolumes().empty()) {
// No volumes specified - all are potentially possible
goto create_mesh;
potentialG4Mesh = true;
} else {
// Name and (optionally) copy number of container volume is specified
for (const auto& pvNameCopyNo: fpMP->GetSpecialMeshVolumes()) {
if (pVPV->GetName() == pvNameCopyNo.GetName()) {
// We have a name match
if (pvNameCopyNo.GetCopyNo() < 0) {
// Any copy number is OK
goto create_mesh;
} else {
if (pVPV->GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
// We have a name and copy number match
goto create_mesh;
}
}
}
if (pVPV->GetName() == pvNameCopyNo.GetName()) {
// We have a name match
if (pvNameCopyNo.GetCopyNo() < 0) {
// Any copy number is OK
potentialG4Mesh = true;
} else {
if (pVPV->GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
// We have a name and copy number match
potentialG4Mesh = true;
}
}
}
}
// We have fallen out of this loop without finding a match
goto continue_processing;
}
create_mesh:
// Create - or at least attempt to create - a mesh. If it cannot be created
// out of this pVPV the type will be "invalid".
G4Mesh mesh(pVPV,theNewAT);
if (mesh.GetMeshType() != G4Mesh::invalid) {
fFullPVPath.push_back(nodeID);
fDrawnPVPath.push_back(nodeID);
sceneHandler.AddCompound(mesh);
fFullPVPath.pop_back();
fDrawnPVPath.pop_back();
delete tempVisAtts; // Needs cleaning up (Coverity warning!!)
return;
} // else continue processing
if (potentialG4Mesh) {
// Create - or at least attempt to create - a mesh. If it cannot be created
// out of this pVPV the type will be "invalid".
G4Mesh mesh(pVPV,theNewAT);
if (mesh.GetMeshType() != G4Mesh::invalid) {
// Create "artificial" nodeID to represent the replaced volumes
G4int artCopyNo = 0;
auto artPV = mesh.GetParameterisedVolume();
auto artDepth = fCurrentDepth + 1;
auto artNodeID = G4PhysicalVolumeNodeID(artPV,artCopyNo,artDepth);
fFullPVPath.push_back(artNodeID);
fDrawnPVPath.push_back(artNodeID);
sceneHandler.AddCompound(mesh);
fFullPVPath.pop_back();
fDrawnPVPath.pop_back();
delete tempVisAtts; // Needs cleaning up (Coverity warning!!)
return; // Mesh found and processed - nothing more to do.
} // else continue processing
}
}
continue_processing:
// Make decision to draw...
G4bool thisToBeDrawn = true;
@@ -839,7 +844,6 @@ G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
// the geometry tree but under some circumstances this consumed lots of CPU
// time. Instead, let us simply check that the volume (fpTopPV) exists in the
// physical volume store.
const auto& pvStore = G4PhysicalVolumeStore::GetInstance();
auto iterator = find(pvStore->begin(),pvStore->end(),fpTopPV);
if (iterator == pvStore->end()) {
@@ -852,56 +856,6 @@ G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
} else {
return true;
}
// Previous algorithm
// G4TransportationManager* transportationManager =
// G4TransportationManager::GetTransportationManager ();
// size_t nWorlds = transportationManager->GetNoWorlds();
// G4bool found = false;
// std::vector<G4VPhysicalVolume*>::iterator iterWorld =
// transportationManager->GetWorldsIterator();
// for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
// G4VPhysicalVolume* world = (*iterWorld);
// if (!world) break; // This can happen if geometry has been cleared/destroyed.
// // The idea now is to seek a PV with the same name and copy no
// // in the hope it's the same one!!
// G4PhysicalVolumeModel searchModel (world);
// G4int verbosity = 0; // Suppress messages from G4PhysicalVolumeSearchScene.
// G4PhysicalVolumeSearchScene searchScene
// (&searchModel, fTopPVName, fTopPVCopyNo, verbosity);
// G4ModelingParameters mp; // Default modeling parameters for this search.
// mp.SetDefaultVisAttributes(fpMP? fpMP->GetDefaultVisAttributes(): 0);
// searchModel.SetModelingParameters (&mp);
// searchModel.DescribeYourselfTo (searchScene);
// G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
// if (foundVolume) {
// if (foundVolume != fpTopPV && warn) {
// G4cout <<
// "G4PhysicalVolumeModel::Validate(): A volume of the same name and"
// "\n copy number (\""
// << fTopPVName << "\", copy " << fTopPVCopyNo
// << ") still exists and is being used."
// "\n But it is not the same volume you originally specified"
// "\n in /vis/scene/add/."
// << G4endl;
// }
// fpTopPV = foundVolume;
// CalculateExtent ();
// found = true;
// }
// }
// if (found) return true;
// else {
// if (warn) {
// G4cout <<
// "G4PhysicalVolumeModel::Validate(): No volume of name and"
// "\n copy number (\""
// << fTopPVName << "\", copy " << fTopPVCopyNo
// << ") exists."
// << G4endl;
// }
// return false;
// }
}
const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
@@ -915,29 +869,33 @@ const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
(*store)["BasePVPath"] =
G4AttDef("BasePVPath","Base Physical Volume Path","Physics","","G4String");
(*store)["LVol"] =
G4AttDef("LVol","Logical Volume","Physics","","G4String");
G4AttDef("LVol","Logical Volume","Physics","","G4String");
(*store)["Solid"] =
G4AttDef("Solid","Solid Name","Physics","","G4String");
G4AttDef("Solid","Solid Name","Physics","","G4String");
(*store)["EType"] =
G4AttDef("EType","Entity Type","Physics","","G4String");
G4AttDef("EType","Entity Type","Physics","","G4String");
(*store)["DmpSol"] =
G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
(*store)["LocalTrans"] =
G4AttDef("LocalTrans","Local transformation of volume","Physics","","G4String");
G4AttDef("LocalTrans","Local transformation of volume","Physics","","G4String");
(*store)["LocalExtent"] =
G4AttDef("LocalExtent","Local extent of volume","Physics","","G4String");
(*store)["GlobalTrans"] =
G4AttDef("GlobalTrans","Global transformation of volume","Physics","","G4String");
G4AttDef("GlobalTrans","Global transformation of volume","Physics","","G4String");
(*store)["GlobalExtent"] =
G4AttDef("GlobalExtent","Global extent of volume","Physics","","G4String");
(*store)["Material"] =
G4AttDef("Material","Material Name","Physics","","G4String");
G4AttDef("Material","Material Name","Physics","","G4String");
(*store)["Density"] =
G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
(*store)["State"] =
G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
(*store)["Radlen"] =
G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
(*store)["Region"] =
G4AttDef("Region","Cuts Region","Physics","","G4String");
G4AttDef("Region","Cuts Region","Physics","","G4String");
(*store)["RootRegion"] =
G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
}
return store;
}
@@ -996,34 +954,54 @@ std::vector<G4AttValue>* G4PhysicalVolumeModel::CreateCurrentAttValues() const
std::ostringstream oss; oss << fFullPVPath;
values->push_back(G4AttValue("PVPath", oss.str(),""));
oss.str(""); oss << fBaseFullPVPath;
values->push_back(G4AttValue("BasePVPath", oss.str(),""));
values->push_back(G4AttValue("LVol", fpCurrentLV->GetName(),""));
G4VSolid* pSol = fpCurrentLV->GetSolid();
values->push_back(G4AttValue("Solid", pSol->GetName(),""));
values->push_back(G4AttValue("EType", pSol->GetEntityType(),""));
oss.str(""); oss << '\n' << *pSol;
values->push_back(G4AttValue("DmpSol", oss.str(),""));
const G4RotationMatrix localRotation = fpCurrentPV->GetObjectRotationValue();
const G4ThreeVector& localTranslation = fpCurrentPV->GetTranslation();
oss.str(""); oss << '\n' << G4Transform3D(localRotation,localTranslation);
values->push_back(G4AttValue("LocalTrans", oss.str(),""));
oss.str(""); oss << '\n' << pSol->GetExtent() << std::endl;
values->push_back(G4AttValue("LocalExtent", oss.str(),""));
oss.str(""); oss << '\n' << fCurrentTransform;
values->push_back(G4AttValue("GlobalTrans", oss.str(),""));
oss.str(""); oss << '\n' << (pSol->GetExtent()).Transform(fCurrentTransform) << std::endl;
values->push_back(G4AttValue("GlobalExtent", oss.str(),""));
G4String matName = fpCurrentMaterial? fpCurrentMaterial->GetName(): G4String("No material");
values->push_back(G4AttValue("Material", matName,""));
G4double matDensity = fpCurrentMaterial? fpCurrentMaterial->GetDensity(): 0.;
values->push_back(G4AttValue("Density", G4BestUnit(matDensity,"Volumic Mass"),""));
G4State matState = fpCurrentMaterial? fpCurrentMaterial->GetState(): kStateUndefined;
oss.str(""); oss << matState;
values->push_back(G4AttValue("State", oss.str(),""));
G4double matRadlen = fpCurrentMaterial? fpCurrentMaterial->GetRadlen(): 0.;
values->push_back(G4AttValue("Radlen", G4BestUnit(matRadlen,"Length"),""));
G4Region* region = fpCurrentLV->GetRegion();
G4String regionName = region? region->GetName(): G4String("No region");
values->push_back(G4AttValue("Region", regionName,""));
oss.str(""); oss << fpCurrentLV->IsRootRegion();
values->push_back(G4AttValue("RootRegion", oss.str(),""));
return values;
}
@@ -1,103 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// John Allison 10th August 1998.
// An artificial scene to find physical volumes.
#include "G4PhysicalVolumeSearchScene.hh"
#include "G4VSolid.hh"
#include "G4Vector3D.hh"
#include "G4PhysicalVolumeModel.hh"
G4PhysicalVolumeSearchScene::G4PhysicalVolumeSearchScene
(G4PhysicalVolumeModel* pPVModel,
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo,
G4int verbosity):
fpPVModel (pPVModel),
fRequiredPhysicalVolumeName (requiredPhysicalVolumeName),
fRequiredCopyNo (requiredCopyNo),
fFoundDepth (0),
fpFoundPV (0),
fVerbosity (verbosity),
fMultipleOccurrence (false)
{}
G4PhysicalVolumeSearchScene::~G4PhysicalVolumeSearchScene () {}
void G4PhysicalVolumeSearchScene::ProcessVolume (const G4VSolid&) {
G4VPhysicalVolume* pCurrentPV = fpPVModel->GetCurrentPV();
/**************************************************
G4cout << "Required volume: \"" << fRequiredPhysicalVolumeName
<< "\", copy no. " << fRequiredCopyNo << G4endl;
G4cout << "PhysicalVolume: \"" << pCurrentPV -> GetName ()
<< "\", copy no. " << pCurrentPV -> GetCopyNo () << G4endl;
*******************************************/
const G4String& name = fpPVModel->GetCurrentPV() -> GetName ();
if (name.length() == fRequiredPhysicalVolumeName.length()) {
if (fRequiredPhysicalVolumeName == name) {
typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
typedef std::vector<PVNodeID> PVPath;
const PVPath& fullPVPath = fpPVModel->GetFullPVPath();
G4int currentDepth = fpPVModel->GetCurrentDepth();
if ((fRequiredCopyNo < 0 || // I.e., ignore negative request.
fRequiredCopyNo == pCurrentPV -> GetCopyNo ())) {
// Current policy - take first one found!!
if (!fpFoundPV) { // i.e., if not already found.
fFoundFullPVPath = fullPVPath;
fFoundDepth = currentDepth;
fpFoundPV = pCurrentPV;
fFoundObjectTransformation = *fpCurrentObjectTransformation;
}
else {
if (!fMultipleOccurrence && fVerbosity > 0) {
fMultipleOccurrence = true;
G4cout << "G4PhysicalVolumeSearchScene::FindVolume:"
<< "\n Required volume \""
<< fRequiredPhysicalVolumeName
<< "\"";
if (fRequiredCopyNo >= 0) {
G4cout << ", copy no. " << fRequiredCopyNo << ",";
}
G4cout << " found more than once."
"\n This function is not smart enough to distinguish identical"
"\n physical volumes which have different parentage. It is"
"\n tricky to specify in general. This function gives you access"
"\n to the first occurrence only."
<< G4endl;
}
}
}
}
}
}
@@ -36,14 +36,12 @@
#include <regex>
G4PhysicalVolumesSearchScene::G4PhysicalVolumesSearchScene
(G4PhysicalVolumeModel* pSearchVolumesModel, // usually a world
(G4PhysicalVolumeModel* pSearchVolumesModel,
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo,
G4int requiredContinuation)
G4int requiredCopyNo)
: fpSearchVolumesModel (pSearchVolumesModel)
, fMatcher (requiredPhysicalVolumeName)
, fRequiredCopyNo (requiredCopyNo)
, fRequiredContinuation (requiredContinuation)
{}
void G4PhysicalVolumesSearchScene::ProcessVolume (const G4VSolid&)
@@ -69,15 +67,8 @@ void G4PhysicalVolumesSearchScene::ProcessVolume (const G4VSolid&)
copyNo,
fpSearchVolumesModel->GetCurrentDepth(),
basePath,
fpSearchVolumesModel->GetFullPVPath(),
*fpCurrentObjectTransformation));
// If user has asked for limited descent
if (fRequiredContinuation >= 0) {
static G4int firstFoundDepth = fpSearchVolumesModel->GetCurrentDepth();
G4int foundDepth = fpSearchVolumesModel->GetCurrentDepth();
if (foundDepth >= firstFoundDepth + fRequiredContinuation) {
fpSearchVolumesModel->CurtailDescent();
}
}
}
}
}
@@ -31,6 +31,15 @@
#include "G4PseudoScene.hh"
#include "G4Mesh.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
void G4PseudoScene::AddCompound(const G4Mesh& mesh) {
// Catches mesh if special mesh rendering set
ProcessVolume(*mesh.GetContainerVolume()->GetLogicalVolume()->GetSolid());
}
void G4PseudoScene::ProcessVolume (const G4VSolid& solid)
{
G4ExceptionDescription ed;
@@ -71,6 +71,7 @@ void G4TouchablePropertiesScene::ProcessVolume (const G4VSolid& /*solid*/) {
fFoundTouchableProperties.fTouchableBaseFullPVPath = fpSearchPVModel->GetFullPVPath();
// Base path is one down from found PV
fFoundTouchableProperties.fTouchableBaseFullPVPath.pop_back();
fFoundTouchableProperties.fTouchableFullPVPath = fpSearchPVModel->GetFullPVPath();
fpSearchPVModel->Abort(); // No need to look further.
}
}