ROOT logo
// @(#)root/treeplayer:$Id$
// Author: Rene Brun   19/01/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
// ---------------------------------- TreeFormula.h

#ifndef ROOT_TTreeFormula
#define ROOT_TTreeFormula



//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TTreeFormula                                                         //
//                                                                      //
// The Tree formula class                                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TFormula
#include "TFormula.h"
#endif

#ifndef ROOT_TLeaf
#include "TLeaf.h"
#endif

#ifndef ROOT_TObjArray
#include "TObjArray.h"
#endif

#include <string>
#include <vector>

#ifdef R__OLDHPACC
namespace std {
   using ::string;
   using ::vector;
}
#endif

const Int_t kMAXCODES = kMAXFOUND; // must be the same as kMAXFOUND in TFormula
const Int_t kMAXFORMDIM = 5; // Maximum number of array dimensions support in TTreeFormula

class TTree;
class TArrayI;
class TMethodCall;
class TLeafObject;
class TDataMember;
class TStreamerElement;
class TFormLeafInfoMultiVarDim;
class TFormLeafInfo;
class TBranchElement;
class TAxis;
class TTreeFormulaManager;


class TTreeFormula : public TFormula {

friend class TTreeFormulaManager;

protected:
   enum {
      kIsCharacter = BIT(12),
      kMissingLeaf = BIT(15), // true if some of the needed leaves are missing in the current TTree
      kIsInteger   = BIT(17), // true if the branch contains an integer variable
      kNeedEntries = BIT(18)  // true if the formula uses Entries$
   };
   enum { 
      kDirect, kDataMember, kMethod, 
      kIndexOfEntry, kEntries, kLength, kIteration, kLengthFunc, kSum, kEntryList,
      kTreeMember,
      kIndexOfLocalEntry,
      kMin, kMax

   };
   enum { 
      kAlias           = 200,
      kAliasString     = 201,
      kAlternate       = 202,
      kAlternateString = 203,
      kMinIf           = 204,
      kMaxIf           = 205
   };

   TTree       *fTree;            //! pointer to Tree
   Short_t     fCodes[kMAXCODES]; //  List of leaf numbers referenced in formula
   Int_t       fNdata[kMAXCODES]; //! This caches the physical number of element in the leaf or datamember.
   Int_t       fNcodes;           //  Number of leaves referenced in formula
   Bool_t      fHasCast;          //  Record whether the formula contain a cast operation or not
   Int_t       fMultiplicity;     //  Indicator of the variability of the formula
   Int_t       fNindex;           //  Size of fIndex
   Int_t      *fLookupType;       //[fNindex] array indicating how each leaf should be looked-up
   TObjArray   fLeaves;           //!  List of leaf used in this formula.
   TObjArray   fDataMembers;      //!  List of leaf data members
   TObjArray   fMethods;          //!  List of leaf method calls
   TObjArray   fExternalCuts;     //!  List of TCutG and TEntryList used in the formula
   TObjArray   fAliases;          //!  List of TTreeFormula for each alias used.
   TObjArray   fLeafNames;        //   List of TNamed describing leaves
   TObjArray   fBranches;         //!  List of branches to read.  Similar to fLeaces but duplicates are zeroed out.
   Bool_t      fQuickLoad;        //!  If true, branch GetEntry is only called when the entry number changes.
   Bool_t      fNeedLoading;      //!  If true, the current entry has not been loaded yet.

   Int_t       fNdimensions[kMAXCODES];              //Number of array dimensions in each leaf
   Int_t       fFixedSizes[kMAXCODES][kMAXFORMDIM];  //Physical sizes of lower dimensions for each leaf
   UChar_t     fHasMultipleVarDim[kMAXCODES];        //True if the corresponding variable is an array with more than one variable dimension.

   //the next line should have a mutable in front. See GetNdata()
   Int_t       fCumulSizes[kMAXCODES][kMAXFORMDIM];  //Accumulated sizes of lower dimensions for each leaf after variable dimensions has been calculated
   Int_t       fIndexes[kMAXCODES][kMAXFORMDIM];     //Index of array selected by user for each leaf
   TTreeFormula *fVarIndexes[kMAXCODES][kMAXFORMDIM];  //Pointer to a variable index.

