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.
macro/ShipAna.py is the standard post-reconstruction analysis script for FairShip. It opens both the MC simulation file and the matching reconstruction file, joins them via ROOT friend trees, and loops over events to fill histograms characterising track quality, vertex resolution, momentum pulls, and HNL candidate kinematics. A complementary, higher-level interface is provided by the experimental analysis_toolkit module demonstrated in examples/analysis_example.py. This page documents both paths — the low-level ShipAna.py approach and the toolkit approach — so you can choose the one that best fits your workflow.
Running ShipAna
Command-line reference
Path to the MC simulation ROOT file containing the
cbmsim tree. Accepts a
comma-separated list of files, which are opened as a TChain.Path to the geometry ROOT file. Used to initialise detector modules, the magnetic
field map, and GenFit material effects — all needed for track extrapolation.
Path to the reconstruction file (
*_rec.root). If omitted, ShipAna.py
automatically derives the name by replacing .root with _rec.root in the input
filename. Accepts a comma-separated list of files when -f is also a list.Maximum number of events to analyse. The actual count is
min(sTree.GetEntries(), nEvents).Enable verbose per-event debug printing.
Usage examples
Friend-tree setup inside ShipAna
ShipAna.py establishes the MC ↔ reco connection in the file-opening block. For a single file:
AddFriend, every branch in ship_reco_sim is accessible directly on sTree. The event loop then calls sTree.GetEntry(n) once per event and all branches — MC and reco — are loaded together.
The cbmsim tree structure
ShipAna.py reads the following branches from the combined cbmsim + ship_reco_sim view:
| Branch | Source tree | Description |
|---|---|---|
MCTrack | cbmsim | Monte Carlo particle list; index 0 is the primary, index 1+ are daughters |
strawtubesPoint | cbmsim | True MC hit points in the straw spectrometer |
ShipEventHeader | ship_reco_sim | Run/event metadata including event time |
FitTracks | ship_reco_sim | genfit::Track* fitted track objects |
fitTrack2MC | ship_reco_sim | Integer vector: reco track index → MC track index |
Particles | ship_reco_sim | ShipParticle decay-vertex candidates |
Tracklets | ship_reco_sim | Short track segments used during fitting |
_PR variant (from an earlier workflow), ShipAna automatically redirects:
Quality cuts
Four module-level constants inShipAna.py control which tracks and vertices are accepted:
| Variable | Default | Meaning |
|---|---|---|
chi2CutOff | 4.0 | Maximum χ²/NDF for a track to enter momentum-resolution histograms |
fiducialCut | False | If True, require decay vertex inside the fiducial decay volume |
measCutFK | 25 | Minimum number of GenFit measurement degrees of freedom (full Kalman) |
measCutPR | 22 | Minimum NDF when using the _PR pattern-recognition tracks |
docaCut | 2.0 | Maximum DOCA (cm) between the two tracks of a vertex candidate |
measCut is set to measCutFK by default and switched to measCutPR automatically if the FitTracks_PR branch is found. The track loop only enters the chi2 and IP histograms for tracks that pass the NDF cut; only vertices with doca < docaCut enter the HNL mass histogram.
Histograms produced
ShipAna.py books and fills the following histogram families:
- Momentum resolution
- Track quality
- Vertex & HNL
- Veto / timing
| Key | Description |
|---|---|
delPOverP | (p_truth − p_reco) / p_truth vs p_truth |
delPOverPz | (1/pz_truth − 1/pz_reco) × pz_truth vs pz_truth |
delPOverP2 | Same as delPOverP but only for χ²/NDF < chi2CutOff |
pullPOverPx/y/z | Momentum pulls per component vs p_truth |
Output files
At the end of the event loop,makePlots() renders canvas plots and ut.writeHists() writes all histograms. The output filename is derived from the input:
/eos/ or is a comma-separated list, the file is written to the current working directory instead of alongside the input.
The experimental analysis_toolkit
python/experimental/analysis_toolkit.py provides a higher-level object-oriented interface for signal selection studies. It is demonstrated in examples/analysis_example.py.
Opening files and adding the friend tree
selection_check
analysis_toolkit.selection_check(geo_file) initialises geometry-aware selection helpers from the geo ROOT file. It loads FAIRGeom and the ShipGeo dictionary, reads the veto geometry YAML for the configured decay-volume medium (helium or vacuum), and provides the following methods on each ShipParticle candidate:
| Method | Returns | Description |
|---|---|---|
access_event(tree) | None | Must be called once per event before any per-candidate methods |
define_candidate_time(candidate) | float (ns) | Reconstructs decay-vertex time from straw MC hits and propagation speed |
impact_parameter(candidate) | float (cm) | IP of candidate 4-momentum relative to (0, 0, target.z0) |
dist_to_innerwall(candidate) | float (cm) | Distance from vertex to inner wall of decay vessel |
dist_to_vesselentrance(candidate) | float (cm) | Distance from vertex to upstream entrance of decay vessel |
DOCA(candidate) | float (cm) | Distance of closest approach between the two daughter tracks |
invariant_mass(candidate) | float (GeV) | Di-track invariant mass |
daughtermomentum(candidate) | (float, float) (GeV) | Momenta of daughter 1 and daughter 2 |
nDOF(candidate) | (int, int) | NDF of daughter track fits |
chi2nDOF(candidate) | (float, float) | χ²/NDF of daughter track fits |
preselection_cut(candidate, IP_cut, show_table) | bool | Combined pre-selection flag |
event_inspector
analysis_toolkit.event_inspector() provides a lightweight event-dumping utility: