Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ShipSoft/FairShip/llms.txt

Use this file to discover all available pages before exploring further.

FairShip’s physics configuration is spread across four layers: ROOT environment initialisation (shipRoot_conf.py), Pythia8 generator configuration (pythia8_conf.py), Geant4 process and tracking cuts (gconfig/SetCuts.C), and external decay table selection (gconfig/DecayConfig*.C). Each layer must be set up in order — shipRoot_conf.configure() must be called before any FairShip ROOT class is instantiated, Pythia8 configuration follows, and the Geant4 cut and decay macros are loaded automatically by FairRoot at simulation start. This page documents every function, parameter, and configuration knob in each layer.

python/shipRoot_conf.py — ROOT and FairRoot Environment Setup

This module bootstraps the ROOT/FairRoot environment for FairShip. It is loaded at import time and must be the first FairShip module imported in any steering script. The module-level code immediately checks for FAIRSHIP_ROOT; if the variable is absent the process prints a diagnostic and calls quit().
shipRoot_conf.py executes code at import time. Importing it in an environment where FAIRSHIP_ROOT is not set terminates the Python process. Always source the FairShip environment script before running steering jobs.

Module-level initialisation (import time)

When the module is imported the following steps run unconditionally:
  1. ROOT.gSystem.Load("libEGPythia6") — loads the EG Pythia6 interface
  2. ROOT.gSystem.Load("libPythia6") — loads the Pythia6 library
  3. ROOT.gSystem.Load("libpythia8") — loads the Pythia8 library
  4. If GENFIT_ROOT (or GENFIT) is set:
    • ROOT.gSystem.Load("libgenfit2")
    • ROOT.gInterpreter.AddIncludePath(genfit_root + "/include")
    • Declares the following GenFit2 headers via ROOT.gInterpreter.Declare: DAF.h, DetPlane.h, Exception.h, FieldManager.h, MaterialEffects.h, MeasuredStateOnPlane.h, RKTrackRep.h, SharedPlanePtr.h, StateOnPlane.h, TGeoMaterialInterface.h, Tools.h, Track.h, TrackPoint.h, WireMeasurement.h
GenFit 02-03-00 no longer ships .rootmap or unified PCM files, so ROOT’s autoloading cannot discover GenFit classes. The explicit gInterpreter.Declare block is the required workaround; removing it breaks track fitting at runtime.

configure(darkphoton=None) -> None

Completes the PDG database and loads the SHiP globals header. Call this once per process before constructing any FairShip detector or generator object.
import shipRoot_conf

# Standard HNL simulation
shipRoot_conf.configure()

# Dark-photon simulation
shipRoot_conf.configure(darkphoton=True)

# Skip BSM particle registration entirely (handled by pythia8_conf)
shipRoot_conf.configure(darkphoton=0)
darkphoton
bool | int | None
default:"None"
Controls which beyond-Standard-Model particle is registered in the ROOT PDG database:
ValueBehaviour
None (default)Calls addHNLtoROOT() — registers the HNL as N2 (PDG 9900015)
TrueCalls addDPtoROOT() — registers the dark photon
0Returns immediately; BSM particle registration is deferred to pythia8_conf

Registered non-standard particles

The following particles are registered in every call to configure(), regardless of the darkphoton flag:
NamePDG IDMass (GeV)Notes
system900.0Pythia8 internal system particle
Pomeron9900.0Pomeron for diffraction
p_diffr+99022100.0Diffractive proton
n_diffr099021100.0Diffractive neutron
NamePDG IDMass (GeV)Charge
C12 (Carbon-12)100006012012.06
C13 (Carbon-13)100006013013.0033556
These are intermediate states in the NRQCD factorisation framework used by Pythia8 for J/ψ and ψ(2S) production.
NamePDG IDMass (GeV)
J/psi[3PJ(8)]99420033.29692
J/psi[1S0(8)]99410033.29692
J/psi[3S1(8)]99400033.29692
f0(980)90102211.0
psi(3770)304433.77315
psi(3770)[3PJ(8)]99420333.97315
chi_0c[3S1(8)]99400113.61475
psi(2S)[1S0(8)]99411033.88611
psi(2S)[3S1(8)]99401033.88611
psi(2S)[3PJ(8)]99421033.88611
chi_1c[3S1(8)]99400233.71066
chi_2c[3S1(8)]99400053.75620
Upsilon[3S1(8)]99500039.66030

