1.4 TTree 的 MakeClass 方法¶

  • MakeClass方法提供了访问ROOT文件的TTree内部数据所需的类(class)的结构
In [1]:
//%jsroot on
TFile *ipf = new TFile("run0005.root"); 
TTree *tree = (TTree*)  ipf->Get("tree");
In [2]:
tree->Print();
******************************************************************************
*Tree    :tree      : tree must2                                             *
*Entries :   511950 : Total =       917722277 bytes  File  Size =  306046164 *
*        :          : Tree compression factor =   3.00                       *
******************************************************************************
*Br    0 :beamTrig  : beamTrig/I                                             *
*Entries :   511950 : Total  Size=    2049732 bytes  File Size  =      93041 *
*Baskets :       17 : Basket Size=     519680 bytes  Compression=  22.02     *
*............................................................................*
*Br    1 :must2Trig : must2Trig[8]/I                                         *
*Entries :   511950 : Total  Size=   16389351 bytes  File Size  =    1021856 *
*Baskets :       69 : Basket Size=    1369600 bytes  Compression=  16.04     *
*............................................................................*
*Br    2 :PPACF5    : PPACF5[5][5]/F                                         *
*Entries :   511950 : Total  Size=   51211689 bytes  File Size  =   21646784 *
*Baskets :      176 : Basket Size=    3433472 bytes  Compression=   2.37     *
*............................................................................*
*Br    3 :PPACF8    : PPACF8[5][5]/F                                         *
*Entries :   511950 : Total  Size=   51211689 bytes  File Size  =   27255795 *
*Baskets :      176 : Basket Size=    3433472 bytes  Compression=   1.88     *
*............................................................................*
*Br    4 :PPACF9    : PPACF9[5][5]/F                                         *
*Entries :   511950 : Total  Size=   51211689 bytes  File Size  =   14832700 *
*Baskets :      176 : Basket Size=    3433472 bytes  Compression=   3.45     *
*............................................................................*
*Br    5 :FPPosition : FPPosition[12][4]/F                                   *
*Entries :   511950 : Total  Size=   98325682 bytes  File Size  =   30590368 *
*Baskets :      319 : Basket Size=    6226944 bytes  Compression=   3.21     *
*............................................................................*
*Br    6 :F5PPACRawData : F5PPACRawData[5][10]/F                             *
*Entries :   511950 : Total  Size=  102423551 bytes  File Size  =   32627987 *
*Baskets :      332 : Basket Size=    6470144 bytes  Compression=   3.14     *
*............................................................................*
*Br    7 :F8PPACRawData : F8PPACRawData[5][10]/F                             *
*Entries :   511950 : Total  Size=  102423551 bytes  File Size  =   40257142 *
*Baskets :      332 : Basket Size=    6470144 bytes  Compression=   2.54     *
*............................................................................*
*Br    8 :F9PPACRawData : F9PPACRawData[5][10]/F                             *
*Entries :   511950 : Total  Size=  102423551 bytes  File Size  =   27991240 *
*Baskets :      332 : Basket Size=    6470144 bytes  Compression=   3.66     *
*............................................................................*
*Br    9 :F10PPACRawData : F10PPACRawData[5][10]/F                           *
*Entries :   511950 : Total  Size=  102423887 bytes  File Size  =   28125061 *
*Baskets :      332 : Basket Size=    6470656 bytes  Compression=   3.64     *
*............................................................................*
*Br   10 :F11PPACRawData : F11PPACRawData[5][10]/F                           *
*Entries :   511950 : Total  Size=  102423887 bytes  File Size  =   30127047 *
*Baskets :      332 : Basket Size=    6470656 bytes  Compression=   3.40     *
*............................................................................*
*Br   11 :F3PlaRawData : F3PlaRawData[4]/F                                   *
*Entries :   511950 : Total  Size=    8195004 bytes  File Size  =    3689434 *
*Baskets :       35 : Basket Size=     884224 bytes  Compression=   2.22     *
*............................................................................*
*Br   12 :F7PlaRawData : F7PlaRawData[4]/F                                   *
*Entries :   511950 : Total  Size=    8195004 bytes  File Size  =    3170206 *
*Baskets :       35 : Basket Size=     884224 bytes  Compression=   2.58     *
*............................................................................*
*Br   13 :F11PlaRawData : F11PlaRawData[4]/F                                 *
*Entries :   511950 : Total  Size=    8195043 bytes  File Size  =    2787872 *
*Baskets :       35 : Basket Size=     884224 bytes  Compression=   2.94     *
*............................................................................*
*Br   14 :F11ICRawData : F11ICRawData[10]/F                                  *
*Entries :   511950 : Total  Size=   20486459 bytes  File Size  =    6282467 *
*Baskets :       82 : Basket Size=    1612800 bytes  Compression=   3.26     *
*............................................................................*
*Br   15 :TOF       : TOF[8]/F                                               *
*Entries :   511950 : Total  Size=   16388913 bytes  File Size  =    6714974 *
*Baskets :       69 : Basket Size=    1369600 bytes  Compression=   2.44     *
*............................................................................*
*Br   16 :AoQ       : AoQ[9][4]/F                                            *
*Entries :   511950 : Total  Size=   73743159 bytes  File Size  =   28803633 *
*Baskets :      245 : Basket Size=    4768768 bytes  Compression=   2.56     *
*............................................................................*

