A framework-agnostic C++20 library that wraps the SHiP GeoModel geometry behind a
stable interface. The design follows the patterns of DD4HEP's IGeoSvc (LHCb/key4hep)
and ALICE O2's GeometryManager.
┌─────────────────────────────────────────┐
│ IGeometryService (abstract interface) │
│ • geoModelWorld() → GeoVPhysVol* │
│ • geant4WorldLogical() → G4LogicalVol* │ ← lazy, call_once
│ • getLogicalVolume(name) │
└───────────────────┬─────────────────────┘
│ implements
┌───────────────────▼─────────────────────┐
│ SHiPGeometryService │
│ ::fromSource() — SHiPGeometryBuilder │
│ ::fromFile(db) — GeoModelIO::Read │
└─────────────────────────────────────────┘
Design decisions:
IGeometryServicehas no framework headers — can be used standalone or from any framework.- GeoModel tree construction is eager (in the factory functions) to surface geometry errors at startup.
- GeoModel→Geant4 conversion (
geant4WorldLogical()) is lazy (guarded bystd::call_once) becauseExtParameterisedVolumeBuilder::Build()requires aG4RunManagerto exist on the calling thread. Call it from withinG4VUserDetectorConstruction::Construct().
The easiest setup is pixi, which provisions the full
toolchain from conda-forge and the SHiP channel at prefix.dev/ship.
For manual builds you'll need:
- CMake 3.20+
- C++20 compiler
SHiPGeometryinstalled (fromgeometry/repository)- GeoModel 6.22+ (GeoModelCore, GeoModelIO, GeoModelG4)
- Geant4 11.x
- mp-units
pixi run testThat single command provisions the env, configures with CMake/Ninja
(RelWithDebInfo), builds, and runs ctest — the same chain CI uses.
For iteration, the individual tasks defined in pixi.toml are:
pixi run configure # cmake -S . -B build -G Ninja ...
pixi run build # cmake --build build -j
pixi run test # ctest --test-dir build --output-on-failureUse pixi shell to drop into an interactive shell with the env activated
(useful for running individual binaries, debuggers, etc.).
If you already have GeoModel, Geant4, SHiPGeometry, and mp-units
installed (e.g. via spack or a system package manager), you can build
directly with CMake:
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="/path/to/GeoModel/install;/path/to/SHiPGeometry/install"
cmake --build build
cmake --install build --prefix /path/to/install#include <GeometryService/SHiPGeometryService.h>
auto svc = ship::SHiPGeometryService::fromSource();
const GeoVPhysVol* world = svc->geoModelWorld();auto svc = ship::SHiPGeometryService::fromFile("/path/to/ship_geometry.db");Call geant4WorldLogical() from within G4VUserDetectorConstruction::Construct():
G4VPhysicalVolume* Construct() override {
G4LogicalVolume* worldLV = geoSvc_.geant4WorldLogical();
return new G4PVPlacement(nullptr, G4ThreeVector(), worldLV,
"World", nullptr, false, 0);
}// Valid after geant4WorldLogical() has been called
G4LogicalVolume* lv = svc->getLogicalVolume("MuonShield");find_package(SHiPGeometryService CONFIG REQUIRED)
target_link_libraries(myapp PRIVATE SHiPGeometryService::SHiPGeometryService)The package config pulls in SHiPGeometry, GeoModelCore, GeoModelIO,
GeoModelG4, and Geant4 automatically.
LGPL-3.0-or-later. Copyright CERN for the benefit of the SHiP Collaboration.