Low-level integration utilities

This subsection contains details of integrating Geant4 with Celeritas.

Geometry utilities

These utility classes are used to set up the Geant4 global geometry state.

class GeantGdmlLoader

Load a GDML file into memory.

The pointer treatment gives three options:

  • ignore leaves names as they are imported by Geant4’s GDML reader, which strips them from material/region names but leaves solid/logical/physical pointers in place.

  • truncate lets the Geant4 GDML remove the pointers, which cuts everything after 0x including suffixes like _refl added during volume construction.

  • remove uses a regular expression to remove pointers from volume names.

The detectors option reads auxiliary tags in the structure that have auxtype=SensDet and returns a multimap of strings to volume pointers.

inline G4VPhysicalVolume *celeritas::load_gdml(std::string const &filename)

Load a Geant4 geometry, excising pointers.

This provides a good default for using GDML in Celeritas.

Returns:

Geant4-owned world volume

inline void celeritas::save_gdml(G4VPhysicalVolume const *world, std::string const &out_filename)

Write a GDML file to the given filename.

inline std::unordered_set<G4LogicalVolume const*> celeritas::find_geant_volumes(std::unordered_set<std::string> names)

Find Geant4 logical volumes corresponding to a list of names.

If logical volumes with duplicate names are present, they will all show up in the output and a warning will be emitted. If one is missing, a RuntimeError will be raised.

static std::string_view const labels[] = {"Vol1", "Vol2"};
auto vols = find_geant_volumes(make_span(labels));

Physics interfaces

This will be replaced by other utilities in conjunction with the problem input.

class GeantImporter : public celeritas::ImporterInterface

Load problem data directly from Geant4.

This can be used to circumvent ROOT as a serialization tool, whether to simplify the toolchain or to integrate better with user frameworks. As much data as possible is imported (subject to the data selection); downstream Celeritas classes will validate the imported data as needed.

GeantImporter import(GeantSetup("blah.gdml"));
ImportData data = import();
or to import from an existing, initialized Geant4 state:
GeantImport import(world_volume);
ImportData data = import();

class GeantSetup

Construct a Geant 4 run manager and populate internal Geant4 physics.

This is usually passed directly into GeantImporter . It hides Geant4 implementation details (including header files) from the rest of the code. It is safe to include even when Geant4 is unavailable!

The setup is targeted specifically for physics that Celeritas supports.

Todo:

This is a hot mess; it needs to be unified with inp/setup and not passed around by moving it.

Utility interfaces

Logger celeritas::MakeMTSelfLogger(G4RunManager const &runman)

Manually create a G4MT-friendly logger for event-specific info.

This logger redirects Celeritas messages through Geant4. It logger writes the current thread (and maximum number of threads) in each output message, and sends each message through the thread-local G4cerr. It should be used for information about a current track or event, specific to the current thread.

In the main of your application’s executable, set the “process-local” logger:

celeritas::self_logger() = celeritas::MakeMTSelfLogger(*run_manager);

Logger celeritas::MakeMTWorldLogger(G4RunManager const &runman)

Manually create a logger that should only print once in MT or MPI.

A given world log message should only print once per execution: on a single process (if using MPI) and a single thread (if using MT). To provide clarity for tasking/MT Geant4 models, this will print whether it’s running from a manager [M] or worker [W] thread if it’s a multithreaded app.

The CELER_LOG_ALL_LOCAL environment variable allows all CELER_LOG invocations (on all worker threads) to be written for debugging.

In the main of your application’s executable, set the “process-global” logger:

celeritas::world_logger() = celeritas::MakeMTWorldLogger(*run_manager);

class ScopedGeantLogger

Redirect Geant4 logging through Celeritas’ logger.

This parses messages sent to G4cout and G4cerr from Geant4. Based on the message (whether it starts with warning, error, ‘!!!’, ‘***’) it tries to use the appropriate logging level and source context.

Since the Geant4 output streams are thread-local, this class is as well. Multiple geant loggers can be nested in scope, but only the outermost on a given thread will “own” the log destination.

  • When instantiated during setup, this should be constructed with celeritas::world_logger to avoid printing duplicate messages per thread/process.

  • When instantiated during runtime, it should take the celeritas::self_logger so that only warning/error messages are printed for event/track-specific details.

class ScopedGeantExceptionHandler

Convert Geant4 exceptions to RuntimeError during this class lifetime.

Because the underlying Geant4 error handler is thread-local, this class must be scoped to inside each worker thread. Additionally, since throwing from a worker thread terminates the program, an error handler must be specified if used in a worker thread: you should probably use a celeritas::MultiExceptionHandler if used inside a worker thread.

Note

Creating a G4RunManagerKernel resets the exception handler, so errors thrown during setup cannot be caught by Celeritas, and this class can only be used after creating the G4RunManager.