2025-stereograph
This repository contains pre-trained models, computed results, and analysis code for evaluating machine learning approaches (Random Forests, FCNs, and GNNs) on gamma-ray event reconstruction tasks.
Cite this software
Description
Stereograph Results 2026
Application of Graph Neural Networks (GNNs) to CTAO stereoscopic event reconstruction.
This repository contains pre-trained models, computed results, and analysis code for evaluating machine learning approaches (Random Forests, FCNs, and GNNs) on gamma-ray event reconstruction tasks as supplementary material of H. Ali Messaoud et al 2026.
The figures of the paper are reproduced (see below) and available online here : https://2025-stereograph-9fa6dd.pages.in2p3.fr/
Installation
Requirements
- Python 3.8+
- uv package manager
Setup
Install dependencies using uv:
uv sync
This will create a virtual environment and install all dependencies specified in uv.lock, including gammapy, ctapipe, and jupyterlab.
To activate the environment:
source .venv/bin/activate
Project Contents
Configurations (configs/)
YAML configuration files for model training:
config_class.yml- Classification model configurationconfig_dir.yml- Direction reconstruction configurationconfig_energy.yml- Energy reconstruction configuration
These files specify hyperparameters, loss functions, and training settings for each task.
Trained Models (models/)
Pre-trained models for three tasks:
class/- Gamma-ray vs cosmic-ray classification modeldirection/- Angular direction reconstruction modelenergy/- Energy reconstruction model
Each directory contains best-checkpoint.ckpt (checkpoint) and model.pth (PyTorch model weights).
Results (results/)
Computed performance metrics stored as FITS files:
RF/- Random Forest benchmark resultsFC/- Fully Connected Neural Network resultsGNN/- Graph Neural Network results
About the results: Performance metrics (angular resolution, energy resolution, sensitivity) have been computed using ctapipe-compute-irf from the ctapipe framework. The FITS files contain the computed Instrument Response Functions (IRFs) with energy-dependent performance metrics.
Scripts (scripts/)
Analysis and processing scripts:
analysis.sh- Data analysis pipelinegraphs.sh- Visualization and plottinginference.sh- Model inference on test datajob.submit- job submission for HTCondor
Usage
Viewing Results
The notebooks/irfs.ipynb Jupyter notebook provides code to visualize the obtained results:
uv run jupyter lab notebooks/irfs.ipynb
The notebook displays:
- Angular resolution vs. energy
- Energy resolution and bias
- Sensitivity curves
- Comparative performance metrics across methods (RF vs FCN vs GNN)
Running Inference
To apply the trained models to new data:
bash scripts/inference.sh
Continuous Integration in this repo
Results are automatically generated and published to GitLab Pages on each push to main. The notebook is executed in the CI environment via .gitlab-ci.yml.
Analyses included
This repository includes two types of analyses:
-
Fully Connected Neural Network approach
https://gitlab.in2p3.fr/gammalearn/stereograph/fully-connected-net -
Graph Neural Network approach
https://gitlab.in2p3.fr/gammalearn/stereograph/stereograph
Data
The data used in this study come from the Prod5b_lapalma_alpha_zen020az180nsb01x_v0.19.3 simulation dataset.
However, the full analysis can also be reproduced using public CTAO data, which are available on Zenodo:
https://zenodo.org/records/7298569
Stereograph Tutorial : How to run an experiment on HTCondor
This document is a step-by-step tutorial explaining how to use Stereograph to create, train, and analyze experiments using a containerized environment. It is intended as a practical guide for new users.
1. Creating an Experiment Directory
Each experiment should be organized in its own directory.
cd /lapp_data/cta/stereograph/experiments
mkdir exp_251204_001
cd exp_251204_001
This directory will contain configuration files, job scripts, and output results.
2. Container Setup
Pulling the Stereograph Image
First, retrieve the Stereograph image from the container registry: If you're using prod 5 data
apptainer pull docker://gitlab-registry.in2p3.fr/gammalearn/stereograph/stereograph:main_ctapipe_v0.19.0
if prod6 :
apptainer pull docker://gitlab-registry.in2p3.fr/gammalearn/stereograph/stereograph:main_ctapipe_v0.24.0
3. Set up configuration file
Example :
exp_name: test_energy
output_dir: 'tests'
scaling:
scaler_path: scaler.pkl
network:
model: EnergyRegressor #GNNClassifier,EnergyRegressor,DirectionRegressor
task_type: energy
batch_size: 12
dropout_rate: 0.1
epochs: 3
hidden_dim: 512
learning_rate: 0.001
seed: 42
num_layers: 5
patience: 4
factor: 0.5
lr_patience: 10
weight_decay: 0
data:
input_features:
- hillas_intensity
- hillas_r
- hillas_length
- hillas_width
- hillas_skewness
- hillas_kurtosis
- timing_slope
- timing_deviation
- leakage_intensity_width_1
- leakage_intensity_width_2
- leakage_pixels_width_1
- leakage_pixels_width_2
- concentration_cog
- concentration_core
- morphology_n_islands
- morphology_n_large_islands
- morphology_n_medium_islands
- morphology_n_pixels
- morphology_n_small_islands
# - HillasReconstructor_tel_impact_distance
# - HillasReconstructor_average_intensity
#- HillasReconstructor_h_max
- peak_time_std
- peak_time_skewness
- peak_time_kurtosis
- intensity_max
- intensity_mean
- intensity_std
- intensity_skewness
- intensity_kurtosis
- type
- tel_id
- area
tel_ids:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 19
- 35
min_tel: 1
train_ratio: 0.7
val_ratio: 0.2
test_ratio: 0.1
max_events: 200000 #to train on all events set to null
- Telescopes 1–4 correspond to LSTs.
- The remaining telescopes are MSTs.
- It is possible to select only a subset of telescopes.
- The number of events can also be limited by setting a desired value for max_events.
- If you want to use the whole dataset set max_events to null
4. Update job.sh
Update your job.sh with the commands appropriate for your task. Below is an example :
#!/bin/bash
# Run the experiment in the container
# Parameters:
# --nv to use nvidia gpus from inside the container
# CUDA_VISIBLE_DEVICES env variable used by pytorch to discover the gpus
# NUMBA_CACHE_DIR a writable directory where numba can store its compiled functions
# (needs to be outside of the container, which is read-only)
# CTAPIPE_CACHE ctapipe needs a writable place, to store its downloaded files.
# Mounts: input (data and settings file) and output directories
#
# We call the stereograph entrypoint directly in /opt/conda/bin, because micromamba is not initialized
# inside the container for a new user (and every user is new, since with apptainer the user remains the same
# as the user on the host system by default (only users defined in the containers are known))
apptainer run \
--nv \
--env "CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES" \
--env "NUMBA_CACHE_DIR=/tmp/NUMBA" \
--env "CTAPIPE_CACHE=/tmp/CTAPIPE" \
--mount type=bind,source=/path/to/input/data_dir/,destination=/corresponding/path/in/container/ \
$CONTAINER \
# Example sequence of commands for Stereograph
# 1. Produce graph files
/opt/stereograph/scripts/script_produce_graphs.py \
--filename $GAMMA_TRAIN \
--config_file $CONFIG_FILE \
--output $GAMMA_GRAPHS \
--disable_scaler && \
# 2. Train the model
/opt/stereograph/scripts/train.py \
$TRAIN_FILE \
--config_file $CONFIG_FILE \
--gamma_file $GAMMA_GRAPHS \
--overwrite && \
# 3. Run inference
/opt/stereograph/scripts/inference.py \
--config_file $CONFIG_FILE \
--ckpt results/exp_name/best-checkpoint.ckpt \
--gamma_test $GAMMA_TEST_GRAPHS \
--overwrite && \
# 4. Plot IRFs
/opt/stereograph/scripts/script_plot_performances.py \
-f results/exp_name/dl2_energy_test.h5 \
-o results/energy.png \
--overwrite \
-d
- Replace
$CONFIG_FILE,$TRAIN_FILE,$CONTAINER..etc with your specific file paths. - For classification tasks, ensure both gamma and proton graph files are provided.
5. Update job.submit
Universe = vanilla
Executable = job.sh
getenv = True
output = job_output.$(Cluster).$(Process).txt
error = job_error.$(Cluster).$(Process).txt
log = job_log.$(Cluster).txt
notification = complete
environment = "NCCL_P2P_DISABLE=1"
notify_user = user@lapp.in2p3.fr
# Request GPUs (optional)
# request_GPUs = 1
# +WantGpuType = "v100"
# CPU and memory resources
request_cpus = 8
request_memory = 128GB
queue 1
6. IRFs and Experiment Monitoring
6.1 Wandb logging
Experiments can be monitored using Weights & Biases (wandb). To enable wandb logging:
Add your wandb API key to your .bashrc:
export WANDB_API_KEY=<your_api_key>
make sure to set getenv=True to the job.submit file so that environment variables are correctly passed.
6.2 IRFS
Instrument Response Functions (IRFs) can be plotted using pyirfs. An optimized version by applying selection cuts, for example on gamaness and the origin direction can be computed using the scripts provided by ctapipe : see IRF tool
Stereograph outputs results in HDF5 (.h5) files containing data frames. However, ctapipe scripts require data to follow the expected DL2 format. To ensure compatibility, use the write_dl2 function from stereograph.data to write Stereograph results back into the original HDF5 files. This guarantees that the output can be processed correctly by ctapipe tools.
CONTRIBUTING
Thank you for your interest in contributing to Stereograph! All contributions are welcome If you find an issue, please use the issue tracker of this repository, or contact the authors directly via email. See CONTRIBUTING.md and read our code of conduct.
License
This project is licensed under the MIT License - see LICENSE for details.