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.

rootUtils is the standard histogram management library used across FairShip analysis scripts. It abstracts the boilerplate of creating, accumulating, and persisting ROOT histograms behind a simple dictionary-keyed interface: histograms are stored in plain Python dicts keyed by any hashable value (string or integer), so scripts never need to manage ROOT name registration manually. The module also provides file-validation utilities, an error-count accumulator, and EOS-aware file opening for CERN infrastructure.
import rootUtils as ut
import ROOT

# Book histograms into a dict
h = {}
ut.bookHist(h, "px",  "Track p_x; p_{x} [GeV]",       nbinsx=200, xmin=-5, xmax=5)
ut.bookHist(h, "pxy", "Track p_{xy}; p_x; p_y",
            nbinsx=200, xmin=-5, xmax=5,
            nbinsy=200, ymin=-5, ymax=5)
ut.bookCanvas(h, "c1", "Analysis canvas", nx=1200, ny=600, cx=2, cy=1)

# Fill from an event loop
for event in tree:
    h["px"].Fill(event.px)

# Read histograms from an existing file
ut.readHists(h, "recohists.root")

# Write to a new file
ut.writeHists(h, "output.root")

readHists

readHists(h, fname, wanted=None) -> None
Read all (or a selected subset of) histograms from a ROOT file into a dictionary. Keys in the dictionary are the histogram names as stored in the file; integer-parseable names are stored as int keys. For every TH2D or TH2F histogram loaded, readHists automatically creates _projx and _projy projection companions. If a histogram with the same key already exists in h, the newly read histogram is added to it via TH1::Add, enabling straightforward accumulation across multiple files. All histograms are detached from their source file (SetDirectory(ROOT.gROOT)) so they persist after the file is closed.
h
dict
required
Destination dictionary. Histograms are inserted or accumulated here. The dict is modified in place.
fname
str
required
Path to the ROOT file. Paths beginning with /eos are opened via the CERN EOS gateway: the prefix $EOSSHIP (an environment variable) is prepended to the path before opening.
wanted
list | None
default:"None"
Optional filter list. When non-empty, only keys present in wanted are loaded into h. Both string and integer keys are matched. Defaults to None (load everything).
import rootUtils as ut

h = {}

# Load all histograms
ut.readHists(h, "recohists.root")
print(list(h.keys()))

# Load a subset (mixed int and string keys are fine)
ut.readHists(h, "recohists.root", wanted=["nTracks", "chi2", 42])

# Load from EOS (requires $EOSSHIP env var)
ut.readHists(h, "/eos/ship/data/recohists.root")

# For TH2D 'xy', projections are created automatically
assert "xy_projx" in h
assert "xy_projy" in h

# Accumulate across files — histograms are added if key exists
ut.readHists(h, "recohists_run2.root")

bookHist

bookHist(
    h,
    key=None,
    title: str = "",
    nbinsx: int = 100,
    xmin: float = 0,
    xmax: float = 1,
    nbinsy: int = 0,
    ymin: float = 0,
    ymax: float = 1,
    nbinsz: int = 0,
    zmin: float = 0,
    zmax: float = 1,
) -> None
Create a ROOT histogram of the appropriate dimensionality (1-D, 2-D, or 3-D) and register it in the dictionary h under key. The dimensionality is determined automatically from the values of nbinsy and nbinsz:
  • nbinsz > 0TH3D
  • nbinsy > 0TH2D
  • otherwise → TH1D
If key already exists in h, the existing histogram is reset rather than replaced, preserving its pointer identity.
h
dict
required
Histogram registry dictionary. The new histogram is stored as h[key].
key
str | int | None
default:"None"
Dictionary key and ROOT histogram name. Integer or float keys are coerced to strings for the ROOT name. If None, a warning is printed and the function returns without creating anything.
title
str
default:"\"\""
ROOT histogram title string, supporting the "title;x-axis;y-axis" semicolon-separated convention.
nbinsx
int
default:"100"
Number of bins along the x-axis.
xmin
float
default:"0"
Lower edge of the x-axis range.
xmax
float
default:"1"
Upper edge of the x-axis range.
nbinsy
int
default:"0"
Number of bins along the y-axis. A value greater than 0 promotes the histogram to TH2D. Defaults to 0 (1-D histogram).
ymin
float
default:"0"
Lower edge of the y-axis range (only used when nbinsy > 0).
ymax
float
default:"1"
Upper edge of the y-axis range (only used when nbinsy > 0).
nbinsz
int
default:"0"
Number of bins along the z-axis. A value greater than 0 promotes the histogram to TH3D. Defaults to 0.
zmin
float
default:"0"
Lower edge of the z-axis range (only used when nbinsz > 0).
zmax
float
default:"1"
Upper edge of the z-axis range (only used when nbinsz > 0).
import rootUtils as ut