调用MakeClass方法¶

root -l run0005.root
root[q] tree->MakeClass("ppac")
In [3]:
tree->MakeClass("ppac");// creates a class to loop over the tree.
Info in <TTreePlayer::MakeClass>: Files: ppac.h and ppac.C generated from TTree: tree

tree->MakeClass("MyClass") 创建 MyClass.h 和 MyClass.C 文件¶

  • MyClass.h
    • 声明所有的TTree的Branch内的变量
    • 设置TBranch的地址(SetBranchAdress)
  • MyClass.C
    • MyClass::Loop()函数的代码框架-用户需要填入自己的代码。
In [4]:
ipf->Close();
In [5]:
!ls -lh ppac.*
-rw-r--r--@ 1 zhli  staff   1.4K Feb 19 10:46 ppac.C
-rw-r--r--@ 1 zhli  staff   1.4K Mar 23  2019 ppac.C~
-rw-r--r--@ 1 zhli  staff   3.1K Mar 23  2019 ppac.cpp
-rw-r--r--@ 1 zhli  staff   5.7K Feb 19 10:46 ppac.h
-rw-r--r--@ 1 zhli  staff    71K Mar 23  2019 ppac.png
-rw-r--r--  1 zhli  staff   5.8M Feb 19 10:43 ppac.root

ppac.h¶

  • declarations for all tree branches
  • setting the corresponding branch address
//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Tue Mar  5 11:08:38 2019 by ROOT version 6.14/02
// from TTree tree/tree must2
// found on file: run0005.root
//////////////////////////////////////////////////////////

#ifndef ppac_h
#define ppac_h

#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>

// Header file for the classes stored in the TTree if any.

class ppac {
public :
   TTree          *fChain;   //!pointer to the analyzed TTree or TChain
   Int_t           fCurrent; //!current Tree number in a TChain

// Fixed size dimensions of array or collections stored in the TTree if any.

   // Declaration of leaf types
   Int_t           beamTrig;
   Int_t           must2Trig[8];
   Float_t         PPACF5[5][5];
   Float_t         PPACF8[5][5];
   Float_t         PPACF9[5][5];
   Float_t         FPPosition[12][4];
   Float_t         F5PPACRawData[5][10];
   Float_t         F8PPACRawData[5][10];
   Float_t         F9PPACRawData[5][10];
   Float_t         F10PPACRawData[5][10];
   Float_t         F11PPACRawData[5][10];
   Float_t         F3PlaRawData[4];
   Float_t         F7PlaRawData[4];
   Float_t         F11PlaRawData[4];
   Float_t         F11ICRawData[10];
   Float_t         TOF[8];
   Float_t         AoQ[9][4];

   // List of branches
   TBranch        *b_beamTrig;   //!
   TBranch        *b_must2Trig;   //!
   TBranch        *b_PPACF5;   //!
   TBranch        *b_PPACF8;   //!
   TBranch        *b_PPACF9;   //!
   TBranch        *b_FPPosition;   //!
   TBranch        *b_F5PPACRawData;   //!
   TBranch        *b_F8PPACRawData;   //!
   TBranch        *b_F9PPACRawData;   //!
   TBranch        *b_F10PPACRawData;   //!
   TBranch        *b_F11PPACRawData;   //!
   TBranch        *b_F3PlaRawData;   //!
   TBranch        *b_F7PlaRawData;   //!
   TBranch        *b_F11PlaRawData;   //!
   TBranch        *b_F11ICRawData;   //!
   TBranch        *b_TOF;   //!
   TBranch        *b_AoQ;   //!

