diff --git a/hist/inc/TF1.h b/hist/inc/TF1.h index f5444186daa3114b0331a02dc1f3bba7724ade14..be0a6bc8fd7784f590ec021afa5193362e5fe87e 100644 --- a/hist/inc/TF1.h +++ b/hist/inc/TF1.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF1.h,v 1.34 2003/05/06 13:14:46 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TF1.h,v 1.35 2003/05/15 13:56:29 brun Exp $ // Author: Rene Brun 18/08/95 /************************************************************************* @@ -83,6 +83,7 @@ public: TF1(const char *name, void *fcn, Double_t xmin, Double_t xmax, Int_t npar); TF1(const char *name, Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin=0, Double_t xmax=1, Int_t npar=0); TF1(const TF1 &f1); + TF1& operator=(const TF1 &rhs); virtual ~TF1(); virtual void Browse(TBrowser *b); virtual void Copy(TObject &f1) const; diff --git a/hist/inc/TF2.h b/hist/inc/TF2.h index bc160cc3372e7f2f9ac0193f6199fb7682782ce3..c82d1faa9d9a5e6a94c9f3075e9e62ad28aa5514 100644 --- a/hist/inc/TF2.h +++ b/hist/inc/TF2.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF2.h,v 1.14 2003/01/15 21:45:39 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TF2.h,v 1.15 2003/03/31 16:04:35 brun Exp $ // Author: Rene Brun 23/08/95 /************************************************************************* @@ -44,6 +44,7 @@ public: TF2(const char *name, void *fcn, Double_t xmin=0, Double_t xmax=1, Double_t ymin=0, Double_t ymax=1, Int_t npar=0); TF2(const char *name, Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin=0, Double_t xmax=1, Double_t ymin=0, Double_t ymax=1, Int_t npar=0); TF2(const TF2 &f2); + TF2 &operator=(const TF2& rhs); virtual ~TF2(); virtual void Copy(TObject &f2) const; virtual Int_t DistancetoPrimitive(Int_t px, Int_t py); diff --git a/hist/inc/TF3.h b/hist/inc/TF3.h index b5a759f5926f5e021819d5cf73d01b2633649a32..f1f97f24af684af215a07e62d6c7f4840dece105 100644 --- a/hist/inc/TF3.h +++ b/hist/inc/TF3.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF3.h,v 1.9 2002/12/02 18:50:03 rdm Exp $ +// @(#)root/hist:$Name: $:$Id: TF3.h,v 1.10 2003/03/31 16:04:35 brun Exp $ // Author: Rene Brun 27/10/95 /************************************************************************* @@ -44,6 +44,7 @@ public: Double_t ymax=1, Double_t zmin=0, Double_t zmax=1, Int_t npar=0); TF3(const TF3 &f3); + TF3& operator=(const TF3 &rhs); virtual ~TF3(); virtual void Copy(TObject &f3) const; virtual Int_t DistancetoPrimitive(Int_t px, Int_t py); diff --git a/hist/inc/TFormula.h b/hist/inc/TFormula.h index 4f93027a7db0697a214ca2f6db234fee9c8f065d..d6a34e5efdd71aa22d7f8631de4592a8e5c82277 100644 --- a/hist/inc/TFormula.h +++ b/hist/inc/TFormula.h @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TFormula.h,v 1.19 2003/06/17 20:07:33 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TFormula.h,v 1.20 2003/06/18 16:48:28 brun Exp $ // Author: Nicolas Brun 19/08/95 /************************************************************************* @@ -54,9 +54,10 @@ protected: TObjArray fFunctions; //Array of function calls to make TBits fAlreadyFound; //! cache for information - void ClearFormula(Option_t *option=""); - Bool_t IsInitialized() { return TestBit(kInitialized); } - Int_t GetOperType(Int_t oper) const; + void ClearFormula(Option_t *option=""); + Bool_t IsInitialized() { return TestBit(kInitialized); } + Int_t GetOperType(Int_t oper) const; + virtual Bool_t IsString(Int_t oper) const; enum { kConstants = 50000, @@ -76,6 +77,7 @@ public: TFormula(); TFormula(const char *name,const char *formula); TFormula(const TFormula &formula); + TFormula& operator=(const TFormula &rhs); virtual ~TFormula(); public: diff --git a/hist/src/TF1.cxx b/hist/src/TF1.cxx index d93839ae8114639c0a37e3b32f4d7196d60d4aff..382e6d8488c66031c6fcad728b49ffcc201bfedb 100644 --- a/hist/src/TF1.cxx +++ b/hist/src/TF1.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF1.cxx,v 1.63 2003/05/21 20:13:09 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TF1.cxx,v 1.64 2003/06/10 16:45:57 brun Exp $ // Author: Rene Brun 18/08/95 /************************************************************************* @@ -454,6 +454,15 @@ TF1::TF1(const char *name,Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin } +//______________________________________________________________________________ +TF1& TF1::operator=(const TF1 &rhs) +{ + if (this != &rhs) { + rhs.Copy(*this); + } + return *this; +} + //______________________________________________________________________________ TF1::~TF1() { diff --git a/hist/src/TF2.cxx b/hist/src/TF2.cxx index 31ba9f0b6a6e8952f755332596b35e22e56d12c8..5de5b868303fcd90816c2f14fee61cdf314f047a 100644 --- a/hist/src/TF2.cxx +++ b/hist/src/TF2.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF2.cxx,v 1.19 2003/03/31 16:04:35 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TF2.cxx,v 1.20 2003/04/20 20:03:04 brun Exp $ // Author: Rene Brun 23/08/95 /************************************************************************* @@ -117,6 +117,15 @@ TF2::TF2(const char *name, Double_t (*fcn)(Double_t *, Double_t *), Double_t xmi } +//______________________________________________________________________________ +TF2& TF2::operator=(const TF2 &rhs) +{ + if (this != &rhs) { + rhs.Copy(*this); + } + return *this; +} + //______________________________________________________________________________ TF2::~TF2() { diff --git a/hist/src/TF3.cxx b/hist/src/TF3.cxx index e0ec80d1968c4d0d6640fb9bc5ec49a07eb019c8..ead667df666b4a386a6f93c49b9f00bd3385cf6c 100644 --- a/hist/src/TF3.cxx +++ b/hist/src/TF3.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TF3.cxx,v 1.9 2002/10/31 07:27:36 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TF3.cxx,v 1.10 2003/03/31 16:04:35 brun Exp $ // Author: Rene Brun 27/10/95 /************************************************************************* @@ -98,6 +98,15 @@ TF3::TF3(const char *name,Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin fNdim = 3; } +//______________________________________________________________________________ +TF3& TF3::operator=(const TF3 &rhs) +{ + if (this != &rhs) { + rhs.Copy(*this); + } + return *this; +} + //______________________________________________________________________________ TF3::~TF3() { diff --git a/hist/src/TFormula.cxx b/hist/src/TFormula.cxx index ab010594199bce68423f2a45a8dcf076e26c88bf..20180c3a2edcc389f3186bcf8e9311602c555c9c 100644 --- a/hist/src/TFormula.cxx +++ b/hist/src/TFormula.cxx @@ -1,4 +1,4 @@ -// @(#)root/hist:$Name: $:$Id: TFormula.cxx,v 1.43 2003/06/21 13:27:19 brun Exp $ +// @(#)root/hist:$Name: $:$Id: TFormula.cxx,v 1.44 2003/06/26 17:44:29 rdm Exp $ // Author: Nicolas Brun 19/08/95 /************************************************************************* @@ -164,6 +164,15 @@ TFormula::TFormula(const TFormula &formula) : TNamed() ((TFormula&)formula).Copy(*this); } +//______________________________________________________________________________ +TFormula& TFormula::operator=(const TFormula &rhs) +{ + if (this != &rhs) { + rhs.Copy(*this); + } + return *this; +} + //______________________________________________________________________________ TFormula::~TFormula() { @@ -175,7 +184,6 @@ TFormula::~TFormula() ClearFormula(); } - //______________________________________________________________________________ Bool_t TFormula::AnalyzeFunction(TString &chaine, Int_t &err, Int_t offset) { @@ -404,7 +412,7 @@ void TFormula::Analyze(const char *schain, Int_t &err, Int_t offset) //*-* //*-* * strings : //*-* -//*-* s0 80000 s1 80001 etc.. +//*-* sX 80000 (80001 to 99999) to not used yet //*-* //*-* * variables : //*-* @@ -879,8 +887,8 @@ if (err==0) { if (find == 0) { //*-*- Check if chaine is a defined variable. //*-*- Note that DefinedVariable can be overloaded - ctemp = chaine; - ctemp.ReplaceAll(escapedSlash, slash); + ctemp = chaine; + ctemp.ReplaceAll(escapedSlash, slash); k = DefinedVariable(ctemp); if (k >= 5000 && k < 10000) { fExpr[fNoper] = ctemp; @@ -1490,7 +1498,7 @@ if (err==0) { if (chaine(0,1)=="\"" && chaine(chaine.Length()-1,1)=="\"") { //*-* It is a string !!! fExpr[fNoper] = chaine(1,chaine.Length()-2); - fOper[fNoper] = 80000; + fOper[fNoper] = kStrings; fNoper++; } else { @@ -1776,42 +1784,43 @@ Int_t TFormula::Compile(const char *expression) Int_t is_it_string,last_string=0,before_last_string=0; if (!fOper) fNoper = 0; enum { kIsCharacter = BIT(12) }; - for (i=0; i<fNoper; i++) { - is_it_string = 0; - if ((fOper[i]>=105000 && fOper[i]<110000) || fOper[i] == 80000) is_it_string = 1; - else if (last_string) { - - if (fOper[i] == 62) { - if (!before_last_string) { - Error("Compile", "Both operands of the operator == have to be either numbers or strings"); - return -1; - } - fOper[i] = 76; - SetBit(kIsCharacter); - } else if (fOper[i] == 63) { - if (!before_last_string) { - Error("Compile", "Both operands of the operator != have to be either numbers or strings"); - return -1; - } - fOper[i] = 77; - SetBit(kIsCharacter); - } - else if (fOper[i] == 23) { - if (! (before_last_string && last_string) ) { - Error("Compile", "strstr requires 2 string arguments"); - return -1; - } - SetBit(kIsCharacter); - } else if (before_last_string) { - // the i-2 element is a string not used in a string operation, let's down grade it - // to a char array: - if (fOper[i-2]>=105000) { - fOper[i-2] -= 5000; - fNval++; - fNstring--; - } - } - + for (i=0; i<fNoper; i++, + before_last_string = last_string, + last_string = is_it_string) { + is_it_string = IsString(i); + if (is_it_string) continue; + if (last_string) { + if (fOper[i] == 62) { + if (!before_last_string) { + Error("Compile", "Both operands of the operator == have to be either numbers or strings"); + return -1; + } + fOper[i] = 76; + SetBit(kIsCharacter); + } else if (fOper[i] == 63) { + if (!before_last_string) { + Error("Compile", "Both operands of the operator != have to be either numbers or strings"); + return -1; + } + fOper[i] = 77; + SetBit(kIsCharacter); + } + else if (fOper[i] == 23) { + if (! (before_last_string && last_string) ) { + Error("Compile", "strstr requires 2 string arguments"); + return -1; + } + SetBit(kIsCharacter); + } else if (before_last_string) { + // the i-2 element is a string not used in a string operation, let's down grade it + // to a char array: + if (fOper[i-2]>=105000) { + fOper[i-2] -= 5000; + fNval++; + fNstring--; + } + } + } else if (before_last_string) { // the i-2 element is a string not used in a string operation, let's down grade it // to a char array: @@ -1821,8 +1830,6 @@ Int_t TFormula::Compile(const char *expression) fNstring--; } } - before_last_string = last_string; - last_string = is_it_string; } if (err) { fNdim = 0; return 1; } @@ -2097,7 +2104,7 @@ Double_t TFormula::EvalPar(const Double_t *x, const Double_t *params) continue; } //*-*- String - if (action == 80000) { + if (action == kStrings) { pos2++; tab2[pos2-1] = (char*)fExpr[i].Data(); continue; } @@ -2408,6 +2415,15 @@ Int_t TFormula::GetParNumber(const char *parName) const return -1; } +//______________________________________________________________________________ +Bool_t TFormula::IsString(Int_t oper) const +{ + // return true if the expression at the index 'oper' is to be treated as + // as string + + return fOper[oper] == kStrings; +} + //______________________________________________________________________________ void TFormula::Print(Option_t *) const { diff --git a/test/dt_DrawTest.C b/test/dt_DrawTest.C index bd794e725c0293e4353fd2167d2d9fdebbdcc26b..d32e323e15322b892ce18b760c60824656b53434 100644 --- a/test/dt_DrawTest.C +++ b/test/dt_DrawTest.C @@ -105,6 +105,8 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 2, int quietLevel = 0) tree->Draw("fNpoint>>hNpoint","fPx < 0","goff"); tree->Draw("fValid>>hValid", "fPx < 0","goff"); DrawSkippable(tree,"fPointValue","hPointValue", gBranchStyle!=0); + tree->SetAlias("mult","fPx*fPy"); + DrawSkippable(tree,"fEvtHdr.fEvtNum*6+mult", "hAlias", 1); tree->Draw("fMatrix>>hFullMatrix","","goff"); tree->Draw("fMatrix[][0]>>hColMatrix","","goff"); @@ -137,6 +139,8 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 2, int quietLevel = 0) // Test string operations DrawSkippable(tree,"fEvtHdr.fEvtNum","fType==\"type1\" ","hString",(level>0)); DrawSkippable(tree,"fEvtHdr.fEvtNum","strstr(fType,\"1\") ","+hString",(level>0)); + tree->SetAlias("typ","fType"); + DrawSkippable(tree,"strstr(typ,\"1\") ", "hAliasStr", 1); // Test binary operators DrawSkippable(tree,"fValid<<4","hShiftValid",(level>0)); diff --git a/test/dt_MakeRef.C b/test/dt_MakeRef.C index ce34ad47321d071cbf1e81daf4d79194980812b3..a27a39c13e6a0b2b1f692e51fbe77248028fdfea 100644 --- a/test/dt_MakeRef.C +++ b/test/dt_MakeRef.C @@ -70,6 +70,7 @@ void MakeHisto(TTree *tree, TDirectory* To) { TH1F *refNpoint = RefClone(where,"hNpoint"); TH1F *refValid = RefClone(where,"hValid"); TH1F *refPointValue = RefClone(where,"hPointValue"); + TH1F *refAlias = RefClone(where,"hAlias"); TH1F *refFullMatrix = RefClone(where,"hFullMatrix"); TH1F *refColMatrix = RefClone(where,"hColMatrix"); @@ -97,6 +98,7 @@ void MakeHisto(TTree *tree, TDirectory* To) { TH1F *refAndValid = RefClone(where,"hAndValid"); TH1F *refString = RefClone(where,"hString"); + TH1F *refAliasStr = RefClone(where,"hAliasStr"); TH1F *refPxBx = RefClone(where,"hPxBx"); TH1F *refPxBxWeight = RefClone(where,"hPxBxWeight"); @@ -140,8 +142,10 @@ void MakeHisto(TTree *tree, TDirectory* To) { if (!strcmp("type1",event->GetType())) refString->Fill(event->GetHeader()->GetEvtNum()); - if (strstr(event->GetType(),"1")) + if (strstr(event->GetType(),"1")) { refString->Fill(event->GetHeader()->GetEvtNum()); + } + refAliasStr->Fill(strstr(event->GetType(),"1")!=0); Nvertex = event->GetNvertex(); for(i0=0;i0<Nvertex;i0++) { @@ -250,6 +254,8 @@ void MakeHisto(TTree *tree, TDirectory* To) { } if (bits.TestBitNumber(5)) refFiltTrackTrigger->Fill(t->GetPx()); refBreit->Fill(TMath::BreitWigner(t->GetPx(),3,2)); + + refAlias->Fill(head->GetEvtNum()*6+t->GetPx()*t->GetPy()); } } diff --git a/tree/inc/TChain.h b/tree/inc/TChain.h index 54bc710910363b8f20fc12ffe3635dc131f73a8f..2a3f8b5c14b6226f62637753eda91ba9588f3373 100644 --- a/tree/inc/TChain.h +++ b/tree/inc/TChain.h @@ -1,4 +1,4 @@ -// @(#)root/tree:$Name: $:$Id: TChain.h,v 1.30 2003/03/19 14:01:50 rdm Exp $ +// @(#)root/tree:$Name: $:$Id: TChain.h,v 1.31 2003/06/24 14:00:59 brun Exp $ // Author: Rene Brun 03/02/97 /************************************************************************* @@ -82,6 +82,7 @@ public: TObjArray *GetListOfBranches(); TObjArray *GetListOfFiles() const {return fFiles;} TObjArray *GetListOfLeaves(); + const char *GetAlias(const char *aliasName) const; virtual Double_t GetMaximum(const char *columname); virtual Double_t GetMinimum(const char *columname); virtual Int_t GetNbranches(); diff --git a/tree/inc/TTree.h b/tree/inc/TTree.h index 8e019830547a519ff5538cc1f1d3be97a2b9c551..bbd5632467911e86bfabc3764066eba15402ef54 100644 --- a/tree/inc/TTree.h +++ b/tree/inc/TTree.h @@ -1,4 +1,4 @@ -// @(#)root/tree:$Name: $:$Id: TTree.h,v 1.45 2003/01/17 17:48:56 brun Exp $ +// @(#)root/tree:$Name: $:$Id: TTree.h,v 1.46 2003/03/19 14:01:50 rdm Exp $ // Author: Rene Brun 12/01/96 /************************************************************************* @@ -111,6 +111,7 @@ protected: TDirectory *fDirectory; //! Pointer to directory holding this tree TObjArray fBranches; // List of Branches TObjArray fLeaves; // Direct pointers to individual branch leaves + TList *fAliases; // List of aliases for expressions based on the tree branches. TEventList *fEventList; //! Pointer to event selection list (if one) TArrayD fIndexValues; // Sorted index values TArrayI fIndex; // Index of sorted values @@ -170,6 +171,7 @@ public: virtual Int_t Fit(const char *funcname ,const char *varexp, const char *selection="",Option_t *option="" ,Option_t *goption="" ,Int_t nentries=1000000000, Int_t firstentry=0); // *MENU* + virtual const char *GetAlias(const char *aliasName) const; virtual TBranch *GetBranch(const char *name); virtual Bool_t GetBranchStatus(const char *branchname) const; static Int_t GetBranchStyle(); @@ -200,6 +202,7 @@ public: virtual TObjArray *GetListOfBranches() {return &fBranches;} virtual TObjArray *GetListOfLeaves() {return &fLeaves;} virtual TList *GetListOfFriends() const {return fFriends;} + virtual TSeqCollection *GetListOfAliases() const {return fAliases;} virtual Int_t GetMakeClass() const {return fMakeClass;} virtual Int_t GetMaxEntryLoop() const {return fMaxEntryLoop;} virtual Double_t GetMaximum(const char *columname); @@ -251,6 +254,7 @@ public: virtual void Reset(Option_t *option=""); virtual Int_t Scan(const char *varexp="", const char *selection="", Option_t *option="" ,Int_t nentries=1000000000, Int_t firstentry=0); // *MENU* + virtual Bool_t SetAlias(const char *aliasName, const char *aliasFormula); virtual void SetAutoSave(Int_t autos=10000000) {fAutoSave=autos;} virtual void SetBasketSize(const char *bname,Int_t buffsize=16000); virtual void SetBranchAddress(const char *bname,void *add); @@ -278,7 +282,7 @@ public: ,Int_t nentries=1000000000, Int_t firstentry=0); void UseCurrentStyle(); - ClassDef(TTree,9) //Tree descriptor (the main ROOT I/O class) + ClassDef(TTree,10) //Tree descriptor (the main ROOT I/O class) }; ////////////////////////////////////////////////////////////////////////// diff --git a/tree/src/TChain.cxx b/tree/src/TChain.cxx index 8cd402ad7de9d18aa1e8d1b1218eaecc5826a502..6b2ca253da2fe451b2fb23c44f70b194f165e9ad 100644 --- a/tree/src/TChain.cxx +++ b/tree/src/TChain.cxx @@ -1,4 +1,4 @@ -// @(#)root/tree:$Name: $:$Id: TChain.cxx,v 1.67 2003/06/02 10:36:05 brun Exp $ +// @(#)root/tree:$Name: $:$Id: TChain.cxx,v 1.68 2003/06/24 14:00:59 brun Exp $ // Author: Rene Brun 03/02/97 /************************************************************************* @@ -651,6 +651,19 @@ Int_t TChain::GetNbranches() return 0; } +//______________________________________________________________________________ +const char *TChain::GetAlias(const char *aliasName) const +{ + // Returns the expanded value of the alias. Search in the friend if any + + const char *alias = TTree::GetAlias(aliasName); + if (alias) return alias; + + if (fTree) return fTree->GetAlias(aliasName); + const_cast<TChain*>(this)->LoadTree(0); + if (fTree) return fTree->GetAlias(aliasName); + return 0; +} //______________________________________________________________________________ Double_t TChain::GetWeight() const diff --git a/tree/src/TTree.cxx b/tree/src/TTree.cxx index 96c59b645cb785e646f096d18d73aa6a5f3fd974..64e83a6ef869d004eadc2b0e27c73e6f536a5097 100644 --- a/tree/src/TTree.cxx +++ b/tree/src/TTree.cxx @@ -1,4 +1,4 @@ -// @(#)root/tree:$Name: $:$Id: TTree.cxx,v 1.147 2003/04/17 07:44:45 brun Exp $ +// @(#)root/tree:$Name: $:$Id: TTree.cxx,v 1.148 2003/06/10 20:52:50 rdm Exp $ // Author: Rene Brun 12/01/96 /************************************************************************* @@ -332,6 +332,7 @@ TTree::TTree(): TNamed() fDebugMin = 0; fDebugMax = 9999999; fFriends = 0; + fAliases = 0; fMakeClass = 0; fNotify = 0; fFileNumber = 0; @@ -374,6 +375,7 @@ TTree::TTree(const char *name,const char *title, Int_t splitlevel) fDebugMin = 0; fDebugMax = 9999999; fFriends = 0; + fAliases = 0; fMakeClass = 0; fNotify = 0; fFileNumber = 0; @@ -417,6 +419,11 @@ TTree::~TTree() delete fFriends; fFriends = 0; } + if (fAliases) { + fAliases->Delete(); + delete fAliases; + fAliases = 0; + } fDirectory = 0; //must be done after the destruction of friends } @@ -2197,6 +2204,32 @@ Int_t TTree::Fit(const char *funcname ,const char *varexp, const char *selection else return -1; } +//______________________________________________________________________________ +const char *TTree::GetAlias(const char *aliasName) const +{ + // Returns the expanded value of the alias. Search in the friends if any + + if (fAliases) { + TObject *alias = fAliases->FindObject(aliasName); + if (alias) return alias->GetTitle(); + } + TIter nextf(fFriends); + TFriendElement *fe; + while ((fe = (TFriendElement*)nextf())) { + TTree *t = fe->GetTree(); + if (t) { + const char *alias = t->GetAlias(aliasName); + if (alias) return alias; + const char *subAliasName = strstr(aliasName,fe->GetName()); + if (subAliasName && subAliasName[strlen(fe->GetName())]=='.') { + alias = t->GetAlias(aliasName+strlen(fe->GetName())+1); + if (alias) return alias; + } + } + } + return 0; +} + //______________________________________________________________________________ TBranch *TTree::GetBranch(const char *name) { @@ -2514,6 +2547,17 @@ Int_t TTree::GetEntryWithIndex(Int_t major, Int_t minor) const char *TTree::GetFriendAlias(TTree *tree) const { // If the the 'tree' is a friend, this method returns its alias name +// This 'alias' is a an alias for the TTree itself. +// It can be used in conjunction with a branch or leaf name in a TTreeFormula. +// Is can alos be used in conjunction with an alias created using +// TTree::SetAlias in a TTreeFormula, eg: +// maintree->Draw("treealias.fPx - treealias.myAlias"); +// where fPx is a branch of the friend tree aliased as 'treealias' and 'myAlias; +// was created using TTree::SetAlias on the tree aliases as 'treealias'. +// +// However, note that 'treealias.myAlias' will be expanded literally, without +// 'remembering' it comes from the aliased friend and thus might the branch +// name might not be disambiguated properly. if (!fFriends) return 0; TIter nextf(fFriends); @@ -3167,6 +3211,50 @@ Int_t TTree::Scan(const char *varexp, const char *selection, Option_t *option, else return -1; } +//______________________________________________________________________________ +Bool_t TTree::SetAlias(const char *aliasName, const char *aliasFormula) +{ +//*-*-*-*-*-*-*-*-*-*-*Set a tree variable alias*-*-*-*-*-* +//*-* ==================================== +// +// Set an alias for an expression/formula based on the tree 'variables'. +// +// The content of 'aliasName' can be used in TTreeFormula (i.e. TTree::Draw, +// TTree::Scan, TTreeViewer) and will be evaluated as the content of +// 'aliasFormula'. +// If the alias 'aliasName' already existed, it is replaced by the new +// value. +// When being used, the alias can be preceded by an eventual 'Friend Alias' +// (see TTree::GetFriendAlias) +// +// Return true if it was added properly. +// +// For example: +// tree->SetAlias("x1","(tdc1[1]-tdc1[0])/49"); +// tree->SetAlias("y1","(tdc1[3]-tdc1[2])/47"); +// tree->SetAlias("x2","(tdc2[1]-tdc2[0])/49"); +// tree->SetAlias("y2","(tdc2[3]-tdc2[2])/47"); +// tree->Draw("y2-y1:x2-x1"); +// + + if (aliasName==0 || aliasFormula==0) return false; + if (strlen(aliasName)==0 || strlen(aliasFormula)==0) return false; + + if (fAliases==0) fAliases = new TList; + else { + TNamed *oldHolder = (TNamed*)fAliases->FindObject(aliasName); + if (oldHolder) { + oldHolder->SetTitle(aliasFormula); + return kTRUE; + } + } + + TNamed *holder = new TNamed(aliasName,aliasFormula); + fAliases->Add(holder); + + return kTRUE; +} + //_______________________________________________________________________ void TTree::SetBasketSize(const char *bname, Int_t buffsize) { diff --git a/treeplayer/inc/TTreeFormula.h b/treeplayer/inc/TTreeFormula.h index 335d21f928ff0a09ff9e7edd63894f47c32ed846..dea8b5ffebef5adc6c656ab63163248bb5b1f03c 100644 --- a/treeplayer/inc/TTreeFormula.h +++ b/treeplayer/inc/TTreeFormula.h @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.27 2003/01/30 06:40:33 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.28 2003/02/27 21:10:52 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -56,6 +56,9 @@ protected: enum { kIsCharacter = BIT(12) }; enum { kDirect, kDataMember, kMethod, kIndexOfEntry, kEntries, kLength, kIteration }; + enum { kAlias = TFormula::kVariable+10000+1, + kAliasString = kAlias+1 + }; TTree *fTree; //! pointer to Tree Short_t fCodes[kMAXCODES]; // List of leaf numbers referenced in formula @@ -68,8 +71,9 @@ protected: TObjArray fLeaves; //! List of leaf used in this formula. TObjArray fDataMembers; //! List of leaf data members TObjArray fMethods; //! List of leaf method calls + TObjArray fAliases; //! List of TTreeFormula for each alias used. TObjArray fLeafNames; // List of TNamed describing leaves - + 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. @@ -103,35 +107,45 @@ protected: void ResetDimensions(); Bool_t LoadCurrentDim(); + + virtual Bool_t IsLeafInteger(Int_t code) const; + + virtual Bool_t IsString(Int_t oper) const; + virtual Bool_t IsLeafString(Int_t code) const; +private: + // Not implemented yet + TTreeFormula(const TTreeFormula&); + TTreeFormula& operator=(const TTreeFormula&); public: TTreeFormula(); TTreeFormula(const char *name,const char *formula, TTree *tree); virtual ~TTreeFormula(); - virtual Int_t DefinedVariable(TString &variable); - virtual TClass* EvalClass() const; - virtual Double_t EvalInstance(Int_t i=0); - virtual void* EvalObject(Int_t i=0); + virtual Int_t DefinedVariable(TString &variable); + virtual TClass* EvalClass() const; + virtual Double_t EvalInstance(Int_t i=0, const char *stringStack[]=0); + 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; - 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(); + TFormLeafInfo *GetLeafInfo(Int_t code) const; + 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(Int_t code = 0) const; - virtual Bool_t IsString(Int_t code = 0) const; - virtual char *PrintValue(Int_t mode=0) const; - virtual void SetAxis(TAxis *axis=0); - virtual void SetTree(TTree *tree) {fTree = tree;} - virtual void UpdateFormulaLeaves(); - - ClassDef(TTreeFormula,7) //The Tree formula + virtual Bool_t IsInteger() const; + virtual Bool_t IsString() const; + virtual char *PrintValue(Int_t mode=0) const; + virtual void SetAxis(TAxis *axis=0); + virtual void SetTree(TTree *tree) {fTree = tree;} + virtual void UpdateFormulaLeaves(); + + ClassDef(TTreeFormula,8) //The Tree formula }; #endif diff --git a/treeplayer/src/TTreeFormula.cxx b/treeplayer/src/TTreeFormula.cxx index 360c8bafac97318c8b01ae796e3d4c9475da8033..9a5fc29e3145d57b57afb32be45058977fcd1382 100644 --- a/treeplayer/src/TTreeFormula.cxx +++ b/treeplayer/src/TTreeFormula.cxx @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.119 2003/06/21 13:27:19 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.120 2003/06/25 07:16:22 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -1361,13 +1361,13 @@ TTreeFormula::TTreeFormula(const char *name,const char *expression, TTree *tree) fNcodes = kMAXFOUND; } SetName(name); - for (i=0;i<fNcodes;i++) { - if (fCodes[i] < 0) continue; - TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i); - if (!leaf) continue; + for (i=0;i<fNoper;i++) { + if (fOper[i] >= 105000 && fOper[i]<110000) { + Int_t string_code = fOper[i]-105000; + TLeaf *leafc = (TLeaf*)fLeaves.UncheckedAt(string_code); + if (!leafc) continue; - if (fOper[i] >= 105000) { // We have a string used as a string // This dormant portion of code would be used if (when?) we allow the histogramming @@ -1385,11 +1385,16 @@ TTreeFormula::TTreeFormula(const char *name,const char *expression, TTree *tree) // just make part of a useless expression (for example: mystring+0) SetBit(kIsCharacter); } + continue; } - + } + if (fNoper==1 && fOper[0]==kAliasString) { + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(0)); + Assert(subform); + if (subform->TestBit(kIsCharacter)) SetBit(kIsCharacter); } - fManager->Sync(); + fManager->Sync(); // Let's verify the indexes and dies if we need to. Int_t k0,k1; @@ -1424,6 +1429,7 @@ TTreeFormula::~TTreeFormula() } fLeafNames.Delete(); fDataMembers.Delete(); + fAliases.Delete(); if (fLookupType) delete [] fLookupType; for (int j=0; j<fNcodes; j++) { for (int k = 0; k<fNdimensions[j]; k++) { @@ -1994,6 +2000,23 @@ Int_t TTreeFormula::DefinedVariable(TString &name) final = leaf->IsOnTerminalBranch(); } + if (!leaf) { + // Check for an alias. + const char *aliasValue = fTree->GetAlias(work); + if (aliasValue) { + TTreeFormula *subform = new TTreeFormula(work,aliasValue,fTree); + + fManager->Add(subform); + fAliases.AddAtAndExpand(subform,fNoper); + + if (subform->IsString()) { + return kAliasString - kVariable; // need to compensate for the TFormula induced offset + } else { + return kAlias - kVariable; // need to compensate for the TFormula induced offset + } + } + } + if (leaf) { // We found a Leaf. if (leaf->GetBranch() && leaf->GetBranch()->TestBit(kDoNotProcess)) { @@ -2271,7 +2294,7 @@ Int_t TTreeFormula::DefinedVariable(TString &name) maininfo = clonesinfo; clones = (TClonesArray*)clonesinfo->GetLocalValuePointer(leaf,0); - //clones = *(TClonesArray**)((TBranchElement*)branch)->GetAddress(); + //clones = *(TClonesArray**)((TBranchElement*)branch)->GetAdress(); } else { TClass *mother_cl; if (leaf->IsA()==TLeafObject::Class()) { @@ -2619,7 +2642,7 @@ Int_t TTreeFormula::DefinedVariable(TString &name) } } - if (IsString(code)) { + if (IsLeafString(code)) { if (fLookupType[code]==kDirect && leaf->InheritsFrom("TLeafElement")) { TBranchElement * br = (TBranchElement*)leaf->GetBranch(); if (br->GetType()==31) { @@ -3154,9 +3177,34 @@ void* TTreeFormula::EvalObject(int instance) } +//______________________________________________________________________________ +const char* TTreeFormula::EvalStringInstance(Int_t instance) +{ + const Int_t kMAXSTRINGFOUND = 10; + const char *stringStack[kMAXSTRINGFOUND]; + + if (fNoper==1 && fNcodes>0 && IsString()) { + TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0); + + Int_t real_instance = GetRealInstance(instance,0); + + if (!instance) leaf->GetBranch()->GetEntry(leaf->GetBranch()->GetTree()->GetReadEntry()); + else if (real_instance>fNdata[0]) return 0; + + if (fLookupType[0]==kDirect) { + return (char*)leaf->GetValuePointer(); + } else { + return (char*)GetLeafInfo(0)->GetValuePointer(leaf,0); + } + } + + EvalInstance(instance,stringStack); + + return stringStack[0]; +} //______________________________________________________________________________ -Double_t TTreeFormula::EvalInstance(Int_t instance) +Double_t TTreeFormula::EvalInstance(Int_t instance, const char *stringStackArg[]) { //*-*-*-*-*-*-*-*-*-*-*Evaluate this treeformula*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ========================= @@ -3167,7 +3215,8 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) Float_t aresult; Double_t tab[kMAXFOUND]; Double_t dexp; - char *tab2[kMAXSTRINGFOUND]; + const char *stringStackLocal[kMAXSTRINGFOUND]; + const char **stringStack = stringStackArg?stringStackArg:stringStackLocal; if (fNoper == 1 && fNcodes > 0) { switch (fCodes[0]) { @@ -3185,6 +3234,17 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) return fx->EvalInstance(instance); } } +// if (fOper[0]==kAlias) { +// TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(0)); +// Assert(subform); +// return subform->EvalInstance(instance); +// } +// if (fOper[0]==kAliasString) { +// TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(0)); +// Assert(subform); +// if (fAxis) ... +// return subform->EvalInstance(instance); +// } switch (fLookupType[0]) { case kIndexOfEntry: return fTree->GetReadEntry(); case kEntries: return fTree->GetEntries(); @@ -3201,7 +3261,7 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) if (fAxis) { char * label; // This portion is a duplicate (for speed reason) of the code - // located in the main for loop at "a tree string". + // located in the main for loop at "a tree string" (and in EvalStringInstance) if (fLookupType[0]==kDirect) { label = (char*)leaf->GetValuePointer(); } else { @@ -3227,7 +3287,7 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) if (action >= kFunctionCall) { int fno = (action-kFunctionCall) / 1000; int nargs = (action-kFunctionCall) % 1000; - + // Retrieve the function TMethodCall *method = (TMethodCall*)fFunctions.At(fno); @@ -3252,6 +3312,27 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) method->Execute(args,ret); tab[pos-1] = ret; // check for the correct conversion! + continue; + } +//*-*- a TTree Variable Alias (i.e. a sub-TTreeFormula) + if (action == kAlias) { + int aliasN = i; + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(aliasN)); + Assert(subform); + + Double_t param = subform->EvalInstance(instance); + + tab[pos] = param; pos++; + continue; + } +//*-*- a TTree Variable Alias String (i.e. a sub-TTreeFormula) + if (action == kAliasString) { + int aliasN = i; + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(aliasN)); + Assert(subform); + + pos2++; + stringStack[pos2-1] = subform->EvalStringInstance(instance); continue; } //*-*- a tree string @@ -3267,9 +3348,9 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) pos2++; if (fLookupType[string_code]==kDirect) { - tab2[pos2-1] = (char*)leafc->GetValuePointer(); + stringStack[pos2-1] = (char*)leafc->GetValuePointer(); } else { - tab2[pos2-1] = (char*)GetLeafInfo(string_code)->GetValuePointer(leafc,real_instance); + stringStack[pos2-1] = (char*)GetLeafInfo(string_code)->GetValuePointer(leafc,real_instance); } continue; } @@ -3327,8 +3408,8 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) continue; } //*-*- String - if (action == 80000) { - pos2++; tab2[pos2-1] = (char*)fExpr[i].Data(); + if (action == kStrings) { + pos2++; stringStack[pos2-1] = (char*)fExpr[i].Data(); continue; } //*-*- numerical value @@ -3378,7 +3459,8 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) case 20 : pos--; tab[pos-1] = TMath::Power(tab[pos-1],tab[pos]); break; case 21 : tab[pos-1] = tab[pos-1]*tab[pos-1]; break; case 22 : tab[pos-1] = TMath::Sqrt(TMath::Abs(tab[pos-1])); break; - case 23 : pos2 -= 2; pos++;if (tab2[pos2] && strstr(tab2[pos2],tab2[pos2+1])) tab[pos-1]=1; + case 23 : pos2 -= 2; pos++;if (stringStack[pos2] && + strstr(stringStack[pos2],stringStack[pos2+1])) tab[pos-1]=1; else tab[pos-1]=0; break; case 24 : pos--; tab[pos-1] = TMath::Min(tab[pos-1],tab[pos]); break; case 25 : pos--; tab[pos-1] = TMath::Max(tab[pos-1],tab[pos]); break; @@ -3414,9 +3496,9 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) case 67 : pos--; if (tab[pos-1]>=tab[pos]) tab[pos-1]=1; else tab[pos-1]=0; break; case 68 : if (tab[pos-1]!=0) tab[pos-1] = 0; else tab[pos-1] = 1; break; - case 76 : pos2 -= 2; pos++; if (!strcmp(tab2[pos2+1],tab2[pos2])) tab[pos-1]=1; + case 76 : pos2 -= 2; pos++; if (!strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1; else tab[pos-1]=0; break; - case 77 : pos2 -= 2; pos++;if (strcmp(tab2[pos2+1],tab2[pos2])) tab[pos-1]=1; + case 77 : pos2 -= 2; pos++;if (strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1; else tab[pos-1]=0; break; case 78 : pos--; tab[pos-1]= ((Int_t) tab[pos-1]) & ((Int_t) tab[pos]); break; case 79 : pos--; tab[pos-1]= ((Int_t) tab[pos-1]) | ((Int_t) tab[pos]); break; @@ -3561,16 +3643,23 @@ void* TTreeFormula::GetValuePointerFromMethod(Int_t i, TLeaf *leaf) const } //______________________________________________________________________________ -Bool_t TTreeFormula::IsInteger(Int_t code) const +Bool_t TTreeFormula::IsInteger() const { // return TRUE if the formula corresponds to one single Tree leaf // and this leaf is short, int or unsigned short, int // When a leaf is of type integer, the generated histogram is forced // to have an integer bin width + if (fNoper > 1) return kFALSE; + if (fOper[0]==kAlias) { + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(0)); + Assert(subform); + return subform->IsInteger(); + } + if (fLeaves.GetEntries() != 1) { - switch (fLookupType[code]) { + switch (fLookupType[0]) { case kIndexOfEntry: case kEntries: case kLength: @@ -3583,8 +3672,29 @@ Bool_t TTreeFormula::IsInteger(Int_t code) const if (EvalClass()==TBits::Class()) return kTRUE; + return IsLeafInteger(0); +} + +//______________________________________________________________________________ +Bool_t TTreeFormula::IsLeafInteger(Int_t code) const +{ + // return TRUE if the leaf corresponding to code is short, int or unsigned + // short, int When a leaf is of type integer, the generated histogram is + // forced to have an integer bin width + TLeaf *leaf = (TLeaf*)fLeaves.At(code); - if (!leaf) return kFALSE; + if (!leaf) { + switch (fLookupType[code]) { + case kIndexOfEntry: + case kEntries: + case kLength: + case kIteration: + return kTRUE; + default: + return kFALSE; + } + return kFALSE; + } if (fAxis) return kTRUE; TFormLeafInfo * info; switch (fLookupType[code]) { @@ -3602,64 +3712,83 @@ Bool_t TTreeFormula::IsInteger(Int_t code) const return kFALSE; } - //______________________________________________________________________________ -Bool_t TTreeFormula::IsString(Int_t code) const +Bool_t TTreeFormula::IsString() const { - // return TRUE if the leaf or data member corresponding to code is a string + // return TRUE if the formula is a string + + return TestBit(kIsCharacter) || (fNoper==1 && IsString(0)); +} +//______________________________________________________________________________ +Bool_t TTreeFormula::IsString(Int_t oper) const +{ + // (fOper[i]>=105000 && fOper[i]<110000) || fOper[i] == kStrings) + + // return true if the expression at the index 'oper' is to be treated as + // as string + + if (TFormula::IsString(oper)) return kTRUE; + if (fOper[oper]>=105000 && fOper[oper]<110000) return kTRUE; + if (fOper[oper]==kAliasString) return kTRUE; + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TTreeFormula::IsLeafString(Int_t code) const +{ + // return TRUE if the leaf or data member corresponding to code is a string TLeaf *leaf = (TLeaf*)fLeaves.At(code); if (!leaf) return kFALSE; - + TFormLeafInfo * info; switch(fLookupType[code]) { - case kDirect: - if ( !leaf->IsUnsigned() && (leaf->InheritsFrom("TLeafC") || leaf->InheritsFrom("TLeafB") ) ) { - // Need to find out if it is an 'array' or a pointer. - if (leaf->GetLenStatic() > 1) return kTRUE; - - // Now we need to differantiate between a variable length array and - // a TClonesArray. - if (leaf->GetLeafCount()) { - const char* indexname = leaf->GetLeafCount()->GetName(); - if (indexname[strlen(indexname)-1] == '_' ) { - // This in a clones array - return kFALSE; - } else { - // this is a variable length char array - return kTRUE; - } - } - } else if (leaf->InheritsFrom("TLeafElement")) { - TBranchElement * br = (TBranchElement*)leaf->GetBranch(); - Int_t bid = br->GetID(); - if (bid < 0) return kFALSE; - TStreamerElement * elem = (TStreamerElement*) br->GetInfo()->GetElems()[bid]; - if (elem->GetType()== TStreamerInfo::kOffsetL +kChar_t) { - // Check whether a specific element of the string is specified! - if (fIndexes[code][fNdimensions[code]-1] != -1) return kFALSE; - return kTRUE; - } - if ( elem->GetType()== TStreamerInfo::kCharStar) { - // Check whether a specific element of the string is specified! - if (fNdimensions[code] && fIndexes[code][fNdimensions[code]-1] != -1) return kFALSE; - return kTRUE; - } - return kFALSE; - } else { - return kFALSE; - } - case kMethod: - //TMethodCall *m = GetMethodCall(code); - //TMethodCall::EReturnType r = m->ReturnType(); - return kFALSE; - case kDataMember: - info = GetLeafInfo(code); - return info->IsString(); - default: - return kFALSE; + case kDirect: + if ( !leaf->IsUnsigned() && (leaf->InheritsFrom("TLeafC") || leaf->InheritsFrom("TLeafB") ) ) { + // Need to find out if it is an 'array' or a pointer. + if (leaf->GetLenStatic() > 1) return kTRUE; + + // Now we need to differantiate between a variable length array and + // a TClonesArray. + if (leaf->GetLeafCount()) { + const char* indexname = leaf->GetLeafCount()->GetName(); + if (indexname[strlen(indexname)-1] == '_' ) { + // This in a clones array + return kFALSE; + } else { + // this is a variable length char array + return kTRUE; + } + } + } else if (leaf->InheritsFrom("TLeafElement")) { + TBranchElement * br = (TBranchElement*)leaf->GetBranch(); + Int_t bid = br->GetID(); + if (bid < 0) return kFALSE; + TStreamerElement * elem = (TStreamerElement*) br->GetInfo()->GetElems()[bid]; + if (elem->GetType()== TStreamerInfo::kOffsetL +kChar_t) { + // Check whether a specific element of the string is specified! + if (fIndexes[code][fNdimensions[code]-1] != -1) return kFALSE; + return kTRUE; + } + if ( elem->GetType()== TStreamerInfo::kCharStar) { + // Check whether a specific element of the string is specified! + if (fNdimensions[code] && fIndexes[code][fNdimensions[code]-1] != -1) return kFALSE; + return kTRUE; + } + return kFALSE; + } else { + return kFALSE; + } + case kMethod: + //TMethodCall *m = GetMethodCall(code); + //TMethodCall::EReturnType r = m->ReturnType(); + return kFALSE; + case kDataMember: + info = GetLeafInfo(code); + return info->IsString(); + default: + return kFALSE; } - } //______________________________________________________________________________ @@ -3724,7 +3853,14 @@ char *TTreeFormula::PrintValue(Int_t mode) const void TTreeFormula::SetAxis(TAxis *axis) { if (!axis) {fAxis = 0; return;} - if (TestBit(kIsCharacter)) fAxis = axis; + if (TestBit(kIsCharacter)) { + fAxis = axis; + if (fNoper==1 && fOper[0]==kAliasString){ + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(0)); + Assert(subform); + subform->SetAxis(axis); + } + } if (IsInteger()) axis->SetBit(TAxis::kIsInteger); } @@ -3798,6 +3934,13 @@ void TTreeFormula::UpdateFormulaLeaves() } } } + for(Int_t k=0;k<fNoper;k++) { + if (fOper[k]==kAlias || (fOper[k]==kAliasString) ) { + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(k)); + Assert(subform); + subform->UpdateFormulaLeaves(); + } + } } //______________________________________________________________________________ @@ -3821,7 +3964,7 @@ void TTreeFormula::ResetDimensions() { last_code = info->fCode; fNdimensions[last_code] = 0; } - if (fOper[last_code]>=105000) { + if (fOper[last_code]>=105000 && fOper[last_code]<110000) { // We have a string used as a string (and not an array of number) // We need to determine which is the last dimension and skip it. DimensionInfo *nextinfo = (DimensionInfo*)next(); @@ -3844,6 +3987,36 @@ void TTreeFormula::ResetDimensions() { } fMultiplicity = 0; + for(i=0;i<fNoper;i++) { + if (fOper[i]==kAlias || fOper[i]==kAliasString) { + TTreeFormula *subform = dynamic_cast<TTreeFormula*>(fAliases.UncheckedAt(i)); + Assert(subform); + switch(subform->GetMultiplicity()) { + case 0: break; + case 1: fMultiplicity = 1; break; + case 2: if (fMultiplicity!=1) fMultiplicity = 2; break; + } + fManager->Add(subform); + // since we are addint to this manager 'subform->ResetDimensions();' + // will be called a little latter + continue; + } + if (fOper[i] >= 105000 && fOper[i]<110000) { + // We have a string used as a string + + // This dormant portion of code would be used if (when?) we allow the histogramming + // of the integral content (as opposed to the string content) of strings + // held in a variable size container delimited by a null (as opposed to + // a fixed size container or variable size container whose size is controlled + // by a variable). In GetNdata, we will then use strlen to grab the current length. + //fCumulSizes[i][fNdimensions[i]-1] = 1; + //fUsedSizes[fNdimensions[i]-1] = -TMath::Abs(fUsedSizes[fNdimensions[i]-1]); + //fUsedSizes[0] = - TMath::Abs( fUsedSizes[0]); + + //continue; + } + } + for (i=0;i<fNcodes;i++) { if (fCodes[i] < 0) { TCutG *gcut = (TCutG*)fMethods.At(i); @@ -3870,22 +4043,6 @@ void TTreeFormula::ResetDimensions() { continue; } - if (fOper[i] >= 105000) { - // We have a string used as a string - - // This dormant portion of code would be used if (when?) we allow the histogramming - // of the integral content (as opposed to the string content) of strings - // held in a variable size container delimited by a null (as opposed to - // a fixed size container or variable size container whose size is controlled - // by a variable). In GetNdata, we will then use strlen to grab the current length. - //fCumulSizes[i][fNdimensions[i]-1] = 1; - //fUsedSizes[fNdimensions[i]-1] = -TMath::Abs(fUsedSizes[fNdimensions[i]-1]); - //fUsedSizes[0] = - TMath::Abs( fUsedSizes[0]); - - //continue; - } - - if (fLookupType[i]==kIteration) { fMultiplicity = 1; continue; diff --git a/treeplayer/src/TTreeFormulaManager.cxx b/treeplayer/src/TTreeFormulaManager.cxx index 00ac2057528f7305b0f30bd732e46899a6276cfb..470f0a046fc0f0956d75a695978ea715af08581e 100644 --- a/treeplayer/src/TTreeFormulaManager.cxx +++ b/treeplayer/src/TTreeFormulaManager.cxx @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormulaManager.cxx,v 1.1 2002/03/26 08:24:01 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormulaManager.cxx,v 1.2 2002/04/04 17:28:52 rdm Exp $ // Author: Philippe Canal 20/03/02 /************************************************************************* @@ -79,7 +79,6 @@ void TTreeFormulaManager::Add(TTreeFormula* adding) TTreeFormulaManager * old = adding->fManager; if (old) { - if (old==this) { if (fFormulas.FindObject(adding)) return; } else {