Skip to content

CLAS12 GEMC Systems

Test ASCII Geometry Comparison Deploy Sanitize CodeQL Advanced Doxygen Binary Tarballs Nightly Dev Release HIPO Histos Comparison macOS Tarball Valgrind Profile

CLAS12 GEMC Systems contains the GEMC3 implementation of CLAS12 detector geometry systems and their system-specific plugins. It is the CLAS12 companion repository to the core GEMC application and Python geometry API:

  • gemc/src provides the GEMC C++ application, Geant4 integration, SQLite/ASCII/CAD/GDML geometry loaders, dynamic plugin infrastructure, streamers, and bundled pygemc environment.
  • gemc/pygemc provides the Python API used to define geometry and materials, write GEMC databases, preview geometry with PyVista, and export VTK.js scenes.
  • gemc/home contains the public GEMC website, installation pages, tutorials, examples, and generated documentation assets.

Current Scope

This repository is under active migration from gemc/clas12Tags.

System Status Notes
dc geometry and plugin Uses coatjava as geometry source
ec geometry and plugin Uses coatjava and the shared ecal plugin
field plugin CLAS12 mapped magnetic field via the cMag library
ft geometry and plugins Upcoming next release: FTCAL, FTHODO, and FTTRK
ftof geometry and plugin Uses coatjava as geometry source
ltcc geometry and plugin Native and CAD geometry with optical surfaces
pcal geometry and shared plugin Uses coatjava and the shared ecal plugin

GEMC

The core GEMC repository, gemc/src, owns the runtime behavior. This includes:

  • Geant4 solid, logical-volume, and physical-placement construction
  • dynamic C++ plugins
  • event generation, sensitive detectors, and output streamers

This repository owns CLAS12-specific inputs to that runtime:

  • detector geometry, material definitions,
  • run and variation mappings needed to reproduce CLAS12 geometry
  • validation against GEMC2 CLAS12 reference geometry and output

The gemc/pygemc repository defines the Python API.


Geometry Workflow

Each detector system is self-contained under geometry_src/<system>.

A typical system directory contains:

File Role
<system>.py Executable main script; creates autogeometry() and publishes materials and volumes
geometry.py Geometry construction code
materials.py System material definitions
variations.py Optional run and variation mapping
<system>.yaml GEMC steering card for quick local runs
../coatjava_factories/CoatjavaFactory.java Optional coatjava bridge, in case of Java geometry services
plugin/meson.build Optional C++ plugin registration for digitization or other runtime extensions

The main script should be executable and runnable directly from its directory:

cd geometry_src/dc
./dc.py 

Use PyVista options from pygemc when a system is ready for visual inspection:

./dc.py -pvb

Run GEMC with the local steering card:

gemc dc.yaml
gemc dc.yaml -gui

Sensitive geometry rows select their runtime plugin through the volume's digitization field. The optional digitization key on a YAML gsystem entry has a narrower purpose: it tells GEMC which differently named plugin to probe before parsing options, as when the ec and pcal systems share ecal.gplugin. FT has three sensitive names (ft_cal, ft_hodo, and ft_trk), so its YAML keeps a plain name: ft entry. The options-only ft.gplugin registers all three domains during the bootstrap probe; geometry loading then discovers and loads the three digitizers from the sensitive rows.


Reference Checks

Use scripts/compare_ascii_databases.py to compare generated GEMC3 ASCII databases (geometry and materials) with the matching gemc/clas12Tags reference files:

scripts/compare_ascii_databases.py dc

With no system arguments, the script checks every local geometry_src/<system>/<system>.py implementation. The script maps GEMC2 and GEMC3 ASCII columns onto common geometry fields — name, mother, position, rotation, solid, dimensions, material, digitization (GEMC2 sensitivity), and identifier (GEMC2 identifiers, expanded to a canonical name=value form) — and compares only those field values by volume name, so formatting and column-order differences do not hide real geometry matches. Materials are compared the same way by material name (density, components, optical and scintillation properties), for systems that define custom materials. Numeric spellings and the GEMC2/GEMC3 polycone array orders are normalized before comparison.

When any field differs the script prints the field-level mismatches and exits with status 1; an all-match run exits with status 0.


Placement And Rotations

GEMC3 supports both Geant4 placement conventions through GVolume.g4placement_type:

Value Meaning
active Default GEMC3 behavior; uses G4Transform3D(rotation, translation)
passive GEMC2/clas12Tags-compatible behavior; uses G4PVPlacement(rotation, translation, ...)