forReadingOldFile() -> None

Injects a C++ typedef into Cling so that pre-2018 ROOT files containing Double32_t branches can be read without type-resolution errors.
shipRoot_conf.forReadingOldFile()
Call this before opening any ROOT file produced by a FairShip version prior to approximately 2018. It is harmless to call even when reading new files.

python/pythia8_conf.py — Pythia8 Generator Configuration

This module provides functions that configure a HNLPythia8Generator (or compatible Pythia8 wrapper) for specific SHiP signal processes. All functions accept the generator object as their first argument and call P8gen.SetParameters(...) to set Pythia8 string parameters. When debug=True (the default), all method calls on the generator are mirrored to pythia8_conf.txt via MethodLogger.

configure() — HNL Generator

from pythia8_conf import configure

configure(
    P8gen,
    mass=1.0,
    production_couplings=[0.0, 1e-4, 0.0],
    decay_couplings=[0.0, 1e-4, 0.0],
    process_selection="c",
    deepCopy=False,
    debug=True,
)
Configures a HNLPythia8Generator instance for Heavy Neutral Lepton (HNL) production at SHiP. The HNL is assigned PDG ID 9900015 (N2). Its lifetime is computed from the supplied couplings using the hnl module and converted to a proper decay length for Pythia8.
P8gen
HNLPythia8Generator
required
The Pythia8 generator instance to configure. Must already be constructed (but not yet initialised) before this function is called.
mass
float
required
HNL mass in GeV.
production_couplings
list[float]
required
List of three mixing matrix elements [Ue2, Umu2, Utau2] used to compute branching ratios for production processes (charm/beauty decays to HNL).
decay_couplings
list[float]
required
List of three mixing matrix elements [Ue2, Umu2, Utau2] used to compute the HNL lifetime and decay channel branching ratios. May differ from production couplings in phenomenological scans.
process_selection
str | bool
default:"\"inclusive\""
Selects the hard process from which the HNL is produced.
ValueDescription
"inclusive" (or True)Full inelastic pp collision: SoftQCD:inelastic, PhotonCollision:gmgm2mumu, PromptPhoton:all, WeakBosonExchange:all
"c"Charm decays only (D+, D0, D_s+, Λ_c+) with secondary HNL production via D_s+ → τ+ → N
"b"Beauty decays only (B+, B0)
"bc"B_c meson decays
deepCopy
bool
default:"False"
When True, calls P8gen.UseDeepCopy() so that each generated event is deep-copied before storage. Required for some grid submission frameworks that share the generator object across threads.
debug
bool
default:"True"
When True, wraps P8gen in a MethodLogger and writes all SetParameters calls to pythia8_conf.txt in the working directory. Set to False for batch production to avoid the extra I/O.

Branching ratio scaling

For charm and beauty selections the function reads interpolated branching ratio tables from $FAIRSHIP/shipgen/branchingratios.dat and rescales all decay channels by 1 / max_total_BR so that the most probable production process has unit weight. The scale factor is printed to stdout via print_scale_factor.

configurerpvsusy() — RPV SUSY Neutralino Generator

from pythia8_conf import configurerpvsusy