   ppac(TTree *tree=0);
   virtual ~ppac();
   virtual Int_t    Cut(Long64_t entry);
   virtual Int_t    GetEntry(Long64_t entry);
   virtual Long64_t LoadTree(Long64_t entry);
   virtual void     Init(TTree *tree);
   virtual void     Loop();//implemented in ppac.C
   virtual Bool_t   Notify();
   virtual void     Show(Long64_t entry = -1);
};

#endif

#ifdef ppac_cxx
ppac::ppac(TTree *tree) : fChain(0) 
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
   if (tree == 0) {
      TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("run0005.root");
      if (!f || !f->IsOpen()) {
         f = new TFile("run0005.root");
      }
      f->GetObject("tree",tree);

   }
   Init(tree);//inialize the tree for reading. It associates each branch with the corresponding leaf data member.
}

ppac::~ppac()
{
   if (!fChain) return;
   delete fChain->GetCurrentFile();
}

Int_t ppac::GetEntry(Long64_t entry)
{
// Read contents of entry.
   if (!fChain) return 0;
   return fChain->GetEntry(entry);
}
Long64_t ppac::LoadTree(Long64_t entry)
{
// Set the environment to read one entry
   if (!fChain) return -5;
   Long64_t centry = fChain->LoadTree(entry);
   if (centry < 0) return centry;
   if (fChain->GetTreeNumber() != fCurrent) {
      fCurrent = fChain->GetTreeNumber();
      Notify();
   }
   return centry;
}

void ppac::Init(TTree *tree)
{
   // The Init() function is called when the selector needs to initialize
   // a new tree or chain. Typically here the branch addresses and branch
   // pointers of the tree will be set.
   // It is normally not necessary to make changes to the generated
   // code, but the routine can be extended by the user if needed.
   // Init() will be called many times when running on PROOF
   // (once per file to be processed).

   // Set branch addresses and branch pointers
   if (!tree) return;
   fChain = tree;
   fCurrent = -1;
   fChain->SetMakeClass(1);

   fChain->SetBranchAddress("beamTrig", &beamTrig, &b_beamTrig);
   fChain->SetBranchAddress("must2Trig", must2Trig, &b_must2Trig);
   fChain->SetBranchAddress("PPACF5", PPACF5, &b_PPACF5);
   fChain->SetBranchAddress("PPACF8", PPACF8, &b_PPACF8);
   fChain->SetBranchAddress("PPACF9", PPACF9, &b_PPACF9);
   fChain->SetBranchAddress("FPPosition", FPPosition, &b_FPPosition);
   fChain->SetBranchAddress("F5PPACRawData", F5PPACRawData, &b_F5PPACRawData);
   fChain->SetBranchAddress("F8PPACRawData", F8PPACRawData, &b_F8PPACRawData);
   fChain->SetBranchAddress("F9PPACRawData", F9PPACRawData, &b_F9PPACRawData);
   fChain->SetBranchAddress("F10PPACRawData", F10PPACRawData, &b_F10PPACRawData);
   fChain->SetBranchAddress("F11PPACRawData", F11PPACRawData, &b_F11PPACRawData);
   fChain->SetBranchAddress("F3PlaRawData", F3PlaRawData, &b_F3PlaRawData);
   fChain->SetBranchAddress("F7PlaRawData", F7PlaRawData, &b_F7PlaRawData);
   fChain->SetBranchAddress("F11PlaRawData", F11PlaRawData, &b_F11PlaRawData);
   fChain->SetBranchAddress("F11ICRawData", F11ICRawData, &b_F11ICRawData);
   fChain->SetBranchAddress("TOF", TOF, &b_TOF);
   fChain->SetBranchAddress("AoQ", AoQ, &b_AoQ);
   Notify();
}

Bool_t ppac::Notify()
{
   // The Notify() function is called when a new file is opened. This
   // can be either for a new TTree in a TChain or when when a new TTree
   // is started when using PROOF. It is normally not necessary to make changes
   // to the generated code, but the routine can be extended by the
   // user if needed. The return value is currently not used.

   return kTRUE;
}

void ppac::Show(Long64_t entry)
{
// Print contents of entry.
// If entry is not specified, print current entry
   if (!fChain) return;
   fChain->Show(entry);
}
Int_t ppac::Cut(Long64_t entry)
{
// This function may be called from Loop.
// returns  1 if entry is accepted.
// returns -1 otherwise.
   return 1;
}
#endif // #ifdef ppac_cxx

ppac.C¶

It is the skeleton method that loops through each entry of the tree. - User needs to customize it for the analysis.

#define ppac_cxx
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include "ppac.h"

void ppac::Loop()
{
//   In a ROOT session, you can do:
//      root> .L ppac.C
//      root> ppac t
//      root> t.GetEntry(12); // Fill t data members with entry number 12
//      root> t.Show();       // Show values of entry 12
//      root> t.Show(16);     // Read and show values of entry 16
//      root> t.Loop();       // Loop on all entries
//

//     This is the loop skeleton where:
//    jentry is the global entry number in the chain
//    ientry is the entry number in the current Tree
//  Note that the argument to GetEntry must be:
//    jentry for TChain::GetEntry
//    ientry for TTree::GetEntry and TBranch::GetEntry
//
//       To read only selected branches, Insert statements like:
// METHOD1:
//    fChain->SetBranchStatus("*",0);  // disable all branches
//    fChain->SetBranchStatus("branchname",1);  // activate branchname
// METHOD2: replace line
//    fChain->GetEntry(jentry);       //read all branches
//by  b_branchname->GetEntry(ientry); //read only this branch

//------------------------------------------------------

    //Ttree *fChain - Pointer pointing to the tree
   if (fChain == 0) return;

   Long64_t nentries = fChain->GetEntriesFast();

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry = 0; jentry < nentries; jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;
   }
}

customized ppac.C -> ppac1.C¶

#define ppac_cxx
#include "ppac.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
TCanvas *c1 = new TCanvas("c1","c1");
TH1D *h1 = new TH1D("h1", "h1", 2000, 0, 2000);
void ppac::Loop()
{   
  //new tree and root file  
  TFile *opf = new TFile("ppac.root", "recreate");
  TTree *tree = new TTree("tree", "ppac");

  Double_t txl, txr, tyd, tyu, ta;
  Double_t x, y;
  tree->Branch("txl", &txl, "txl/D");
  tree->Branch("txr", &txr, "txr/D");
  tree->Branch("tyd", &tyd, "tyd/D");
  tree->Branch("tyu", &tyu, "tyu/D");
  tree->Branch("ta",  &ta,  "ta/D");
  tree->Branch("x",   &x,   "x/D");
  tree->Branch("y",   &y,   "y/D");

    //TTree *fChain - Pointer pointing to the tree 
   if (fChain == 0) return;

   Long64_t nentries = fChain->GetEntriesFast();

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry = 0; jentry < nentries; jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;

     //user code
     if(jentry % 10 ==0) 
         h1->Fill(F8PPACRawData[0][1] + F8PPACRawData[0][0] - 2*F8PPACRawData[0][4]);

     txl = F8PPACRawData[0][0];
     txr = F8PPACRawData[0][1];
     tyd = F8PPACRawData[0][2];
     tyu = F8PPACRawData[0][3];
     ta = F8PPACRawData[0][4];

     bool bx = txl<4900 && txr<4900;
     bool by = tyu<4900 && tyd<4900;
     bool ba = ta<600 && ta>250; 

     x =- 5000;
     y =- 5000;
     if(bx && by && ba) {
         x = txr - txl;
         y = tyu - tyd;
         tree->Fill();
     }
        if(jentry%100000 == 0) cout << "processing " << jentry << endl;
   }
    tree->Write();
    opf->Close();
}

load funcion¶

  • in code: gROOT->ProcessLine(".L ppac1.C")
  • in ROOT command line: .L ppac1.C