CLAS12 detector volumes ported from GEMC2 should use the passive placement convention:

gvolume.g4placement_type = "passive"

Keep ordered rotations ordered in the database. For example, do not flatten:

ordered: yxz, 0*deg, 0*deg, 6*deg

GEMC applies ordered rotations in the specified order. This is required for DC and is expected to matter for other CLAS12 systems ported from clas12Tags.


Coatjava

Some CLAS12 systems use coatjava so simulation geometry follows the same Java geometry service used by reconstruction. This repository keeps coatjava local to geometry_src:

./geometry_src/install_coatjava.sh -l

Meson configure installs coatjava automatically if geometry_src/coatjava is missing. CI and Docker images must provide the prerequisites first:

  • Java
  • Maven
  • git-lfs
  • jq

The helper scripts are:

Path Purpose
geometry_src/install_coatjava.sh Installs the local coatjava copy
ci/install_coatjava_deps.sh Installs Java, Maven, git-lfs, and jq in supported CI images
ci/setup_coatjava.sh CI helper that installs prerequisites and then coatjava if needed

Do not remove an existing coatjava installation unless the reset flag is explicitly requested.


Build And Test

This repository is built with Meson and uses the GEMC and Geant4 dependencies configured under meson/.

Configure, build, and test:

meson setup build --prefix="$PWD/install"
meson compile -C build
meson test -C build --print-errorlogs

Use these independent options to reuse existing library installations and magnetic field maps. The three library options and configured field-plugin default are upcoming in the next release.

Meson option Path to supply
-Duse-ccdb-location=<dir> CCDB installation prefix
-Duse-hipo-location=<dir> HIPO installation prefix
-Duse-clas12-cmag-location=<dir> clas12-cmag installation prefix
-Duse-fields-location=<dir> Directory containing the CLAS12 magnetic field maps

For example, to reuse all four:

meson setup build --prefix="$PWD/install" \
  -Duse-ccdb-location=/absolute/path/to/ccdb \
  -Duse-hipo-location=/absolute/path/to/hipo \
  -Duse-clas12-cmag-location=/absolute/path/to/clas12-cmag \
  -Duse-fields-location=/absolute/path/to/magfield

Each option defaults to empty and can be set independently. An empty library option preserves the existing dependency setup. A supplied library path must be absolute and skips that subproject; invalid installations fail configuration. Headers are expected under include/ (also includes/ for older clas12-cmag installations), and libraries under lib/ or lib64/. Meson's -Dprefer_static=true prefers static libraries when both kinds are installed; static libraries used by plugins must be built with position-independent code. Installed CCDB needs MySQL/MariaDB client development tools and SQLite; installed HIPO needs LZ4 and fmt development packages. External installations are not copied by meson install.

With -Duse-fields-location=<dir>, no maps are fetched or installed, and the field plugin uses that directory by default. An explicit field dir parameter still takes precedence. When the option is empty, maps come from the magfield git-lfs subproject and are installed under <prefix>/fields; the plugin locates that directory relative to its own installed location. Fetching the maps requires git-lfs.

Upcoming in the next release: bundled CCDB uses system SQLite through ccdb_system_sqlite.patch, avoiding its private SQLite amalgamation. Existing unpatched CCDB subproject checkouts must be refreshed before rebuilding:

meson subprojects purge --confirm ccdb

Then configure a clean build directory so Meson fetches CCDB and applies the wrap patches.

The geometry tests run each registered Python system and write the combined SQLite database:

meson test -C build geometry_dc --print-errorlogs
sqlite3 build/clas12.db "select system, variation, run, count(*) from geometry group by 1,2,3;"

The CLAS12 system registry is currently in meson.build:

clas12_systems = [
    'dc',
    'ec',
    'ft',
    'ftof',
    'ltcc',
    'pcal',
]

Add a detector name to this list only when geometry_src/<system>/<system>.py is ready to generate valid GEMC geometry.


CCDB Calibration Constants

The detector digitization plugins (dc, ecal, ft_cal, ft_hodo, ftof, ltcc) load their calibration constants from CCDB. By default they connect to the JLab database at mysql://clas12reader@clasdb.jlab.org/clas12; set the CCDB_CONNECTION environment variable to point at a different server or a local SQLite snapshot (sqlite:///path/to/ccdb.sqlite). Note this is the CCDB database, not the GEMC2 clas12.sqlite detector database — pointing at the latter yields empty constants. On any CCDB failure (unreachable host, wrong database, empty table) the plugins now abort the run with a clear error instead of silently producing empty digitized output.

