library: libTree #include "TTree.h"

# TTreeFriendLeafIter

class description - source file - inheritance tree (.pdf)

## class TTreeFriendLeafIter : public TIterator

| Inheritance Chart:
`TIterator`
| <- | `TTreeFriendLeafIter` |

        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)

### Data Members

        protected:

              TTree* fTree       tree being iterated
          TIterator* fLeafIter   current leaf sub-iterator.
          TIterator* fTreeIter   current tree sub-iterator.
              Bool_t fDirection  iteration direction

## Class Description

     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.256 2005/06/22 17:01:55 brun Exp $
Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *