Geant4 adapter
This section provides specific instructions for importing a Geant4 geometry in Goupil. Refer to the Overview section of this document for a general description of Goupil.
Note
The following instructions assume technical familiarity with Geant4 and prior experience in defining a Monte Carlo geometry. If you are not familiar with Geant4, please refer first to the Geant4 documentation.
In addition, it will be required to build a shared library, which is neither covered by this guide as there are multiple ways to achieve this depending on your OS and build system.
Locating G4Goupil
Goupil comes with a source distribution of a Geant4 adapter, hereafter called
G4Goupil. The corresponding source files can be accessed as:
$ ls "$(python3 -m goupil --prefix)/interfaces/geant4"
G4Goupil.cc G4Goupil.hh goupil.h
Warning
Using G4Goupil requires a working installation of Geant4.
Preparing the geometry
G4Goupil allows a Geant4 geometry to be exported as a shared library,
which can then be navigated using Goupil’s Python interface. To illustrate this
mechanism, let us consider the following example. Let Geometry be a
subclass of G4VDetectorConstruction that implements a Geant4 geometry.
This geometry is exported by embedding the following
G4Goupil::NewGeometry function in a shared library.
const G4VPhysicalVolume * G4Goupil::NewGeometry() {
// Build the geometry and return the top "World" volume.
Geometry geometry();
return geometry.Construct();
}
Warning
The geometry shared library must also link to or include both the
Geometry and G4Goupil implementations. In particular, this
means that G4Goupil.cc must be compiled at some point.
Optionally, a cleanup function (G4Goupil::DropGeometry) can also be
included in the shared library, for when the geometry is released by Goupil. The
implementation of this function must be consistent with the memory policy used
when building the geometry. For example, assuming that materials are managed by
a global store (e.g. G4NistManager), the following code could be used.
void G4Goupil::DropGeometry(const G4VPhysicalVolume * volume) {
// Delete any sub-volume(s).
auto && logical = volume->GetLogicalVolume();
while (logical->GetNoDaughters()) {
auto daughter = logical->GetDaughter(0);
logical->RemoveDaughter(daughter);
G4Goupil::DropGeometry(daughter);
}
// Delete this volume.
delete logical->GetSolid();
delete logical;
delete volume;
}
Importing the geometry
The previous geometry library is imported in Python by using an ExternalGeometry wrapper object. First, let us import goupil module as
>>> import goupil
Then, the geometry library (let’s say "libgeometry.so" on Linux) is
loaded as
>>> geometry = goupil.ExternalGeometry("path/to/libgeometry.so")
According to Goupil’s model, a Monte Carlo geometry is a set of sectors that are
connected by one or more interface. Each sector is filled with a material that
has a uniform atomic composition, but its density may vary continuously.
Following, an ExternalGeometry has two read-only attributes:
materials and sectors. These attributes list all the materials and sectors
that are defined by the geometry. For instance, as:
>>> geometry.materials
(G4_AIR, G4_CALCIUM_CARBONATE)
Modifying the geometry
The physical properties of an ExternalGeometry can be modified with
the update_material and
update_sector methods. For example,
let us define an exponential DensityGradient to describe the air
density in the lower part of the Earth atmosphere (i.e. the troposphere).
>>> gradient = goupil.DensityGradient(1.225E-03, 1.04E+06)
Then, the density model of the first sector (index 0) can be changed
as:
>>> geometry.update_sector(0, density=gradient)
Note
It is not possible to modify the structural properties of the external
geometry, such as the number of sectors, directly from goupil. However, it is possible to implement mutable structural
properties at the C level in the geometry library, which can be accessed from
Python e.g. using ctypes. In this case, the
ExternalGeometry must be reloaded whenever the Geant4 geometry
needs to be rebuilt, (i.e. when Geometry::Construct is invoked, in the
current example).