MariaDB vs MySQL connector (macOS)

The CCDB client library needs care on macOS. The clas12reader account authenticates with mysql_native_password, a scheme that Oracle removed from the MySQL client library in version 9.0 (it is SHA1-based and was deprecated for security). A CCDB linked against MySQL 9.x therefore cannot authenticate to clasdb and fails at connection time — this is a limitation of the client library, not a CCDB bug, and no CCDB source change can restore a capability compiled out of the library. Install a connector that still provides it:

brew install mariadb-connector-c   # preferred: maintained; supports native_password and caching_sha2_password
# or
brew install mysql-client@8.4      # Oracle LTS that still ships native_password

The Meson build selects the CCDB connector automatically (meson/meson.build), preferring, in order, mariadb-connector-c, mysql-client@8.4, mysql-client, then mysql, so a clean build links a working client with no manual relink. If only MySQL 9.x is installed, CCDB still builds but connecting to clasdb fails with a clear error until a compatible connector is installed (or the server account migrates to caching_sha2_password).

There is a second, unrelated catch specific to MariaDB: mariadb-connector-c enforces TLS by default, while clasdb runs without SSL, so an out-of-the-box MariaDB build fails with Error 2026 (SSL is required, but the server does not support it). The ccdb subproject is patched (via subprojects/ccdb.wrap diff_filessubprojects/packagefiles/ccdb_ssl_no_enforce.patch) to disable TLS enforcement when built against MariaDB, matching Oracle libmysqlclient's plaintext-fallback default. The patch is guarded with #ifdef LIBMARIADB, so it is a no-op for the MySQL/Oracle clients (which removed that option and do not enforce TLS anyway). With that in place, mariadb-connector-c connects to clasdb and is the recommended connector.


Plugin Path

CLAS12 system plugins are installed as .gplugin shared libraries under <prefix>/lib/. GEMC locates plugins by searching, in order: GEMC_PLUGIN_PATH, its own lib/ and build/ directories, then the OS dynamic-library search path (LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on macOS).

The simplest setup is to install the CLAS12 systems into GEMC's own prefix, so the .gplugin libraries land in the lib/ directory GEMC already searches and no runtime variable is needed. GEMC's prefix is one level above its bin/ directory, so command -v gemc derives it:

meson setup build --prefix="$(dirname "$(dirname "$(command -v gemc)")")"
meson install -C build
gemc dc.yaml

If GEMC is on PATH but a different prefix is configured, Meson prints a warning at configure time. In that case set GEMC_PLUGIN_PATH to the CLAS12 systems library directory before running gemc:

export GEMC_PLUGIN_PATH=$(pkg-config --variable=plugindir clas12-systems)
gemc dc.yaml

Or pass it on the command line:

gemc dc.yaml -plugin_path=/path/to/clas12-systems/lib

If a plugin is not found, GEMC prints the current value of GEMC_PLUGIN_PATH alongside the error to help diagnose path problems.

The installed prefix from a Meson build exposes the plugin directory through a pkg-config file:

# After: meson install -C build --prefix=/my/clas12/prefix
export PKG_CONFIG_PATH=/my/clas12/prefix/lib/pkgconfig:$PKG_CONFIG_PATH
export GEMC_PLUGIN_PATH=$(pkg-config --variable=plugindir clas12-systems)

Plugin Build Model

System plugins use a registry pattern:

  1. A detector-specific geometry_src/<system>/plugin/meson.build appends dictionaries to clas12_plugins.
  2. The top-level meson.build is the only place that turns those entries into installed shared libraries.
  3. Installed GEMC plugins must use the .gplugin suffix.

This keeps plugin installation consistent across CLAS12 systems and avoids each detector inventing its own build logic.


Magnetic Field

CLAS12 uses a mapped magnetic field — the measured solenoid and torus field maps — rather than an analytic model. The field is provided by the gfieldclas12-cmag plugin under plugins/field/, which reads the CLAS12 solenoid and torus binary maps through David Heddle's cMag library (the clas12-cmag subproject) and returns the composite field at each step point.

The field is configured with the core GEMC generic gfields node, selecting this plugin with type: clas12-cmag:

gfields:
  - name: clas12
    type: clas12-cmag
    solenoid: Symm_solenoid_r601_phi1_z1201_13June2018
    torus: Symm_torus_r2501_phi16_z251_24Apr2018
    solenoid_scale: 1
    torus_scale: 1

global_field: clas12