configurerpvsusy(
    P8gen,
    mass=1.5,
    couplings=[0.0, 1e-3, 0.0],
    sfermionmass=1000.0,
    benchmark=1,
    inclusive="c",
    deepCopy=False,
    debug=True,
)
Configures Pythia8 for RPV SUSY neutralino (N2, PDG 9900015) production. The neutralino lifetime is computed by the rpvsusy module. Branching ratio tables are read from $FAIRSHIP/shipgen/branchingratiosrpvsusybench{benchmark}.dat.
mass
float
required
Neutralino mass in GeV.
couplings
list[float]
required
RPV coupling vector. Index 1 (couplings[1]) is the muon-sector coupling used for charm and beauty BR calculations.
sfermionmass
float
required
Sfermion mass in GeV, passed to the rpvsusy.RPVSUSY lifetime calculator.
benchmark
int
required
Benchmark scenario index. Selects the branching ratio data file via the filename pattern branchingratiosrpvsusybench{benchmark}.dat.
inclusive
str
default:"\"c\""
Production channel: "c" (charm), "b" (beauty), or "True" / True for fully inclusive production via setup_pythia_inclusive.

add_hnl() — HNL particle registration helper

from pythia8_conf import add_hnl

add_hnl(P8gen, mass=1.0, decay_couplings=[0.0, 1e-4, 0.0])
Adds the HNL particle entry to Pythia8 and to the ROOT PDG database. Reads decay channels from $FAIRSHIP/python/DecaySelection.conf. Calls P8gen.SetHNLId(9900015) to mark the signal particle.

setup_pythia_inclusive() — Inclusive production

from pythia8_conf import setup_pythia_inclusive

setup_pythia_inclusive(P8gen)
Enables the four Pythia8 process groups that together cover the full inelastic pp cross section relevant for SHiP:
SoftQCD:inelastic          = on
PhotonCollision:gmgm2mumu  = on
PromptPhoton:all           = on
WeakBosonExchange:all      = on

python/pythia8_conf_utils.py — Generator Utility Functions

Helper functions used internally by pythia8_conf.py. Import directly for low-level generator manipulation.

addHNLtoROOT(pid, m, g)

Registers a single particle entry in the ROOT PDG database.
pid
int
default:"9900015"
PDG ID to register. Default is the SHiP HNL ID.
m
float
default:"1.0"
Particle mass in GeV.
g
float
default:"3.654e-21"
Particle width in GeV (inverse lifetime × ℏ). Computed in pythia8_conf.py as u.hbarc / ctau.

make_particles_stable(P8gen, above_lifetime)

Iterates over all Pythia8 particle entries and sets mayDecay = false for any particle with τ₀ > above_lifetime. This forces long-lived particles (kaons, pions, hyperons) to be handed to Geant4 for decay rather than being decayed inside the generator.
above_lifetime
float
required
Lifetime threshold in Pythia8 natural units. Particles with τ₀ above this value are made stable in Pythia8.

python/global_variables.py — Global State

This module provides a namespace for global state that must be visible across multiple FairShip Python modules. It uses a __getattr__ stub so that attribute access on the module never raises AttributeError — any attribute that has not been set yet returns ... (Ellipsis) rather than raising an exception. This pattern allows conditional imports and deferred initialisation without guard logic scattered across steering scripts.
from typing import Any

def __getattr__(name: str) -> Any: ...
The __getattr__ fallback returns the Python Ellipsis object (...), not None. Code that tests global variables should check var is not ... rather than var is not None.

gconfig/SetCuts.C — Geant4 Process and Tracking Cuts

SetCuts.C is a ROOT macro loaded automatically by FairRoot at the start of each Geant4 simulation job. It calls gMC->SetProcess and gMC->SetCut to configure which electromagnetic and hadronic processes are active and what energy thresholds govern secondary particle production and tracking.

Enabled processes

All standard processes are enabled. The table below lists every SetProcess call and its physics meaning:
Process keyDescriptionSetting
PAIRPair production (γ → e⁺e⁻)1 (on)
COMPCompton scattering1 (on)
PHOTPhotoelectric effect1 (on)
PFISPhotofission0 (off)
DRAYDelta-ray (knock-on electron) production1 (on)
ANNIPositron annihilation1 (on)
BREMBremsstrahlung1 (on)
HADRHadronic interactions1 (on)
MUNUMuon nuclear interaction1 (on)
DCAYParticle decay1 (on)
LOSSContinuous energy loss1 (on)
MULSMultiple Coulomb scattering1 (on)
For a GEANE comparison study or a simulation without secondary particle generation, set LOSS=2, DRAY=0, BREM=1 and raise the bremsstrahlung and pair-production cuts (BCUTE, BCUTM, DCUTE, DCUTM, PPCUTM) to 10 TeV while keeping CUTGAMCUTMUO at 1 MeV or less.