In [6]:
.L ppac.C
In [7]:
ppac t;
In [8]:
t.GetEntry(13);
In [9]:
t.Show();
======> EVENT:13
 beamTrig        = 1
 must2Trig       = 0, 
                  0, 0, 0, 0, 0, 0, 0
 PPACF5          = 63.2696, 
                  -7.9987, -418.7, -410.1, 75.8291, 62.9437, 
                  -8.3079, -381.3, -389.9, 63.184, 72.3041, 
                  -10.2965, 231.3, 239.9, 58.0741, 64.6791, 
                  -9.92849, 268.7, 260.1, 58.4691
 PPACF8          = 4.79569, 
                  -39.693, -1750.7, -1742.1, 43.7375, 4.19174, 
                  -34.1586, -1713.3, -1721.9, 54.5781, 3.61046, 
                  -32.6964, -1250.7, -1242.1, 58.1063, 4.50848, 
                  -31.5826, -1213.3, -1221.9, 51.2145
 PPACF9          = 1.18403, 
                  26.8555, -18.7, -10.1, 423.968, 0.852346, 
                  -1000, 18.7, 10.1, 406.757, -1000, 
                  18.8675, 681.3, 689.9, 415.817, 2.42226, 
                  18.6448, 718.7, 710.1, 420.787
 FPPosition      = 0, 
                  0, 0, 0, 0, 0, 
                  0, 0, 0, 0, 0, 
                  0, -1000, -1000, -1000, -1000, 
                  0, 0, 0, 0
 F5PPACRawData   = 608, 
                  1220, 734, 663, 540, 0, 
                  0, 0, 0, 0, 634, 
                  1269, 709, 797, 445, 0, 
                  0, 0, 0, 0
 F8PPACRawData   = 870, 
                  903, 402, 878, 298, 0, 
                  0, 0, 0, 0, 881, 
                  932, 525, 807, 368, 0, 
                  0, 0, 0, 0
 F9PPACRawData   = 3016, 
                  2988, 3086, 2719, 2927, 0, 
                  0, 0, 0, 0, 3044, 
                  2978, 2855, 2649, 2887, 0, 
                  0, 0, 0, 0
 F10PPACRawData  = 3008, 
                  2931, 2807, 2955, 2763, 0, 
                  0, 0, 0, 0, 2878, 
                  2901, 2632, 2840, 2850, 0, 
                  0, 0, 0, 0
 F11PPACRawData  = 3031, 
                  3123, 2917, 2713, 3554, 0, 
                  0, 0, 0, 0, 3090, 
                  2854, 2938, 2568, 3465, 0, 
                  0, 0, 0, 0
 F3PlaRawData    = 1643, 
                  1507, 0, 0
 F7PlaRawData    = 785, 
                  733, 0, 0
 F11PlaRawData   = 2329, 
                  2116, 0, 0
 F11ICRawData    = 0, 
                  1418, 1348, 1358, 1299, 1229, 
                  0, 0, 0, 0
 TOF             = -1000, 
                  -1000, -1000, -1000, -1000, -1000, 
                  -1000, -1000
 AoQ             = 7.03884, 
                  -1000, -1000, -1000, 7.03884, -1000, 
                  -1000, -1000, 6.85817, -1000, -1000, 
                  -1000, 6.8509, -1000, -1000, -1000, 
                  7.03884, -1000, -1000, -1000
In [10]:
t.Loop();
processing 0
processing 100000
processing 200000
processing 300000
processing 400000
processing 500000
In [11]:
h1->Draw();
c1->Draw();
In [12]:
TFile *ipf1 = new TFile("ppac.root");
TTree *tree1 = (TTree*) ipf1->Get("tree");
In [13]:
tree1->Draw("x:y>>(1000,-800,800,1000,-800,800)","","colz");
c1->Draw();

MakeClass with TChain¶

TChain object is a list of Root files containing the same tree. As an example, assume we have 3 Root files called file1.root, file2.root, file3.root. Each file contains one tree called "T". We can create a chain with the following statements:

TChain *chain=new TChain("tree");
   chain->Add("file1.root");
   chain->Add("file2.root");
   chain->Add("file3.root");

The class TChain is derived from the class TTree . For example, to generate an histogram corresponding to the attribute "x" in tree "tree" by processing sequentially the 3 files of this chain, we can do:

chain->Draw("x");

Chain files with loop

TChain *chain=new TChain("chain", "chainname");
const Int_t fNFile=11;
Int_t iFile;
for (iFile=0; iFile<fNFile; ++iFile) {
    chain->Add(Form("../anadata/data%03d.root", iFile+10));
}
In [14]:
TChain* chain = new TChain("tree");
In [15]:
chain->Add("run0001.root");
chain->Add("run0002.root");
chain->Add("run0003.root");
chain->Add("run0004.root");
chain->Add("run0005.root");
In [16]:
chain->MakeClass("ppac_chain");
Info in <TTreePlayer::MakeClass>: Files: ppac_chain.h and ppac_chain.C generated from TTree: tree
ppac_chain::ppac_chain(TTree *tree) : fChain(0) 
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
   if (tree == 0) {

#ifdef SINGLE_TREE
      // The following code should be used if you want this class to access
      // a single tree instead of a chain
      TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("Memory Directory");
      if (!f || !f->IsOpen()) {
         f = new TFile("Memory Directory");
      }
      f->GetObject("tree",tree);

#else // SINGLE_TREE

      // The following code should be used if you want this class to access a chain
      // of trees.
      TChain * chain = new TChain("tree","");
      chain->Add("run0001.root/tree");
      chain->Add("run0002.root/tree");
      chain->Add("run0003.root/tree");
      chain->Add("run0004.root/tree");
      chain->Add("run0005.root/tree");
      tree = chain;
#endif // SINGLE_TREE

   }
   Init(tree);
}