.. _root: ==== ROOT ==== .. contents:: In this section: :local: :depth: 2 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 ================== .. code-block:: bash # Load ROOT module load root/6.10.02 # Verify installation root --version which root Job Submission ============== .. code-block:: bash :caption: 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++) ========================= .. code-block:: cpp :caption: analysis.cpp #include #include #include #include #include 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) ================================ .. code-block:: bash :caption: 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 .. code-block:: python :caption: 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 ================ .. code-block:: bash :caption: 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 ========================= .. code-block:: bash :caption: 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 =================== .. code-block:: bash :caption: 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 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/ .. seealso:: - :ref:`installation_via_conda` - Installing Python packages - :ref:`R` - Statistical analysis - :ref:`running_simulations` - How to submit jobs