Energy thresholds

Two threshold constants are defined:
Double_t cut1   = 1.0E-3;  // GeV  →  1 MeV
Double_t cutb   = 1.0E4;   // GeV  →  10 TeV  (not used in current SHiP cuts)
Double_t tofmax = 1.E10;   // seconds (time-of-flight cut)
Cut keyThresholdApplies to
CUTGAM1 MeVPhoton tracking threshold
CUTELE1 MeVElectron/positron tracking threshold
CUTNEU1 MeVNeutral hadron tracking threshold
CUTHAD1 MeVCharged hadron tracking threshold
CUTMUO1 MeVMuon tracking threshold
BCUTE1 MeVElectron bremsstrahlung production threshold
BCUTM1 MeVMuon/hadron bremsstrahlung production threshold
DCUTE1 MeVDelta-ray production by electrons
DCUTM1 MeVDelta-ray production by muons
PPCUTM1 MeVDirect pair production by muons
TOFMAX1 × 10¹⁰ sMaximum particle time of flight
The 1 MeV tracking threshold is appropriate for a full SHiP simulation that must correctly account for energy deposition in thin detectors (emulsion films, SciFi mats). Raising the thresholds to tens of MeV speeds up the simulation by roughly a factor of two but degrades resolution in the SND subsystem.

gconfig/DecayConfig*.C — External Decay Table Configuration

FairRoot selects a DecayConfig.C variant at runtime based on which generator backend is in use. Each variant installs an external decayer that intercepts particle decays for specific PDG IDs and handles them outside Geant4’s native decay mechanism.

Variant overview

The default no-op variant. Contains an empty DecayConfig() function body. Used when the simulation does not require any external decay handling (e.g. muon-only background studies where charm decay kinematics are irrelevant).
void DecayConfig() {
  // do nothing
}

gconfig/USERDECAY.DEC

An EvtGen user decay file present alongside the DecayConfig*.C macros. It is read by DecayConfigTEvtGen.C (via the EVTGENDATA path) when custom EvtGen decay tables are needed, for example to override J/ψ polarisation or add rare charmonium decay modes not present in the default DECAY.DEC.

Full Setup Sequence

1

Source the FairShip environment

source /path/to/FairShip/build/config.sh
# Sets FAIRSHIP, FAIRSHIP_ROOT, GENFIT_ROOT, EVTGENDATA, etc.
2

Import shipRoot_conf (bootstraps ROOT)

import shipRoot_conf
This loads libEGPythia6, libPythia6, libpythia8, and optionally libgenfit2 at import time.
3

Call configure() to register PDG particles

# For HNL studies (default)
shipRoot_conf.configure()

# For dark-photon studies
shipRoot_conf.configure(darkphoton=True)

# When pythia8_conf will register the BSM particle itself
shipRoot_conf.configure(darkphoton=0)
4

Build the geometry config

from geometry_config import create_config
ship_geo = create_config()
5

Configure the Pythia8 generator

from pythia8_conf import configure

configure(
    P8gen,
    mass=1.0,
    production_couplings=[0.0, 1e-4, 0.0],
    decay_couplings=[0.0, 1e-4, 0.0],
    process_selection="c",
)
6

Run the FairRoot simulation

FairRoot loads gconfig/SetCuts.C and the appropriate gconfig/DecayConfig*.C automatically at simulation start.

Quick Reference

import shipRoot_conf

# Must be called before any FairShip ROOT classes are used
shipRoot_conf.configure()

# For dark photon studies
shipRoot_conf.configure(darkphoton=True)

# For reading old (pre-2018) ROOT files
shipRoot_conf.forReadingOldFile()

Build docs developers (and LLMs) love