   TAxis                    *fAxis;           //! pointer to histogram axis if this is a string
   Bool_t                    fDidBooleanOptimization;  //! True if we executed one boolean optimization since the last time instance number 0 was evaluated
   TTreeFormulaManager      *fManager;        //! The dimension coordinator.

   // Helper members and function used during the construction and parsing
   TList                    *fDimensionSetup; //! list of dimension setups, for delayed creation of the dimension information.
   std::vector<std::string>  fAliasesUsed;    //! List of aliases used during the parsing of the expression.

   LongDouble_t*        fConstLD;   // local version of fConsts able to store bigger numbers

   TTreeFormula(const char *name, const char *formula, TTree *tree, const std::vector<std::string>& aliases);
   void Init(const char *name, const char *formula);
   Bool_t      BranchHasMethod(TLeaf* leaf, TBranch* branch, const char* method,const char* params, Long64_t readentry) const;
   Int_t       DefineAlternate(const char* expression);
   void        DefineDimensions(Int_t code, Int_t size, TFormLeafInfoMultiVarDim * info, Int_t& virt_dim);
   Int_t       FindLeafForExpression(const char* expression, TLeaf *&leaf, TString &leftover, Bool_t &final, UInt_t &paran_level, TObjArray &castqueue, std::vector<std::string>& aliasUsed, Bool_t &useLeafCollectionObject, const char *fullExpression);
   TLeaf*      GetLeafWithDatamember(const char* topchoice, const char* nextchice, Long64_t readentry) const;
   Int_t       ParseWithLeaf(TLeaf *leaf, const char *expression, Bool_t final, UInt_t paran_level, TObjArray &castqueue, Bool_t useLeafCollectionObject, const char *fullExpression);
   Int_t       RegisterDimensions(Int_t code, Int_t size, TFormLeafInfoMultiVarDim * multidim = 0);
   Int_t       RegisterDimensions(Int_t code, TBranchElement *branch);
   Int_t       RegisterDimensions(Int_t code, TFormLeafInfo *info, TFormLeafInfo *maininfo, Bool_t useCollectionObject);
   Int_t       RegisterDimensions(Int_t code, TLeaf *leaf);
   Int_t       RegisterDimensions(const char *size, Int_t code);

   virtual Double_t  GetValueFromMethod(Int_t i, TLeaf *leaf) const;
   virtual void*     GetValuePointerFromMethod(Int_t i, TLeaf *leaf) const;
   Int_t             GetRealInstance(Int_t instance, Int_t codeindex);

   void              LoadBranches();
   Bool_t            LoadCurrentDim();
   void              ResetDimensions();

   virtual TClass*   EvalClass(Int_t oper) const;
   virtual Bool_t    IsLeafInteger(Int_t code) const;
   virtual Bool_t    IsString(Int_t oper) const;
   virtual Bool_t    IsLeafString(Int_t code) const;
   virtual Bool_t    SwitchToFormLeafInfo(Int_t code);
   virtual Bool_t    StringToNumber(Int_t code);

   void              Convert(UInt_t fromVersion);

private:
   // Not implemented yet
   TTreeFormula(const TTreeFormula&);
   TTreeFormula& operator=(const TTreeFormula&);

   template<typename T> T GetConstant(Int_t k);

public:
   TTreeFormula();
   TTreeFormula(const char *name,const char *formula, TTree *tree);
   virtual   ~TTreeFormula();

   virtual Int_t       DefinedVariable(TString &variable, Int_t &action);
   virtual TClass*     EvalClass() const;

   template<typename T> T EvalInstance(Int_t i=0, const char *stringStack[]=0);
   virtual Double_t       EvalInstance(Int_t i=0, const char *stringStack[]=0) {return EvalInstance<Double_t>(i, stringStack); }
   virtual Long64_t       EvalInstance64(Int_t i=0, const char *stringStack[]=0) {return EvalInstance<Long64_t>(i, stringStack); }
   virtual LongDouble_t   EvalInstanceLD(Int_t i=0, const char *stringStack[]=0) {return EvalInstance<LongDouble_t>(i, stringStack); }

   virtual const char *EvalStringInstance(Int_t i=0);
   virtual void*       EvalObject(Int_t i=0);
   // EvalInstance should be const.  See comment on GetNdata()
   TFormLeafInfo      *GetLeafInfo(Int_t code) const;
   TTreeFormulaManager*GetManager() const { return fManager; }
   TMethodCall        *GetMethodCall(Int_t code) const;
   virtual Int_t       GetMultiplicity() const {return fMultiplicity;}
   virtual TLeaf      *GetLeaf(Int_t n) const;
   virtual Int_t       GetNcodes() const {return fNcodes;}
   virtual Int_t       GetNdata();
   //GetNdata should probably be const.  However it need to cache some information about the actual dimension
   //of arrays, so if GetNdata is const, the variables fUsedSizes and fCumulUsedSizes need to be declared
   //mutable.  We will be able to do that only when all the compilers supported for ROOT actually implemented
   //the mutable keyword.
   //NOTE: Also modify the code in PrintValue which current goes around this limitation :(
   virtual Bool_t      IsInteger(Bool_t fast=kTRUE) const;
           Bool_t      IsQuickLoad() const { return fQuickLoad; }
   virtual Bool_t      IsString() const;
   virtual Bool_t      Notify() { UpdateFormulaLeaves(); return kTRUE; }
   virtual char       *PrintValue(Int_t mode=0) const;
   virtual char       *PrintValue(Int_t mode, Int_t instance, const char *decform = "9.9") const;
   virtual void        SetAxis(TAxis *axis=0);
           void        SetQuickLoad(Bool_t quick) { fQuickLoad = quick; }
   virtual void        SetTree(TTree *tree) {fTree = tree;}
   virtual void        ResetLoading();
   virtual TTree*      GetTree() const {return fTree;}
   virtual void        UpdateFormulaLeaves();

   ClassDef(TTreeFormula,9)  //The Tree formula
};

