Abstract

We discuss the CERN's ROOT library as a histogramming tool for PSANA project.

Objectives

In PSANA framework we need in package which allows to accumulate data in form of histograms and tuples and save them in file for further analysis. An official package which performs this job is PSHist. PSHist provides an abstract interface to the selected set of methods. Actual implementation of these methods is provided in the RootHist package, which is based on CERN's ROOT library. In case if user would need in full brute force of ROOT, we could suggest to use it directly. In this note we present only the basic interface, equivalent to the PSHist, which allows to accumulate data save the file and browse this file interactively in ROOT. Complete documentation for ROOT library can be found here.

Data accumulation interface in ROOT

Root class headers

To accumulate statistics using ROOT in a standalone application one have to add headers

// ROOT Class Headers
#include "root/TFile.h"
#include "root/TH1D.h"
#include "root/TH2D.h"
#include "root/TTree.h"
#include "root/TBranch.h"
#include "root/TRandom.h" // For random number generators.

Histograms

A minimal interface for accumulation of histograms in ROOT is shown below.

// Open output file
TFile* pfile = new TFile("file.root", "RECREATE", "Created for you by RootManager" );

// Create histograms
TH1D *pHis1 = new TH1D("pHis1","My comment to TH1D", 100, 0.5, 100.5);
TH2D *pHis2 = new TH2D("pHis2","My comment to TH1D", 100, 0.5, 100.5,
                                                     200, 0.5, 200.5);
// Fill histograms in each event
pHis1 -> Fill( value, [weight] );
pHis2 -> Fill( x, y, [weight] );

// Write histograms in file in the very end
pHis1 -> Write();
pHis2 -> Write();

// Close file
pfile -> Close();

This interface allows to

  • open file file.root in mode RECREATE.
  • create 1d histogram with name pHis1, title "My comment to TH1D", with 100 bins in the range from 0.5 to 100.5; histogram is addressed by their pointer *pHis1.
  • create 2d histogram, which is very similar to 1d, but, in addition, defines a second axis with 200 bins in the range from 0.5 to 200.5.
  • fill histograms in each event; we assume that parameters value, x, y, and optional weight are defined.
  • save histogram(s) in file by the command like pHis1 -> Write(); at the end of job.
  • and close file with accumulated histograms.

NTuple

Assuming that file is already open,

// Define some structures for TTree
typedef struct {float x,y,z;} POINT;
static POINT point;
float new_v;

// Create TTree
TTree *ptree = new TTree("ptree", "My comment to TTree");

// Create branch(es)
TBranch *pbranch = ptree->Branch("new_v", &new_v, "new_v/F");
// or create branch without pointer
                   ptree->Branch("point",&point,"x:y:z");

// Fill data structures for each event
      new_v   = gRandom->Gaus(0, 1);
      point.x = gRandom->Gaus(1, 1);
      point.y = gRandom->Gaus(2, 1);
      point.z = gRandom->Gaus(3, 1);

// Add an event record to the tree
      ptree->Fill();

// Write the tree in the file
ptree -> Write();

These commands allow to

  • create the "Tree" object with name ptree, title "My comment to TTree", and pointer *ptree.
  • create the "Branch" object, representing a single variable of data structure, with name new_v, address of the data structure &new_v, and the variable name/type new_v/F.
  • fill variables for each event, using commands like new_v = gRandom->Gaus(0, 1);.
  • save all the parameters in the Tree using command ptree->Fill();.
  • save the Tree in ROOT file by the command ptree -> Write();.

Code examples

Accumulation of data and saving in ROOT file

//-----------------
// C/C++ Headers --
//-----------------
#include <iostream>

using std::cout;
using std::endl;

//----------------------
// Root Class Headers --
//----------------------

#include "root/TROOT.h"
#include "root/TFile.h"
#include "root/TH1D.h"
#include "root/TTree.h"
#include "root/TBranch.h"
#include "root/TRandom.h"

int main ()
{
  cout << "Start main()" << endl;

  TFile *pfile = new TFile("file.root", "RECREATE", "Created for you by RootManager" );
  cout << "Open Root file with name : " << pfile -> GetName() << endl;

  cout << "Create histogram" << endl;
  TH1D *pHis1 = new TH1D("pHis1","My comment to TH1D", 100, 0.5, 100+0.5);

  cout << "Reset and fill histogram" << endl;
        pHis1 -> Reset();
        for (int i=0 ;i<10000;i++)
          {
            double random = 100 * gRandom->Rndm(1);
            //pHis1 -> Fill( double(i), 0.1*i );
            pHis1 -> Fill( random );

          }

  cout << "Write histogram in file" << endl;
        pHis1 -> Write();

// Define some simple structures
   typedef struct {float x,y,z;} POINT;
   static POINT point;

  cout << "Create tree" << endl;
//TTree *t3 = (TTree*) -> Get("t3"); // if tuple existed
  TTree *ptree = new TTree("ptree", "My comment to TTree");

  cout << "Create  a couple of branches" << endl;
  float new_v;
  TBranch *pbranch = ptree -> Branch("new_v", &new_v, "new_v/F");
                     ptree -> Branch("point",&point,"x:y:z");

  cout << "Fill branch" << endl;
  for (int i = 0; i < 10000; i++){

      new_v   = gRandom->Gaus(0, 1); // Gaus(0, 1) generates a random number
                                     // for normal distribution with mean=0 and sigma=1
      point.x = gRandom->Gaus(1, 1);
      point.y = gRandom->Gaus(2, 1);
      point.z = gRandom->Gaus(3, 1);

      ptree->Fill();
  }

  cout << "Write tree in file" << endl;
  ptree -> Write();

  cout << "Close file" << endl;
  pfile -> Close();

  return 0;

}

Execution of this program produces the ROOT file with name file.root.

Browse the ROOT file interactively and plot histograms

In order to plot histograms and data from Ntuple, accumulated in the file.root one has to run ROOT interactively, or use a script. For example, we provide a script with name proc.C:

//void proc(int Nplot=1)
{
  // Settings for good style
   gStyle -> SetPadColor(3);
   gStyle -> SetPadBorderSize(0);
   gStyle -> SetPadBorderMode(0);
   gStyle -> SetTitleXSize(0.05); // set size of axes titles
   gStyle -> SetTitleYSize(0.05);
   gStyle -> SetTitleH(0.1); // set size of the title in top box

  TFile *f = new TFile("file.root");

  f->ls();
  ptree->Print();

  c1 = new TCanvas("c1","",0,0,500,500);
  c1->Divide(2,3);

  c1->cd(1); pHis1->Draw();
  c1->cd(2); ptree->Draw("new_v");
  c1->cd(3); ptree->Draw("x");
  c1->cd(4); ptree->Draw("y");
  c1->cd(5); ptree->Draw("z");

  gPad -> Update();

  c1->Print("histograms.gif");

  cout << "Sleep for 10 sec..." << endl;
  gSystem->Sleep(10*1000);
  cout << "Wake up!" << endl;

  f -> Close();
}

To run this script use command:

root -q -f proc.C

This script draws a few histograms, as shown below, and save this plot in the histograms.gif file.

  • No labels