library: libTree #include "TTree.h" |
TTreeFriendLeafIter
class description - source file - inheritance tree (.pdf)
protected:
TTreeFriendLeafIter()
public:
TTreeFriendLeafIter(const TTree* t, Bool_t dir = kIterForward)
TTreeFriendLeafIter(const TTreeFriendLeafIter& iter)
~TTreeFriendLeafIter()
static TClass* Class()
virtual const TCollection* GetCollection() const
virtual Option_t* GetOption() const
virtual TClass* IsA() const
virtual TObject* Next()
virtual TIterator& operator=(const TIterator& rhs)
TTreeFriendLeafIter& operator=(const TTreeFriendLeafIter& rhs)
virtual void Reset()
virtual void ShowMembers(TMemberInspector& insp, char* parent)
virtual void Streamer(TBuffer& b)
void StreamerNVirtual(TBuffer& b)
protected:
TTree* fTree tree being iterated
TIterator* fLeafIter current leaf sub-iterator.
TIterator* fTreeIter current tree sub-iterator.
Bool_t fDirection iteration direction
TTree
a TTree object has a header with a name and a title.
It consists of a list of independent branches (TBranch). Each branch
has its own definition and list of buffers. Branch buffers may be
automatically written to disk or kept in memory until the Tree attribute
fMaxVirtualSize is reached.
Variables of one branch are written to the same buffer.
A branch buffer is automatically compressed if the file compression
attribute is set (default).
Branches may be written to different files (see TBranch::SetFile).
The ROOT user can decide to make one single branch and serialize one
object into one single I/O buffer or to make several branches.
Making one single branch and one single buffer can be the right choice
when one wants to process only a subset of all entries in the tree.
(you know for example the list of entry numbers you want to process).
Making several branches is particularly interesting in the data analysis
phase, when one wants to histogram some attributes of an object (entry)
without reading all the attributes.
/*
*/
==> TTree *tree = new TTree(name, title, maxvirtualsize)
Creates a Tree with name and title. Maxvirtualsize is by default 64Mbytes,
maxvirtualsize = 64000000(default) means: Keeps as many buffers in memory until
the sum of all buffers is greater than 64 Megabyte. When this happens,
memory buffers are written to disk and deleted until the size of all
buffers is again below the threshold.
maxvirtualsize = 0 means: keep only one buffer in memory.
Various kinds of branches can be added to a tree:
A - simple structures or list of variables. (may be for C or Fortran structures)
B - any object (inheriting from TObject). (we expect this option be the most frequent)
C - a ClonesArray. (a specialized object for collections of same class objects)
==> Case A
======
TBranch *branch = tree->Branch(branchname,address, leaflist, bufsize)
* address is the address of the first item of a structure
* leaflist is the concatenation of all the variable names and types
separated by a colon character :
The variable name and the variable type are separated by a slash (/).
The variable type may be 0,1 or 2 characters. If no type is given,
the type of the variable is assumed to be the same as the previous
variable. If the first variable does not have a type, it is assumed
of type F by default. The list of currently supported types is given below:
- C : a character string terminated by the 0 character
- B : an 8 bit signed integer (Char_t)
- b : an 8 bit unsigned integer (UChar_t)
- S : a 16 bit signed integer (Short_t)
- s : a 16 bit unsigned integer (UShort_t)
- I : a 32 bit signed integer (Int_t)
- i : a 32 bit unsigned integer (UInt_t)
- F : a 32 bit floating point (Float_t)
- D : a 64 bit floating point (Double_t)
- L : a 64 bit signed integer (Long64_t)
- l : a 64 bit unsigned integer (ULong64_t)
- O : a boolean (Bool_t)
==> Case B
======
TBranch *branch = tree->Branch(branchname,className,object, bufsize, splitlevel)
object is the address of a pointer to an existing object (derived from TObject).
if splitlevel=0, the object is serialized in the branch buffer.
if splitlevel=1 (default), this branch will automatically be split
into subbranches, with one subbranch for each data member or object
of the object itself. In case the object member is a TClonesArray,
the mechanism described in case C is applied to this array.
if splitlevel=2 ,this branch will automatically be split
into subbranches, with one subbranch for each data member or object
of the object itself. In case the object member is a TClonesArray,
it is processed as a TObject*, only one branch.
==> Case C
======
TBranch *branch = tree->Branch(branchname,clonesarray, bufsize, splitlevel)
clonesarray is the address of a pointer to a TClonesArray.
The TClonesArray is a direct access list of objects of the same class.
For example, if the TClonesArray is an array of TTrack objects,
this function will create one subbranch for each data member of
the object TTrack.
==> branch->SetAddress(Void *address)
In case of dynamic structures changing with each entry for example, one must
redefine the branch address before filling the branch again.
This is done via the TBranch::SetAddress member function.
==> tree->Fill()
loops on all defined branches and for each branch invokes the Fill function.
See also the class TNtuple (a simple Tree with branches of floats)
Adding a Branch to an Existing Tree
===================================
You may want to add a branch to an existing tree. For example,
if one variable in the tree was computed with a certain algorithm,
you may want to try another algorithm and compare the results.
One solution is to add a new branch, fill it, and save the tree.
The code below adds a simple branch to an existing tree.
Note the kOverwrite option in the Write method, it overwrites the
existing tree. If it is not specified, two copies of the tree headers
are saved.
void tree3AddBranch(){
TFile f("tree3.root","update");
Float_t new_v;
TTree *t3 = (TTree*)f->Get("t3");
TBranch *newBranch = t3->Branch("new_v",&new_v,"new_v/F");
//read the number of entries in the t3
Long64_t nentries = t3->GetEntries();
for (Long64_t i = 0; i < nentries; i++){
new_v= gRandom->Gaus(0,1);
newBranch->Fill();
}
// save only the new version of the tree
t3->Write("",TObject::kOverwrite);
}
Adding a branch is often not possible because the tree is in a read-only
file and you do not have permission to save the modified tree with the
new branch. Even if you do have the permission, you risk loosing the
original tree with an unsuccessful attempt to save the modification.
Since trees are usually large, adding a branch could extend it over the
2GB limit. In this case, the attempt to write the tree fails, and the
original data is erased.
In addition, adding a branch to a tree enlarges the tree and increases
the amount of memory needed to read an entry, and therefore decreases
the performance.
For these reasons, ROOT offers the concept of friends for trees (and chains).
We encourage you to use TTree::AddFriend rather than adding a branch manually.
/*
*/
=============================================================================
______________________________________________________________________________
*-*-*-*-*-*-*A simple example with histograms and a tree*-*-*-*-*-*-*-*-*-*
*-* ===========================================
This program creates :
- a one dimensional histogram
- a two dimensional histogram
- a profile histogram
- a tree
These objects are filled with some random numbers and saved on a file.
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#include "TFile.h"
#include "TH1.h"
#include "TH2.h"
#include "TProfile.h"
#include "TRandom.h"
#include "TTree.h"
//______________________________________________________________________________
main(int argc, char **argv)
{
// Create a new ROOT binary machine independent file.
// Note that this file may contain any kind of ROOT objects, histograms,trees
// pictures, graphics objects, detector geometries, tracks, events, etc..
// This file is now becoming the current directory.
TFile hfile("htree.root","RECREATE","Demo ROOT file with histograms & trees");
// Create some histograms and a profile histogram
TH1F *hpx = new TH1F("hpx","This is the px distribution",100,-4,4);
TH2F *hpxpy = new TH2F("hpxpy","py ps px",40,-4,4,40,-4,4);
TProfile *hprof = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
// Define some simple structures
typedef struct {Float_t x,y,z;} POINT;
typedef struct {
Int_t ntrack,nseg,nvertex;
UInt_t flag;
Float_t temperature;
} EVENTN;
static POINT point;
static EVENTN eventn;
// Create a ROOT Tree
TTree *tree = new TTree("T","An example of ROOT tree with a few branches");
tree->Branch("point",&point,"x:y:z");
tree->Branch("eventn",&eventn,"ntrack/I:nseg:nvertex:flag/i:temperature/F");
tree->Branch("hpx","TH1F",&hpx,128000,0);
Float_t px,py,pz;
static Float_t p[3];
//--------------------Here we start a loop on 1000 events
for ( Int_t i=0; i<1000; i++) {
gRandom->Rannor(px,py);
pz = px*px + py*py;
Float_t random = gRandom->::Rndm(1);
// Fill histograms
hpx->Fill(px);
hpxpy->Fill(px,py,1);
hprof->Fill(px,pz,1);
// Fill structures
p[0] = px;
p[1] = py;
p[2] = pz;
point.x = 10*(random-1);;
point.y = 5*random;
point.z = 20*random;
eventn.ntrack = Int_t(100*random);
eventn.nseg = Int_t(2*eventn.ntrack);
eventn.nvertex = 1;
eventn.flag = Int_t(random+0.5);
eventn.temperature = 20+random;
// Fill the tree. For each event, save the 2 structures and 3 objects
// In this simple example, the objects hpx, hprof and hpxpy are slightly
// different from event to event. We expect a big compression factor!
tree->Fill();
}
//--------------End of the loop
tree->Print();
// Save all objects in this file
hfile.Write();
// Close the file. Note that this is automatically done when you leave
// the application.
hfile.Close();
return 0;
}
TTreeFriendLeafIter(const TTree * tree, Bool_t dir)
: fTree(const_cast<TTree*>(tree)),fLeafIter(0),fTreeIter(0),fDirection(dir)
Create a new iterator. By default the iteration direction
is kIterForward. To go backward use kIterBackward.
TTreeFriendLeafIter(const TTreeFriendLeafIter&iter) : TIterator(iter)
Copy constructor
TObject* Next()
Option_t* GetOption() const
Returns the object option stored in the list.
Inline Functions
void ~TTreeFriendLeafIter()
TTreeFriendLeafIter TTreeFriendLeafIter(const TTreeFriendLeafIter& iter)
TIterator& operator=(const TIterator& rhs)
TTreeFriendLeafIter& operator=(const TTreeFriendLeafIter& rhs)
const TCollection* GetCollection() const
void Reset()
TClass* Class()
TClass* IsA() const
void ShowMembers(TMemberInspector& insp, char* parent)
void Streamer(TBuffer& b)
void StreamerNVirtual(TBuffer& b)
Author: Rene Brun 12/01/96
Last update: root/tree:$Name: $:$Id: TTree.cxx,v 1.264 2005/09/08 14:22:17 brun Exp $
Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.