ROOT
In this section:
Description
According to the page of ROOT, ROOT is a data processing framework born at CERN, at the heart of high-energy physics research. Thousands of physicists use ROOT applications daily to analyze data or perform simulations.
Available Versions
root/6.10.02 (default)
Loading the Module
# Load ROOT
module load root/6.10.02
# Verify installation
root --version
which root
Job Submission
submit_root.sh
#!/bin/bash
#SBATCH -J root_job
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 24:00:00
#SBATCH --mem=8G
export INPUT="analysis.cpp"
export OUTPUT="analysis.root"
module load root/6.10.02
job-nanny root -b -l -q analysis.cpp
ROOT Script Example (C++)
analysis.cpp
#include <TFile.h>
#include <TTree.h>
#include <TH1F.h>
#include <TCanvas.h>
#include <iostream>
void analysis() {
// Open data file
TFile *input = TFile::Open("data.root");
TTree *tree = (TTree*)input->Get("tree");
// Create histograms
TH1F *h_x = new TH1F("h_x", "X distribution", 100, -5, 5);
TH1F *h_y = new TH1F("h_y", "Y distribution", 100, -5, 5);
// Variables for reading
float x, y;
tree->SetBranchAddress("x", &x);
tree->SetBranchAddress("y", &y);
// Loop over events
Long64_t nentries = tree->GetEntries();
for (Long64_t i = 0; i < nentries; i++) {
tree->GetEntry(i);
h_x->Fill(x);
h_y->Fill(y);
if (i % 100000 == 0) {
std::cout << "Processed " << i << " events" << std::endl;
}
}
// Statistics
std::cout << "Mean of x: " << h_x->GetMean() << std::endl;
std::cout << "RMS of x: " << h_x->GetRMS() << std::endl;
std::cout << "Mean of y: " << h_y->GetMean() << std::endl;
std::cout << "RMS of y: " << h_y->GetRMS() << std::endl;
// Save results
TFile *output = TFile::Open("results.root", "RECREATE");
h_x->Write();
h_y->Write();
output->Close();
# Plot
TCanvas *c1 = new TCanvas("c1", "Histograms", 800, 400);
c1->Divide(2,1);
c1->cd(1);
h_x->Draw();
c1->cd(2);
h_y->Draw();
c1->SaveAs("histograms.png");
input->Close();
}
ROOT Script with Python (PyROOT)
submit_pyroot.sh
#!/bin/bash
#SBATCH -J pyroot
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 12:00:00
#SBATCH --mem=8G
export INPUT="analysis.py"
export OUTPUT="pyroot_results.root"
module load root/6.10.02
job-nanny python analysis.py
analysis.py
import ROOT
import numpy as np
# Generate data
data = np.random.normal(0, 1, 1000000)
# Create ROOT histogram
hist = ROOT.TH1F("hist", "Normal Distribution", 100, -5, 5)
for value in data:
hist.Fill(value)
# Statistics
print(f"Mean: {hist.GetMean()}")
print(f"RMS: {hist.GetMean()}")
print(f"Entries: {hist.GetEntries()}")
# Gaussian fit
fit = ROOT.TF1("fit", "gaus", -5, 5)
hist.Fit(fit, "Q")
print(f"Fit parameters:")
print(f" Constant: {fit.GetParameter(0)}")
print(f" Mean: {fit.GetParameter(1)}")
print(f" Sigma: {fit.GetParameter(2)}")
# Save
output = ROOT.TFile("pyroot_results.root", "RECREATE")
hist.Write()
output.Close()
Batch Processing
submit_root_batch.sh
#!/bin/bash
#SBATCH -J root_batch
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 48:00:00
#SBATCH --mem=16G
export INPUT="files.txt"
export OUTPUT="merged_results.root"
module load root/6.10.02
# Create script to process multiple files
cat > batch_process.C << 'EOF'
void batch_process() {
// List of files
ifstream file_list("files.txt");
string filename;
TChain chain("tree");
while (file_list >> filename) {
cout << "Adding: " << filename << endl;
chain.Add(filename.c_str());
}
# Process chain
TH1F *h = new TH1F("h", "Distribution", 100, -5, 5);
chain.Draw("x>>h");
# Save
TFile *output = TFile::Open("merged_results.root", "RECREATE");
h->Write();
output->Close();
}
EOF
job-nanny root -b -l -q batch_process.C
Job Array for Simulations
submit_root_array.sh
#!/bin/bash
#SBATCH -J root_array
#SBATCH --array=1-10
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 24:00:00
#SBATCH --mem=8G
SEED=$((12345 + SLURM_ARRAY_TASK_ID))
export INPUT="simulation.C"
export OUTPUT="sim_${SLURM_ARRAY_TASK_ID}.root"
module load root/6.10.02
cat > sim_${SLURM_ARRAY_TASK_ID}.C << EOF
void sim_${SLURM_ARRAY_TASK_ID}() {
gRandom->SetSeed($SEED);
# Simulation
TH1F *h = new TH1F("h", "Simulation", 100, -5, 5);
for (int i = 0; i < 1000000; i++) {
h->Fill(gRandom->Gaus(0, 1));
}
# Save
TFile *f = TFile::Open("sim_${SLURM_ARRAY_TASK_ID}.root", "RECREATE");
h->Write();
f->Close();
cout << "Simulation ${SLURM_ARRAY_TASK_ID} completed" << endl;
}
EOF
job-nanny root -b -l -q sim_${SLURM_ARRAY_TASK_ID}.C
RDataFrame Analysis
submit_rdf.sh
#!/bin/bash
#SBATCH -J rdf
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -t 12:00:00
#SBATCH --mem=8G
export INPUT="rdf_analysis.C"
export OUTPUT="rdf_results.root"
module load root/6.10.02
cat > rdf_analysis.C << 'EOF'
#include <ROOT/RDataFrame.hxx>
void rdf_analysis() {
// Create dataframe from files
ROOT::RDataFrame df("tree", "data_*.root");
# Define filters and operations
auto df_filtered = df.Filter("x > 0 && y < 10");
# Calculate means
auto x_mean = df_filtered.Mean("x");
auto y_mean = df_filtered.Mean("y");
# Create histograms
auto hx = df_filtered.Histo1D({"hx", "X distribution", 100, 0, 10}, "x");
auto hy = df_filtered.Histo1D({"hy", "Y distribution", 100, 0, 10}, "y");
# Results
std::cout << "Mean of x: " << *x_mean << std::endl;
std::cout << "Mean of y: " << *y_mean << std::endl;
# Save
TFile *f = TFile::Open("rdf_results.root", "RECREATE");
hx->Write();
hy->Write();
f->Close();
}
EOF
job-nanny root -b -l -q rdf_analysis.C
References
Documentation: https://root.cern/doc/master/
Tutorial: https://root.cern/guides/primer
Forum: https://root-forum.cern.ch/
See also
Installation via Conda - Installing Python packages
R - Statistical analysis
Running Simulations - How to submit jobs