ROOT

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

See also