h = {}
# 1-D momentum histogram
ut.bookHist(h, "p", "Reconstructed momentum; p [GeV]", nbinsx=200, xmin=0, xmax=300)

# 2-D vertex position
ut.bookHist(h, "vtx_xy", "Vertex XY; x [cm]; y [cm]",
            nbinsx=100, xmin=-200, xmax=200,
            nbinsy=100, ymin=-200, ymax=200)

# 3-D phase space
ut.bookHist(h, "pxyz", "Momentum components",
            nbinsx=50, xmin=-5, xmax=5,
            nbinsy=50, ymin=-5, ymax=5,
            nbinsz=50, zmin=0,  zmax=300)

bookProf

bookProf(
    h,
    key=None,
    title: str = "",
    nbinsx: int = 100,
    xmin: float = 0,
    xmax: float = 1,
    ymin: float | None = None,
    ymax: float | None = None,
    option: str = "",
) -> None
Create a ROOT TProfile and register it in h under key. If ymin and ymax are both provided they are passed to the TProfile constructor to restrict the y-range; otherwise the profile uses the full y-range.
h
dict
required
Histogram registry dictionary.
key
str | int | None
default:"None"
Dictionary key and ROOT histogram name.
title
str
default:"\"\""
ROOT histogram title string.
nbinsx
int
default:"100"
Number of x bins.
xmin
float
default:"0"
Lower x-axis limit.
xmax
float
default:"1"
Upper x-axis limit.
ymin
float | None
default:"None"
Optional lower y-range restriction passed to TProfile.
ymax
float | None
default:"None"
Optional upper y-range restriction passed to TProfile.
option
str
default:"\"\""
Option string forwarded to the TProfile constructor (e.g. "s" to store the spread).

writeHists

writeHists(h, fname, plusCanvas: bool = False) -> None
Write all TH* and TP* histograms (and optionally TCanvas objects) from the dictionary h to a ROOT file in RECREATE mode.
h
dict
required
Dictionary of histograms to write. Objects without a ROOT Class method are silently skipped.
fname
str
required
Destination ROOT file path. The file is created or overwritten (RECREATE).
plusCanvas
bool
default:"False"
When True, TCanvas objects in h (class name containing "TC") are also written to the file in addition to histograms.

bookCanvas

bookCanvas(h, key=None, title: str = "", nx: int = 900, ny: int = 600, cx: int = 1, cy: int = 1) -> None
Create a TCanvas, divide it into a cx × cy grid of pads, and register it in h under key. If key already exists in h the call is a no-op.
h
dict
required
Dictionary to store the canvas.
key
str | None
default:"None"
Dictionary key and ROOT canvas name. If None, a warning is printed.
title
str
default:"\"\""
Canvas window title.
nx
int
default:"900"
Canvas width in pixels.
ny
int
default:"600"
Canvas height in pixels.
cx
int
default:"1"
Number of pad columns.
cy
int
default:"1"
Number of pad rows.

Error logging

rootUtils maintains a module-level Counter (_error_log) to accumulate non-fatal error messages. Use reportError to record incidents and errorSummary to print a summary at the end of a job.

reportError

reportError(s) -> None
Increment the count for error string s in the module-level error log.
s
str
required
Error message string to record. Repeated calls with the same string increment a counter rather than generating duplicate output.

errorSummary

errorSummary() -> None
Print a summary of all recorded errors and their occurrence counts to stdout. Prints nothing if no errors were recorded.
import rootUtils as ut

# In an event loop:
for event in tree:
    if not event.FitTracks:
        ut.reportError("missing FitTracks")

# At the end of the script:
ut.errorSummary()
# Summary of recorded incidents:
# missing FitTracks : 42

File validation helpers

checkFileExists

checkFileExists(x) -> str
Verify that one or more ROOT files exist and determine whether they contain a cbmsim tree or ntuple data. Exits the process via sys.exit(1) if any file cannot be opened.
x
str | list[str]
required
A single file path or a list of file paths. EOS paths beginning with /eos are opened via $EOSSHIP. All files in a list must be of the same type.
return
str
"tree" if the file(s) contain a cbmsim tree, or "ntuple" otherwise.

checkForBranch

checkForBranch(inFile, branchName) -> bool
Check whether a named branch exists in the cbmsim tree of one or more ROOT files. Raises FileNotFoundError if a file cannot be opened and ValueError if files in a list disagree on branch presence.
inFile
str | list[str]
required
A single file path or a list of file paths to inspect.
branchName
str
required
The branch name to look for inside the cbmsim tree.
return
bool
True if the branch is present in all supplied files, False if absent from all files.
import rootUtils as ut

file_type = ut.checkFileExists("ship.conical.Pythia8-TGeant4.root")
print(file_type)  # 'tree'

has_branch = ut.checkForBranch("ship.conical.Pythia8-TGeant4_rec.root", "Particles")
print(has_branch)  # True or False

Build docs developers (and LLMs) love