#endif
 TTreeFormula.h:1
 TTreeFormula.h:2
 TTreeFormula.h:3
 TTreeFormula.h:4
 TTreeFormula.h:5
 TTreeFormula.h:6
 TTreeFormula.h:7
 TTreeFormula.h:8
 TTreeFormula.h:9
 TTreeFormula.h:10
 TTreeFormula.h:11
 TTreeFormula.h:12
 TTreeFormula.h:13
 TTreeFormula.h:14
 TTreeFormula.h:15
 TTreeFormula.h:16
 TTreeFormula.h:17
 TTreeFormula.h:18
 TTreeFormula.h:19
 TTreeFormula.h:20
 TTreeFormula.h:21
 TTreeFormula.h:22
 TTreeFormula.h:23
 TTreeFormula.h:24
 TTreeFormula.h:25
 TTreeFormula.h:26
 TTreeFormula.h:27
 TTreeFormula.h:28
 TTreeFormula.h:29
 TTreeFormula.h:30
 TTreeFormula.h:31
 TTreeFormula.h:32
 TTreeFormula.h:33
 TTreeFormula.h:34
 TTreeFormula.h:35
 TTreeFormula.h:36
 TTreeFormula.h:37
 TTreeFormula.h:38
 TTreeFormula.h:39
 TTreeFormula.h:40
 TTreeFormula.h:41
 TTreeFormula.h:42
 TTreeFormula.h:43
 TTreeFormula.h:44
 TTreeFormula.h:45
 TTreeFormula.h:46
 TTreeFormula.h:47
 TTreeFormula.h:48
 TTreeFormula.h:49
 TTreeFormula.h:50
 TTreeFormula.h:51
 TTreeFormula.h:52
 TTreeFormula.h:53
 TTreeFormula.h:54
 TTreeFormula.h:55
 TTreeFormula.h:56
 TTreeFormula.h:57
 TTreeFormula.h:58
 TTreeFormula.h:59
 TTreeFormula.h:60
 TTreeFormula.h:61
 TTreeFormula.h:62
 TTreeFormula.h:63
 TTreeFormula.h:64
 TTreeFormula.h:65
 TTreeFormula.h:66
 TTreeFormula.h:67
 TTreeFormula.h:68
 TTreeFormula.h:69
 TTreeFormula.h:70
 TTreeFormula.h:71
 TTreeFormula.h:72
 TTreeFormula.h:73
 TTreeFormula.h:74
 TTreeFormula.h:75
 TTreeFormula.h:76
 TTreeFormula.h:77
 TTreeFormula.h:78
 TTreeFormula.h:79
 TTreeFormula.h:80
 TTreeFormula.h:81
 TTreeFormula.h:82
 TTreeFormula.h:83
 TTreeFormula.h:84
 TTreeFormula.h:85
 TTreeFormula.h:86
 TTreeFormula.h:87
 TTreeFormula.h:88
 TTreeFormula.h:89
 TTreeFormula.h:90
 TTreeFormula.h:91
 TTreeFormula.h:92
 TTreeFormula.h:93
 TTreeFormula.h:94
 TTreeFormula.h:95
 TTreeFormula.h:96
 TTreeFormula.h:97
 TTreeFormula.h:98
 TTreeFormula.h:99
 TTreeFormula.h:100
 TTreeFormula.h:101
 TTreeFormula.h:102
 TTreeFormula.h:103
 TTreeFormula.h:104
 TTreeFormula.h:105
 TTreeFormula.h:106
 TTreeFormula.h:107
 TTreeFormula.h:108
 TTreeFormula.h:109
 TTreeFormula.h:110
 TTreeFormula.h:111
 TTreeFormula.h:112
 TTreeFormula.h:113
 TTreeFormula.h:114
 TTreeFormula.h:115
 TTreeFormula.h:116
 TTreeFormula.h:117
 TTreeFormula.h:118
 TTreeFormula.h:119
 TTreeFormula.h:120
 TTreeFormula.h:121
 TTreeFormula.h:122
 TTreeFormula.h:123
 TTreeFormula.h:124
 TTreeFormula.h:125
 TTreeFormula.h:126
 TTreeFormula.h:127
 TTreeFormula.h:128
 TTreeFormula.h:129
 TTreeFormula.h:130
 TTreeFormula.h:131
 TTreeFormula.h:132
 TTreeFormula.h:133
 TTreeFormula.h:134
 TTreeFormula.h:135
 TTreeFormula.h:136
 TTreeFormula.h:137
 TTreeFormula.h:138
 TTreeFormula.h:139
 TTreeFormula.h:140
 TTreeFormula.h:141
 TTreeFormula.h:142
 TTreeFormula.h:143
 TTreeFormula.h:144
 TTreeFormula.h:145
 TTreeFormula.h:146
 TTreeFormula.h:147
 TTreeFormula.h:148
 TTreeFormula.h:149
 TTreeFormula.h:150
 TTreeFormula.h:151
 TTreeFormula.h:152
 TTreeFormula.h:153
 TTreeFormula.h:154
 TTreeFormula.h:155
 TTreeFormula.h:156
 TTreeFormula.h:157
 TTreeFormula.h:158
 TTreeFormula.h:159
 TTreeFormula.h:160
 TTreeFormula.h:161
 TTreeFormula.h:162
 TTreeFormula.h:163
 TTreeFormula.h:164
 TTreeFormula.h:165
 TTreeFormula.h:166
 TTreeFormula.h:167
 TTreeFormula.h:168
 TTreeFormula.h:169
 TTreeFormula.h:170
 TTreeFormula.h:171
 TTreeFormula.h:172
 TTreeFormula.h:173
 TTreeFormula.h:174
 TTreeFormula.h:175
 TTreeFormula.h:176
 TTreeFormula.h:177
 TTreeFormula.h:178
 TTreeFormula.h:179
 TTreeFormula.h:180
 TTreeFormula.h:181
 TTreeFormula.h:182
 TTreeFormula.h:183
 TTreeFormula.h:184
 TTreeFormula.h:185
 TTreeFormula.h:186
 TTreeFormula.h:187
 TTreeFormula.h:188
 TTreeFormula.h:189
 TTreeFormula.h:190
 TTreeFormula.h:191
 TTreeFormula.h:192
 TTreeFormula.h:193
 TTreeFormula.h:194
 TTreeFormula.h:195
 TTreeFormula.h:196
 TTreeFormula.h:197
 TTreeFormula.h:198
 TTreeFormula.h:199
 TTreeFormula.h:200
 TTreeFormula.h:201
 TTreeFormula.h:202
 TTreeFormula.h:203
 TTreeFormula.h:204
 TTreeFormula.h:205
 TTreeFormula.h:206
 TTreeFormula.h:207
 TTreeFormula.h:208
 TTreeFormula.h:209
 TTreeFormula.h:210
 TTreeFormula.h:211