// VolumeList.cc
// Contact person: Phil Jones
// See VolumeList.hh for more details
//———————————————————————//
#include
#include
#include
#include
#include
#include
#include
#include
#include
using std::string;
using std::vector;
namespace RAT{
// File-private utility methods:
// Locate a volume named "name" that is a descendant of "ancestor",
// by recursively traversing all daughter volumes.
// Return true if "name" is a descendant of "ancestor", false otherwise.
// Construct a local-to-global transform on the way out,
// by recursively composing the daughter-to-mother transforms.
// If successful, store volume and transform in "result".
void FindVolume(G4LogicalVolume const* ancestor,
G4String const& name, vector& result)
{
// For simplicity, do not check if the name of 'ancestor' is 'name' -
// 'name' is assumed to be a strict descendant of 'ancestor'.
for (int i = 0; i < ancestor->GetNoDaughters(); i++)
{
G4VPhysicalVolume* daughter = ancestor->GetDaughter(i);
if (daughter->GetName() == name)
{
G4AffineTransform trans(daughter->GetRotation(), daughter->GetTranslation());
// Translation/Rotation are daughter-to-mother transforms
result.push_back(VolumeList::VolTransform(daughter,trans));
}
unsigned int subtreeIndex = result.size();
FindVolume(daughter->GetLogicalVolume(), name, result);
for(; subtreeIndex < result.size(); subtreeIndex++)
result.at(subtreeIndex).fTransform *= G4AffineTransform(daughter->GetRotation(),daughter->GetTranslation());
}
}
//Class method implementations:
void VolumeList::AddVolTransform(VolTransform const& vol)
{
fList.push_back(vol);
}
void VolumeList::AddVolume(std::string const& name, volumes vol)
{
G4VPhysicalVolume* worldVolume =
G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking()->GetWorldVolume();
vector result;
// Look for "name" as a descendant of the world, or die.
FindVolume(worldVolume->GetLogicalVolume(), G4String(name),result);
Log::Assert(result.size() > 0, "Failed to find volume: "+name);
if(result.size() > 1)
{
warn << "Found multiple volumes by name " << name << ": "
<< result.size() << newline;
debug << "Volumes have local to global translations: " << newline;
for(unsigned int i=0; i::iterator it;
for(it=result.begin(); it
GetNavigatorForTracking();
// LocateGlobalPointAndSetup finds the volume, and sets up nav
// for computing GetLocalToGlobalTransform
G4VPhysicalVolume* volume = nav->LocateGlobalPointAndSetup(point);
G4AffineTransform transform = nav->GetLocalToGlobalTransform();
VolTransform voltrans(volume, transform);
if(vol == BOTH)
{
fList.push_back(voltrans);
AddDaughters(voltrans);
}
else if(vol == DAUGHTERS)
{
AddDaughters(voltrans);
}
else if(vol == SELF)
{
fList.push_back(voltrans);
}
}
void VolumeList::AddString(std::string const& value, volumes vol)
{
// Split on whitespace, and decide how to add based on number of fields
vector values = split(trim(value), " ");
switch(values.size())
{
case 1:
AddVolume(values[0], vol);
break;
case 3:
// IMPORTANT: to_double does not throw if passed something that
// doesn't look like a double, it will just make a best guess;
// i.e. "a" -> 0.0
AddVolume(G4ThreeVector(to_double(values[0]),
to_double(values[1]), to_double(values[2])), vol);
break;
default:
Log::Die("Volume must be specified either by one field"
" representing a name, or three fields representing"
" the x, y, and z coordinates of a point");
break;
}
}
void VolumeList::AddDaughters(VolTransform const& vol)
{
int noDaughters = vol.fVolume->GetLogicalVolume()->GetNoDaughters();
for(int iDaughter=0; iDaughter < noDaughters; iDaughter++)
{
G4VPhysicalVolume* daughter = vol.fVolume->GetLogicalVolume()->GetDaughter(iDaughter);
G4AffineTransform daughterTrans(daughter->GetRotation(),daughter->GetTranslation());
fList.push_back(VolTransform(daughter, vol.fTransform * daughterTrans));
}
}
double VolumeList::ComputeVolume(const G4VPhysicalVolume* volume)
{
if(fSolidVolumes.count(volume->GetName()))
return fSolidVolumes[volume->GetName()];
else
{
double solidVolume = volume->GetLogicalVolume()->GetSolid()->GetCubicVolume();
int numDaughters = volume->GetLogicalVolume()->GetNoDaughters();
for(int iDaughter = 0; iDaughter < numDaughters; iDaughter++)
{
G4VSolid* daughterSolid = volume->GetLogicalVolume()->GetDaughter(iDaughter)->GetLogicalVolume()->GetSolid();
solidVolume -= daughterSolid->GetCubicVolume();
}
fSolidVolumes[volume->GetName()] = solidVolume;
return solidVolume;
}
}
std::map VolumeList::fSolidVolumes;
} //namespace RAT