The global_field value is the configured field name (clas12 above), not the solenoid/torus map names. The map names and the per-map scale factors belong to the gfields entry. This replaces the GEMC2 global_field: Symm_solenoid_...:Symm_torus_... style and the old hardcoded binary_torus / binary_solenoid scale targets with explicit torus, solenoid, torus_scale, and solenoid_scale parameters.

Any additional scalar keys (per-map displacements, overall origin/rotation, interpolation) are forwarded verbatim to the plugin.

Field maps come from the magfield git-lfs subproject and are copied to <prefix>/fields during meson install (see meson/install_fields.py); the plugin reads them from the fields directory installed next to it (<plugin_dir>/../fields). Configuring with -Duse-fields-location=<dir> skips the subproject and points at an existing maps directory instead (nothing is cloned or installed). No FIELD or FIELD_DIR environment variable is needed at runtime; an explicit dir parameter can override the location.


Streaming Readout (SRO)

Upcoming in the next release. CLAS12 systems can emit streaming-readout (SRO) frames in the JLAB DAQ binary format instead of, or alongside, ordinary event output. GEMC owns the generic sro streamer; a system plugin supplies the payloads by exporting a GSROImplementationFactory next to its digitizer. Currently only FT-Cal supplies SRO payloads (through ft_cal.gplugin); the other FT digitizers keep their normal output with no SRO model.

Activate SRO from the command line by selecting the sro streamer format and the plugin that provides the payloads, and by giving the acquisition a non-zero event time width:

gemc geometry_src/ft/ft.yaml -n=10000 \
  -gstreamer='[{format: sro, filename: ftcal_sro, implementation: ft_cal}]' \
  -eventTimeWidth='10*ns'
  • format: sro selects GEMC's SRO streamer; implementation: ft_cal names the plugin that produces the payloads; filename is the output basename.
  • -eventTimeWidth sets the spacing between consecutive events on the acquisition timeline. Its default of zero rejects an SRO run, so it must be set explicitly (the 10*ns above is an example, not a measured CLAS12 beam parameter). Ordinary output runs do not need it.
  • Output files are written per crate as <basename>_r<resolved_run>_crate<crate>.ev; reusing a basename and run overwrites them.

The FT bootstrap registrar ft.gplugin supplies the options for ft_cal.gplugin, so no extra options node is needed. See geometry_src/sro/README.md for the translation-table convention, worker timing model (including ft_cal_sro_min_signal_time), the binary layout, and the sro test suite; the ported DAQ definitions and their provenance live in geometry_src/sro/daq/README.md.


Validation

For each ported detector, validate both the produced database rows and the runtime geometry behavior.

Recommended checks:

  • Compare generated geometry rows against the GEMC2 reference under geometry_source/<system> in gemc/clas12Tags.
  • Confirm names, mothers, descriptions, positions, rotations, solids, parameters, and materials match where the fields are shared.
  • Verify run and variation mappings are local to the system directory.
  • Use PyVista exports for quick placement checks before running full Geant4.
  • Run GEMC in batch and GUI modes when a detector has enough geometry to inspect.

For DC, the generated default geometry should token-match:

https://github.com/gemc/clas12Tags/blob/main/geometry_source/dc/dc__geometry_default.txt

Known DC expectations:

  • default run is 11
  • all DC volumes use g4placement_type = "passive"
  • ordered rotations are preserved as ordered: ...
  • obsolete original variation is not supported

CI And Releases

CI builds this repository against GEMC base images published by gemc/src. The workflow guide documents triggers, deployment authorization, cross-repository contracts, permissions, retries, and expected skipped runs.

Relevant automation:

Workflow Purpose
deploy.yml Build and test CLAS12 systems in GEMC base images, then publish the images
pr-docker-image.yml Build a per-PR preview image so reviewers can test the branch without a local build
sanitize.yml Run CLAS12-system sanitizer builds without sanitizing third-party subprojects
codeql.yml Static analysis
doxygen.yml Documentation generation
binary_tarballs.yml Package installed CLAS12 systems prefixes
dev_release.yml Development release automation

Deploy images use the pattern:

ghcr.io/gemc/clas12-systems:<gemc-tag>-<os>-<version>[-<arch>]

The base images come from:

ghcr.io/gemc/src

Each pull request additionally publishes a ready-to-run, multi-arch preview image built from the branch (ghcr.io/gemc/clas12-systems:<gemc-tag>-almalinux-<version>-pr-<number>), so authors and reviewers can test it without a local build — see Preview Container Image in the contributing guide. The image is deleted automatically when the pull request is closed.


Documentation

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages