From 9cd6bea0a0e4ca406ee115407aa387a244e301e1 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Fri, 1 Jun 2001 07:05:03 +0000 Subject: [PATCH] New additions by Philippe. git-svn-id: http://root.cern.ch/svn/root/trunk@2348 27541ba8-7e3a-0410-8455-c3a389f83636 --- treeplayer/inc/TTreeFormula.h | 6 +- treeplayer/src/TTreeFormula.cxx | 212 ++++++++++++++++++++++++++------ 2 files changed, 175 insertions(+), 43 deletions(-) diff --git a/treeplayer/inc/TTreeFormula.h b/treeplayer/inc/TTreeFormula.h index d606c4ea93d..97969f76dbb 100644 --- a/treeplayer/inc/TTreeFormula.h +++ b/treeplayer/inc/TTreeFormula.h @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.13 2001/05/28 06:29:54 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.14 2001/05/31 08:56:32 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -79,7 +79,7 @@ protected: Int_t fIndexes[kMAXCODES][kMAXFORMDIM]; //Index of array selected by user for each leaf TTreeFormula *fVarIndexes[kMAXCODES][kMAXFORMDIM]; //Pointer to a variable index. TArrayI *fVarDims[kMAXFORMDIM+1]; //List of variable sizes dimensions. - TArrayI *fCumulUsedVarDims; //fCumulUsedSizes for multi variable dimensions case + TArrayI *fCumulUsedVarDims; //fCumulUsedSizes(1) for multi variable dimensions case void DefineDimensions(Int_t code, Int_t size, Int_t& virt_dim); void DefineDimensions(Int_t code, TBranchElement *branch, Int_t& virt_dim); @@ -94,7 +94,7 @@ public: virtual Int_t DefinedVariable(TString &variable); virtual Double_t EvalInstance(Int_t i=0); // EvalInstance should be const. See comment on GetNdata() - TObject *GetLeafInfo(Int_t code) const; + 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; diff --git a/treeplayer/src/TTreeFormula.cxx b/treeplayer/src/TTreeFormula.cxx index 0b55c4cf02e..dff53087406 100644 --- a/treeplayer/src/TTreeFormula.cxx +++ b/treeplayer/src/TTreeFormula.cxx @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.46 2001/05/31 09:48:39 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.47 2001/05/31 16:59:36 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -48,17 +48,86 @@ public: TStreamerElement* element = 0) : fClass(classptr),fOffset(offset),fElement(element), fCounter(0), fNext(0) { - if (fClass) fInfo = fClass->GetStreamerInfo(); - else fInfo = 0; + if (fClass) fClassName = fClass->GetName(); + if (fElement) { + fElementName = fElement->GetName(); + } }; virtual ~TFormLeafInfo() { delete fCounter; delete fNext; }; - TClass *fClass; - TStreamerInfo *fInfo; - Long_t fOffset; - TStreamerElement *fElement; - TFormLeafInfo *fCounter; - TFormLeafInfo *fNext; + TClass *fClass; //! This is the class of the data pointed to + // TStreamerInfo *fInfo; //! == fClass->GetStreamerInfo() + Long_t fOffset; //! Offset of the data pointed inside the class fClass + TStreamerElement *fElement; //! Descriptor of the data pointed to. + //Warning, the offset in fElement is NOT correct because it does not take into + //account base classes and nested objects (which fOffset does). + TFormLeafInfo *fCounter; + TFormLeafInfo *fNext; // follow this to grab the inside information + + TString fClassName; + //TString fElementClassOwnerName; + TString fElementName; + + virtual Bool_t Update() { + if (fClass) { + TClass * new_class = gROOT->GetClass(fClassName); + if (new_class==fClass) { + if (fNext) fNext->Update(); + if (fCounter) fCounter->Update(); + return kFALSE; + } + fClass = new_class; + } + if (fElement) { + TClass *cl = fClass; + // We have to drill down the element name within the class. + Int_t offset,i; + TStreamerElement* element; + char * current; + Int_t nchname = fElementName.Length(); + char * work = new char[nchname+2]; + for (i=0, current = &(work[0]), fOffset=0; i<nchname+1;i++ ) { + if (i==nchname || fElementName[i]=='.') { + // A delimiter happened let's see if what we have seen + // so far does point to a data member. + *current = '\0'; + element = cl->GetStreamerInfo()->GetStreamerElement(work,offset); + if (element) { + Int_t type = element->GetType(); + if (type<60) { + fOffset += offset; + } else if (type == TStreamerInfo::kAny || + type == TStreamerInfo::kObject || + type == TStreamerInfo::kTString || + type == TStreamerInfo::kTNamed || + type == TStreamerInfo::kTObject || + type == TStreamerInfo::kObjectp || + type == TStreamerInfo::kObjectP || + type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp || + type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP) { + fOffset += offset; + cl = element->GetClassPointer(); + } + fElement = element; + current = &(work[0]); + } + } else { + if (i<nchname) *current++ = fElementName[i]; + } + } + } + if (fNext) fNext->Update(); + if (fCounter) fCounter->Update(); + return kTRUE; + } + virtual void AddOffset(Int_t offset, TStreamerElement* element) { + fOffset += offset; + fElement = element; + if (fElement ) { + // fElementClassOwnerName = cl->GetName(); + fElementName.Append(".").Append(element->GetName()); + } + } virtual Int_t GetCounterValue(TLeaf* leaf); virtual Double_t ReadValue(char *where, Int_t instance = 0); virtual Double_t GetValue(TLeaf *leaf, Int_t instance = 0); @@ -250,12 +319,25 @@ public: // on a TClonesArray object stored in a TTree. class TFormLeafInfoMethod : public TFormLeafInfo { -public: TMethodCall *fMethod; - + TString fMethodName; + TString fParams; +public: + TFormLeafInfoMethod(TClass* classptr = 0, TMethodCall *method = 0) : - TFormLeafInfo(classptr,0,0),fMethod(method) {}; + TFormLeafInfo(classptr,0,0),fMethod(method) { + if (method) { + fMethodName = method->GetMethodName(); + fParams = method->GetParams(); + } + }; + virtual Bool_t Update() { + if (!TFormLeafInfo::Update()) return kFALSE; + delete fMethod; + fMethod = new TMethodCall(fClass, fMethodName, fParams); + return kTRUE; + } virtual Double_t ReadValue(char *where, Int_t instance = 0) { // Execute the method on the given address @@ -303,12 +385,28 @@ public: { } + virtual Bool_t Update() { + Bool_t res = TFormLeafInfo::Update(); + if (fCounter2) fCounter2->Update(); + return res; + } + virtual Double_t GetValue(TLeaf *leaf, Int_t instance = 0) { return ((TLeafElement*)leaf)->GetValueSubArray(fPrimaryIndex,instance); + /* + char * where; + if (leaf->InheritsFrom("TLeafObject") ) { + where = (char*)((TLeafObject*)leaf)->GetObject(); + } else { + where = GetObjectAddress((TLeafElement*)leaf); + } + return ReadValue(where,instance); + */ } virtual Double_t ReadValue(char *where, Int_t instance = 0) { - // Return a dummy value for now + // TClonesArray* clones = (TClonesArray*)where; + // return br->GetInfo()->GetValueClones(clones,br->GetID(),fPrimaryIndex,instance,br->fOffset) return 0; } @@ -428,8 +526,8 @@ TTreeFormula::TTreeFormula(const char *name,const char *expression, TTree *tree) // We assume only one possible variable length dimension (the left most) fMultiplicity = 1; } else if (fLookupType[i]==kDataMember) { - TFormLeafInfo * leafinfo = (TFormLeafInfo*)GetLeafInfo(i); - TStreamerElement * elem = ((TFormLeafInfo*)GetLeafInfo(i))->fElement; + TFormLeafInfo * leafinfo = GetLeafInfo(i); + TStreamerElement * elem = leafinfo->fElement; if (fMultiplicity!=1) { if (leafinfo->fCounter) fMultiplicity = 1; else if (elem && elem->GetArrayDim()>0) fMultiplicity = 2; @@ -997,10 +1095,8 @@ Int_t TTreeFormula::DefinedVariable(TString &name) int bracket_level = 1; int j; for (j=++i; j<rightlen && (bracket_level>0 || right[j]=='['); j++, i++) { - if (right[j]=='[') - bracket_level++; - else if (right[j]==']') - bracket_level--; + if (right[j]=='[') bracket_level++; + else if (right[j]==']') bracket_level--; } if (bracket_level != 0) { //Error("TTreeFormula::DefinedVariable","Bracket unbalanced"); @@ -1032,7 +1128,12 @@ Int_t TTreeFormula::DefinedVariable(TString &name) } else { fIndexes[code][dim] = -2; // Index is calculated via a variable. strcpy(varindex,current); - char *end = (char*)strstr( varindex, "]" ); + char *end = varindex; + for(char bracket_level = 0;*end!=0;end++) { + if (*end=='[') bracket_level++; + if (bracket_level==0 && *end==']') break; + if (*end==']') bracket_level--; + } if (end != 0) { *end = '\0'; fVarIndexes[code][dim] = new TTreeFormula("index_var", @@ -1050,14 +1151,9 @@ Int_t TTreeFormula::DefinedVariable(TString &name) } } - // fLeaves.Add( leaf ); - // fCodes[code] = fLeaves.GetLast(); // reference to the leaf // We need to record the location in the list of leaves because // the tree might actually be a chain and in that case the leaf will // change from tree to tree!. - // This actually could be wrong if the trees of the chain have a different - // structure. - //fCodes[code] = fTree->GetListOfLeaves()->IndexOf(leaf); TTree *tleaf = leaf->GetBranch()->GetTree(); fCodes[code] = tleaf->GetListOfLeaves()->IndexOf(leaf); TNamed *named = new TNamed(leaf->GetName(),tleaf->GetName()); @@ -1250,8 +1346,8 @@ Int_t TTreeFormula::DefinedVariable(TString &name) if (type<60) { // This is a basic type ... if (leafinfo) { - leafinfo->fOffset += offset; - leafinfo->fElement = element; + // leafinfo->fOffset += offset; + leafinfo->AddOffset(offset,element); } else { leafinfo = new TFormLeafInfo(cl,offset,element); } @@ -1274,8 +1370,8 @@ Int_t TTreeFormula::DefinedVariable(TString &name) type == TStreamerInfo::kTObject ) { // this is an embedded object. We can increase the offset. if (leafinfo) { - leafinfo->fOffset += offset; - leafinfo->fElement = element; + // leafinfo->fOffset += offset; + leafinfo->AddOffset(offset,element); } else { leafinfo = new TFormLeafInfo(cl,offset,element); } @@ -1440,10 +1536,9 @@ Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) { // NOTE: We could unroll some of this loops to avoid a few tests. TFormLeafInfoMultiVarDim * info; - info = dynamic_cast<TFormLeafInfoMultiVarDim *>(fDataMembers.At(0)); + info = dynamic_cast<TFormLeafInfoMultiVarDim *>(fDataMembers.At(codeindex)); Int_t local_index; - fCumulUsedSizes[kMAXFORMDIM] = 1; if (fIndexes[codeindex][0]<0) { local_index = 0; if (instance) { @@ -1462,6 +1557,12 @@ Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) { // Inform the (appropriate) MultiVarLeafInfo that the clones array index is // local_index. + + if (fVarDims[kMAXFORMDIM]) { + fCumulUsedSizes[kMAXFORMDIM] = fVarDims[kMAXFORMDIM]->At(local_index); + } else { + fCumulUsedSizes[kMAXFORMDIM] = fUsedSizes[kMAXFORMDIM]; + } for(Int_t d = kMAXFORMDIM-1; d>0; d--) { if (fVarDims[d]) { fCumulUsedSizes[d] = fCumulUsedSizes[d+1] * fVarDims[d]->At(local_index); @@ -1500,6 +1601,15 @@ Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) { if (fIndexes[codeindex][dim]==-2) { // NOTE: Should we check that this is a valid index? local_index = (Int_t)fVarIndexes[codeindex][dim]->EvalInstance(local_index); + if (local_index<0 || + local_index>=(fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1])) { + Error("EvalInstance","Index %s is out of bound (%d/%d) in formula %s", + fVarIndexes[codeindex][dim]->GetTitle(), + local_index, + (fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1]), + GetTitle()); + local_index = (fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1])-1; + } } real_instance += local_index * fCumulSizes[codeindex][dim+1]; virt_dim ++; @@ -1516,6 +1626,15 @@ Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) { } if (fIndexes[codeindex][max_dim]==-2) { local_index = (Int_t)fVarIndexes[codeindex][max_dim]->EvalInstance(local_index); + if (local_index<0 || + local_index>=fCumulSizes[codeindex][max_dim]) { + Error("EvalInstance","Index %s is out of bound (%d/%d) in formula %s", + fVarIndexes[codeindex][max_dim]->GetTitle(), + local_index, + fCumulSizes[codeindex][max_dim], + GetTitle()); + local_index = fCumulSizes[codeindex][max_dim]-1; + } } real_instance += local_index; } @@ -1704,7 +1823,7 @@ Double_t TTreeFormula::EvalInstance(Int_t instance) } //______________________________________________________________________________ -TObject *TTreeFormula::GetLeafInfo(Int_t code) const +TFormLeafInfo *TTreeFormula::GetLeafInfo(Int_t code) const { //*-*-*-*-*-*-*-*Return DataMember corresponding to code*-*-*-*-*-* //*-* ======================================= @@ -1712,7 +1831,7 @@ TObject *TTreeFormula::GetLeafInfo(Int_t code) const // function called by TLeafObject::GetValue // with the value of fLookupType computed in TTreeFormula::DefinedVariable - return fDataMembers.UncheckedAt(code); + return (TFormLeafInfo *)fDataMembers.UncheckedAt(code); } @@ -1723,7 +1842,6 @@ TLeaf *TTreeFormula::GetLeaf(Int_t n) const //*-* ============================================ // - //return (TLeaf*)fTree->GetListOfLeaves()->UncheckedAt(fCodes[n]); return (TLeaf*)fLeaves.UncheckedAt(n); } @@ -1790,13 +1908,15 @@ Int_t TTreeFormula::GetNdata() if (leaf->IsA() == TLeafElement::Class()) { //if branchcount address not yet set, GetEntry will set the address // read branchcount value - if (!branchcount->GetAddress()) branchcount->GetEntry(fTree->GetReadEntry()); - else branchcount->TBranch::GetEntry(fTree->GetReadEntry()); + Int_t readentry = fTree->GetReadEntry(); + if (readentry==-1) readentry=0; + if (!branchcount->GetAddress()) branchcount->GetEntry(readentry); + else branchcount->TBranch::GetEntry(readentry); size = ((TBranchElement*)branchcount)->GetNdata(); TBranchElement* branch = (TBranchElement*) leaf->GetBranch(); if (branch->GetBranchCount2()) { - branch->GetBranchCount2()->GetEntry(fTree->GetReadEntry()); + branch->GetBranchCount2()->GetEntry(readentry); // Here we need to add the code to take in consideration the // double variable length @@ -1822,7 +1942,9 @@ Int_t TTreeFormula::GetNdata() //} } } else { - branchcount->GetEntry(fTree->GetReadEntry()); + Int_t readentry = fTree->GetReadEntry(); + if (readentry==-1) readentry=0; + branchcount->GetEntry(readentry); size = leaf->GetLen() / leaf->GetLenStatic(); } if (hasBranchCount2) { @@ -1861,7 +1983,9 @@ Int_t TTreeFormula::GetNdata() TFormLeafInfo *leafinfo = (TFormLeafInfo*)fDataMembers.UncheckedAt(i); if (leafinfo->fCounter) { TBranch *branch = leaf->GetBranch(); - branch->GetEntry(fTree->GetReadEntry()); + Int_t readentry = fTree->GetReadEntry(); + if (readentry==-1) readentry=0; + branch->GetEntry(readentry); size = (Int_t) leafinfo->GetCounterValue(leaf); if (fIndexes[i][0]==-1) { // Case where the index is not specified AND the 1st dimension has a variable @@ -2268,5 +2392,13 @@ void TTreeFormula::UpdateFormulaLeaves() TLeaf *leaf = fTree->GetLeaf(fNames[i]->GetName()); fLeaves[i] = leaf; } - + for (Int_t j=0; j<kMAXCODES; j++) { + for (Int_t k = 0; k<kMAXFORMDIM; k++) { + if (fVarIndexes[j][k]) { + fVarIndexes[j][k]->UpdateFormulaLeaves(); + } + } + if (fLookupType[j]==kDataMember) GetLeafInfo(j)->Update(); + } + } -- GitLab