GVolume is the Python class that defines a Geant4 physical volume in GEMC. Every volume in a detector system is an instance of GVolume, published to the active database factory via gvolume.publish(cfg).

from gvolume import GVolume

gvolume = GVolume("my_box")
gvolume.make_box(30, 20, 10)           # 30 × 20 × 10 mm half-lengths
gvolume.material = "G4_Al"
gvolume.mother   = "world"
gvolume.publish(cfg)



Mandatory properties

These three must be set before calling publish(), or GEMC will exit with an error.

Property Type Description
solid str Geant4 solid name, e.g. "G4Box", "G4Tubs", "G4Trap"
parameters str Comma-separated dimensions with units, matching the solid’s constructor order
material str Geant4 NIST name ("G4_Al") or a custom GMaterial name

Solids and their parameter strings are described in the solid types reference.



Placement

mother

Name of the parent volume. Defaults to "root" (the world volume).

gvolume.mother = "sector_envelope"

position

Location of this volume’s centre relative to its mother, in mm. Use set_position() to set it with explicit units:

gvolume.set_position(0, 0, 150)              # mm (default)
gvolume.set_position(0, 0, 15, lunit='cm')   # explicit unit

The default is "0*mm, 0*mm, 0*mm".

rotations / set_rotation() / add_rotation()

The orientation of the volume relative to its mother frame. Three methods are available:

set_rotation(x, y, z, lunit='deg', order='') — defines a single rotation applied to the x, y, z axes in that order (or in the order given by order):

gvolume.set_rotation(10, 45, 30)             # 10° around x, then 45° y, then 30° z
gvolume.set_rotation(30, 45, 10, order='zyx')  # 30° around z first, then y, then x

add_rotation(x, y, z, lunit='deg') — appends a further xyz rotation on top of whatever has already been set. Cumulative calls stack left-to-right:

gvolume.add_rotation(0, 0, 40)   # first: 40° around z
gvolume.add_rotation(10, 0, 0)   # then:  10° around x

Ordered rotations are stored as "ordered: zxy, 90*deg, 25*deg, 0*deg" in the database, so the axis order is preserved for Geant4 and for pyvista rendering.



Placement type and rotation convention

g4placement_type controls which Geant4 constructor places the volume, and therefore how the rotation matrix R relates local-frame points to world-frame points.

gvolume.g4placement_type = "active"    # default
gvolume.g4placement_type = "passive"   # GEMC2 / clas12Tags compatibility

Active — G4Transform3D(R, T)

Geant4 stores frot = R⁻¹ = Rᵀ internally. Navigation inverts the stored matrix, so the forward transformation from local to world coordinates is:

p_world = R_raw × p_local + T

This is the default and matches the behaviour of new GEMC3 geometries written in Python.

Passive — G4PVPlacement(&rot, T)

Geant4 stores frot = R directly (no inversion). Navigation applies frot to map from world to local, so the forward transformation is:

p_world = R_rawᵀ × p_local + T

Use "passive" when porting geometries from GEMC2 or clas12Tags, where the G4PVPlacement(rotation, translation, ...) constructor was used. The rotation matrix R in those systems is the frame rotation (a passive rotation of the coordinate axes), so transposing it gives the correct active transformation needed to move points into the world frame.

Example — DC region 1, sector 1:

gvolume.set_rotation(90, 25, 0, order='zxy')  # ordered: zxy, 90*deg, 25*deg, 0*deg
gvolume.g4placement_type = "passive"

R_raw = Rx(25°) @ Rz(90°).
With passive placement: R_rawᵀ @ (0, 0, 1) ≈ (0.42, 0, 0.91) — the local z-axis points radially outward at 25° polar tilt, which is the correct orientation for the drift chamber wedge.



Display properties

Property Type Default Description
visible int 1 1 = visible, 0 = invisible (rendered as faint wireframe in pyvista)
style int 1 1 = solid surface, 0 = wireframe, 2 = point cloud
color str "778899" Six-digit hex RGB string, e.g. "ff0000" for red. An optional 7th digit (0–5) sets transparency: 0 = opaque, 5 = fully transparent
opacity float 1 Opacity override for pyvista rendering (0.0–1.0)
gvolume.color   = "0000ff4"   # mostly transparent blue
gvolume.visible = 1
gvolume.style   = 0           # wireframe



Sensitivity

Property Type Default Description
digitization str None Name of the digitization plugin. Built-in choices: "flux", "particle_counter", "integral_counter", "dosimeter". Custom plugins use a .gplugin filename
identifier str None Set with set_identifier(*pairs) — unique key/value pairs that tag every hit in this volume
gvolume.digitization = "flux"
gvolume.set_identifier("sector", 1, "layer", 3, "wire", 42)



Fields and existence

Property Type Default Description
mfield str None Name of a magnetic field file attached to this volume
exist int 1 1 = volume is built, 0 = volume is skipped (can be toggled via jcard modifiers)
description str None Free-text description stored in the database



Not yet implemented

Property Description
copyOf Intended to copy an existing volume
solidsOpr Intended for boolean solid operations
mirror Intended to define a G4OpticalSurface