53 const Int_t kMaxLen = 1024;
93 ClassImp(TTreeFormula);
97 inline static void R__LoadBranch(TBranch* br, Long64_t entry, Bool_t quickLoad)
99 if (!quickLoad || (br->GetReadEntry() != entry)) {
109 class TDimensionInfo :
public TObject {
114 TFormLeafInfoMultiVarDim* fMultiDim;
115 TDimensionInfo(Int_t code, Int_t oper, Int_t size, TFormLeafInfoMultiVarDim* multiDim)
116 : fCode(code), fOper(oper), fSize(size), fMultiDim(multiDim) {};
117 ~TDimensionInfo() {};
122 TTreeFormula::TTreeFormula(): ROOT::v5::TFormula(), fQuickLoad(kFALSE), fNeedLoading(kTRUE),
123 fDidBooleanOptimization(kFALSE), fDimensionSetup(0)
139 for (j=0; j<kMAXCODES; j++) {
143 fHasMultipleVarDim[j] = kFALSE;
144 for (k = 0; k<kMAXFORMDIM; k++) {
146 fCumulSizes[j][k] = 1;
147 fVarIndexes[j][k] = 0;
155 TTreeFormula::TTreeFormula(
const char *name,
const char *expression, TTree *tree)
156 :ROOT::v5::TFormula(), fTree(tree), fQuickLoad(kFALSE), fNeedLoading(kTRUE),
157 fDidBooleanOptimization(kFALSE), fDimensionSetup(0)
159 Init(name,expression);
165 TTreeFormula::TTreeFormula(
const char *name,
const char *expression, TTree *tree,
166 const std::vector<std::string>& aliases)
167 :ROOT::v5::TFormula(), fTree(tree), fQuickLoad(kFALSE), fNeedLoading(kTRUE),
168 fDidBooleanOptimization(kFALSE), fDimensionSetup(0), fAliasesUsed(aliases)
170 Init(name,expression);
176 void TTreeFormula::Init(
const char*name,
const char* expression)
178 TDirectory *
const savedir=gDirectory;
181 fLookupType =
new Int_t[fNindex];
188 fManager =
new TTreeFormulaManager;
191 for (j=0; j<kMAXCODES; j++) {
193 fLookupType[j] = kDirect;
196 fHasMultipleVarDim[j] = kFALSE;
197 for (k = 0; k<kMAXFORMDIM; k++) {
199 fCumulSizes[j][k] = 1;
200 fVarIndexes[j][k] = 0;
204 fDimensionSetup =
new TList;
206 if (Compile(expression)) {
207 fTree = 0; fNdim = 0;
208 if(savedir) savedir->cd();
212 if (fNcodes >= kMAXFOUND) {
213 Warning(
"TTreeFormula",
"Too many items in expression:%s",expression);
218 for (i=0;i<fNoper;i++) {
220 if (GetAction(i)==kDefinedString) {
221 Int_t string_code = GetActionParam(i);
222 TLeaf *leafc = (TLeaf*)fLeaves.UncheckedAt(string_code);
223 if (!leafc)
continue;
240 SetBit(kIsCharacter);
244 if (GetAction(i)==kJump && GetActionParam(i)==(fNoper-1)) {
246 if (IsString(fNoper-1)) SetBit(kIsCharacter);
249 if (fNoper == 1 && GetAction(0)==kStringConst) {
250 SetBit(kIsCharacter);
252 if (fNoper==1 && GetAction(0)==kAliasString) {
253 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
255 if (subform->IsString()) SetBit(kIsCharacter);
256 }
else if (fNoper==2 && GetAction(0)==kAlternateString) {
257 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
259 if (subform->IsString()) SetBit(kIsCharacter);
266 for(k0 = 0; k0 < fNcodes; k0++) {
267 for(k1 = 0; k1 < fNdimensions[k0]; k1++ ) {
269 if ( fIndexes[k0][k1]>=0 && fFixedSizes[k0][k1]>=0
270 && fIndexes[k0][k1]>=fFixedSizes[k0][k1]) {
271 Error(
"TTreeFormula",
272 "Index %d for dimension #%d in %s is too high (max is %d)",
273 fIndexes[k0][k1],k1+1, expression,fFixedSizes[k0][k1]-1);
274 fTree = 0; fNdim = 0;
275 if(savedir) savedir->cd();
282 for(k=0; k<fNcodes ; k++) {
283 TLeaf *leaf = k <= fLeaves.GetLast() ? (TLeaf*)fLeaves.UncheckedAt(k) : 0;
286 branch = leaf->GetBranch();
287 if (fBranches.FindObject(branch)) branch = 0;
289 fBranches.AddAtAndExpand(branch,k);
292 if (IsInteger(kFALSE)) SetBit(kIsInteger);
294 if (TestBit(TTreeFormula::kNeedEntries)) {
300 Long64_t readentry = fTree->GetReadEntry();
301 Int_t treenumber = fTree->GetTreeNumber();
303 if (treenumber != fTree->GetTreeNumber()) {
304 if (readentry >= 0) {
305 fTree->LoadTree(readentry);
307 UpdateFormulaLeaves();
309 if (readentry >= 0) {
310 fTree->LoadTree(readentry);
316 if(savedir) savedir->cd();
322 TTreeFormula::~TTreeFormula()
325 fManager->Remove(
this);
326 if (fManager->fFormulas.GetLast()<0) {
334 fDataMembers.Delete();
337 if (fLookupType)
delete [] fLookupType;
338 for (
int j=0; j<fNcodes; j++) {
339 for (
int k = 0; k<fNdimensions[j]; k++) {
340 if (fVarIndexes[j][k])
delete fVarIndexes[j][k];
341 fVarIndexes[j][k] = 0;
344 if (fDimensionSetup) {
345 fDimensionSetup->Delete();
346 delete fDimensionSetup;
354 void TTreeFormula::DefineDimensions(Int_t code, Int_t size,
355 TFormLeafInfoMultiVarDim * info,
358 fManager->EnableMultiVarDims();
360 info->fVirtDim = virt_dim;
361 fManager->AddVarDims(virt_dim);
366 bool scalarindex =
false;
368 if (fIndexes[code][fNdimensions[code]]==-2) {
369 TTreeFormula *indexvar = fVarIndexes[code][fNdimensions[code]];
371 Int_t index_multiplicity = indexvar->GetMultiplicity();
372 switch (index_multiplicity) {
379 vsize = indexvar->GetNdata();
387 fCumulSizes[code][fNdimensions[code]] = size;
389 if ( !scalarindex && fIndexes[code][fNdimensions[code]] < 0 ) {
390 fManager->UpdateUsedSize(virt_dim, vsize);
393 fNdimensions[code] ++;
400 Int_t TTreeFormula::RegisterDimensions(
const char *info, Int_t code)
403 const char * current;
404 Int_t size, scanindex, vardim;
412 if (current[0] !=
'[') current--;
415 scanindex = sscanf(current,
"%d",&size);
419 if (scanindex==0) size = -1;
421 vardim += RegisterDimensions(code, size);
423 if (fNdimensions[code] >= kMAXFORMDIM) {
428 current = (
char*)strstr( current,
"[" );
437 Int_t TTreeFormula::RegisterDimensions(Int_t code, Int_t size, TFormLeafInfoMultiVarDim * multidim) {
438 TDimensionInfo * info =
new TDimensionInfo(code,fNoper,size,multidim);
439 fDimensionSetup->Add(info);
440 fCumulSizes[code][fNdimensions[code]] = size;
441 fNdimensions[code] ++;
442 return (size==-1) ? 1 : 0;
448 Int_t TTreeFormula::RegisterDimensions(Int_t code, TFormLeafInfo *leafinfo,
450 Bool_t useCollectionObject) {
451 Int_t ndim, size, current, vardim;
454 const TStreamerElement * elem = leafinfo->fElement;
455 TClass* c = elem ? elem->GetClassPointer() : 0;
457 TFormLeafInfoMultiVarDim * multi =
dynamic_cast<TFormLeafInfoMultiVarDim *
>(leafinfo);
460 fManager->EnableMultiVarDims();
461 multi->fDim = fNdimensions[code];
462 return RegisterDimensions(code, -1, multi);
464 if (elem->IsA() == TStreamerBasicPointer::Class()) {
466 if (elem->GetArrayDim()>0) {
468 ndim = elem->GetArrayDim();
469 size = elem->GetMaxIndex(0);
470 vardim += RegisterDimensions(code, -1);
476 TStreamerBasicPointer *array = (TStreamerBasicPointer*)elem;
477 TClass *cl = leafinfo->fClass;
479 TStreamerElement* counter = ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(array->GetCountName(),offset);
481 leafinfo->fCounter =
new TFormLeafInfo(cl,offset,counter);
483 if (maininfo==0 || maininfo==leafinfo || 1) {
484 leafinfo->fCounter =
new TFormLeafInfo(cl,offset,counter);
486 leafinfo->fCounter = maininfo->DeepCopy();
487 TFormLeafInfo *currentinfo = leafinfo->fCounter;
488 while(currentinfo->fNext && currentinfo->fNext->fNext) currentinfo=currentinfo->fNext;
489 delete currentinfo->fNext;
490 currentinfo->fNext =
new TFormLeafInfo(cl,offset,counter);
493 }
else if (!useCollectionObject && elem->GetClassPointer() == TClonesArray::Class() ) {
498 TClass * clonesClass = TClonesArray::Class();
500 TStreamerElement *counter = ((TStreamerInfo*)clonesClass->GetStreamerInfo())->GetStreamerElement(
"fLast",c_offset);
501 leafinfo->fCounter =
new TFormLeafInfo(clonesClass,c_offset,counter);
503 }
else if (!useCollectionObject && elem->GetClassPointer() && elem->GetClassPointer()->GetCollectionProxy() ) {
505 if (
typeid(*leafinfo) ==
typeid(TFormLeafInfoCollection) ) {
509 R__ASSERT( fHasMultipleVarDim[code] );
514 }
else if ( c && c->GetReferenceProxy() && c->GetReferenceProxy()->HasCounter() ) {
517 }
else if (elem->GetArrayDim()>0) {
519 ndim = elem->GetArrayDim();
520 size = elem->GetMaxIndex(0);
522 }
else if ( elem->GetNewType()== TStreamerInfo::kCharStar) {
536 vardim += RegisterDimensions(code, size);
538 if (fNdimensions[code] >= kMAXFORMDIM) {
544 size = elem->GetMaxIndex(current);
545 }
while (current<ndim);
553 Int_t TTreeFormula::RegisterDimensions(Int_t code, TBranchElement *branch) {
554 TBranchElement * leafcount2 = branch->GetBranchCount2();
557 TBranchElement *leafcount =
dynamic_cast<TBranchElement*
>(branch->GetBranchCount());
559 R__ASSERT(leafcount);
561 fManager->EnableMultiVarDims();
562 TFormLeafInfoMultiVarDim * info =
new TFormLeafInfoMultiVarDimDirect();
563 fDataMembers.AddAtAndExpand(info, code);
564 fHasMultipleVarDim[code] = kTRUE;
566 info->fCounter =
new TFormLeafInfoDirect(leafcount);
567 info->fCounter2 =
new TFormLeafInfoDirect(leafcount2);
568 info->fDim = fNdimensions[code];
573 return RegisterDimensions(code, -1, info);
581 Int_t TTreeFormula::RegisterDimensions(Int_t code, TLeaf *leaf) {
582 Int_t numberOfVarDim = 0;
587 const char *tname = leaf->GetTitle();
588 char *leaf_dim = (
char*)strstr( tname,
"[" );
590 const char *bname = leaf->GetBranch()->GetName();
591 char *branch_dim = (
char*)strstr(bname,
"[");
592 if (branch_dim) branch_dim++;
594 Bool_t isString = kFALSE;
595 if (leaf->IsA() == TLeafElement::Class()) {
596 Int_t type =((TBranchElement*)leaf->GetBranch())->GetStreamerType();
597 isString = (type == TStreamerInfo::kOffsetL+TStreamerInfo::kChar)
598 || (type == TStreamerInfo::kCharStar);
600 isString = (leaf->IsA() == TLeafC::Class());
604 if (!branch_dim || strncmp(branch_dim,leaf_dim,strlen(branch_dim))) {
606 numberOfVarDim += RegisterDimensions( leaf_dim, code);
607 }
else if (branch_dim && strncmp(branch_dim,leaf_dim,strlen(branch_dim))==0
608 && strlen(leaf_dim)>strlen(branch_dim)
609 && (leaf_dim+strlen(branch_dim))[0]==
'[') {
611 numberOfVarDim += RegisterDimensions( leaf_dim+strlen(branch_dim)+1, code);
617 numberOfVarDim += RegisterDimensions( code, 1);
619 numberOfVarDim += RegisterDimensions( branch_dim, code);
622 if (leaf->IsA() == TLeafElement::Class()) {
623 TBranchElement* branch = (TBranchElement*) leaf->GetBranch();
624 if (branch->GetBranchCount2()) {
626 if (!branch->GetBranchCount()) {
627 Warning(
"DefinedVariable",
628 "Noticed an incorrect in-memory TBranchElement object (%s).\nIt has a BranchCount2 but no BranchCount!\nThe result might be incorrect!",
630 return numberOfVarDim;
634 if (fLookupType[code] == kDataMember)
635 Warning(
"DefinedVariable",
636 "Already in kDataMember mode when handling multiple variable dimensions");
637 fLookupType[code] = kDataMember;
640 numberOfVarDim += RegisterDimensions( code, branch);
644 return numberOfVarDim;
655 Int_t TTreeFormula::DefineAlternate(
const char *expression)
657 static const char *altfunc =
"Alt$(";
658 static const char *minfunc =
"MinIf$(";
659 static const char *maxfunc =
"MaxIf$(";
663 if ( strncmp(expression,altfunc,strlen(altfunc))==0
664 && expression[strlen(expression)-1]==
')' ) {
666 start = strlen(altfunc);
668 if ( strncmp(expression,maxfunc,strlen(maxfunc))==0
669 && expression[strlen(expression)-1]==
')' ) {
671 start = strlen(maxfunc);
673 if ( strncmp(expression,minfunc,strlen(minfunc))==0
674 && expression[strlen(expression)-1]==
')' ) {
676 start = strlen(minfunc);
680 TString full = expression;
686 for(
unsigned int i=start;i<strlen(expression);++i) {
687 switch (expression[i]) {
688 case '(': paran++;
break;
689 case ')': paran--;
break;
690 case '"': instr = instr ? 0 : 1;
break;
691 case '[': brack++;
break;
692 case ']': brack--;
break;
694 if (expression[i]==
',' && paran==0 && instr==0 && brack==0) {
695 part1 = full( start, i-start );
696 part2 = full( i+1, full.Length() -1 - (i+1) );
700 if (part1.Length() && part2.Length()) {
701 TTreeFormula *primary =
new TTreeFormula(
"primary",part1,fTree);
702 TTreeFormula *alternate =
new TTreeFormula(
"alternate",part2,fTree);
706 if (action == kAlternate) {
707 if (alternate->GetManager()->GetMultiplicity() != 0 ) {
708 Error(
"DefinedVariable",
"The 2nd arguments in %s can not be an array (%s,%d)!",
709 expression,alternate->GetTitle(),
710 alternate->GetManager()->GetMultiplicity());
715 if (primary->IsString()) {
716 if (!alternate->IsString()) {
717 Error(
"DefinedVariable",
718 "The 2nd arguments in %s has to return the same type as the 1st argument (string)!",
723 }
else if (alternate->IsString()) {
724 Error(
"DefinedVariable",
725 "The 2nd arguments in %s has to return the same type as the 1st argument (numerical type)!",
730 primary->GetManager()->Add( alternate );
731 primary->GetManager()->Sync();
732 if (primary->IsString() || alternate->IsString()) {
733 if (!alternate->IsString()) {
734 Error(
"DefinedVariable",
735 "The arguments of %s can not be strings!",
742 fAliases.AddAtAndExpand(primary,fNoper);
744 SetAction(fNoper, (Int_t)action + isstring, 0 );
747 fAliases.AddAtAndExpand(alternate,fNoper);
748 return (Int_t)kAlias + isstring;
762 Int_t TTreeFormula::ParseWithLeaf(TLeaf* leaf,
const char* subExpression, Bool_t
final, UInt_t paran_level, TObjArray& castqueue, Bool_t useLeafCollectionObject,
const char* fullExpression)
766 Int_t numberOfVarDim = 0;
769 char scratch[kMaxLen]; scratch[0] =
'\0';
770 char work[kMaxLen]; work[0] =
'\0';
772 const char *right = subExpression;
773 TString name = fullExpression;
775 TBranch *branch = leaf ? leaf->GetBranch() : 0;
776 Long64_t readentry = fTree->GetTree()->GetReadEntry();
777 if (readentry < 0) readentry=0;
779 Bool_t useLeafReferenceObject =
false;
780 Int_t code = fNcodes-1;
783 if (leaf && leaf->IsA()==TLeafElement::Class()) {
784 TBranchElement *br = 0;
785 if( branch->IsA() == TBranchElement::Class() )
787 br = ((TBranchElement*)branch);
789 if ( br->GetInfo() == 0 ) {
790 Error(
"DefinedVariable",
"Missing StreamerInfo for %s. We will be unable to read!",
796 TBranch *bmom = branch->GetMother();
797 if( bmom->IsA() == TBranchElement::Class() )
799 TBranchElement *mom = (TBranchElement*)br->GetMother();
801 if (mom->GetInfo()==0) {
802 Error(
"DefinedVariable",
"Missing StreamerInfo for %s."
803 " We will be unable to read!",
807 if ((mom->GetType()) < -1 && !mom->GetAddress()) {
808 Error(
"DefinedVariable",
"Address not set when the type of the branch is negative for for %s. We will be unable to read!", mom->GetName());
820 TTree *realtree = fTree->GetTree();
821 const char* alias = 0;
823 if (realtree) alias = realtree->GetFriendAlias(leaf->GetBranch()->GetTree());
824 if (!alias && realtree!=fTree) {
826 alias = fTree->GetFriendAlias(leaf->GetBranch()->GetTree());
829 if (alias) snprintf(scratch,kMaxLen-1,
"%s.%s",alias,leaf->GetName());
830 else if (leaf) strlcpy(scratch,leaf->GetName(),kMaxLen);
832 TTree *tleaf = realtree;
834 tleaf = leaf->GetBranch()->GetTree();
835 fCodes[code] = tleaf->GetListOfLeaves()->IndexOf(leaf);
836 const char *mother_name = leaf->GetBranch()->GetMother()->GetName();
837 TString br_extended_name;
838 if (leaf->GetBranch()!=leaf->GetBranch()->GetMother()) {
839 if (mother_name[strlen(mother_name)-1]!=
'.') {
840 br_extended_name = mother_name;
841 br_extended_name.Append(
'.');
844 br_extended_name.Append( leaf->GetBranch()->GetName() );
845 Ssiz_t dim = br_extended_name.First(
'[');
846 if (dim >= 0) br_extended_name.Remove(dim);
848 TNamed *named =
new TNamed(scratch,br_extended_name.Data());
849 fLeafNames.AddAtAndExpand(named,code);
850 fLeaves.AddAtAndExpand(leaf,code);
855 if (tleaf != realtree && tleaf->GetTreeIndex()) {
857 if (fMultiplicity >= 0) fMultiplicity = 1;
864 TFormLeafInfo *maininfo = 0;
865 TFormLeafInfo *previnfo = 0;
866 Bool_t unwindCollection = kFALSE;
867 const static TClassRef stdStringClass = TClass::GetClass(
"string");
870 TNamed *names = (TNamed*)fLeafNames.UncheckedAt(code);
871 fLeafNames.AddAt(0,code);
872 TTree *what = (TTree*)fLeaves.UncheckedAt(code);
873 fLeaves.AddAt(0,code);
875 cl = what ? what->IsA() : TTree::Class();
876 maininfo =
new TFormLeafInfoTTree(fTree,names->GetName(),what);
880 }
else if (leaf->InheritsFrom(TLeafObject::Class()) ) {
881 TBranchObject *bobj = (TBranchObject*)leaf->GetBranch();
882 cl = TClass::GetClass(bobj->GetClassName());
883 }
else if (leaf->InheritsFrom(TLeafElement::Class())) {
884 TBranchElement *branchEl = (TBranchElement *)leaf->GetBranch();
885 branchEl->SetupAddresses();
886 TStreamerInfo *info = branchEl->GetInfo();
887 TStreamerElement *element = 0;
888 Int_t type = branchEl->GetStreamerType();
890 case TStreamerInfo::kBase:
891 case TStreamerInfo::kObject:
892 case TStreamerInfo::kTString:
893 case TStreamerInfo::kTNamed:
894 case TStreamerInfo::kTObject:
895 case TStreamerInfo::kAny:
896 case TStreamerInfo::kAnyP:
897 case TStreamerInfo::kAnyp:
898 case TStreamerInfo::kSTL:
899 case TStreamerInfo::kSTLp:
900 case TStreamerInfo::kObjectp:
901 case TStreamerInfo::kObjectP: {
902 element = info->GetElement(branchEl->GetID());
903 if (element) cl = element->GetClassPointer();
906 case TStreamerInfo::kOffsetL + TStreamerInfo::kSTL:
907 case TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp:
908 case TStreamerInfo::kOffsetL + TStreamerInfo::kAny:
909 case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp:
910 case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP:
911 case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp:
912 case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP:
913 case TStreamerInfo::kOffsetL + TStreamerInfo::kObject: {
914 element = info->GetElement(branchEl->GetID());
916 cl = element->GetClassPointer();
921 cl = info->GetClass();
928 if (cl && branchEl->GetBranchCount()) {
929 if (branchEl->GetType()==31) {
933 Warning(
"DefinedVariable",
934 "Missing TStreamerElement in object in TClonesArray section");
937 TFormLeafInfo* clonesinfo =
new TFormLeafInfoClones(cl, 0, element, kTRUE);
945 maininfo = clonesinfo;
949 info->GetStreamerElement(element->GetName(),offset);
950 if (type == TStreamerInfo::kObjectp ||
951 type == TStreamerInfo::kObjectP ||
952 type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp ||
953 type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP ||
954 type == TStreamerInfo::kSTLp ||
955 type == TStreamerInfo::kAnyp ||
956 type == TStreamerInfo::kAnyP ||
957 type == TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp ||
958 type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp ||
959 type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP) {
960 previnfo =
new TFormLeafInfoPointer(cl,offset+branchEl->GetOffset(),element);
962 previnfo =
new TFormLeafInfo(cl,offset+branchEl->GetOffset(),element);
964 maininfo->fNext = previnfo;
965 unwindCollection = kTRUE;
967 }
else if (branchEl->GetType()==41) {
972 Warning(
"DefinedVariable",
"Missing TStreamerElement in object in Collection section");
976 TBranchElement *count = branchEl->GetBranchCount();
977 TFormLeafInfo* collectioninfo;
978 if ( count->GetID() >= 0 ) {
979 TStreamerElement *collectionElement =
980 count->GetInfo()->GetElement(count->GetID());
981 TClass *collectionCl = collectionElement->GetClassPointer();
984 new TFormLeafInfoCollection(collectionCl, 0, collectionElement, kTRUE);
986 TClass *collectionCl = TClass::GetClass(count->GetClassName());
988 new TFormLeafInfoCollection(collectionCl, 0, collectionCl, kTRUE);
997 maininfo = collectioninfo;
1001 info->GetStreamerElement(element->GetName(),offset);
1002 if (type == TStreamerInfo::kObjectp ||
1003 type == TStreamerInfo::kObjectP ||
1004 type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp ||
1005 type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP ||
1006 type == TStreamerInfo::kSTLp ||
1007 type == TStreamerInfo::kAnyp ||
1008 type == TStreamerInfo::kAnyP ||
1009 type == TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp ||
1010 type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp ||
1011 type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP) {
1012 previnfo =
new TFormLeafInfoPointer(cl,offset+branchEl->GetOffset(),element);
1014 previnfo =
new TFormLeafInfo(cl,offset+branchEl->GetOffset(),element);
1016 maininfo->fNext = previnfo;
1017 unwindCollection = kTRUE;
1019 }
else if ( branchEl->GetType()==3) {
1020 TFormLeafInfo* clonesinfo;
1021 if (useLeafCollectionObject) {
1022 clonesinfo =
new TFormLeafInfoCollectionObject(cl);
1024 clonesinfo =
new TFormLeafInfoClones(cl, 0, kTRUE);
1026 numberOfVarDim += RegisterDimensions(code,clonesinfo,maininfo,useLeafCollectionObject);
1029 maininfo = clonesinfo;
1030 previnfo = maininfo;
1032 }
else if (!useLeafCollectionObject && branchEl->GetType()==4) {
1034 TFormLeafInfo* collectioninfo;
1035 if (useLeafCollectionObject) {
1036 collectioninfo =
new TFormLeafInfoCollectionObject(cl);
1038 collectioninfo =
new TFormLeafInfoCollection(cl, 0, cl, kTRUE);
1040 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,useLeafCollectionObject);
1043 maininfo = collectioninfo;
1044 previnfo = maininfo;
1046 }
else if (branchEl->GetStreamerType()==-1 && cl && cl->GetCollectionProxy()) {
1048 if (useLeafCollectionObject) {
1050 TFormLeafInfo *collectioninfo =
new TFormLeafInfoCollectionObject(cl);
1051 maininfo = collectioninfo;
1052 previnfo = collectioninfo;
1055 TFormLeafInfo *collectioninfo =
new TFormLeafInfoCollection(cl, 0, cl, kTRUE);
1057 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
1059 maininfo = collectioninfo;
1060 previnfo = collectioninfo;
1062 if (cl->GetCollectionProxy()->GetValueClass()!=0 &&
1063 cl->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()!=0) {
1065 TFormLeafInfo *multi =
new TFormLeafInfoMultiVarDimCollection(cl,0,
1066 cl->GetCollectionProxy()->GetValueClass(),collectioninfo);
1068 fHasMultipleVarDim[code] = kTRUE;
1069 numberOfVarDim += RegisterDimensions(code,multi,maininfo,kFALSE);
1070 previnfo->fNext = multi;
1071 cl = cl->GetCollectionProxy()->GetValueClass();
1072 multi->fNext =
new TFormLeafInfoCollection(cl, 0, cl,
false);
1073 previnfo = multi->fNext;
1076 if (cl->GetCollectionProxy()->GetValueClass()==0 &&
1077 cl->GetCollectionProxy()->GetType()>0) {
1080 new TFormLeafInfoNumerical(cl->GetCollectionProxy());
1081 previnfo = previnfo->fNext;
1087 }
else if (strlen(right)==0 && cl && element &&
final) {
1089 TClass *elemCl = element->GetClassPointer();
1090 if (!useLeafCollectionObject
1091 && elemCl && elemCl->GetCollectionProxy()
1092 && elemCl->GetCollectionProxy()->GetValueClass()
1093 && elemCl->GetCollectionProxy()->GetValueClass()->GetCollectionProxy()) {
1095 TFormLeafInfo *collectioninfo =
1096 new TFormLeafInfoCollection(cl, 0, elemCl);
1099 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
1101 maininfo = collectioninfo;
1102 previnfo = collectioninfo;
1104 TFormLeafInfo *multi =
1105 new TFormLeafInfoMultiVarDimCollection(elemCl, 0,
1106 elemCl->GetCollectionProxy()->GetValueClass(),
1109 fHasMultipleVarDim[code] = kTRUE;
1110 numberOfVarDim += RegisterDimensions(code,multi,maininfo,kFALSE);
1111 previnfo->fNext = multi;
1112 cl = elemCl->GetCollectionProxy()->GetValueClass();
1113 multi->fNext =
new TFormLeafInfoCollection(cl, 0, cl,
false);
1114 previnfo = multi->fNext;
1116 if (cl->GetCollectionProxy()->GetValueClass()==0 &&
1117 cl->GetCollectionProxy()->GetType()>0) {
1120 new TFormLeafInfoNumerical(cl->GetCollectionProxy());
1121 previnfo = previnfo->fNext;
1124 }
else if (!useLeafCollectionObject
1125 && elemCl && elemCl->GetCollectionProxy()
1126 && elemCl->GetCollectionProxy()->GetValueClass()==0
1127 && elemCl->GetCollectionProxy()->GetType()>0) {
1134 TFormLeafInfo* collectioninfo =
1135 new TFormLeafInfoCollection(cl, 0, elemCl);
1138 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
1140 collectioninfo->fNext =
1141 new TFormLeafInfoNumerical(elemCl->GetCollectionProxy());
1143 maininfo = collectioninfo;
1144 previnfo = maininfo->fNext;
1146 }
else if (!useLeafCollectionObject
1147 && elemCl && elemCl->GetCollectionProxy()) {
1148 if (elemCl->GetCollectionProxy()->GetValueClass()==TString::Class()) {
1150 }
else if (elemCl->GetCollectionProxy()->GetValueClass()==stdStringClass) {
1154 }
else if (!element->IsaPointer()) {
1156 maininfo =
new TFormLeafInfoDirect(branchEl);
1157 previnfo = maininfo;
1161 else if ( cl && cl->GetReferenceProxy() ) {
1162 if ( useLeafCollectionObject || fullExpression[0] ==
'@' || fullExpression[strlen(scratch)] ==
'@' ) {
1163 useLeafReferenceObject =
true;
1167 maininfo = previnfo =
new TFormLeafInfoReference(cl, element, 0);
1168 numberOfVarDim += RegisterDimensions(code,maininfo,maininfo,kFALSE);
1170 TVirtualRefProxy *refproxy = cl->GetReferenceProxy();
1171 for(Long64_t i=0; i<leaf->GetBranch()->GetEntries()-readentry; ++i) {
1172 R__LoadBranch(leaf->GetBranch(), readentry+i, fQuickLoad);
1173 void *refobj = maininfo->GetValuePointer(leaf,0);
1175 cl = refproxy->GetValueClass(refobj);
1180 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->GetName());
1188 if (leaf) numberOfVarDim += RegisterDimensions(code,leaf);
1191 if (unwindCollection) {
1194 R__ASSERT(numberOfVarDim==1 && maininfo);
1196 if (!useLeafCollectionObject && cl && cl->GetCollectionProxy()) {
1197 TFormLeafInfo *multi =
1198 new TFormLeafInfoMultiVarDimCollection(cl, 0, cl, maininfo);
1199 fHasMultipleVarDim[code] = kTRUE;
1200 numberOfVarDim += RegisterDimensions(code,multi,maininfo,kFALSE);
1201 previnfo->fNext = multi;
1203 multi->fNext =
new TFormLeafInfoCollection(cl, 0, cl,
false);
1204 previnfo = multi->fNext;
1206 if (cl->GetCollectionProxy()->GetValueClass()==0 &&
1207 cl->GetCollectionProxy()->GetType()>0) {
1210 new TFormLeafInfoNumerical(cl->GetCollectionProxy());
1211 previnfo = previnfo->fNext;
1213 }
else if (!useLeafCollectionObject && cl == TClonesArray::Class()) {
1215 TFormLeafInfo *multi =
1216 new TFormLeafInfoMultiVarDimClones(cl, 0, cl, maininfo);
1217 fHasMultipleVarDim[code] = kTRUE;
1218 numberOfVarDim += RegisterDimensions(code,multi,maininfo,kFALSE);
1219 previnfo->fNext = multi;
1221 multi->fNext =
new TFormLeafInfoClones(cl, 0,
false);
1222 previnfo = multi->fNext;
1226 if (cl == TString::Class() && strcmp(right,
"fData")==0) {
1231 Int_t nchname = strlen(right);
1232 TFormLeafInfo *leafinfo = 0;
1233 TStreamerElement* element = 0;
1243 TClass * casted = (TClass*) castqueue.At(paran_level+1);
1244 if (casted && cl != TClonesArray::Class()) {
1245 if ( ! casted->InheritsFrom(cl) ) {
1246 Error(
"DefinedVariable",
"%s does not inherit from %s. Casting not possible!",
1247 casted->GetName(),cl->GetName());
1250 leafinfo =
new TFormLeafInfoCast(cl,casted);
1253 maininfo = leafinfo;
1256 previnfo = leafinfo;
1258 previnfo->fNext = leafinfo;
1259 previnfo = leafinfo;
1264 castqueue.AddAt(0,paran_level);
1268 Bool_t prevUseCollectionObject = useLeafCollectionObject;
1269 Bool_t useCollectionObject = useLeafCollectionObject;
1270 Bool_t useReferenceObject = useLeafReferenceObject;
1271 Bool_t prevUseReferenceObject = useLeafReferenceObject;
1272 for (i=0, current = &(work[0]); i<=nchname;i++ ) {
1274 if (right[i] ==
'(') {
1277 *current++ = right[i++];
1278 }
while(right[i]!=
')' && right[i]);
1279 *current++ = right[i];
1281 char *params = strchr(work,
'(');
1283 *params = 0; params++;
1284 }
else params = (
char *)
")";
1286 Error(
"DefinedVariable",
"Can not call '%s' with a class",work);
1289 if (!cl->HasDataMemberInfo() && !cl->GetCollectionProxy()) {
1290 Error(
"DefinedVariable",
"Class probably unavailable:%s",cl->GetName());
1293 if (!useCollectionObject && cl == TClonesArray::Class()) {
1298 TBranch *clbranch = leaf->GetBranch();
1299 R__LoadBranch(clbranch,readentry,fQuickLoad);
1300 TClonesArray * clones;
1301 if (previnfo) clones = (TClonesArray*)previnfo->GetLocalValuePointer(leaf,0);
1303 Bool_t top = (clbranch==((TBranchElement*)clbranch)->GetMother()
1304 || !leaf->IsOnTerminalBranch());
1306 if (leaf->IsA()==TLeafObject::Class()) {
1310 mother_cl = ((TBranchElement*)clbranch)->GetInfo()->GetClass();
1312 TFormLeafInfo* clonesinfo =
new TFormLeafInfoClones(mother_cl, 0, top);
1315 numberOfVarDim += RegisterDimensions(code,clonesinfo,maininfo,kFALSE);
1317 previnfo = clonesinfo;
1318 maininfo = clonesinfo;
1320 clones = (TClonesArray*)clonesinfo->GetLocalValuePointer(leaf,0);
1322 TClass * inside_cl = clones->GetClass();
1326 else if (!useCollectionObject && cl && cl->GetCollectionProxy() ) {
1334 Bool_t top = (branch==((TBranchElement*)branch)->GetMother()
1335 || !leaf->IsOnTerminalBranch());
1338 if (leaf->IsA()==TLeafObject::Class()) {
1342 mother_cl = ((TBranchElement*)branch)->GetInfo()->GetClass();
1345 TFormLeafInfo* collectioninfo =
1346 new TFormLeafInfoCollection(mother_cl, 0,cl,top);
1348 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
1350 previnfo = collectioninfo;
1351 maininfo = collectioninfo;
1355 TClass * inside_cl = cl->GetCollectionProxy()->GetValueClass();
1356 if (inside_cl) cl = inside_cl;
1357 else if (cl->GetCollectionProxy()->GetType()>0) {
1358 Warning(
"DefinedVariable",
"Can not call method on content of %s in %s\n",
1359 cl->GetName(),name.Data());
1363 TMethodCall *method = 0;
1365 Error(
"DefinedVariable",
1366 "Could not discover the TClass corresponding to (%s)!",
1369 }
else if (cl==TClonesArray::Class() && strcmp(work,
"size")==0) {
1370 method =
new TMethodCall(cl,
"GetEntriesFast",
"");
1371 }
else if (cl->GetCollectionProxy() && strcmp(work,
"size")==0) {
1373 TFormLeafInfo* collectioninfo=0;
1374 if (useLeafCollectionObject) {
1376 Bool_t top = (branch==((TBranchElement*)branch)->GetMother()
1377 || !leaf->IsOnTerminalBranch());
1378 collectioninfo =
new TFormLeafInfoCollectionObject(cl,top);
1380 maininfo=previnfo=collectioninfo;
1382 leafinfo =
new TFormLeafInfoCollectionSize(cl);
1385 if (!cl->HasDataMemberInfo()) {
1386 Error(
"DefinedVariable",
1387 "Can not call method %s on class without dictionary (%s)!",
1388 right,cl->GetName());
1391 method =
new TMethodCall(cl, work, params);
1394 if (!method->GetMethod()) {
1395 Error(
"DefinedVariable",
"Unknown method:%s in %s",right,cl->GetName());
1398 switch(method->ReturnType()) {
1399 case TMethodCall::kLong:
1400 leafinfo =
new TFormLeafInfoMethod(cl,method);
1403 case TMethodCall::kDouble:
1404 leafinfo =
new TFormLeafInfoMethod(cl,method);
1407 case TMethodCall::kString:
1408 leafinfo =
new TFormLeafInfoMethod(cl,method);
1410 numberOfVarDim += RegisterDimensions(code,1);
1413 case TMethodCall::kOther:
1415 leafinfo =
new TFormLeafInfoMethod(cl,method);
1416 cl = TFormLeafInfoMethod::ReturnTClass(method);
1420 Error(
"DefineVariable",
"Method %s from %s has an impossible return type %d",
1421 work,cl->GetName(), (Int_t)method->ReturnType());
1426 maininfo = leafinfo;
1429 previnfo = leafinfo;
1431 previnfo->fNext = leafinfo;
1432 previnfo = leafinfo;
1435 current = &(work[0]);
1437 prevUseCollectionObject = kFALSE;
1438 prevUseReferenceObject = kFALSE;
1439 useCollectionObject = kFALSE;
1441 if (cl && cl->GetCollectionProxy()) {
1442 if (numberOfVarDim>1) {
1443 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1445 leafinfo =
new TFormLeafInfo(cl,0,0);
1446 useCollectionObject = kTRUE;
1447 }
else if (numberOfVarDim==0) {
1448 R__ASSERT(maininfo);
1449 leafinfo =
new TFormLeafInfoCollection(cl,0,cl);
1450 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1451 }
else if (numberOfVarDim==1) {
1452 R__ASSERT(maininfo);
1454 new TFormLeafInfoMultiVarDimCollection(cl,0,
1455 (TStreamerElement*)0,maininfo);
1456 previnfo->fNext = leafinfo;
1457 previnfo = leafinfo;
1458 leafinfo =
new TFormLeafInfoCollection(cl,0,cl);
1460 fHasMultipleVarDim[code] = kTRUE;
1461 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1463 previnfo->fNext = leafinfo;
1464 previnfo = leafinfo;
1468 }
else if (right[i] ==
')') {
1471 TClass * casted = (TClass*) ((
int(--paran_level)>=0) ? castqueue.At(paran_level) : 0);
1473 leafinfo =
new TFormLeafInfoCast(cl,casted);
1477 maininfo = leafinfo;
1480 previnfo = leafinfo;
1482 previnfo->fNext = leafinfo;
1483 previnfo = leafinfo;
1486 current = &(work[0]);
1493 }
else if (i > 0 && (right[i] ==
'.' || right[i] ==
'[' || right[i] ==
'\0') ) {
1496 Bool_t needClass = kTRUE;
1500 if (strlen(work)==0)
continue;
1502 prevUseCollectionObject = useCollectionObject;
1503 prevUseReferenceObject = useReferenceObject;
1505 useReferenceObject = kTRUE;
1506 useCollectionObject = kTRUE;
1508 for(l=0;work[l+1]!=0;++l) work[l] = work[l+1];
1510 }
else if (work[strlen(work)-1]==
'@') {
1511 useReferenceObject = kTRUE;
1512 useCollectionObject = kTRUE;
1513 work[strlen(work)-1] =
'\0';
1515 useReferenceObject = kFALSE;
1516 useCollectionObject = kFALSE;
1519 Bool_t mustderef = kFALSE;
1520 if ( !prevUseReferenceObject && cl && cl->GetReferenceProxy() ) {
1521 R__LoadBranch(leaf->GetBranch(), readentry, fQuickLoad);
1523 maininfo = previnfo =
new TFormLeafInfoReference(cl, element, offset);
1524 if ( cl->GetReferenceProxy()->HasCounter() ) {
1525 numberOfVarDim += RegisterDimensions(code,-1);
1527 prevUseReferenceObject = kFALSE;
1529 previnfo->fNext =
new TFormLeafInfoReference(cl, element, offset);
1530 previnfo = previnfo->fNext;
1532 TVirtualRefProxy *refproxy = cl->GetReferenceProxy();
1534 for(Long64_t entry=0; entry<leaf->GetBranch()->GetEntries()-readentry; ++entry) {
1535 R__LoadBranch(leaf->GetBranch(), readentry+i, fQuickLoad);
1536 void *refobj = maininfo->GetValuePointer(leaf,0);
1538 cl = refproxy->GetValueClass(refobj);
1545 else if (!prevUseCollectionObject && cl == TClonesArray::Class()) {
1550 TBranch *clbranch = leaf->GetBranch();
1551 R__LoadBranch(clbranch,readentry,fQuickLoad);
1552 TClonesArray * clones;
1554 clones = (TClonesArray*)maininfo->GetValuePointer(leaf,0);
1560 if (leaf->IsA()==TLeafObject::Class()) {
1564 mother_cl = ((TBranchElement*)clbranch)->GetInfo()->GetClass();
1567 TFormLeafInfo* clonesinfo =
new TFormLeafInfoClones(mother_cl, 0);
1569 numberOfVarDim += RegisterDimensions(code,clonesinfo,maininfo,kFALSE);
1572 previnfo = clonesinfo;
1573 maininfo = clonesinfo;
1575 if (clbranch->GetListOfBranches()->GetLast()>=0) {
1576 if (clbranch->IsA() != TBranchElement::Class()) {
1577 Error(
"DefinedVariable",
"Unimplemented usage of ClonesArray");
1581 clones = (TClonesArray*)((TBranchElement*)clbranch)->GetObject();
1583 clones = (TClonesArray*)clonesinfo->GetLocalValuePointer(leaf,0);
1587 Warning(
"DefinedVariable",
1588 "TClonesArray object was not retrievable for %s!",
1592 TClass * inside_cl = clones->GetClass();
1597 if (1 || inside_cl) cl = inside_cl;
1599 if (0 && strlen(work)==0) {
1605 }
else if (!prevUseCollectionObject && cl && cl->GetCollectionProxy() ) {
1611 TBranch *clbranch = leaf->GetBranch();
1612 R__LoadBranch(clbranch,readentry,fQuickLoad);
1620 if (leaf->IsA()==TLeafObject::Class()) {
1624 mother_cl = ((TBranchElement*)clbranch)->GetInfo()->GetClass();
1627 TFormLeafInfo* collectioninfo =
1628 new TFormLeafInfoCollection(mother_cl, 0, cl);
1630 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
1633 previnfo = collectioninfo;
1634 maininfo = collectioninfo;
1640 TClass * inside_cl = cl->GetCollectionProxy()->GetValueClass();
1643 Error(
"DefinedVariable",
"Could you not find the inner class for %s with coll type = %d",
1644 cl->GetName(),cl->GetCollectionProxy()->GetType());
1646 if (!inside_cl && cl->GetCollectionProxy()->GetType() > 0) {
1647 Warning(
"DefinedVariable",
"No data member in content of %s in %s\n",
1648 cl->GetName(),name.Data());
1655 if (leaf) leaf->GetBranch()->Print();
1656 Warning(
"DefinedVariable",
"Missing class for %s!",name.Data());
1658 element = ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(work,offset);
1661 if (!element && !prevUseCollectionObject) {
1664 TIter next( cl->GetStreamerInfo()->GetElements() );
1665 TStreamerElement * curelem;
1666 while ((curelem = (TStreamerElement*)next())) {
1667 if (curelem->GetClassPointer() == TClonesArray::Class()) {
1668 Int_t clones_offset = 0;
1669 ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(curelem->GetName(),clones_offset);
1670 TFormLeafInfo* clonesinfo =
1671 new TFormLeafInfo(cl, clones_offset, curelem);
1672 TClonesArray * clones;
1673 R__LoadBranch(leaf->GetBranch(),readentry,fQuickLoad);
1676 previnfo->fNext = clonesinfo;
1677 clones = (TClonesArray*)maininfo->GetValuePointer(leaf,0);
1678 previnfo->fNext = 0;
1680 clones = (TClonesArray*)clonesinfo->GetLocalValuePointer(leaf,0);
1683 TClass *sub_cl = clones->GetClass();
1684 if (sub_cl) element = ((TStreamerInfo*)sub_cl->GetStreamerInfo())->GetStreamerElement(work,offset);
1688 leafinfo =
new TFormLeafInfoClones(cl,clones_offset,curelem);
1689 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1690 if (maininfo==0) maininfo = leafinfo;
1691 if (previnfo==0) previnfo = leafinfo;
1693 previnfo->fNext = leafinfo;
1694 previnfo = leafinfo;
1700 }
else if (curelem->GetClassPointer() && curelem->GetClassPointer()->GetCollectionProxy()) {
1702 Int_t coll_offset = 0;
1703 ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(curelem->GetName(),coll_offset);
1706 curelem->GetClassPointer()->GetCollectionProxy()->GetValueClass();
1708 element = ((TStreamerInfo*)sub_cl->GetStreamerInfo())->GetStreamerElement(work,offset);
1711 if (numberOfVarDim>1) {
1712 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1713 curelem->GetName());
1714 leafinfo =
new TFormLeafInfo(cl,coll_offset,curelem);
1715 useCollectionObject = kTRUE;
1716 }
else if (numberOfVarDim==1) {
1717 R__ASSERT(maininfo);
1719 new TFormLeafInfoMultiVarDimCollection(cl,coll_offset,
1721 fHasMultipleVarDim[code] = kTRUE;
1722 leafinfo->fNext =
new TFormLeafInfoCollection(cl,coll_offset,curelem);
1723 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1725 leafinfo =
new TFormLeafInfoCollection(cl,coll_offset,curelem);
1726 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1728 if (maininfo==0) maininfo = leafinfo;
1729 if (previnfo==0) previnfo = leafinfo;
1731 previnfo->fNext = leafinfo;
1732 previnfo = leafinfo;
1734 if (leafinfo->fNext) {
1735 previnfo = leafinfo->fNext;
1747 Int_t type = element->GetNewType();
1748 if (type<60 && type!=0) {
1750 if (numberOfVarDim>=1 && type>40) {
1752 leafinfo =
new TFormLeafInfoMultiVarDim(cl,offset,element,maininfo);
1753 fHasMultipleVarDim[code] = kTRUE;
1755 if (leafinfo && type<=40 ) {
1756 leafinfo->AddOffset(offset,element);
1758 leafinfo =
new TFormLeafInfo(cl,offset,element);
1762 Bool_t
object = kFALSE;
1763 Bool_t pointer = kFALSE;
1764 Bool_t objarr = kFALSE;
1766 case TStreamerInfo::kObjectp:
1767 case TStreamerInfo::kObjectP:
1768 case TStreamerInfo::kSTLp:
1769 case TStreamerInfo::kAnyp:
1770 case TStreamerInfo::kAnyP:
1771 case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP:
1772 case TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp:
1773 case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp:
1774 case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp:
1775 case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP:
1778 case TStreamerInfo::kBase:
1779 case TStreamerInfo::kAny :
1780 case TStreamerInfo::kSTL:
1781 case TStreamerInfo::kObject:
1782 case TStreamerInfo::kTString:
1783 case TStreamerInfo::kTNamed:
1784 case TStreamerInfo::kTObject:
1787 case TStreamerInfo::kOffsetL + TStreamerInfo::kAny:
1788 case TStreamerInfo::kOffsetL + TStreamerInfo::kSTL:
1789 case TStreamerInfo::kOffsetL + TStreamerInfo::kObject:
1792 case TStreamerInfo::kStreamer:
1793 case TStreamerInfo::kStreamLoop:
1795 Error(
"DefinedVariable",
1796 "%s is a datamember of %s BUT is not yet of a supported type (%d)",
1797 right,cl ? cl->GetName() :
"unknown class",type);
1801 Error(
"DefinedVariable",
1802 "%s is a datamember of %s BUT is not of a unknown type (%d)",
1803 right,cl ? cl->GetName() :
"unknown class",type);
1807 if (
object && !useCollectionObject &&
1808 ( element->GetClassPointer() == TClonesArray::Class()
1809 || element->GetClassPointer()->GetCollectionProxy() ) )
1813 if (
object && leafinfo) {
1814 leafinfo->AddOffset(offset,element);
1815 }
else if (objarr) {
1817 leafinfo =
new TFormLeafInfo(cl,offset,element);
1821 if (!useCollectionObject && element->GetClassPointer() == TClonesArray::Class()) {
1823 leafinfo =
new TFormLeafInfoClones(cl,offset,element);
1826 }
else if (!useCollectionObject && element->GetClassPointer()
1827 && element->GetClassPointer()->GetCollectionProxy()) {
1830 if (numberOfVarDim>1) {
1831 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1832 element->GetName());
1833 leafinfo =
new TFormLeafInfo(cl,offset,element);
1834 useCollectionObject = kTRUE;
1835 }
else if (numberOfVarDim==1) {
1836 R__ASSERT(maininfo);
1838 new TFormLeafInfoMultiVarDimCollection(cl,offset,element,maininfo);
1840 fHasMultipleVarDim[code] = kTRUE;
1850 leafinfo->fNext =
new TFormLeafInfoCollection(cl, offset, element);
1851 if (element->GetClassPointer()->GetCollectionProxy()->GetValueClass()==0) {
1852 TFormLeafInfo *info =
new TFormLeafInfoNumerical(
1853 element->GetClassPointer()->GetCollectionProxy());
1854 if (leafinfo->fNext) leafinfo->fNext->fNext = info;
1855 else leafinfo->fNext = info;
1858 leafinfo =
new TFormLeafInfoCollection(cl, offset, element);
1860 TClass *elemCl = element->GetClassPointer();
1861 TClass *valueCl = elemCl->GetCollectionProxy()->GetValueClass();
1862 if (!maininfo) maininfo = leafinfo;
1864 if (valueCl!=0 && valueCl->GetCollectionProxy()!=0) {
1866 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,kFALSE);
1867 if (previnfo==0) previnfo = leafinfo;
1869 previnfo->fNext = leafinfo;
1870 previnfo = leafinfo;
1872 leafinfo =
new TFormLeafInfoMultiVarDimCollection(elemCl,0,
1873 elemCl->GetCollectionProxy()->GetValueClass(),maininfo);
1875 fHasMultipleVarDim[code] = kTRUE;
1877 leafinfo->fNext =
new TFormLeafInfoCollection(elemCl,0,
1881 if (elemCl->GetCollectionProxy() &&
1882 elemCl->GetCollectionProxy()->GetValueClass()==0) {
1883 TFormLeafInfo *info =
new TFormLeafInfoNumerical(elemCl->GetCollectionProxy());
1884 if (leafinfo->fNext) leafinfo->fNext->fNext = info;
1885 else leafinfo->fNext = info;
1888 }
else if ( (
object || pointer) && !useReferenceObject && element->GetClassPointer()->GetReferenceProxy() ) {
1889 TClass* c = element->GetClassPointer();
1890 R__LoadBranch(leaf->GetBranch(),readentry,fQuickLoad);
1892 leafinfo =
new TFormLeafInfoReference(c, element, offset);
1895 leafinfo =
new TFormLeafInfoPointer(cl,offset,element);
1896 leafinfo->fNext =
new TFormLeafInfoReference(c, element, 0);
1901 prevUseReferenceObject = kFALSE;
1904 }
else if (pointer) {
1906 leafinfo =
new TFormLeafInfoPointer(cl,offset,element);
1911 leafinfo =
new TFormLeafInfo(cl,offset,element);
1916 if (cl) Error(
"DefinedVariable",
"%s is not a datamember of %s",work,cl->GetName());
1921 numberOfVarDim += RegisterDimensions(code,leafinfo,maininfo,useCollectionObject);
1923 maininfo = leafinfo;
1926 previnfo = leafinfo;
1927 }
else if (previnfo!=leafinfo) {
1928 previnfo->fNext = leafinfo;
1929 previnfo = leafinfo;
1931 while (previnfo->fNext) previnfo = previnfo->fNext;
1933 if ( right[i] !=
'\0' ) {
1934 if ( !needClass && mustderef ) {
1935 maininfo->SetBranch(leaf->GetBranch());
1936 char *ptr = (
char*)maininfo->GetValuePointer(leaf,0);
1937 TFormLeafInfoReference* refInfo = 0;
1938 if ( !maininfo->IsReference() ) {
1939 for( TFormLeafInfo* inf = maininfo->fNext; inf; inf = inf->fNext ) {
1940 if ( inf->IsReference() ) {
1941 refInfo = (TFormLeafInfoReference*)inf;
1946 refInfo = (TFormLeafInfoReference*)maininfo;
1949 cl = refInfo->GetValueClass(ptr);
1951 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->GetName());
1954 element = ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(work,offset);
1957 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->GetName());
1961 else if ( needClass ) {
1962 cl = element->GetClassPointer();
1965 if (mustderef) leafinfo = 0;
1966 current = &(work[0]);
1968 R__ASSERT(right[i] !=
'[');
1970 if (cl == TString::Class() && strcmp(right+i+1,
"fData") == 0) {
1975 nchname = strlen(right);
1979 *current++ = right[i];
1982 fDataMembers.AddAtAndExpand(maininfo,code);
1983 if (leaf) fLookupType[code] = kDataMember;
1984 else fLookupType[code] = kTreeMember;
1988 if (strlen(work)!=0) {
1993 TClass *objClass = EvalClass(code);
1994 if (objClass && !useLeafCollectionObject && objClass->GetCollectionProxy() && objClass->GetCollectionProxy()->GetValueClass()) {
1995 TFormLeafInfo *last = 0;
1996 if ( SwitchToFormLeafInfo(code) ) {
1998 last = (TFormLeafInfo*)fDataMembers.At(code);
2000 if (!last)
return action;
2001 while (last->fNext) { last = last->fNext; }
2004 if (last && last->GetClass() != objClass) {
2006 if (leaf->IsA()==TLeafObject::Class()) {
2010 mother_cl = ((TBranchElement*)branch)->GetInfo()->GetClass();
2013 TFormLeafInfo* collectioninfo =
new TFormLeafInfoCollection(mother_cl, 0, objClass, kFALSE);
2015 numberOfVarDim += RegisterDimensions(code,collectioninfo,maininfo,kFALSE);
2016 last->fNext = collectioninfo;
2018 numberOfVarDim += RegisterDimensions(code,1);
2019 objClass = objClass->GetCollectionProxy()->GetValueClass();
2021 if (IsLeafString(code) || objClass == TString::Class() || objClass == stdStringClass) {
2023 TFormLeafInfo *last = 0;
2024 if ( SwitchToFormLeafInfo(code) ) {
2026 last = (TFormLeafInfo*)fDataMembers.At(code);
2028 if (!last)
return action;
2029 while (last->fNext) { last = last->fNext; }
2032 const char *funcname = 0;
2033 if (objClass == TString::Class()) {
2036 }
else if (objClass == stdStringClass) {
2041 TMethodCall *method =
new TMethodCall(objClass, funcname,
"");
2043 last->fNext =
new TFormLeafInfoMethod(objClass,method);
2045 fDataMembers.AddAtAndExpand(
new TFormLeafInfoMethod(objClass,method),code);
2046 if (leaf) fLookupType[code] = kDataMember;
2047 else fLookupType[code] = kTreeMember;
2050 return kDefinedString;
2054 TMethodCall *method =
new TMethodCall(objClass,
"AsDouble",
"");
2055 if (method->IsValid()
2056 && (method->ReturnType() == TMethodCall::kLong || method->ReturnType() == TMethodCall::kDouble)) {
2058 TFormLeafInfo *last = 0;
2059 if (SwitchToFormLeafInfo(code)) {
2060 last = (TFormLeafInfo*)fDataMembers.At(code);
2066 while (last->fNext) { last = last->fNext; }
2069 last->fNext =
new TFormLeafInfoMethod(objClass,method);
2071 fDataMembers.AddAtAndExpand(
new TFormLeafInfoMethod(objClass,method),code);
2072 if (leaf) fLookupType[code] = kDataMember;
2073 else fLookupType[code] = kTreeMember;
2076 return kDefinedVariable;
2079 method =
new TMethodCall(objClass,
"AsString",
"");
2080 if (method->IsValid()
2081 && method->ReturnType() == TMethodCall::kString) {
2083 TFormLeafInfo *last = 0;
2084 if (SwitchToFormLeafInfo(code)) {
2085 last = (TFormLeafInfo*)fDataMembers.At(code);
2091 while (last->fNext) { last = last->fNext; }
2094 last->fNext =
new TFormLeafInfoMethod(objClass,method);
2096 fDataMembers.AddAtAndExpand(
new TFormLeafInfoMethod(objClass,method),code);
2097 if (leaf) fLookupType[code] = kDataMember;
2098 else fLookupType[code] = kTreeMember;
2102 return kDefinedString;
2104 if (method->IsValid()
2105 && method->ReturnType() == TMethodCall::kOther) {
2107 TClass *rcl = TFormLeafInfoMethod::ReturnTClass(method);
2108 if ((rcl == TString::Class() || rcl == stdStringClass) ) {
2110 TFormLeafInfo *last = 0;
2111 if (SwitchToFormLeafInfo(code)) {
2112 last = (TFormLeafInfo*)fDataMembers.At(code);
2118 while (last->fNext) { last = last->fNext; }
2121 last->fNext =
new TFormLeafInfoMethod(objClass,method);
2124 last =
new TFormLeafInfoMethod(objClass,method);
2125 fDataMembers.AddAtAndExpand(last,code);
2126 if (leaf) fLookupType[code] = kDataMember;
2127 else fLookupType[code] = kTreeMember;
2132 const char *funcname = 0;
2133 if (objClass == TString::Class()) {
2135 }
else if (objClass == stdStringClass) {
2139 method =
new TMethodCall(objClass, funcname,
"");
2140 last->fNext =
new TFormLeafInfoMethod(objClass,method);
2142 return kDefinedString;
2166 Int_t TTreeFormula::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)
2170 if (fTree->GetTree()==0) {
2172 if (fTree->GetTree()==0)
return -1;
2174 Long64_t readentry = fTree->GetTree()->GetReadEntry();
2175 if (readentry < 0) readentry=0;
2176 const char *cname = expression;
2177 char first[kMaxLen]; first[0] =
'\0';
2178 char second[kMaxLen*2]; second[0] =
'\0';
2179 char right[kMaxLen*2]; right[0] =
'\0';
2180 char work[kMaxLen]; work[0] =
'\0';
2181 char left[kMaxLen]; left[0] =
'\0';
2182 char scratch[kMaxLen*5];
2183 char scratch2[kMaxLen*5];
2184 std::string currentname;
2185 Int_t previousdot = 0;
2188 TBranch *branch=0, *tmp_branch=0;
2189 Int_t nchname = strlen(cname);
2191 Bool_t foundAtSign = kFALSE;
2192 Bool_t startWithParan = kFALSE;
2194 for (i=0, current = &(work[0]); i<=nchname && !
final;i++ ) {
2196 *current++ = cname[i];
2198 if (cname[i] ==
'(') {
2201 if (current==work+1) {
2204 startWithParan = kTRUE;
2216 if (cname[i] ==
')') {
2217 if (paran_level==0) {
2218 Error(
"DefinedVariable",
"Unmatched paranthesis in %s",fullExpression);
2223 if (startWithParan) {
2224 startWithParan = kFALSE;
2228 TString cast_name = gInterpreter->TypeName(work);
2229 TClass *cast_cl = TClass::GetClass(cast_name);
2232 castqueue.AddAtAndExpand(cast_cl,paran_level);
2233 current = &(work[0]);
2237 }
else if (gROOT->GetType(cast_name)) {
2239 current = &(work[0]);
2241 Warning(
"DefinedVariable",
2242 "Casting to primary types like \"%s\" is not supported yet",cast_name.Data());
2249 char *params = strchr(work,
'(');
2251 *params = 0; params++;
2253 if (branch && !leaf) {
2256 if (BranchHasMethod(0, branch, work, params, readentry)) {
2263 TIter next(fTree->GetIteratorOnAllLeaves());
2265 while (!leaf && (leafcur = (TLeaf*) next())) {
2266 TBranch* br = leafcur->GetBranch();
2267 Bool_t yes = BranchHasMethod(leafcur, br, work, params, readentry);
2275 if (strlen(left) && left[strlen(left)-1]==
'.') left[strlen(left)-1]=0;
2276 const char *aliasValue = fTree->GetAlias(left);
2277 if (aliasValue && strcspn(aliasValue,
"+*/-%&!=<>|")==strlen(aliasValue)) {
2280 if (find(aliasUsed.begin(),
2282 left) != aliasUsed.end()) {
2283 Error(
"DefinedVariable",
2284 "The substitution of the branch alias \"%s\" by \"%s\" in \"%s\" failed\n"\
2285 "\tbecause \"%s\" is used [recursively] in its own definition!",
2286 left,aliasValue,fullExpression,left);
2289 aliasUsed.push_back(left);
2290 TString newExpression = aliasValue;
2291 newExpression += (cname+strlen(left));
2292 Int_t res = FindLeafForExpression(newExpression, leaf, leftover,
final, paran_level,
2293 castqueue, aliasUsed, useLeafCollectionObject, fullExpression);
2295 Error(
"DefinedVariable",
2296 "The substitution of the alias \"%s\" by \"%s\" failed.",left,aliasValue);
2313 strlcpy(right,work,2*kMaxLen);
2314 strncat(right,
"(",2*kMaxLen-1-strlen(right));
2315 strncat(right,params,2*kMaxLen-1-strlen(right));
2319 i += strlen(params);
2322 current = &(work[0]);
2327 if (cname[i] ==
'.' || cname[i] ==
'\0' || cname[i] ==
')') {
2332 Int_t len = strlen(work);
2334 foundAtSign = kTRUE;
2336 for(l=0;work[l+1]!=0;++l) work[l] = work[l+1];
2339 }
else if (len>=2 && work[len-2]==
'@') {
2340 foundAtSign = kTRUE;
2341 work[len-2] = cname[i];
2345 foundAtSign = kFALSE;
2348 if (left[0]==0) strlcpy(left,work,kMaxLen);
2349 if (!leaf && !branch) {
2351 strlcpy(first,work,kMaxLen);
2353 std::string treename(first);
2354 if (treename.size() && treename[treename.size()-1]==
'.') {
2355 treename.erase(treename.size()-1);
2357 if (treename==
"This" ) {
2359 TNamed *named =
new TNamed(fTree->GetName(),fTree->GetName());
2360 fLeafNames.AddAtAndExpand(named,fNcodes);
2361 fLeaves.AddAtAndExpand(fTree,fNcodes);
2362 if (cname[i]) leftover = &(cname[i+1]);
2389 branch = fTree->FindBranch(first);
2390 leaf = fTree->FindLeaf(first);
2394 if (cname[i]) first[strlen(first)-1]=
'\0';
2395 if (!branch) branch = fTree->FindBranch(first);
2396 if (!leaf) leaf = fTree->FindLeaf(first);
2398 if ( branch && branch->InheritsFrom(TBranchElement::Class()) ) {
2400 TBranchElement* bElt = (TBranchElement*)branch;
2401 TStreamerInfo* info = bElt->GetInfo();
2402 TStreamerElement* element = info ? info->GetStreamerElement(first,offset) : 0;
2403 if (element) cl = element->GetClassPointer();
2404 if ( cl && !cl->GetReferenceProxy() ) cl = 0;
2408 useLeafCollectionObject = foundAtSign;
2410 current = &(work[0]);
2413 else if (branch && (foundAtSign || cname[i] != 0) ) {
2421 if (branch->InheritsFrom(TBranchElement::Class()) ) {
2422 Int_t type = ((TBranchElement*)branch)->GetType();
2423 if ( type == 3 || type ==4) {
2425 leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
2427 useLeafCollectionObject = foundAtSign;
2428 foundAtSign = kFALSE;
2429 current = &(work[0]);
2439 useLeafCollectionObject = foundAtSign;
2440 foundAtSign = kFALSE;
2441 current = &(work[0]);
2443 }
else if (leaf || branch) {
2444 if (leaf && branch) {
2452 if (leaf && leaf->IsOnTerminalBranch()) {
2458 current = &(work[0]);
2463 TLeaf *leafcur = GetLeafWithDatamember(first,work,readentry);
2466 branch = leaf->GetBranch();
2467 if (leaf->IsOnTerminalBranch()) {
2469 strlcpy(right,first,kMaxLen);
2471 if (foundAtSign) strncat(right,
"@",2*kMaxLen-1-strlen(right));
2472 if (cname[i]==
'.') strncat(right,
".",2*kMaxLen-1-strlen(right));
2475 current = &(work[0]);
2478 }
else if (cname[i] ==
'.') {
2484 TIter next( fTree->GetListOfBranches() );
2485 while(!branch && (branchcur=(TBranch*)next()) ) {
2486 branch = branchcur->FindBranch(first);
2490 current = &(work[0]);
2497 Error(
"DefinedVariable",
"Unexpected control flow!");
2503 if (cname[i]) work[strlen(work)-1] =
'\0';
2504 snprintf(scratch,
sizeof(scratch),
"%s.%s",first,work);
2505 snprintf(scratch2,
sizeof(scratch2),
"%s.%s.%s",first,second,work);
2508 currentname = &(work[previousdot+1]);
2514 tmp_leaf = branch->FindLeaf(work);
2515 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(scratch);
2516 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(scratch2);
2517 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(currentname.c_str());
2519 if (tmp_leaf && tmp_leaf->IsOnTerminalBranch() ) {
2526 tmp_branch = branch->FindBranch(work);
2527 if (!tmp_branch) tmp_branch = branch->FindBranch(scratch);
2528 if (!tmp_branch) tmp_branch = branch->FindBranch(scratch2);
2529 if (!tmp_branch) tmp_branch = branch->FindBranch(currentname.c_str());
2536 tmp_leaf = branch->FindLeaf(work);
2537 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(scratch);
2538 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(scratch2);
2539 if (!tmp_leaf) tmp_leaf = branch->FindLeaf(currentname.c_str());
2540 if (tmp_leaf && tmp_leaf->IsOnTerminalBranch() ) {
2550 if (second[0]) strncat(second,
".",2*kMaxLen-1-strlen(second));
2551 strncat(second,work,2*kMaxLen-1-strlen(second));
2553 useLeafCollectionObject = foundAtSign;
2554 foundAtSign = kFALSE;
2557 current = &(work[0]);
2563 Int_t where = strlen(work);
2565 work[where+1] = cname[i];
2567 previousdot = where+1;
2569 previousdot = strlen(work);
2570 work[strlen(work)] = cname[i];
2580 strncat(right,work,2*kMaxLen-1-strlen(right));
2584 if (strlen(right) && right[strlen(right)-1]!=
'.' && cname[i]!=
'.') {
2588 strncat(right,
".",2*kMaxLen-1-strlen(right));
2590 strncat(right,&cname[i],2*kMaxLen-1-strlen(right));
2593 if (!
final && branch) {
2595 leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
2596 if (!leaf)
return -1;
2598 final = leaf->IsOnTerminalBranch();
2601 if (leaf && leaf->InheritsFrom(TLeafObject::Class()) ) {
2602 if (strlen(right)==0) strlcpy(right,work,2*kMaxLen);
2605 if (leaf==0 && left[0]!=0) {
2606 if (left[strlen(left)-1]==
'.') left[strlen(left)-1]=0;
2609 const char *aliasValue = fTree->GetAlias(left);
2610 if (aliasValue && strcspn(aliasValue,
"()[]+*/-%&!=<>|")==strlen(aliasValue)) {
2613 if (find(aliasUsed.begin(),
2615 left) != aliasUsed.end()) {
2616 Error(
"DefinedVariable",
2617 "The substitution of the branch alias \"%s\" by \"%s\" in \"%s\" failed\n"\
2618 "\tbecause \"%s\" is used [recursively] in its own definition!",
2619 left,aliasValue,fullExpression,left);
2622 aliasUsed.push_back(left);
2623 TString newExpression = aliasValue;
2624 newExpression += (cname+strlen(left));
2625 Int_t res = FindLeafForExpression(newExpression, leaf, leftover,
final, paran_level,
2626 castqueue, aliasUsed, useLeafCollectionObject, fullExpression);
2628 Error(
"DefinedVariable",
2629 "The substitution of the alias \"%s\" by \"%s\" failed.",left,aliasValue);
2676 Int_t TTreeFormula::DefinedVariable(TString &name, Int_t &action)
2679 action = kDefinedVariable;
2680 if (!fTree)
return -1;
2683 if (name.Length() > kMaxLen)
return -1;
2686 if (name ==
"Entry$") {
2687 Int_t code = fNcodes++;
2689 fLookupType[code] = kIndexOfEntry;
2692 if (name ==
"LocalEntry$") {
2693 Int_t code = fNcodes++;
2695 fLookupType[code] = kIndexOfLocalEntry;
2698 if (name ==
"Entries$") {
2699 Int_t code = fNcodes++;
2701 fLookupType[code] = kEntries;
2702 SetBit(kNeedEntries);
2703 fManager->SetBit(kNeedEntries);
2706 if (name ==
"LocalEntries$") {
2707 Int_t code = fNcodes++;
2709 fLookupType[code] = kLocalEntries;
2710 SetBit(kNeedEntries);
2711 fManager->SetBit(kNeedEntries);
2714 if (name ==
"Iteration$") {
2715 Int_t code = fNcodes++;
2717 fLookupType[code] = kIteration;
2720 if (name ==
"Length$") {
2721 Int_t code = fNcodes++;
2723 fLookupType[code] = kLength;
2726 static const char *lenfunc =
"Length$(";
2727 if (strncmp(name.Data(),
"Length$(",strlen(lenfunc))==0
2728 && name[name.Length()-1]==
')') {
2730 TString subform = name.Data()+strlen(lenfunc);
2731 subform.Remove( subform.Length() - 1 );
2732 TTreeFormula *lengthForm =
new TTreeFormula(
"lengthForm",subform,fTree);
2733 fAliases.AddAtAndExpand(lengthForm,fNoper);
2734 Int_t code = fNcodes++;
2736 fLookupType[code] = kLengthFunc;
2739 static const char *minfunc =
"Min$(";
2740 if (strncmp(name.Data(),
"Min$(",strlen(minfunc))==0
2741 && name[name.Length()-1]==
')') {
2743 TString subform = name.Data()+strlen(minfunc);
2744 subform.Remove( subform.Length() - 1 );
2745 TTreeFormula *minForm =
new TTreeFormula(
"minForm",subform,fTree);
2746 fAliases.AddAtAndExpand(minForm,fNoper);
2747 Int_t code = fNcodes++;
2749 fLookupType[code] = kMin;
2752 static const char *maxfunc =
"Max$(";
2753 if (strncmp(name.Data(),
"Max$(",strlen(maxfunc))==0
2754 && name[name.Length()-1]==
')') {
2756 TString subform = name.Data()+strlen(maxfunc);
2757 subform.Remove( subform.Length() - 1 );
2758 TTreeFormula *maxForm =
new TTreeFormula(
"maxForm",subform,fTree);
2759 fAliases.AddAtAndExpand(maxForm,fNoper);
2760 Int_t code = fNcodes++;
2762 fLookupType[code] = kMax;
2765 static const char *sumfunc =
"Sum$(";
2766 if (strncmp(name.Data(),
"Sum$(",strlen(sumfunc))==0
2767 && name[name.Length()-1]==
')') {
2769 TString subform = name.Data()+strlen(sumfunc);
2770 subform.Remove( subform.Length() - 1 );
2771 TTreeFormula *sumForm =
new TTreeFormula(
"sumForm",subform,fTree);
2772 fAliases.AddAtAndExpand(sumForm,fNoper);
2773 Int_t code = fNcodes++;
2775 fLookupType[code] = kSum;
2782 Int_t res = DefineAlternate(name.Data());
2785 if (res<0)
return res;
2792 char cname[kMaxLen]; strlcpy(cname,name.Data(),kMaxLen);
2793 char dims[kMaxLen]; dims[0] =
'\0';
2795 Bool_t
final = kFALSE;
2797 UInt_t paran_level = 0;
2798 TObjArray castqueue;
2801 Int_t cnamelen = strlen(cname);
2802 for(i=0,k=0; i<cnamelen; ++i, ++k) {
2803 if (cname[i] ==
'[') {
2805 int bracket_level = 1;
2807 for (j=++i; j<cnamelen && (bracket_level>0 || cname[j]==
'['); j++, i++) {
2808 if (cname[j]==
'[') bracket_level++;
2809 else if (cname[j]==
']') bracket_level--;
2811 if (bracket_level != 0) {
2815 strncat(dims,&cname[bracket],j-bracket);
2818 if (i!=k) cname[k] = cname[i];
2822 Bool_t useLeafCollectionObject = kFALSE;
2826 std::vector<std::string> aliasSofar = fAliasesUsed;
2827 res = FindLeafForExpression(cname, leaf, leftover,
final, paran_level, castqueue, aliasSofar, useLeafCollectionObject, name);
2829 if (res<0)
return res;
2831 if (!leaf && res!=2) {
2833 const char *aliasValue = fTree->GetAlias(cname);
2837 if (find(fAliasesUsed.begin(),
2839 cname) != fAliasesUsed.end()) {
2840 Error(
"DefinedVariable",
2841 "The substitution of the alias \"%s\" by \"%s\" failed\n"\
2842 "\tbecause \"%s\" is recursively used in its own definition!",
2843 cname,aliasValue,cname);
2848 if (strcspn(aliasValue,
"()+*/-%&!=<>|")!=strlen(aliasValue)) {
2853 std::vector<std::string> aliasSofar = fAliasesUsed;
2854 aliasSofar.push_back( cname );
2856 TString subValue( aliasValue );
2861 TTreeFormula *subform =
new TTreeFormula(cname,subValue,fTree,aliasSofar);
2863 if (subform->GetNdim()==0) {
2865 Error(
"DefinedVariable",
2866 "The substitution of the alias \"%s\" by \"%s\" failed.",cname,aliasValue);
2870 fManager->Add(subform);
2871 fAliases.AddAtAndExpand(subform,fNoper);
2873 if (subform->IsString()) {
2874 action = kAliasString;
2881 TString thisAlias( aliasValue );
2883 Int_t aliasRes = DefinedVariable(thisAlias,action);
2889 Error(
"Compile",
" Bad numerical expression : \"%s\"",thisAlias.Data());
2890 }
else if (aliasRes==-2) {
2891 Error(
"Compile",
" Part of the Variable \"%s\" exists but some of it is not accessible or useable",thisAlias.Data());
2894 Error(
"DefinedVariable",
2895 "The substitution of the alias \"%s\" by \"%s\" failed.",cname,aliasValue);
2904 if (leaf || res==2) {
2906 if (leaf && leaf->GetBranch() && leaf->GetBranch()->TestBit(kDoNotProcess)) {
2907 Error(
"DefinedVariable",
"the branch \"%s\" has to be enabled to be used",leaf->GetBranch()->GetName());
2911 Int_t code = fNcodes++;
2916 char *current = &( dims[0] );
2923 if (current[0] ==
']') {
2924 fIndexes[code][dim] = -1;
2926 scanindex = sscanf(current,
"%d",&index);
2928 fIndexes[code][dim] = index;
2930 fIndexes[code][dim] = -2;
2932 char *end = (
char*)(varindex.Data());
2933 for(
char bracket_level = 0;*end!=0;end++) {
2934 if (*end==
'[') bracket_level++;
2935 if (bracket_level==0 && *end==
']')
break;
2936 if (*end==
']') bracket_level--;
2939 fVarIndexes[code][dim] =
new TTreeFormula(
"index_var",
2942 if (fVarIndexes[code][dim]->GetNdim() == 0) {
2946 current += strlen(varindex)+1;
2950 if (dim >= kMAXFORMDIM) {
2954 current = (
char*)strstr( current,
"[" );
2961 res = ParseWithLeaf(leaf,leftover,
final,paran_level,castqueue,useLeafCollectionObject,name);
2962 if (res<0)
return res;
2963 if (res>0) action = res;
2968 TCutG *gcut = (TCutG*)gROOT->GetListOfSpecials()->FindObject(name.Data());
2970 if (gcut->GetObjectX()) {
2971 if(!gcut->GetObjectX()->InheritsFrom(TTreeFormula::Class()))
2972 gcut->SetObjectX(
nullptr);
2974 if (gcut->GetObjectY()) {
2975 if(!gcut->GetObjectY()->InheritsFrom(TTreeFormula::Class()))
2976 gcut->SetObjectY(
nullptr);
2979 Int_t code = fNcodes;
2981 if (strlen(gcut->GetVarX()) && strlen(gcut->GetVarY()) ) {
2983 TTreeFormula *fx =
new TTreeFormula(
"f_x",gcut->GetVarX(),fTree);
2984 gcut->SetObjectX(fx);
2986 TTreeFormula *fy =
new TTreeFormula(
"f_y",gcut->GetVarY(),fTree);
2987 gcut->SetObjectY(fy);
2991 }
else if (strlen(gcut->GetVarX())) {
2997 Int_t n = gcut->GetN();
2998 Double_t *x = gcut->GetX();
3000 for(Int_t i2 = 1; i2<n; i2++) {
3001 if (x[i2] < min) min = x[i2];
3002 if (x[i2] > max) max = x[i2];
3004 TString formula =
"(";
3007 formula += gcut->GetVarX();
3009 formula += gcut->GetVarX();
3014 TTreeFormula *fx =
new TTreeFormula(
"f_x",formula.Data(),fTree);
3015 gcut->SetObjectX(fx);
3021 Error(
"DefinedVariable",
"Found a TCutG without leaf information (%s)",
3027 fExternalCuts.AddAtAndExpand(gcut,code);
3029 fLookupType[code] = -1;
3034 TEntryList *elist =
dynamic_cast<TEntryList*
> (gDirectory->Get(name.Data()));
3036 Int_t code = fNcodes;
3038 fExternalCuts.AddAtAndExpand(elist, code);
3040 fLookupType[code] = kEntryList;
3052 TLeaf* TTreeFormula::GetLeafWithDatamember(
const char* topchoice,
const char* nextchoice, Long64_t readentry)
const
3055 TIter nextleaf (fTree->GetIteratorOnAllLeaves());
3056 TFormLeafInfo* clonesinfo = 0;
3058 while ((leafcur = (TLeaf*)nextleaf())) {
3064 if (leafcur->InheritsFrom(TLeafObject::Class()) &&
3065 leafcur->GetBranch()->GetListOfBranches()->Last()==0) {
3066 TLeafObject *lobj = (TLeafObject*)leafcur;
3067 cl = lobj->GetClass();
3068 }
else if (leafcur->InheritsFrom(TLeafElement::Class()) && leafcur->IsOnTerminalBranch()) {
3069 TLeafElement * lElem = (TLeafElement*) leafcur;
3070 if (lElem->IsOnTerminalBranch()) {
3071 TBranchElement *branchEl = (TBranchElement *)leafcur->GetBranch();
3072 Int_t type = branchEl->GetStreamerType();
3074 cl = branchEl->GetInfo() ? branchEl->GetInfo()->GetClass() : 0;
3075 }
else if (type>60 || type==0) {
3079 TStreamerElement* element = branchEl->GetInfo()->GetElement(branchEl->GetID());
3080 if (element) cl = element->GetClassPointer();
3086 if (clonesinfo) {
delete clonesinfo; clonesinfo = 0; }
3087 if (cl == TClonesArray::Class()) {
3091 R__LoadBranch(leafcur->GetBranch(),readentry,fQuickLoad);
3092 TClonesArray * clones;
3094 TBranch *branch = leafcur->GetBranch();
3095 if ( branch->IsA()==TBranchElement::Class()
3096 && ((TBranchElement*)branch)->GetType()==31) {
3106 Bool_t toplevel = (branch == branch->GetMother());
3107 clonesinfo =
new TFormLeafInfoClones(cl, 0, toplevel);
3108 clones = (TClonesArray*)clonesinfo->GetLocalValuePointer(leafcur,0);
3110 if (clones) cl = clones->GetClass();
3111 }
else if (cl && cl->GetCollectionProxy()) {
3117 TBranch *branch = leafcur->GetBranch();
3118 if ( branch->IsA()==TBranchElement::Class()
3119 && ((TBranchElement*)branch)->GetType()==41) {
3129 clonesinfo =
new TFormLeafInfoCollection(cl, 0);
3131 cl = cl->GetCollectionProxy()->GetValueClass();
3137 TStreamerInfo* info = (TStreamerInfo*)cl->GetStreamerInfo();
3138 TStreamerElement* element = info?info->GetStreamerElement(topchoice,offset):0;
3140 TIter nextel( cl->GetStreamerInfo()->GetElements() );
3141 TStreamerElement * curelem;
3142 while ((curelem = (TStreamerElement*)nextel())) {
3144 if (curelem->GetClassPointer() == TClonesArray::Class()) {
3149 TBranch *branch = leafcur->GetBranch();
3150 TFormLeafInfo *leafinfo = 0;
3152 leafinfo = clonesinfo;
3153 }
else if (branch->IsA()==TBranchElement::Class()
3154 && ((TBranchElement*)branch)->GetType()==31) {
3156 TBranchElement *branchEl = (TBranchElement*)branch;
3157 TStreamerInfo *bel_info = branchEl->GetInfo();
3158 TClass * mother_cl = ((TBranchElement*)branch)->GetInfo()->GetClass();
3159 TStreamerElement *bel_element =
3160 bel_info->GetElement(branchEl->GetID());
3161 leafinfo =
new TFormLeafInfoClones(mother_cl, 0, bel_element, kTRUE);
3164 Int_t clones_offset = 0;
3165 ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(curelem->GetName(),clones_offset);
3166 TFormLeafInfo* sub_clonesinfo =
new TFormLeafInfo(cl, clones_offset, curelem);
3168 if (leafinfo->fNext) leafinfo->fNext->fNext = sub_clonesinfo;
3169 else leafinfo->fNext = sub_clonesinfo;
3170 else leafinfo = sub_clonesinfo;
3172 R__LoadBranch(branch,readentry,fQuickLoad);
3174 TClonesArray * clones = (TClonesArray*)leafinfo->GetValuePointer(leafcur,0);
3176 delete leafinfo; clonesinfo = 0;
3181 if (!clones)
continue;
3182 TClass *sub_cl = clones->GetClass();
3185 element = ((TStreamerInfo*)sub_cl->GetStreamerInfo())->GetStreamerElement(nextchoice,offset);
3188 else if (curelem->GetClassPointer() && curelem->GetClassPointer()->GetCollectionProxy()) {
3190 TClass *sub_cl = curelem->GetClassPointer()->GetCollectionProxy()->GetValueClass();
3192 while(sub_cl && sub_cl->GetCollectionProxy())
3193 sub_cl = sub_cl->GetCollectionProxy()->GetValueClass();
3196 if (sub_cl) element = ((TStreamerInfo*)sub_cl->GetStreamerInfo())->GetStreamerElement(nextchoice,offset);
3218 Bool_t TTreeFormula::BranchHasMethod(TLeaf* leafcur, TBranch* branch,
const char* method,
const char* params, Long64_t readentry)
const
3221 TLeafObject* lobj = 0;
3229 if (branch->TestBit(kDoNotProcess)) {
3234 if (branch->InheritsFrom(TBranchObject::Class())) {
3235 lobj = (TLeafObject*) branch->GetListOfLeaves()->At(0);
3236 cl = lobj->GetClass();
3237 }
else if (branch->InheritsFrom(TBranchElement::Class())) {
3238 TBranchElement* branchEl = (TBranchElement*) branch;
3239 Int_t type = branchEl->GetStreamerType();
3241 cl = branchEl->GetInfo() ? branchEl->GetInfo()->GetClass() : 0;
3242 }
else if (type > 60) {
3246 TStreamerElement* element = branchEl->GetInfo()->GetElement(branchEl->GetID());
3248 cl = element->GetClassPointer();
3252 if ((cl == TClonesArray::Class()) && (branchEl->GetType() == 31)) {
3262 if (cl == TClonesArray::Class()) {
3267 TClonesArray* clones = 0;
3268 R__LoadBranch(branch, readentry, fQuickLoad);
3269 if (branch->InheritsFrom(TBranchObject::Class())) {
3270 clones = (TClonesArray*) lobj->GetObject();
3271 }
else if (branch->InheritsFrom(TBranchElement::Class())) {
3275 TBranchElement* bc = (TBranchElement*) branch;
3276 if (bc == bc->GetMother()) {
3279 clones = (TClonesArray*) bc->GetObject();
3280 }
else if (!leafcur || !leafcur->IsOnTerminalBranch()) {
3281 TStreamerElement* element = bc->GetInfo()->GetElement(bc->GetID());
3282 if (element->IsaPointer()) {
3283 clones = *((TClonesArray**) bc->GetAddress());
3287 clones = (TClonesArray*) bc->GetObject();
3291 R__LoadBranch(bc, readentry, fQuickLoad);
3293 mother_cl = bc->GetInfo()->GetClass();
3294 TFormLeafInfo* clonesinfo =
new TFormLeafInfoClones(mother_cl, 0);
3296 clones = (TClonesArray*) clonesinfo->GetLocalValuePointer(leafcur, 0);
3301 Error(
"BranchHasMethod",
"A TClonesArray was stored in a branch type no yet support (i.e. neither TBranchObject nor TBranchElement): %s",branch->IsA()->GetName());
3304 cl = clones ? clones->GetClass() : 0;
3305 }
else if (cl && cl->GetCollectionProxy()) {
3306 cl = cl->GetCollectionProxy()->GetValueClass();
3310 if (cl->GetClassInfo()) {
3311 if (cl->GetMethodAllAny(method)) {
3316 TMethodCall methodcall(cl, method, params);
3317 if (methodcall.GetMethod()) {
3337 Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) {
3338 Int_t real_instance = 0;
3341 Bool_t check = kFALSE;
3347 TFormLeafInfo * info = 0;
3348 Int_t max_dim = fNdimensions[codeindex];
3353 if (!fManager->fMultiVarDim) {
3354 if (fIndexes[codeindex][0]>=0) {
3355 real_instance = fIndexes[codeindex][0] * fCumulSizes[codeindex][1];
3358 local_index = ( instance / fManager->fCumulUsedSizes[virt_dim+1]);
3359 if (fIndexes[codeindex][0]==-2) {
3362 Int_t index_real_instance = fVarIndexes[codeindex][0]->GetRealInstance(local_index,-1);
3363 if (index_real_instance >= fVarIndexes[codeindex][0]->fNdata[0]) {
3368 if (fDidBooleanOptimization && local_index!=0) {
3370 fVarIndexes[codeindex][0]->LoadBranches();
3372 local_index = (Int_t)fVarIndexes[codeindex][0]->EvalInstance(local_index);
3373 if (local_index<0) {
3374 Error(
"EvalInstance",
"Index %s is out of bound (%d) in formula %s",
3375 fVarIndexes[codeindex][0]->GetTitle(),
3381 real_instance = local_index * fCumulSizes[codeindex][1];
3393 if (fHasMultipleVarDim[codeindex]) {
3394 info = (TFormLeafInfo *)(fDataMembers.At(codeindex));
3399 switch (fIndexes[codeindex][0]) {
3401 if (fDidBooleanOptimization && instance!=0) {
3403 fVarIndexes[codeindex][0]->LoadBranches();
3405 local_index = (Int_t)fVarIndexes[codeindex][0]->EvalInstance(instance);
3406 if (local_index<0) {
3407 Error(
"EvalInstance",
"Index %s is out of bound (%d) in formula %s",
3408 fVarIndexes[codeindex][0]->GetTitle(),
3415 if (instance <= fRealInstanceCache.fInstanceCache) {
3416 fRealInstanceCache.fLocalIndexCache = 0;
3417 fRealInstanceCache.fVirtAccumCache = 0;
3419 fRealInstanceCache.fInstanceCache = instance;
3420 local_index = fRealInstanceCache.fLocalIndexCache;
3421 Int_t virt_accum = fRealInstanceCache.fVirtAccumCache;
3423 Int_t maxloop = fManager->fCumulUsedVarDims->GetSize();
3426 instance = fNdata[0]+1;
3427 if (check)
return fNdata[0]+1;
3430 virt_accum += fManager->fCumulUsedVarDims->GetArray()[local_index];
3432 }
while( instance >= virt_accum && local_index<maxloop);
3435 fRealInstanceCache.fVirtAccumCache = virt_accum - fManager->fCumulUsedVarDims->GetArray()[local_index];
3436 fRealInstanceCache.fLocalIndexCache = local_index;
3438 if (local_index==(maxloop-1) && (instance >= virt_accum)) {
3439 instance = fNdata[0]+1;
3440 if (check)
return fNdata[0]+1;
3442 if (fManager->fCumulUsedVarDims->At(local_index)) {
3443 instance -= (virt_accum - fManager->fCumulUsedVarDims->At(local_index));
3445 instance = fNdata[0]+1;
3446 if (check)
return fNdata[0]+1;
3454 local_index = fIndexes[codeindex][0];
3460 if (fManager->fVarDims[kMAXFORMDIM]) {
3461 fManager->fCumulUsedSizes[kMAXFORMDIM] = fManager->fVarDims[kMAXFORMDIM]->At(local_index);
3463 fManager->fCumulUsedSizes[kMAXFORMDIM] = fManager->fUsedSizes[kMAXFORMDIM];
3465 for(Int_t d = kMAXFORMDIM-1; d>0; d--) {
3466 if (fManager->fVarDims[d]) {
3467 fManager->fCumulUsedSizes[d] = fManager->fCumulUsedSizes[d+1] * fManager->fVarDims[d]->At(local_index);
3469 fManager->fCumulUsedSizes[d] = fManager->fCumulUsedSizes[d+1] * fManager->fUsedSizes[d];
3475 info->SetPrimaryIndex(local_index);
3479 Int_t vdim = info->GetVarDim();
3480 Int_t isize = info->GetSize(local_index);
3481 if (fIndexes[codeindex][vdim]>=0) {
3482 info->SetSecondaryIndex(fIndexes[codeindex][vdim]);
3484 if (isize!=1 && fIndexes[codeindex][vdim]>isize) {
3488 fCumulSizes[codeindex][vdim] = isize*fCumulSizes[codeindex][vdim+1];
3489 for(Int_t k=vdim -1; k>0; --k) {
3490 fCumulSizes[codeindex][k] = fCumulSizes[codeindex][k+1]*fFixedSizes[codeindex][k];
3493 real_instance = local_index * fCumulSizes[codeindex][1];
3497 for (Int_t dim = 1; dim < max_dim; dim++) {
3498 if (fIndexes[codeindex][dim]>=0) {
3499 real_instance += fIndexes[codeindex][dim] * fCumulSizes[codeindex][dim+1];
3502 if (virt_dim && fManager->fCumulUsedSizes[virt_dim]>1) {
3503 local_index = ( ( instance % fManager->fCumulUsedSizes[virt_dim] )
3504 / fManager->fCumulUsedSizes[virt_dim+1]);
3506 local_index = ( instance / fManager->fCumulUsedSizes[virt_dim+1]);
3508 if (fIndexes[codeindex][dim]==-2) {
3510 if (fDidBooleanOptimization && local_index!=0) {
3512 fVarIndexes[codeindex][dim]->LoadBranches();
3514 local_index = (Int_t)fVarIndexes[codeindex][dim]->EvalInstance(local_index);
3515 if (local_index<0 ||
3516 local_index>=(fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1])) {
3517 Error(
"EvalInstance",
"Index %s is out of bound (%d/%d) in formula %s",
3518 fVarIndexes[codeindex][dim]->GetTitle(),
3520 (fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1]),
3522 local_index = (fCumulSizes[codeindex][dim]/fCumulSizes[codeindex][dim+1])-1;
3525 real_instance += local_index * fCumulSizes[codeindex][dim+1];
3529 if (fIndexes[codeindex][max_dim]>=0) {
3530 if (!info) real_instance += fIndexes[codeindex][max_dim];
3533 if (virt_dim && fManager->fCumulUsedSizes[virt_dim]>1) {
3534 local_index = instance % fManager->fCumulUsedSizes[virt_dim];
3536 local_index = instance;
3538 if (info && local_index>=fCumulSizes[codeindex][max_dim]) {
3542 if (fIndexes[codeindex][max_dim]==-2) {
3543 if (fDidBooleanOptimization && local_index!=0) {
3545 fVarIndexes[codeindex][max_dim]->LoadBranches();
3547 local_index = (Int_t)fVarIndexes[codeindex][max_dim]->EvalInstance(local_index);
3548 if (local_index<0 ||
3549 local_index>=fCumulSizes[codeindex][max_dim]) {
3550 Error(
"EvalInstance",
"Index %s is of out bound (%d/%d) in formula %s",
3551 fVarIndexes[codeindex][max_dim]->GetTitle(),
3553 fCumulSizes[codeindex][max_dim],
3555 local_index = fCumulSizes[codeindex][max_dim]-1;
3558 real_instance += local_index;
3563 return real_instance;
3572 TClass* TTreeFormula::EvalClass()
const
3574 if (fNoper != 1 || fNcodes <=0 )
return 0;
3576 return EvalClass(0);
3585 TClass* TTreeFormula::EvalClass(Int_t oper)
const
3587 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(oper);
3588 switch(fLookupType[oper]) {
3590 if (leaf->IsA()==TLeafObject::Class()) {
3591 return ((TLeafObject*)leaf)->GetClass();
3592 }
else if ( leaf->IsA()==TLeafElement::Class()) {
3593 TBranchElement * branch = (TBranchElement*)((TLeafElement*)leaf)->GetBranch();
3594 TStreamerInfo * info = branch->GetInfo();
3595 Int_t
id = branch->GetID();
3597 if (info==0 || !info->IsCompiled()) {
3601 TStreamerElement* elem = (TStreamerElement*)info->GetElement(
id);
3606 return elem->GetClass();
3608 }
else return TClass::GetClass( branch->GetClassName() );
3613 case kMethod:
return 0;
3616 TObject *obj = fDataMembers.UncheckedAt(oper);
3618 return ((TFormLeafInfo*)obj)->GetClass();
3634 void* TTreeFormula::EvalObject(
int instance)
3636 if (fNoper != 1 || fNcodes <=0 )
return 0;
3639 switch (fLookupType[0]) {
3641 case kIndexOfLocalEntry:
3651 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
3653 Int_t real_instance = GetRealInstance(instance,0);
3655 if (instance==0 || fNeedLoading) {
3656 fNeedLoading = kFALSE;
3657 R__LoadBranch(leaf->GetBranch(),
3658 leaf->GetBranch()->GetTree()->GetReadEntry(),
3661 else if (real_instance>=fNdata[0])
return 0;
3665 switch(fLookupType[0]) {
3667 if (real_instance) {
3668 Warning(
"EvalObject",
"Not yet implement for kDirect and arrays (for %s).\nPlease contact the developers",GetName());
3670 return leaf->GetValuePointer();
3672 case kMethod:
return GetValuePointerFromMethod(0,leaf);
3674 case kDataMember:
return ((TFormLeafInfo*)fDataMembers.UncheckedAt(0))->GetValuePointer(leaf,real_instance);
3685 const char* TTreeFormula::EvalStringInstance(Int_t instance)
3687 const Int_t kMAXSTRINGFOUND = 10;
3688 const char *stringStack[kMAXSTRINGFOUND];
3690 if (fNoper==1 && fNcodes>0 && IsString()) {
3691 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
3693 Int_t real_instance = GetRealInstance(instance,0);
3695 if (instance==0 || fNeedLoading) {
3696 fNeedLoading = kFALSE;
3697 TBranch *branch = leaf->GetBranch();
3698 R__LoadBranch(branch,branch->GetTree()->GetReadEntry(),fQuickLoad);
3699 }
else if (real_instance>=fNdata[0]) {
3703 if (fLookupType[0]==kDirect) {
3704 return (
char*)leaf->GetValuePointer();
3706 return (
char*)GetLeafInfo(0)->GetValuePointer(leaf,real_instance);
3710 EvalInstance(instance,stringStack);
3712 return stringStack[0];
3715 #define TT_EVAL_INIT \
3716 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0); \
3718 const Int_t real_instance = GetRealInstance(instance,0); \
3720 if (instance==0) fNeedLoading = kTRUE; \
3721 if (real_instance>=fNdata[0]) return 0; \
3727 if (fNeedLoading) { \
3728 fNeedLoading = kFALSE; \
3729 TBranch *br = leaf->GetBranch(); \
3730 Long64_t tentry = br->GetTree()->GetReadEntry(); \
3731 R__LoadBranch(br,tentry,fQuickLoad); \
3738 if (fLookupType[0]==kDirect) { \
3739 label = (char*)leaf->GetValuePointer(); \
3741 label = (char*)GetLeafInfo(0)->GetValuePointer(leaf,instance); \
3743 Int_t bin = fAxis->FindBin(label); \
3747 #define TREE_EVAL_INIT \
3748 const Int_t real_instance = GetRealInstance(instance,0); \
3750 if (real_instance>=fNdata[0]) return 0; \
3756 label = (char*)GetLeafInfo(0)->GetValuePointer((TLeaf*)0x0,instance); \
3757 Int_t bin = fAxis->FindBin(label); \
3761 #define TT_EVAL_INIT_LOOP \
3762 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(code); \
3765 const Int_t real_instance = GetRealInstance(instance,code); \
3768 TBranch *branch = (TBranch*)fBranches.UncheckedAt(code); \
3770 Long64_t treeEntry = branch->GetTree()->GetReadEntry(); \
3771 R__LoadBranch(branch,treeEntry,fQuickLoad); \
3772 } else if (fDidBooleanOptimization) { \
3773 branch = leaf->GetBranch(); \
3774 Long64_t treeEntry = branch->GetTree()->GetReadEntry(); \
3775 if (branch->GetReadEntry() != treeEntry) branch->GetEntry( treeEntry ); \
3781 if (fDidBooleanOptimization) { \
3782 TBranch *br = leaf->GetBranch(); \
3783 Long64_t treeEntry = br->GetTree()->GetReadEntry(); \
3784 if (br->GetReadEntry() != treeEntry) br->GetEntry( treeEntry ); \
3787 if (real_instance>=fNdata[code]) return 0;
3789 #define TREE_EVAL_INIT_LOOP \
3791 const Int_t real_instance = GetRealInstance(instance,code); \
3793 if (real_instance>=fNdata[code]) return 0;
3796 template<
typename T> T Summing(TTreeFormula *sum) {
3797 Int_t len = sum->GetNdata();
3799 for (
int i=0; i<len; ++i) res += sum->EvalInstance<T>(i);
3803 template<
typename T> T FindMin(TTreeFormula *arr) {
3804 Int_t len = arr->GetNdata();
3807 res = arr->EvalInstance<T>(0);
3808 for (
int i=1; i<len; ++i) {
3809 T val = arr->EvalInstance<T>(i);
3818 template<
typename T> T FindMax(TTreeFormula *arr) {
3819 Int_t len = arr->GetNdata();
3822 res = arr->EvalInstance<T>(0);
3823 for (
int i=1; i<len; ++i) {
3824 T val = arr->EvalInstance(i);
3833 template<
typename T> T FindMin(TTreeFormula *arr, TTreeFormula *condition) {
3834 Int_t len = arr->GetNdata();
3840 condval = condition->EvalInstance<T>(i);
3842 }
while (!condval && i<len);
3843 if (!condval && i==len) {
3848 arr->EvalInstance<T>(0);
3851 res = arr->EvalInstance<T>(i-1);
3852 for (; i<len; ++i) {
3853 condval = condition->EvalInstance<T>(i);
3855 T val = arr->EvalInstance<T>(i);
3865 template<
typename T> T FindMax(TTreeFormula *arr, TTreeFormula *condition) {
3866 Int_t len = arr->GetNdata();
3872 condval = condition->EvalInstance<T>(i);
3874 }
while (!condval && i<len);
3875 if (!condval && i==len) {
3880 arr->EvalInstance<T>(0);
3883 res = arr->EvalInstance<T>(i-1);
3884 for (; i<len; ++i) {
3885 condval = condition->EvalInstance<T>(i);
3887 T val = arr->EvalInstance<T>(i);
3899 template <
typename T> T fmod_local(T x, T y) {
return fmod(x,y); }
3900 template <> Long64_t fmod_local(Long64_t x, Long64_t y) {
return fmod((LongDouble_t)x,(LongDouble_t)y); }
3902 template<
typename T>
inline void SetMethodParam(TMethodCall *method, T p) { method->SetParam(p); }
3903 template<>
void SetMethodParam(TMethodCall *method, LongDouble_t p) { method->SetParam((Double_t)p); }
3907 template<
typename T>
inline T TTreeFormula::GetConstant(Int_t k) {
return fConst[k]; }
3908 template<>
inline LongDouble_t TTreeFormula::GetConstant(Int_t k) {
3911 fConstLD =
new LongDouble_t[fNconst];
3912 for (Int_t op=0; op<fNoper ; ++op) {
3913 const Int_t oper = GetOper()[op];
3914 if( (oper >> kTFOperShift) == kConstant ) {
3915 int i = (oper & kTFOperMask);
3916 if( !strncmp(fExpr[op],
"0x", 2) || !strncmp(fExpr[op],
"0X", 2) ) {
3918 sscanf( fExpr[op],
"%llx", &val );
3919 fConstLD[i] = (LongDouble_t)val;
3921 sscanf( fExpr[op],
"%Lg", &fConstLD[i] );
3928 template<>
inline Long64_t TTreeFormula::GetConstant(Int_t k) {
return (Long64_t)GetConstant<LongDouble_t>(k); }
3933 template<
typename T>
3934 T TTreeFormula::EvalInstance(Int_t instance,
const char *stringStackArg[])
3938 if (TestBit(kMissingLeaf))
return 0;
3939 if (fNoper == 1 && fNcodes > 0) {
3941 switch (fLookupType[0]) {
3944 return leaf->GetTypedValue<T>(real_instance);
3948 ((TFormLeafInfo*)fDataMembers.UncheckedAt(0))->SetBranch(leaf->GetBranch());
3949 return GetValueFromMethod(0,leaf);
3953 ((TFormLeafInfo*)fDataMembers.UncheckedAt(0))->SetBranch(leaf->GetBranch());
3954 return ((TFormLeafInfo*)fDataMembers.UncheckedAt(0))->GetTypedValue<T>(leaf,real_instance);
3958 return ((TFormLeafInfo*)fDataMembers.UncheckedAt(0))->GetTypedValue<T>((TLeaf*)0x0,real_instance);
3960 case kIndexOfEntry:
return (T)fTree->GetReadEntry();
3961 case kIndexOfLocalEntry:
return (T)fTree->GetTree()->GetReadEntry();
3962 case kEntries:
return (T)fTree->GetEntries();
3963 case kLocalEntries:
return (T)fTree->GetTree()->GetEntries();
3964 case kLength:
return fManager->fNdata;
3965 case kLengthFunc:
return ((TTreeFormula*)fAliases.UncheckedAt(0))->GetNdata();
3966 case kIteration:
return instance;
3967 case kSum:
return Summing<T>((TTreeFormula*)fAliases.UncheckedAt(0));
3968 case kMin:
return FindMin<T>((TTreeFormula*)fAliases.UncheckedAt(0));
3969 case kMax:
return FindMax<T>((TTreeFormula*)fAliases.UncheckedAt(0));
3971 TEntryList *elist = (TEntryList*)fExternalCuts.At(0);
3972 return elist->Contains(fTree->GetTree()->GetReadEntry());
3976 switch (fCodes[0]) {
3978 TCutG *gcut = (TCutG*)fExternalCuts.At(0);
3979 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
3980 TTreeFormula *fy = (TTreeFormula *)gcut->GetObjectY();
3981 if (fDidBooleanOptimization) {
3985 T xcut = fx->EvalInstance<T>(instance);
3986 T ycut = fy->EvalInstance<T>(instance);
3987 return gcut->IsInside(xcut,ycut);
3990 TCutG *gcut = (TCutG*)fExternalCuts.At(0);
3991 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
3992 if (fDidBooleanOptimization) {
3995 return fx->EvalInstance<T>(instance);
4002 const Int_t kMAXSTRINGFOUND = 10;
4003 const char *stringStackLocal[kMAXSTRINGFOUND];
4004 const char **stringStack = stringStackArg?stringStackArg:stringStackLocal;
4006 const Bool_t willLoad = (instance==0 || fNeedLoading); fNeedLoading = kFALSE;
4007 if (willLoad) fDidBooleanOptimization = kFALSE;
4011 for (Int_t i=0; i<fNoper ; ++i) {
4013 const Int_t oper = GetOper()[i];
4014 const Int_t newaction = oper >> kTFOperShift;
4016 if (newaction<kDefinedVariable) {
4020 if (newaction==kConstant) { pos++; tab[pos-1] = GetConstant<T>(oper & kTFOperMask);
continue; }
4024 case kEnd :
return tab[0];
4025 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4026 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4027 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4028 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4029 else tab[pos-1] /= tab[pos];
4031 case kModulo : {pos--;
4032 Long64_t int1((Long64_t)tab[pos-1]);
4033 Long64_t int2((Long64_t)tab[pos]);
4034 tab[pos-1] = T(int1 % int2);
4037 case kcos : tab[pos-1] = TMath::Cos(tab[pos-1]);
continue;
4038 case ksin : tab[pos-1] = TMath::Sin(tab[pos-1]);
continue;
4039 case ktan :
if (TMath::Cos(tab[pos-1]) == 0) {tab[pos-1] = 0;}
4040 else tab[pos-1] = TMath::Tan(tab[pos-1]);
4042 case kacos :
if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
4043 else tab[pos-1] = TMath::ACos(tab[pos-1]);
4045 case kasin :
if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
4046 else tab[pos-1] = TMath::ASin(tab[pos-1]);
4048 case katan : tab[pos-1] = TMath::ATan(tab[pos-1]);
continue;
4049 case kcosh : tab[pos-1] = TMath::CosH(tab[pos-1]);
continue;
4050 case ksinh : tab[pos-1] = TMath::SinH(tab[pos-1]);
continue;
4051 case ktanh :
if (TMath::CosH(tab[pos-1]) == 0) {tab[pos-1] = 0;}
4052 else tab[pos-1] = TMath::TanH(tab[pos-1]);
4054 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
4055 else tab[pos-1] = TMath::ACosH(tab[pos-1]);
4057 case kasinh: tab[pos-1] = TMath::ASinH(tab[pos-1]);
continue;
4058 case katanh:
if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
4059 else tab[pos-1] = TMath::ATanH(tab[pos-1]);
4061 case katan2: pos--; tab[pos-1] = TMath::ATan2(tab[pos-1],tab[pos]);
continue;
4063 case kfmod : pos--; tab[pos-1] = fmod_local(tab[pos-1],tab[pos]);
continue;
4064 case kpow : pos--; tab[pos-1] = TMath::Power(tab[pos-1],tab[pos]);
continue;
4065 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
4066 case ksqrt : tab[pos-1] = TMath::Sqrt(TMath::Abs(tab[pos-1]));
continue;
4068 case kstrstr : pos2 -= 2; pos++;
if (strstr(stringStack[pos2],stringStack[pos2+1])) tab[pos-1]=1;
4072 case kmin : pos--; tab[pos-1] = std::min(tab[pos-1],tab[pos]);
continue;
4073 case kmax : pos--; tab[pos-1] = std::max(tab[pos-1],tab[pos]);
continue;
4075 case klog :
if (tab[pos-1] > 0) tab[pos-1] = TMath::Log(tab[pos-1]);
4076 else {tab[pos-1] = 0;}
4078 case kexp : { Double_t dexp = tab[pos-1];
4079 if (dexp < -700) {tab[pos-1] = 0;
continue;}
4080 if (dexp > 700) {tab[pos-1] = TMath::Exp(700);
continue;}
4081 tab[pos-1] = TMath::Exp(dexp);
continue;
4083 case klog10:
if (tab[pos-1] > 0) tab[pos-1] = TMath::Log10(tab[pos-1]);
4084 else {tab[pos-1] = 0;}
4087 case kpi : pos++; tab[pos-1] = TMath::ACos(-1);
continue;
4089 case kabs : tab[pos-1] = TMath::Abs(tab[pos-1]);
continue;
4090 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
4092 case kint : tab[pos-1] = T(Long64_t(tab[pos-1]));
continue;
4093 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4094 case krndm : pos++; tab[pos-1] = gRandom->Rndm();
continue;
4096 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
4099 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
4103 case kEqual : pos--; tab[pos-1] = (tab[pos-1] == tab[pos]) ? 1 : 0;
continue;
4104 case kNotEqual : pos--; tab[pos-1] = (tab[pos-1] != tab[pos]) ? 1 : 0;
continue;
4105 case kLess : pos--; tab[pos-1] = (tab[pos-1] < tab[pos]) ? 1 : 0;
continue;
4106 case kGreater : pos--; tab[pos-1] = (tab[pos-1] > tab[pos]) ? 1 : 0;
continue;
4107 case kLessThan : pos--; tab[pos-1] = (tab[pos-1] <= tab[pos]) ? 1 : 0;
continue;
4108 case kGreaterThan: pos--; tab[pos-1] = (tab[pos-1] >= tab[pos]) ? 1 : 0;
continue;
4109 case kNot : tab[pos-1] = (tab[pos-1] != 0) ? 0 : 1;
continue;
4111 case kStringEqual : pos2 -= 2; pos++;
if (!strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1;
4114 case kStringNotEqual: pos2 -= 2; pos++;
if (strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1;
4118 case kBitAnd : pos--; tab[pos-1]= ((ULong64_t) tab[pos-1]) & ((ULong64_t) tab[pos]);
continue;
4119 case kBitOr : pos--; tab[pos-1]= ((ULong64_t) tab[pos-1]) | ((ULong64_t) tab[pos]);
continue;
4120 case kLeftShift : pos--; tab[pos-1]= ((ULong64_t) tab[pos-1]) <<((ULong64_t) tab[pos]);
continue;
4121 case kRightShift: pos--; tab[pos-1]= ((ULong64_t) tab[pos-1]) >>((ULong64_t) tab[pos]);
continue;
4123 case kJump : i = (oper & kTFOperMask);
continue;
4127 i = (oper & kTFOperMask);
4132 if (willLoad) fDidBooleanOptimization = kTRUE;
4137 case kStringConst: {
4139 pos2++; stringStack[pos2-1] = (
char*)fExpr[i].Data();
4142 Int_t bin = fAxis->FindBin(stringStack[pos2-1]);
4148 case kBoolOptimize: {
4151 int param = (oper & kTFOperMask);
4152 Bool_t skip = kFALSE;
4153 int op = param % 10;
4155 if (op == 1 && (!tab[pos-1]) ) {
4164 }
else if (op == 2 && tab[pos-1] ) {
4175 int toskip = param / 10;
4177 if (willLoad) fDidBooleanOptimization = kTRUE;
4182 case kFunctionCall: {
4185 int param = (oper & kTFOperMask);
4186 int fno = param / 1000;
4187 int nargs = param % 1000;
4190 TMethodCall *method = (TMethodCall*)fFunctions.At(fno);
4193 method->ResetParam();
4195 UInt_t argloc = pos-nargs;
4196 for(Int_t j=0;j<nargs;j++,argloc++,pos--) {
4197 SetMethodParam(method, tab[argloc]);
4202 method->Execute(ret);
4216 if (newaction == kDefinedVariable) {
4218 const Int_t code = (oper & kTFOperMask);
4219 const Int_t lookupType = fLookupType[code];
4220 switch (lookupType) {
4221 case kIndexOfEntry: tab[pos++] = (T)fTree->GetReadEntry();
continue;
4222 case kIndexOfLocalEntry: tab[pos++] = (T)fTree->GetTree()->GetReadEntry();
continue;
4223 case kEntries: tab[pos++] = (T)fTree->GetEntries();
continue;
4224 case kLocalEntries: tab[pos++] = (T)fTree->GetTree()->GetEntries();
continue;
4225 case kLength: tab[pos++] = fManager->fNdata;
continue;
4226 case kLengthFunc: tab[pos++] = ((TTreeFormula*)fAliases.UncheckedAt(i))->GetNdata();
continue;
4227 case kIteration: tab[pos++] = instance;
continue;
4228 case kSum: tab[pos++] = Summing<T>((TTreeFormula*)fAliases.UncheckedAt(i));
continue;
4229 case kMin: tab[pos++] = FindMin<T>((TTreeFormula*)fAliases.UncheckedAt(i));
continue;
4230 case kMax: tab[pos++] = FindMax<T>((TTreeFormula*)fAliases.UncheckedAt(i));
continue;
4232 case kDirect: { TT_EVAL_INIT_LOOP; tab[pos++] = leaf->GetTypedValue<T>(real_instance);
continue; }
4233 case kMethod: { TT_EVAL_INIT_LOOP; tab[pos++] = GetValueFromMethod(code,leaf);
continue; }
4234 case kDataMember: { TT_EVAL_INIT_LOOP; tab[pos++] = ((TFormLeafInfo*)fDataMembers.UncheckedAt(code))->
4235 GetTypedValue<T>(leaf,real_instance);
continue; }
4236 case kTreeMember: { TREE_EVAL_INIT_LOOP; tab[pos++] = ((TFormLeafInfo*)fDataMembers.UncheckedAt(code))->
4237 GetTypedValue<T>((TLeaf*)0x0,real_instance);
continue; }
4238 case kEntryList: { TEntryList *elist = (TEntryList*)fExternalCuts.At(code);
4239 tab[pos++] = elist->Contains(fTree->GetReadEntry());
4242 default: tab[pos++] = 0;
continue;
4244 switch (fCodes[code]) {
4246 TCutG *gcut = (TCutG*)fExternalCuts.At(code);
4247 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
4248 TTreeFormula *fy = (TTreeFormula *)gcut->GetObjectY();
4249 if (fDidBooleanOptimization) {
4253 T xcut = fx->EvalInstance<T>(instance);
4254 T ycut = fy->EvalInstance<T>(instance);
4255 tab[pos++] = gcut->IsInside(xcut,ycut);
4259 TCutG *gcut = (TCutG*)fExternalCuts.At(code);
4260 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
4261 if (fDidBooleanOptimization) {
4264 tab[pos++] = fx->EvalInstance<T>(instance);
4278 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(aliasN));
4281 subform->fDidBooleanOptimization = fDidBooleanOptimization;
4282 T param = subform->EvalInstance<T>(instance);
4284 tab[pos] = param; pos++;
4288 case kAliasString: {
4290 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(aliasN));
4294 subform->fDidBooleanOptimization = fDidBooleanOptimization;
4295 stringStack[pos2-1] = subform->EvalStringInstance(instance);
4300 TTreeFormula *primary =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN));
4301 TTreeFormula *condition =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN+1));
4302 T param = FindMin<T>(primary,condition);
4304 tab[pos] = param; pos++;
4309 TTreeFormula *primary =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN));
4310 TTreeFormula *condition =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN+1));
4311 T param = FindMax<T>(primary,condition);
4313 tab[pos] = param; pos++;
4320 TTreeFormula *primary =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN));
4323 if (instance < primary->GetNdata()) {
4325 T param = primary->EvalInstance<T>(instance);
4329 tab[pos] = param; pos++;
4338 case kAlternateString: {
4340 TTreeFormula *primary =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(alternateN));
4343 if (instance < primary->GetNdata()) {
4346 stringStack[pos2-1] = primary->EvalStringInstance(instance);
4360 case kDefinedString: {
4361 Int_t string_code = (oper & kTFOperMask);
4362 TLeaf *leafc = (TLeaf*)fLeaves.UncheckedAt(string_code);
4365 const Int_t real_instance = GetRealInstance(instance,string_code);
4367 if (instance==0 || fNeedLoading) {
4368 fNeedLoading = kFALSE;
4369 TBranch *branch = leafc->GetBranch();
4370 Long64_t readentry = branch->GetTree()->GetReadEntry();
4371 R__LoadBranch(branch,readentry,fQuickLoad);
4376 if (fDidBooleanOptimization) {
4377 TBranch *br = leafc->GetBranch();
4378 Long64_t treeEntry = br->GetTree()->GetReadEntry();
4379 R__LoadBranch(br,treeEntry,kTRUE);
4381 if (real_instance>=fNdata[string_code])
return 0;
4384 if (fLookupType[string_code]==kDirect) {
4385 stringStack[pos2-1] = (
char*)leafc->GetValuePointer();
4387 stringStack[pos2-1] = (
char*)GetLeafInfo(string_code)->GetValuePointer(leafc,real_instance);
4395 R__ASSERT(i<fNoper);
4403 template double TTreeFormula::EvalInstance<double> (int,
char const**);
4404 template long double TTreeFormula::EvalInstance<long double> (int,
char const**);
4405 template long long TTreeFormula::EvalInstance<long long> (int,
char const**);
4413 TFormLeafInfo *TTreeFormula::GetLeafInfo(Int_t code)
const
4415 return (TFormLeafInfo *)fDataMembers.UncheckedAt(code);
4422 TLeaf *TTreeFormula::GetLeaf(Int_t n)
const
4424 return (TLeaf*)fLeaves.UncheckedAt(n);
4433 TMethodCall *TTreeFormula::GetMethodCall(Int_t code)
const
4435 return (TMethodCall *)fMethods.UncheckedAt(code);
4442 Int_t TTreeFormula::GetNdata()
4444 return fManager->GetNdata();
4450 Double_t TTreeFormula::GetValueFromMethod(Int_t i, TLeaf* leaf)
const
4452 TMethodCall* m = GetMethodCall(i);
4459 if (leaf->InheritsFrom(TLeafObject::Class())) {
4460 thisobj = ((TLeafObject*) leaf)->GetObject();
4462 TBranchElement* branch = (TBranchElement*) ((TLeafElement*) leaf)->GetBranch();
4463 Int_t
id = branch->GetID();
4467 TStreamerInfo* info = branch->GetInfo();
4469 offset = info->GetElementOffset(
id);
4471 Warning(
"GetValueFromMethod",
"No streamer info for branch %s.", branch->GetName());
4475 char* address = branch->GetObject();
4479 char* address = branch->GetObject();
4481 thisobj = *((
char**) (address + offset));
4484 thisobj = branch->GetObject();
4489 TMethodCall::EReturnType r = m->ReturnType();
4491 if (r == TMethodCall::kLong) {
4493 m->Execute(thisobj, l);
4494 return (Double_t) l;
4497 if (r == TMethodCall::kDouble) {
4499 m->Execute(thisobj, d);
4503 m->Execute(thisobj);
4511 void* TTreeFormula::GetValuePointerFromMethod(Int_t i, TLeaf* leaf)
const
4513 TMethodCall* m = GetMethodCall(i);
4520 if (leaf->InheritsFrom(TLeafObject::Class())) {
4521 thisobj = ((TLeafObject*) leaf)->GetObject();
4523 TBranchElement* branch = (TBranchElement*) ((TLeafElement*) leaf)->GetBranch();
4524 Int_t
id = branch->GetID();
4527 TStreamerInfo* info = branch->GetInfo();
4529 offset = info->GetElementOffset(
id);
4531 Warning(
"GetValuePointerFromMethod",
"No streamer info for branch %s.", branch->GetName());
4535 char* address = branch->GetObject();
4539 char* address = branch->GetObject();
4541 thisobj = *((
char**) (address + offset));
4544 thisobj = branch->GetObject();
4549 TMethodCall::EReturnType r = m->ReturnType();
4551 if (r == TMethodCall::kLong) {
4553 m->Execute(thisobj, l);
4557 if (r == TMethodCall::kDouble) {
4559 m->Execute(thisobj, d);
4563 if (r == TMethodCall::kOther) {
4565 m->Execute(thisobj, &c);
4569 m->Execute(thisobj);
4580 Bool_t TTreeFormula::IsInteger(Bool_t fast)
const
4583 if (TestBit(kIsInteger))
return kTRUE;
4587 if (fNoper==2 && GetAction(0)==kAlternate) {
4588 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
4590 return subform->IsInteger(kFALSE);
4593 if (GetAction(0)==kMinIf || GetAction(0)==kMaxIf) {
4597 if (fNoper > 1)
return kFALSE;
4599 if (GetAction(0)==kAlias) {
4600 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
4602 return subform->IsInteger(kFALSE);
4605 if (fLeaves.GetEntries() != 1) {
4606 switch (fLookupType[0]) {
4608 case kIndexOfLocalEntry:
4624 if (EvalClass()==TBits::Class())
return kTRUE;
4626 if (IsLeafInteger(0) || IsLeafString(0))
return kTRUE;
4635 Bool_t TTreeFormula::IsLeafInteger(Int_t code)
const
4637 TLeaf *leaf = (TLeaf*)fLeaves.At(code);
4639 switch (fLookupType[code]) {
4641 case kIndexOfLocalEntry:
4656 if (fAxis)
return kTRUE;
4657 TFormLeafInfo * info;
4658 switch (fLookupType[code]) {
4662 info = GetLeafInfo(code);
4663 return info->IsInteger();
4667 if (!strcmp(leaf->GetTypeName(),
"Int_t"))
return kTRUE;
4668 if (!strcmp(leaf->GetTypeName(),
"Short_t"))
return kTRUE;
4669 if (!strcmp(leaf->GetTypeName(),
"UInt_t"))
return kTRUE;
4670 if (!strcmp(leaf->GetTypeName(),
"UShort_t"))
return kTRUE;
4671 if (!strcmp(leaf->GetTypeName(),
"Bool_t"))
return kTRUE;
4672 if (!strcmp(leaf->GetTypeName(),
"Char_t"))
return kTRUE;
4673 if (!strcmp(leaf->GetTypeName(),
"UChar_t"))
return kTRUE;
4674 if (!strcmp(leaf->GetTypeName(),
"Long64_t"))
return kTRUE;
4675 if (!strcmp(leaf->GetTypeName(),
"ULong64_t"))
return kTRUE;
4676 if (!strcmp(leaf->GetTypeName(),
"string"))
return kTRUE;
4683 Bool_t TTreeFormula::IsString()
const
4686 return TestBit(kIsCharacter);
4693 Bool_t TTreeFormula::IsString(Int_t oper)
const
4695 if (ROOT::v5::TFormula::IsString(oper))
return kTRUE;
4696 if (GetAction(oper)==kDefinedString)
return kTRUE;
4697 if (GetAction(oper)==kAliasString)
return kTRUE;
4698 if (GetAction(oper)==kAlternateString)
return kTRUE;
4705 Bool_t TTreeFormula::IsLeafString(Int_t code)
const
4707 TLeaf *leaf = (TLeaf*)fLeaves.At(code);
4708 TFormLeafInfo * info;
4709 if (fLookupType[code]==kTreeMember) {
4710 info = GetLeafInfo(code);
4711 return info->IsString();
4714 switch(fLookupType[code]) {
4716 if ( !leaf->IsUnsigned() && (leaf->InheritsFrom(TLeafC::Class()) || leaf->InheritsFrom(TLeafB::Class()) ) ) {
4718 if (leaf->GetLenStatic() > 1)
return kTRUE;
4722 if (leaf->GetLeafCount()) {
4723 const char* indexname = leaf->GetLeafCount()->GetName();
4724 if (indexname[strlen(indexname)-1] ==
'_' ) {
4733 }
else if (leaf->InheritsFrom(TLeafElement::Class())) {
4734 TBranchElement * br = (TBranchElement*)leaf->GetBranch();
4735 Int_t bid = br->GetID();
4736 if (bid < 0)
return kFALSE;
4737 if (br->GetInfo()==0 || !br->GetInfo()->IsCompiled()) {
4743 TStreamerElement * elem = (TStreamerElement*) br->GetInfo()->GetElement(bid);
4750 if (elem->GetNewType()== TStreamerInfo::kOffsetL +kChar_t) {
4752 if (fIndexes[code][fNdimensions[code]-1] != -1)
return kFALSE;
4755 if ( elem->GetNewType()== TStreamerInfo::kCharStar) {
4757 if (fNdimensions[code] && fIndexes[code][fNdimensions[code]-1] != -1)
return kFALSE;
4769 info = GetLeafInfo(code);
4770 return info->IsString();
4783 char *TTreeFormula::PrintValue(Int_t mode)
const
4785 return PrintValue(mode,0);
4797 char *TTreeFormula::PrintValue(Int_t mode, Int_t instance,
const char *decform)
const
4799 const int kMAXLENGTH = 1024;
4800 static char value[kMAXLENGTH];
4803 for (
int i = 0; i < kMAXLENGTH-1; i++)
4805 value[kMAXLENGTH-1] = 0;
4806 }
else if (mode == -1) {
4807 snprintf(value, kMAXLENGTH-1,
"%s", GetTitle());
4808 }
else if (mode == 0) {
4809 if ( (fNstring && fNval==0 && fNoper==1) || IsString() )
4811 const char * val = 0;
4812 if (GetAction(0)==kStringConst) {
4813 val = fExpr[0].Data();
4814 }
else if (instance<fNdata[0]) {
4816 if (fLookupType[0]==kTreeMember) {
4817 val = (
char*)GetLeafInfo(0)->GetValuePointer((TLeaf*)0x0,instance);
4819 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
4820 TBranch *branch = leaf->GetBranch();
4821 Long64_t readentry = branch->GetTree()->GetReadEntry();
4822 R__LoadBranch(branch,readentry,fQuickLoad);
4823 if (fLookupType[0]==kDirect && fNoper==1) {
4824 val = (
const char*)leaf->GetValuePointer();
4826 val = ((TTreeFormula*)
this)->EvalStringInstance(instance);
4830 val = ((TTreeFormula*)
this)->EvalStringInstance(instance);
4834 strlcpy(value, val, kMAXLENGTH);
4838 value[kMAXLENGTH-1] = 0;
4842 Int_t real_instance = ((TTreeFormula*)
this)->GetRealInstance(instance,-1);
4843 if (real_instance<fNdata[0]) {
4844 Ssiz_t len = strlen(decform);
4845 Char_t outputSizeLevel = 1;
4848 switch (decform[len-2]) {
4851 outputSizeLevel = 2;
4852 if (len>3 && tolower(decform[len-3])==
'l') {
4853 outputSizeLevel = 3;
4857 case 'h': outputSizeLevel = 0;
break;
4860 switch(decform[len-1]) {
4865 switch (outputSizeLevel) {
4866 case 0: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(Short_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4867 case 2: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(Long_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4868 case 3: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(Long64_t)((TTreeFormula*)
this)->EvalInstance<LongDouble_t>(instance));
break;
4870 default: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(Int_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4879 switch (outputSizeLevel) {
4880 case 0: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(UShort_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4881 case 2: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(ULong_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4882 case 3: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(ULong64_t)((TTreeFormula*)
this)->EvalInstance<LongDouble_t>(instance));
break;
4884 default: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(UInt_t)((TTreeFormula*)
this)->EvalInstance(instance));
break;
4894 switch (outputSizeLevel) {
4895 case 2: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),(LongDouble_t)((TTreeFormula*)
this)->EvalInstance<LongDouble_t>(instance));
break;
4897 default: snprintf(value,kMAXLENGTH,Form(
"%%%s",decform),((TTreeFormula*)
this)->EvalInstance(instance));
break;
4899 expo = strchr(value,
'e');
4903 snprintf(value,kMAXLENGTH,Form(
"%%%sg",decform),((TTreeFormula*)
this)->EvalInstance(instance));
4904 expo = strchr(value,
'e');
4909 UInt_t declen = atoi(decform);
4910 if (strlen(value)>declen) {
4911 UInt_t off = strlen(value)-declen;
4912 char *start = expo - off;
4913 UInt_t vlen = strlen(expo);
4914 for(UInt_t z=0;z<=vlen;++z) {
4921 if (isalpha(decform[strlen(decform)-1])) {
4922 TString short_decform(decform);
4923 short_decform.Remove(short_decform.Length()-1);
4924 snprintf(value,kMAXLENGTH,Form(
" %%%sc",short_decform.Data()),
' ');
4926 snprintf(value,kMAXLENGTH,Form(
" %%%sc",decform),
' ');
4938 void TTreeFormula::ResetLoading()
4940 fNeedLoading = kTRUE;
4941 fDidBooleanOptimization = kFALSE;
4943 for(Int_t i=0; i<fNcodes; ++i) {
4944 UInt_t max_dim = fNdimensions[i];
4945 for(UInt_t dim=0; dim<max_dim ;++dim) {
4946 if (fVarIndexes[i][dim]) {
4947 fVarIndexes[i][dim]->ResetLoading();
4951 Int_t n = fAliases.GetLast();
4955 for(Int_t k=0; k <= n; ++k) {
4956 TTreeFormula *f =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(k));
4961 for (
int i=0; i<fExternalCuts.GetSize(); i++) {
4962 auto c =
dynamic_cast<TCutG*
>(fExternalCuts.At(i));
4964 ((TTreeFormula *)(c->GetObjectX()))->ResetLoading();
4965 ((TTreeFormula *)(c->GetObjectY()))->ResetLoading();
4968 fRealInstanceCache.fInstanceCache = 0;
4969 fRealInstanceCache.fLocalIndexCache = 0;
4970 fRealInstanceCache.fVirtAccumCache = 0;
4976 void TTreeFormula::SetAxis(TAxis *axis)
4978 if (!axis) {fAxis = 0;
return;}
4981 if (fNoper==1 && GetAction(0)==kAliasString){
4982 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
4984 subform->SetAxis(axis);
4985 }
else if (fNoper==2 && GetAction(0)==kAlternateString){
4986 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(0));
4988 subform->SetAxis(axis);
4992 axis->SetBit(TAxis::kIsInteger);
4993 }
else if (IsInteger()) {
4994 axis->SetBit(TAxis::kIsInteger);
5001 void TTreeFormula::Streamer(TBuffer &R__b)
5003 if (R__b.IsReading()) {
5005 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
5007 R__b.ReadClassBuffer(TTreeFormula::Class(),
this, R__v, R__s, R__c);
5011 ROOT::v5::TFormula::Streamer(R__b);
5014 R__b.ReadFastArray(fCodes, fNcodes);
5015 R__b >> fMultiplicity;
5020 fLookupType =
new Int_t[fNindex];
5021 R__b.ReadFastArray(fLookupType, fNindex);
5023 fMethods.Streamer(R__b);
5027 R__b.WriteClassBuffer(TTreeFormula::Class(),
this);
5035 Bool_t TTreeFormula::StringToNumber(Int_t oper)
5037 Int_t code = GetActionParam(oper);
5038 if (GetAction(oper)==kDefinedString && fLookupType[code]==kDirect) {
5039 if (oper>0 && GetAction(oper-1)==kJump) {
5043 TLeaf *leaf = (TLeaf*)fLeaves.At(code);
5044 if (leaf && (leaf->InheritsFrom(TLeafC::Class()) || leaf->InheritsFrom(TLeafB::Class()) ) ) {
5045 SetAction(oper, kDefinedVariable, code );
5064 void TTreeFormula::UpdateFormulaLeaves()
5066 Int_t nleaves = fLeafNames.GetEntriesFast();
5067 ResetBit( kMissingLeaf );
5068 for (Int_t i=0;i<nleaves;i++) {
5070 if (!fLeafNames[i])
continue;
5072 TLeaf *leaf = fTree->GetLeaf(fLeafNames[i]->GetTitle(),fLeafNames[i]->GetName());
5074 if (fBranches[i] && leaf) {
5075 fBranches[i] = leaf->GetBranch();
5081 ((TBranch*)fBranches[i])->ResetReadEntry();
5083 if (leaf==0) SetBit( kMissingLeaf );
5085 for (Int_t j=0; j<kMAXCODES; j++) {
5086 for (Int_t k = 0; k<kMAXFORMDIM; k++) {
5087 if (fVarIndexes[j][k]) {
5088 fVarIndexes[j][k]->UpdateFormulaLeaves();
5091 if (fLookupType[j]==kDataMember || fLookupType[j]==kTreeMember) GetLeafInfo(j)->Update();
5092 if (j<fNval && fCodes[j]<0) {
5093 TCutG *gcut = (TCutG*)fExternalCuts.At(j);
5095 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
5096 TTreeFormula *fy = (TTreeFormula *)gcut->GetObjectY();
5097 if (fx) fx->UpdateFormulaLeaves();
5098 if (fy) fy->UpdateFormulaLeaves();
5102 for(Int_t k=0;k<fNoper;k++) {
5103 const Int_t oper = GetOper()[k];
5104 switch(oper >> kTFOperShift) {
5108 case kAlternateString:
5112 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(k));
5114 subform->UpdateFormulaLeaves();
5117 case kDefinedVariable:
5119 Int_t code = GetActionParam(k);
5120 if (fCodes[code]==0)
switch(fLookupType[code]) {
5126 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(k));
5128 subform->UpdateFormulaLeaves();
5144 void TTreeFormula::ResetDimensions() {
5150 TIter next(fDimensionSetup);
5151 Int_t last_code = -1;
5153 for(TDimensionInfo * info; (info = (TDimensionInfo*)next()); ) {
5154 if (last_code!=info->fCode) {
5159 last_code = info->fCode;
5160 fNdimensions[last_code] = 0;
5163 if (GetAction(info->fOper)==kDefinedString) {
5167 TDimensionInfo *nextinfo = (TDimensionInfo*)next();
5168 while(nextinfo && nextinfo->fCode==info->fCode) {
5169 DefineDimensions(info->fCode,info->fSize, info->fMultiDim, virt_dim);
5170 nextinfo = (TDimensionInfo*)next();
5172 if (!nextinfo)
break;
5176 last_code = info->fCode;
5177 fNdimensions[last_code] = 0;
5183 DefineDimensions(info->fCode,info->fSize, info->fMultiDim, virt_dim);
5187 for(i=0;i<fNoper;i++) {
5188 Int_t action = GetAction(i);
5190 if (action==kMinIf || action==kMaxIf) {
5195 if (action==kAlias || action==kAliasString) {
5196 TTreeFormula *subform =
static_cast<TTreeFormula*
>(fAliases.UncheckedAt(i));
5198 switch(subform->GetMultiplicity()) {
5200 case 1: fMultiplicity = 1;
break;
5201 case 2:
if (fMultiplicity!=1) fMultiplicity = 2;
break;
5203 fManager->Add(subform);
5208 if (action==kDefinedString) {
5225 for (i=0;i<fNcodes;i++) {
5226 if (fCodes[i] < 0) {
5227 TCutG *gcut = (TCutG*)fExternalCuts.At(i);
5228 if (!gcut)
continue;
5229 TTreeFormula *fx = (TTreeFormula *)gcut->GetObjectX();
5230 TTreeFormula *fy = (TTreeFormula *)gcut->GetObjectY();
5233 switch(fx->GetMultiplicity()) {
5235 case 1: fMultiplicity = 1;
break;
5236 case 2:
if (fMultiplicity!=1) fMultiplicity = 2;
break;
5241 switch(fy->GetMultiplicity()) {
5243 case 1: fMultiplicity = 1;
break;
5244 case 2:
if (fMultiplicity!=1) fMultiplicity = 2;
break;
5252 if (fLookupType[i]==kIteration) {
5257 TLeaf *leaf = i <= fLeaves.GetLast() ? (TLeaf*)fLeaves.UncheckedAt(i) : 0;
5258 if (!leaf)
continue;
5267 if (leaf->GetLeafCount()) {
5270 }
else if (fLookupType[i]==kDataMember) {
5271 TFormLeafInfo * leafinfo = GetLeafInfo(i);
5272 TStreamerElement * elem = leafinfo->fElement;
5273 if (fMultiplicity!=1) {
5274 if (leafinfo->HasCounter() ) fMultiplicity = 1;
5275 else if (elem && elem->GetArrayDim()>0) fMultiplicity = 2;
5276 else if (leaf->GetLenStatic()>1) fMultiplicity = 2;
5279 if (leaf->GetLenStatic()>1 && fMultiplicity!=1) fMultiplicity = 2;
5281 if (fMultiplicity!=1) {
5285 TTree *realtree = fTree ? fTree->GetTree() : 0;
5286 TTree *tleaf = leaf->GetBranch()->GetTree();
5287 if (tleaf && tleaf != realtree && tleaf->GetTreeIndex()) {
5293 Int_t virt_dim2 = 0;
5294 for (k = 0; k < fNdimensions[i]; k++) {
5297 if ( (fCumulSizes[i][k]>=0) && (fIndexes[i][k] >= fCumulSizes[i][k]) ) {
5299 fManager->CancelDimension(virt_dim2);
5301 if ( fIndexes[i][k] < 0 ) virt_dim2++;
5302 fFixedSizes[i][k] = fCumulSizes[i][k];
5306 for (k = fNdimensions[i]; (k > 0); k--) {
5310 fCumulSizes[i][k-1] *= TMath::Abs(fCumulSizes[i][k]);
5314 if (fCumulSizes[i][0]>0) fNdata[i] = fCumulSizes[i][0];
5326 void TTreeFormula::LoadBranches()
5329 for (i=0; i<fNoper ; ++i) {
5330 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
5331 if (leaf==0)
continue;
5333 TBranch *br = leaf->GetBranch();
5334 Long64_t treeEntry = br->GetTree()->GetReadEntry();
5335 R__LoadBranch(br,treeEntry,kTRUE);
5337 TTreeFormula *alias = (TTreeFormula*)fAliases.UncheckedAt(i);
5338 if (alias) alias->LoadBranches();
5340 Int_t max_dim = fNdimensions[i];
5341 for (Int_t dim = 0; dim < max_dim; ++dim) {
5342 if (fVarIndexes[i][dim]) fVarIndexes[i][dim]->LoadBranches();
5350 Bool_t TTreeFormula::LoadCurrentDim() {
5352 Bool_t outofbounds = kFALSE;
5354 for (Int_t i=0;i<fNcodes;i++) {
5355 if (fCodes[i] < 0)
continue;
5368 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
5370 switch(fLookupType[i]) {
5376 outofbounds = kTRUE;
5381 TTree *realtree = fTree->GetTree();
5382 TTree *tleaf = leaf->GetBranch()->GetTree();
5383 if (tleaf && tleaf != realtree && tleaf->GetTreeIndex()) {
5384 if (tleaf->GetReadEntry() < 0) {
5386 outofbounds = kTRUE;
5389 fNdata[i] = fCumulSizes[i][0];
5392 Bool_t hasBranchCount2 = kFALSE;
5393 if (leaf->GetLeafCount()) {
5394 TLeaf* leafcount = leaf->GetLeafCount();
5395 TBranch *branchcount = leafcount->GetBranch();
5396 TFormLeafInfo * info = 0;
5397 if (leaf->IsA() == TLeafElement::Class()) {
5400 Long64_t readentry = leaf->GetBranch()->GetTree()->GetReadEntry();
5401 if (readentry < 0) readentry=0;
5402 if (!branchcount->GetAddress()) {
5403 R__LoadBranch(branchcount, readentry, fQuickLoad);
5408 branchcount->TBranch::GetEntry(readentry);
5409 branchcount->ResetReadEntry();
5412 size = ((TBranchElement*)branchcount)->GetNdata();
5417 TBranchElement* branch = (TBranchElement*) leaf->GetBranch();
5418 if (branch->GetAddress() == 0) {
5427 if (fHasMultipleVarDim[i]) {
5428 info = (TFormLeafInfo* )fDataMembers.At(i);
5429 if (branch->GetBranchCount2()) R__LoadBranch(branch->GetBranchCount2(),readentry,fQuickLoad);
5430 else R__LoadBranch(branch,readentry,fQuickLoad);
5435 info->LoadSizes(branch);
5436 hasBranchCount2 = kTRUE;
5437 if (info->GetVirtVarDim()>=0) info->UpdateSizes(fManager->fVarDims[info->GetVirtVarDim()]);
5441 Int_t vdim = info->GetVarDim();
5442 fCumulSizes[i][vdim] = fCumulSizes[i][vdim+1];
5443 for(Int_t k=vdim -1; k>=0; k--) {
5444 fCumulSizes[i][k] = fCumulSizes[i][k+1]*fFixedSizes[i][k];
5456 Long64_t readentry = leaf->GetBranch()->GetTree()->GetReadEntry();
5457 if (readentry < 0) readentry=0;
5458 R__LoadBranch(branchcount,readentry,fQuickLoad);
5459 size = leaf->GetLen() / leaf->GetLenStatic();
5461 if (hasBranchCount2) {
5463 fNdata[i] = fCumulSizes[i][1] * ((TFormLeafInfo *)fDataMembers.At(i))->GetSumOfSizes();
5465 fNdata[i] = size * fCumulSizes[i][1];
5467 if (fIndexes[i][0]==-1) {
5470 if (fManager->fUsedSizes[0]==1 || (size<fManager->fUsedSizes[0]) ) fManager->fUsedSizes[0] = size;
5471 if (info && fIndexes[i][info->GetVarDim()]>=0) {
5472 for(Int_t j=0; j<size; j++) {
5473 if (fIndexes[i][info->GetVarDim()] >= info->GetSize(j)) {
5475 if (size>fManager->fCumulUsedVarDims->GetSize()) fManager->fCumulUsedVarDims->Set(size);
5476 fManager->fCumulUsedVarDims->AddAt(-1,j);
5477 }
else if (fIndexes[i][info->GetVarDim()]>=0) {
5480 if (size>fManager->fCumulUsedVarDims->GetSize()) fManager->fCumulUsedVarDims->Set(size);
5481 fManager->fCumulUsedVarDims->AddAt(1,j);
5485 }
else if (fIndexes[i][0] >= size) {
5487 fManager->fUsedSizes[0] = 0;
5489 outofbounds = kTRUE;
5490 }
else if (hasBranchCount2) {
5491 TFormLeafInfo *info2;
5492 info2 = (TFormLeafInfo *)fDataMembers.At(i);
5493 if (fIndexes[i][0]<0
5494 || fIndexes[i][info2->GetVarDim()] >= info2->GetSize(fIndexes[i][0])) {
5496 fManager->fUsedSizes[0] = 0;
5498 outofbounds = kTRUE;
5501 }
else if (fLookupType[i]==kDataMember) {
5502 TFormLeafInfo *leafinfo = (TFormLeafInfo*)fDataMembers.UncheckedAt(i);
5503 if (leafinfo->HasCounter()) {
5504 TBranch *branch = leaf->GetBranch();
5505 Long64_t readentry = branch->GetTree()->GetReadEntry();
5506 if (readentry < 0) readentry=0;
5507 R__LoadBranch(branch,readentry,fQuickLoad);
5508 size = (Int_t) leafinfo->GetCounterValue(leaf);
5509 if (fIndexes[i][0]==-1) {
5512 if (fManager->fUsedSizes[0]==1 || (size<fManager->fUsedSizes[0]) ) {
5513 fManager->fUsedSizes[0] = size;
5515 }
else if (fIndexes[i][0] >= size) {
5517 fManager->fUsedSizes[0] = 0;
5519 outofbounds = kTRUE;
5521 fNdata[i] = size*fCumulSizes[i][1];
5523 Int_t vdim = leafinfo->GetVarDim();
5530 leafinfo->LoadSizes(branch);
5531 hasBranchCount2 = kTRUE;
5532 if (fIndexes[i][0]==-1&&fIndexes[i][vdim] >= 0) {
5533 for(
int z=0; z<size; ++z) {
5534 if (fIndexes[i][vdim] >= leafinfo->GetSize(z)) {
5535 leafinfo->SetSize(z,0);
5537 }
else if (fIndexes[i][vdim] >= 0 ) {
5538 leafinfo->SetSize(z,1);
5542 leafinfo->UpdateSizes(fManager->fVarDims[vdim]);
5546 fCumulSizes[i][vdim] = fCumulSizes[i][vdim+1];
5547 for(Int_t k=vdim -1; k>=0; k--) {
5548 fCumulSizes[i][k] = fCumulSizes[i][k+1]*fFixedSizes[i][k];
5550 fNdata[i] = fCumulSizes[i][1] * leafinfo->GetSumOfSizes();
5552 fNdata[i] = size * fCumulSizes[i][1];
5554 }
else if (leafinfo->GetMultiplicity()==-1) {
5555 TBranch *branch = leaf->GetBranch();
5556 Long64_t readentry = branch->GetTree()->GetReadEntry();
5557 if (readentry < 0) readentry=0;
5558 R__LoadBranch(branch,readentry,fQuickLoad);
5559 if (leafinfo->GetNdata(leaf)==0) {
5560 outofbounds = kTRUE;
5566 TFormLeafInfo * info = 0;
5567 if (fLookupType[i]!=kDirect) {
5568 info = (TFormLeafInfo *)fDataMembers.At(i);
5570 for(Int_t k=0, virt_dim=0; k < fNdimensions[i]; k++) {
5571 if (fIndexes[i][k]<0) {
5572 if (info && fIndexes[i][k]==-2 && fVarIndexes[i][k]->GetManager()->GetMultiplicity()==0) {
5574 Int_t index = fVarIndexes[i][k]->EvalInstance(0);
5575 Int_t index_size = info->GetSize(index);
5576 if (fManager->fUsedSizes[virt_dim]==1 || (index_size!=1 && index_size<fManager->fUsedSizes[virt_dim]) )
5577 fManager->fUsedSizes[virt_dim] = index_size;
5578 }
else if (fIndexes[i][k]==-2 && fManager->fVirtUsedSizes[virt_dim]<0) {
5582 Int_t index_size = fVarIndexes[i][k]->GetNdata();
5583 if (index_size==1) {
5586 if (fVarIndexes[i][k]->GetManager()->GetMultiplicity()==1) {
5587 if (index_size<fManager->fUsedSizes[virt_dim]) fManager->fUsedSizes[virt_dim] = index_size;
5590 }
else if (fManager->fUsedSizes[virt_dim]==-fManager->fVirtUsedSizes[virt_dim] ||
5591 index_size<fManager->fUsedSizes[virt_dim]) {
5592 fManager->fUsedSizes[virt_dim] = index_size;
5595 }
else if (hasBranchCount2 && info && k==info->GetVarDim()) {
5597 if (fIndexes[i][0]>=0) {
5598 Int_t index_size = info->GetSize(fIndexes[i][0]);
5599 if (fManager->fUsedSizes[virt_dim]==1 || (index_size!=1 && index_size<fManager->fUsedSizes[virt_dim]) )
5600 fManager->fUsedSizes[virt_dim] = index_size;
5604 }
else if (hasBranchCount2 && info && k==info->GetVarDim()) {
5617 return ! outofbounds;
5623 void TTreeFormula::Convert(UInt_t oldversion)
5627 enum { kOldAlias = 100000+10000+1,
5628 kOldAliasString = kOldAlias+1,
5629 kOldAlternate = kOldAlias+2,
5630 kOldAlternateString = kOldAliasString+2
5633 for (
int k=0; k<fNoper; k++) {
5636 Int_t action = GetOper()[k];
5640 case kOldAlias: GetOper()[k] = -kOldAlias;
break;
5641 case kOldAliasString: GetOper()[k] = -kOldAliasString;
break;
5642 case kOldAlternate: GetOper()[k] = -kOldAlternate;
break;
5643 case kOldAlternateString: GetOper()[k] = -kOldAlternateString;
break;
5647 ROOT::v5::TFormula::Convert(oldversion);
5649 for (
int i=0,offset=0; i<fNoper; i++) {
5650 Int_t action = GetOper()[i+offset];
5653 case -kOldAlias: SetAction(i, kAlias, 0);
break;
5654 case -kOldAliasString: SetAction(i, kAliasString, 0);
break;
5655 case -kOldAlternate: SetAction(i, kAlternate, 0);
break;
5656 case -kOldAlternateString: SetAction(i, kAlternateString, 0);
break;
5671 Bool_t TTreeFormula::SwitchToFormLeafInfo(Int_t code)
5673 TFormLeafInfo *last = 0;
5674 TLeaf *leaf = (TLeaf*)fLeaves.At(code);
5675 if (!leaf)
return kFALSE;
5677 if (fLookupType[code]==kDirect) {
5678 if (leaf->InheritsFrom(TLeafElement::Class())) {
5679 TBranchElement * br = (TBranchElement*)leaf->GetBranch();
5680 if (br->GetType()==31) {
5682 TStreamerInfo *info = br->GetInfo();
5683 TClass* cl = info->GetClass();
5684 TStreamerElement *element = (TStreamerElement *)info->GetElement(br->GetID());
5685 TFormLeafInfo* clonesinfo =
new TFormLeafInfoClones(cl, 0, element, kTRUE);
5687 info->GetStreamerElement(element->GetName(),offset);
5688 clonesinfo->fNext =
new TFormLeafInfo(cl,offset+br->GetOffset(),element);
5689 last = clonesinfo->fNext;
5690 fDataMembers.AddAtAndExpand(clonesinfo,code);
5691 fLookupType[code]=kDataMember;
5693 }
else if (br->GetType()==41) {
5696 TBranchElement *count = br->GetBranchCount();
5697 TFormLeafInfo* collectioninfo;
5698 if ( count->GetID() >= 0 ) {
5699 TStreamerElement *collectionElement =
5700 (TStreamerElement *)count->GetInfo()->GetElement(count->GetID());
5701 TClass *collectionCl = collectionElement->GetClassPointer();
5704 new TFormLeafInfoCollection(collectionCl, 0, collectionElement, kTRUE);
5706 TClass *collectionCl = TClass::GetClass(count->GetClassName());
5708 new TFormLeafInfoCollection(collectionCl, 0, collectionCl, kTRUE);
5711 TStreamerInfo *info = br->GetInfo();
5712 TClass* cl = info->GetClass();
5713 TStreamerElement *element = (TStreamerElement *)info->GetElement(br->GetID());
5715 info->GetStreamerElement(element->GetName(),offset);
5716 collectioninfo->fNext =
new TFormLeafInfo(cl,offset+br->GetOffset(),element);
5717 last = collectioninfo->fNext;
5718 fDataMembers.AddAtAndExpand(collectioninfo,code);
5719 fLookupType[code]=kDataMember;
5721 }
else if (br->GetID()<0) {
5724 last =
new TFormLeafInfoDirect(br);
5725 fDataMembers.AddAtAndExpand(last,code);
5726 fLookupType[code]=kDataMember;