112 class TDimensionInfo :
public TObject {
119 : fCode(code), fOper(oper), fSize(size), fMultiDim(multiDim) {};
120 ~TDimensionInfo() {};
126 fDidBooleanOptimization(
kFALSE), fDimensionSetup(0)
162 Init(name,expression);
169 const std::vector<std::string>& aliases)
173 Init(name,expression);
211 if(savedir) savedir->
cd();
216 Warning(
"TTreeFormula",
"Too many items in expression:%s",expression);
226 if (!leafc)
continue;
269 for(k0 = 0; k0 <
fNcodes; k0++) {
274 Error(
"TTreeFormula",
275 "Index %d for dimension #%d in %s is too high (max is %d)",
278 if(savedir) savedir->
cd();
307 if (readentry >= 0) {
312 if (readentry >= 0) {
319 if(savedir) savedir->
cd();
341 for (
int j=0; j<
fNcodes; j++) {
374 switch (index_multiplicity) {
388 if (
fIndexes[code][fNdimensions[code]] < 0 ) {
392 fNdimensions[code] ++;
402 const char * current;
403 Int_t size, scanindex, vardim;
411 if (current[0] !=
'[') current--;
414 scanindex = sscanf(current,
"%d",&size);
418 if (scanindex==0) size = -1;
427 current = (
char*)strstr( current,
"[" );
437 TDimensionInfo * info =
new TDimensionInfo(code,
fNoper,size,multidim);
440 fNdimensions[code] ++;
441 return (size==-1) ? 1 : 0;
449 Bool_t useCollectionObject) {
450 Int_t ndim, size, current, vardim;
482 if (maininfo==0 || maininfo==leafinfo || 1) {
488 delete currentinfo->
fNext;
544 }
while (current<ndim);
581 Int_t numberOfVarDim = 0;
586 const char *tname = leaf->
GetTitle();
587 char *leaf_dim = (
char*)strstr( tname,
"[" );
590 char *branch_dim = (
char*)strstr(bname,
"[");
591 if (branch_dim) branch_dim++;
603 if (!branch_dim || strncmp(branch_dim,leaf_dim,strlen(branch_dim))) {
606 }
else if (branch_dim && strncmp(branch_dim,leaf_dim,strlen(branch_dim))==0
607 && strlen(leaf_dim)>strlen(branch_dim)
608 && (leaf_dim+strlen(branch_dim))[0]==
'[') {
627 "Noticed an incorrect in-memory TBranchElement object (%s).\nIt has a BranchCount2 but no BranchCount!\nThe result might be incorrect!",
629 return numberOfVarDim;
635 "Already in kDataMember mode when handling multiple variable dimensions");
643 return numberOfVarDim;
656 static const char *altfunc =
"Alt$(";
657 static const char *minfunc =
"MinIf$(";
658 static const char *maxfunc =
"MaxIf$(";
662 if ( strncmp(expression,altfunc,strlen(altfunc))==0
663 && expression[strlen(expression)-1]==
')' ) {
665 start = strlen(altfunc);
667 if ( strncmp(expression,maxfunc,strlen(maxfunc))==0
668 && expression[strlen(expression)-1]==
')' ) {
670 start = strlen(maxfunc);
672 if ( strncmp(expression,minfunc,strlen(minfunc))==0
673 && expression[strlen(expression)-1]==
')' ) {
675 start = strlen(minfunc);
685 for(
unsigned int i=start;i<strlen(expression);++i) {
686 switch (expression[i]) {
687 case '(': paran++;
break;
688 case ')': paran--;
break;
689 case '"': instr = instr ? 0 : 1;
break;
690 case '[': brack++;
break;
691 case ']': brack--;
break;
693 if (expression[i]==
',' && paran==0 && instr==0 && brack==0) {
694 part1 = full( start, i-start );
695 part2 = full( i+1, full.
Length() -1 - (i+1) );
707 Error(
"DefinedVariable",
"The 2nd arguments in %s can not be an array (%s,%d)!",
716 Error(
"DefinedVariable",
717 "The 2nd arguments in %s has to return the same type as the 1st argument (string)!",
723 Error(
"DefinedVariable",
724 "The 2nd arguments in %s has to return the same type as the 1st argument (numerical type)!",
733 Error(
"DefinedVariable",
734 "The arguments of %s can not be strings!",
765 Int_t numberOfVarDim = 0;
768 char scratch[
kMaxLen]; scratch[0] =
'\0';
769 char work[
kMaxLen]; work[0] =
'\0';
771 const char *right = subExpression;
776 if (readentry < 0) readentry=0;
778 Bool_t useLeafReferenceObject =
false;
789 Error(
"DefinedVariable",
"Missing StreamerInfo for %s. We will be unable to read!",
801 Error(
"DefinedVariable",
"Missing StreamerInfo for %s." 802 " We will be unable to read!",
807 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 const char* alias = 0;
823 if (!alias && realtree!=
fTree) {
831 TTree *tleaf = realtree;
834 fCodes[code] = tleaf->GetListOfLeaves()->IndexOf(leaf);
838 if (mother_name[strlen(mother_name)-1]!=
'.') {
839 br_extended_name = mother_name;
840 br_extended_name.
Append(
'.');
845 if (dim >= 0) br_extended_name.
Remove(dim);
933 "Missing TStreamerElement in object in TClonesArray section");
944 maininfo = clonesinfo;
963 maininfo->
fNext = previnfo;
964 unwindCollection =
kTRUE;
966 }
else if (branchEl->
GetType()==41) {
971 Warning(
"DefinedVariable",
"Missing TStreamerElement in object in Collection section");
977 if ( count->
GetID() >= 0 ) {
996 maininfo = collectioninfo;
1015 maininfo->
fNext = previnfo;
1016 unwindCollection =
kTRUE;
1018 }
else if ( branchEl->
GetType()==3) {
1020 if (useLeafCollectionObject) {
1025 numberOfVarDim +=
RegisterDimensions(code,clonesinfo,maininfo,useLeafCollectionObject);
1028 maininfo = clonesinfo;
1029 previnfo = maininfo;
1031 }
else if (!useLeafCollectionObject && branchEl->
GetType()==4) {
1034 if (useLeafCollectionObject) {
1039 numberOfVarDim +=
RegisterDimensions(code,collectioninfo,maininfo,useLeafCollectionObject);
1042 maininfo = collectioninfo;
1043 previnfo = maininfo;
1047 if (useLeafCollectionObject) {
1050 maininfo = collectioninfo;
1051 previnfo = collectioninfo;
1058 maininfo = collectioninfo;
1059 previnfo = collectioninfo;
1069 previnfo->
fNext = multi;
1072 previnfo = multi->
fNext;
1080 previnfo = previnfo->
fNext;
1086 }
else if (strlen(right)==0 && cl && element &&
final) {
1089 if (!useLeafCollectionObject
1100 maininfo = collectioninfo;
1101 previnfo = collectioninfo;
1110 previnfo->
fNext = multi;
1113 previnfo = multi->
fNext;
1120 previnfo = previnfo->
fNext;
1123 }
else if (!useLeafCollectionObject
1139 collectioninfo->
fNext =
1142 maininfo = collectioninfo;
1143 previnfo = maininfo->
fNext;
1145 }
else if (!useLeafCollectionObject
1156 previnfo = maininfo;
1161 if ( useLeafCollectionObject || fullExpression[0] ==
'@' || fullExpression[strlen(scratch)] ==
'@' ) {
1162 useLeafReferenceObject =
true;
1179 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->
GetName());
1190 if (unwindCollection) {
1193 R__ASSERT(numberOfVarDim==1 && maininfo);
1200 previnfo->
fNext = multi;
1203 previnfo = multi->
fNext;
1210 previnfo = previnfo->
fNext;
1218 previnfo->
fNext = multi;
1221 previnfo = multi->
fNext;
1230 Int_t nchname = strlen(right);
1245 Error(
"DefinedVariable",
"%s does not inherit from %s. Casting not possible!",
1252 maininfo = leafinfo;
1255 previnfo = leafinfo;
1257 previnfo->
fNext = leafinfo;
1258 previnfo = leafinfo;
1263 castqueue.
AddAt(0,paran_level);
1267 Bool_t prevUseCollectionObject = useLeafCollectionObject;
1268 Bool_t useCollectionObject = useLeafCollectionObject;
1269 Bool_t useReferenceObject = useLeafReferenceObject;
1270 Bool_t prevUseReferenceObject = useLeafReferenceObject;
1271 for (i=0, current = &(work[0]); i<=nchname;i++ ) {
1273 if (right[i] ==
'(') {
1276 *current++ = right[i++];
1277 }
while(right[i]!=
')' && right[i]);
1278 *current++ = right[i];
1280 char *params = strchr(work,
'(');
1282 *params = 0; params++;
1283 }
else params = (
char *)
")";
1285 Error(
"DefinedVariable",
"Can not call '%s' with a class",work);
1289 Error(
"DefinedVariable",
"Class probably unavailable:%s",cl->
GetName());
1316 previnfo = clonesinfo;
1317 maininfo = clonesinfo;
1349 previnfo = collectioninfo;
1350 maininfo = collectioninfo;
1355 if (inside_cl) cl = inside_cl;
1357 Warning(
"DefinedVariable",
"Can not call method on content of %s in %s\n",
1364 Error(
"DefinedVariable",
1365 "Could not discover the TClass corresponding to (%s)!",
1369 method =
new TMethodCall(cl,
"GetEntriesFast",
"");
1373 if (useLeafCollectionObject) {
1379 maininfo=previnfo=collectioninfo;
1385 Error(
"DefinedVariable",
1386 "Can not call method %s on class without dictionary (%s)!",
1394 Error(
"DefinedVariable",
"Unknown method:%s in %s",right,cl->
GetName());
1419 Error(
"DefineVariable",
"Method %s from %s has an impossible return type %d",
1425 maininfo = leafinfo;
1428 previnfo = leafinfo;
1430 previnfo->
fNext = leafinfo;
1431 previnfo = leafinfo;
1434 current = &(work[0]);
1436 prevUseCollectionObject =
kFALSE;
1437 prevUseReferenceObject =
kFALSE;
1438 useCollectionObject =
kFALSE;
1441 if (numberOfVarDim>1) {
1442 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1445 useCollectionObject =
kTRUE;
1446 }
else if (numberOfVarDim==0) {
1450 }
else if (numberOfVarDim==1) {
1455 previnfo->
fNext = leafinfo;
1456 previnfo = leafinfo;
1462 previnfo->
fNext = leafinfo;
1463 previnfo = leafinfo;
1467 }
else if (right[i] ==
')') {
1470 TClass * casted = (
TClass*) ((
int(--paran_level)>=0) ? castqueue.
At(paran_level) : 0);
1476 maininfo = leafinfo;
1479 previnfo = leafinfo;
1481 previnfo->
fNext = leafinfo;
1482 previnfo = leafinfo;
1485 current = &(work[0]);
1492 }
else if (i > 0 && (right[i] ==
'.' || right[i] ==
'[' || right[i] ==
'\0') ) {
1499 if (strlen(work)==0)
continue;
1501 prevUseCollectionObject = useCollectionObject;
1502 prevUseReferenceObject = useReferenceObject;
1504 useReferenceObject =
kTRUE;
1505 useCollectionObject =
kTRUE;
1507 for(l=0;work[l+1]!=0;++
l) work[l] = work[l+1];
1509 }
else if (work[strlen(work)-1]==
'@') {
1510 useReferenceObject =
kTRUE;
1511 useCollectionObject =
kTRUE;
1512 work[strlen(work)-1] =
'\0';
1514 useReferenceObject =
kFALSE;
1515 useCollectionObject =
kFALSE;
1526 prevUseReferenceObject =
kFALSE;
1529 previnfo = previnfo->
fNext;
1571 previnfo = clonesinfo;
1572 maininfo = clonesinfo;
1576 Error(
"DefinedVariable",
"Unimplemented usage of ClonesArray");
1587 "TClonesArray object was not retrievable for %s!",
1596 if (1 || inside_cl) cl = inside_cl;
1598 if (0 && strlen(work)==0) {
1632 previnfo = collectioninfo;
1633 maininfo = collectioninfo;
1642 Error(
"DefinedVariable",
"Could you not find the inner class for %s with coll type = %d",
1646 Warning(
"DefinedVariable",
"No data member in content of %s in %s\n",
1655 Warning(
"DefinedVariable",
"Missing class for %s!",name.
Data());
1660 if (!element && !prevUseCollectionObject) {
1667 Int_t clones_offset = 0;
1675 previnfo->
fNext = clonesinfo;
1677 previnfo->
fNext = 0;
1689 if (maininfo==0) maininfo = leafinfo;
1690 if (previnfo==0) previnfo = leafinfo;
1692 previnfo->
fNext = leafinfo;
1693 previnfo = leafinfo;
1699 }
else if (curelem->GetClassPointer() && curelem->GetClassPointer()->GetCollectionProxy()) {
1701 Int_t coll_offset = 0;
1710 if (numberOfVarDim>1) {
1711 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1712 curelem->GetName());
1714 useCollectionObject =
kTRUE;
1715 }
else if (numberOfVarDim==1) {
1727 if (maininfo==0) maininfo = leafinfo;
1728 if (previnfo==0) previnfo = leafinfo;
1730 previnfo->
fNext = leafinfo;
1731 previnfo = leafinfo;
1733 if (leafinfo->
fNext) {
1734 previnfo = leafinfo->
fNext;
1747 if (type<60 && type!=0) {
1749 if (numberOfVarDim>=1 && type>40) {
1754 if (leafinfo && type<=40 ) {
1794 Error(
"DefinedVariable",
1795 "%s is a datamember of %s BUT is not yet of a supported type (%d)",
1800 Error(
"DefinedVariable",
1801 "%s is a datamember of %s BUT is not of a unknown type (%d)",
1806 if (
object && !useCollectionObject &&
1812 if (
object && leafinfo) {
1814 }
else if (objarr) {
1829 if (numberOfVarDim>1) {
1830 Warning(
"DefinedVariable",
"TTreeFormula support only 2 level of variables size collections. Assuming '@' notation for the collection %s.",
1833 useCollectionObject =
kTRUE;
1834 }
else if (numberOfVarDim==1) {
1854 else leafinfo->
fNext = info;
1861 if (!maininfo) maininfo = leafinfo;
1866 if (previnfo==0) previnfo = leafinfo;
1868 previnfo->
fNext = leafinfo;
1869 previnfo = leafinfo;
1884 else leafinfo->
fNext = info;
1900 prevUseReferenceObject =
kFALSE;
1903 }
else if (pointer) {
1915 if (cl)
Error(
"DefinedVariable",
"%s is not a datamember of %s",work,cl->
GetName());
1922 maininfo = leafinfo;
1925 previnfo = leafinfo;
1926 }
else if (previnfo!=leafinfo) {
1927 previnfo->
fNext = leafinfo;
1928 previnfo = leafinfo;
1930 while (previnfo->
fNext) previnfo = previnfo->
fNext;
1932 if ( right[i] !=
'\0' ) {
1933 if ( !needClass && mustderef ) {
1939 if ( inf->IsReference() ) {
1950 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->
GetName());
1956 Error(
"DefinedVariable",
"Failed to access class type of reference target (%s)",element->
GetName());
1960 else if ( needClass ) {
1964 if (mustderef) leafinfo = 0;
1965 current = &(work[0]);
1974 nchname = strlen(right);
1978 *current++ = right[i];
1987 if (strlen(work)!=0) {
1999 if (!last)
return action;
2003 if (last && last->
GetClass() != objClass) {
2015 last->
fNext = collectioninfo;
2027 if (!last)
return action;
2031 const char *funcname = 0;
2035 }
else if (objClass == stdStringClass) {
2078 method =
new TMethodCall(objClass,
"AsString",
"");
2131 const char *funcname = 0;
2134 }
else if (objClass == stdStringClass) {
2174 if (readentry < 0) readentry=0;
2175 const char *cname = expression;
2178 char right[
kMaxLen]; right[0] =
'\0';
2179 char work[
kMaxLen]; work[0] =
'\0';
2180 char left[
kMaxLen]; left[0] =
'\0';
2183 std::string currentname;
2184 Int_t previousdot = 0;
2187 TBranch *branch=0, *tmp_branch=0;
2188 Int_t nchname = strlen(cname);
2193 for (i=0, current = &(work[0]); i<=nchname && !
final;i++ ) {
2195 *current++ = cname[i];
2197 if (cname[i] ==
'(') {
2200 if (current==work+1) {
2203 startWithParan =
kTRUE;
2215 if (cname[i] ==
')') {
2216 if (paran_level==0) {
2217 Error(
"DefinedVariable",
"Unmatched paranthesis in %s",fullExpression);
2222 if (startWithParan) {
2232 current = &(work[0]);
2236 }
else if (
gROOT->GetType(cast_name)) {
2238 current = &(work[0]);
2241 "Casting to primary types like \"%s\" is not supported yet",cast_name.
Data());
2248 char *params = strchr(work,
'(');
2250 *params = 0; params++;
2252 if (branch && !leaf) {
2264 while (!leaf && (leafcur = (
TLeaf*) next())) {
2265 TBranch* br = leafcur->GetBranch();
2274 if (strlen(left) && left[strlen(left)-1]==
'.') left[strlen(left)-1]=0;
2276 if (aliasValue && strcspn(aliasValue,
"+*/-%&!=<>|")==strlen(aliasValue)) {
2279 if (find(aliasUsed.begin(),
2281 left) != aliasUsed.end()) {
2282 Error(
"DefinedVariable",
2283 "The substitution of the branch alias \"%s\" by \"%s\" in \"%s\" failed\n"\
2284 "\tbecause \"%s\" is used [recursively] in its own definition!",
2285 left,aliasValue,fullExpression,left);
2288 aliasUsed.push_back(left);
2289 TString newExpression = aliasValue;
2290 newExpression += (cname+strlen(left));
2292 castqueue, aliasUsed, useLeafCollectionObject, fullExpression);
2294 Error(
"DefinedVariable",
2295 "The substitution of the alias \"%s\" by \"%s\" failed.",left,aliasValue);
2313 strncat(right,
"(",
kMaxLen-1-strlen(right));
2314 strncat(right,params,
kMaxLen-1-strlen(right));
2318 i += strlen(params);
2321 current = &(work[0]);
2326 if (cname[i] ==
'.' || cname[i] ==
'\0' || cname[i] ==
')') {
2331 Int_t len = strlen(work);
2333 foundAtSign =
kTRUE;
2335 for(l=0;work[l+1]!=0;++
l) work[l] = work[l+1];
2338 }
else if (len>=2 && work[len-2]==
'@') {
2339 foundAtSign =
kTRUE;
2340 work[len-2] = cname[i];
2347 if (left[0]==0) strlcpy(left,work,
kMaxLen);
2348 if (!leaf && !branch) {
2352 std::string treename(first);
2353 if (treename.size() && treename[treename.size()-1]==
'.') {
2354 treename.erase(treename.size()-1);
2356 if (treename==
"This" ) {
2361 if (cname[i]) leftover = &(cname[i+1]);
2393 if (cname[i]) first[strlen(first)-1]=
'\0';
2407 useLeafCollectionObject = foundAtSign;
2409 current = &(work[0]);
2412 else if (branch && (foundAtSign || cname[i] != 0) ) {
2422 if ( type == 3 || type ==4) {
2426 useLeafCollectionObject = foundAtSign;
2428 current = &(work[0]);
2438 useLeafCollectionObject = foundAtSign;
2440 current = &(work[0]);
2442 }
else if (leaf || branch) {
2443 if (leaf && branch) {
2457 current = &(work[0]);
2470 if (foundAtSign) strncat(right,
"@",
kMaxLen-1-strlen(right));
2471 if (cname[i]==
'.') strncat(right,
".",
kMaxLen-1-strlen(right));
2474 current = &(work[0]);
2477 }
else if (cname[i] ==
'.') {
2484 while(!branch && (branchcur=(
TBranch*)next()) ) {
2489 current = &(work[0]);
2496 Error(
"DefinedVariable",
"Unexpected control flow!");
2502 if (cname[i]) work[strlen(work)-1] =
'\0';
2503 snprintf(scratch,
sizeof(scratch),
"%s.%s",first,work);
2504 snprintf(scratch2,
sizeof(scratch2),
"%s.%s.%s",first,second,work);
2507 currentname = &(work[previousdot+1]);
2514 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(scratch);
2515 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(scratch2);
2516 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(currentname.c_str());
2526 if (!tmp_branch) tmp_branch = branch->
FindBranch(scratch);
2527 if (!tmp_branch) tmp_branch = branch->
FindBranch(scratch2);
2528 if (!tmp_branch) tmp_branch = branch->
FindBranch(currentname.c_str());
2536 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(scratch);
2537 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(scratch2);
2538 if (!tmp_leaf) tmp_leaf = branch->
FindLeaf(currentname.c_str());
2549 if (second[0]) strncat(second,
".",
kMaxLen-1-strlen(second));
2550 strncat(second,work,
kMaxLen-1-strlen(second));
2552 useLeafCollectionObject = foundAtSign;
2556 current = &(work[0]);
2562 Int_t where = strlen(work);
2564 work[where+1] = cname[i];
2566 previousdot = where+1;
2568 previousdot = strlen(work);
2569 work[strlen(work)] = cname[i];
2579 strncat(right,work,
kMaxLen-1-strlen(right));
2583 if (strlen(right) && right[strlen(right)-1]!=
'.' && cname[i]!=
'.') {
2587 strncat(right,
".",
kMaxLen-1-strlen(right));
2589 strncat(right,&cname[i],
kMaxLen-1-strlen(right));
2592 if (!
final && branch) {
2595 if (!leaf)
return -1;
2601 if (strlen(right)==0) strlcpy(right,work,
kMaxLen);
2604 if (leaf==0 && left[0]!=0) {
2605 if (left[strlen(left)-1]==
'.') left[strlen(left)-1]=0;
2609 if (aliasValue && strcspn(aliasValue,
"[]+*/-%&!=<>|")==strlen(aliasValue)) {
2612 if (find(aliasUsed.begin(),
2614 left) != aliasUsed.end()) {
2615 Error(
"DefinedVariable",
2616 "The substitution of the branch alias \"%s\" by \"%s\" in \"%s\" failed\n"\
2617 "\tbecause \"%s\" is used [recursively] in its own definition!",
2618 left,aliasValue,fullExpression,left);
2621 aliasUsed.push_back(left);
2622 TString newExpression = aliasValue;
2623 newExpression += (cname+strlen(left));
2625 castqueue, aliasUsed, useLeafCollectionObject, fullExpression);
2627 Error(
"DefinedVariable",
2628 "The substitution of the alias \"%s\" by \"%s\" failed.",left,aliasValue);
2679 if (!
fTree)
return -1;
2685 if (name ==
"Entry$") {
2691 if (name ==
"LocalEntry$") {
2697 if (name ==
"Entries$") {
2705 if (name ==
"LocalEntries$") {
2713 if (name ==
"Iteration$") {
2719 if (name ==
"Length$") {
2725 static const char *
lenfunc =
"Length$(";
2726 if (strncmp(name.
Data(),
"Length$(",strlen(lenfunc))==0
2727 && name[name.
Length()-1]==
')') {
2738 static const char *minfunc =
"Min$(";
2739 if (strncmp(name.
Data(),
"Min$(",strlen(minfunc))==0
2740 && name[name.
Length()-1]==
')') {
2751 static const char *maxfunc =
"Max$(";
2752 if (strncmp(name.
Data(),
"Max$(",strlen(maxfunc))==0
2753 && name[name.
Length()-1]==
')') {
2764 static const char *sumfunc =
"Sum$(";
2765 if (strncmp(name.
Data(),
"Sum$(",strlen(sumfunc))==0
2766 && name[name.
Length()-1]==
')') {
2784 if (res<0)
return res;
2792 char dims[
kMaxLen]; dims[0] =
'\0';
2800 Int_t cnamelen = strlen(cname);
2801 for(i=0,k=0; i<cnamelen; ++i, ++k) {
2802 if (cname[i] ==
'[') {
2804 int bracket_level = 1;
2806 for (j=++i; j<cnamelen && (bracket_level>0 || cname[j]==
'['); j++, i++) {
2807 if (cname[j]==
'[') bracket_level++;
2808 else if (cname[j]==
']') bracket_level--;
2810 if (bracket_level != 0) {
2814 strncat(dims,&cname[bracket],j-bracket);
2817 if (i!=k) cname[k] = cname[i];
2826 res =
FindLeafForExpression(cname, leaf, leftover,
final, paran_level, castqueue, aliasSofar, useLeafCollectionObject, name);
2828 if (res<0)
return res;
2830 if (!leaf && res!=2) {
2839 Error(
"DefinedVariable",
2840 "The substitution of the alias \"%s\" by \"%s\" failed\n"\
2841 "\tbecause \"%s\" is recursively used in its own definition!",
2842 cname,aliasValue,cname);
2847 if (strcspn(aliasValue,
"+*/-%&!=<>|")!=strlen(aliasValue)) {
2853 aliasSofar.push_back( cname );
2855 TString subValue( aliasValue );
2864 Error(
"DefinedVariable",
2865 "The substitution of the alias \"%s\" by \"%s\" failed.",cname,aliasValue);
2880 TString thisAlias( aliasValue );
2888 Error(
"Compile",
" Bad numerical expression : \"%s\"",thisAlias.
Data());
2889 }
else if (aliasRes==-2) {
2890 Error(
"Compile",
" Part of the Variable \"%s\" exists but some of it is not accessible or useable",thisAlias.
Data());
2893 Error(
"DefinedVariable",
2894 "The substitution of the alias \"%s\" by \"%s\" failed.",cname,aliasValue);
2903 if (leaf || res==2) {
2906 Error(
"DefinedVariable",
"the branch \"%s\" has to be enabled to be used",leaf->
GetBranch()->
GetName());
2915 char *current = &( dims[0] );
2922 if (current[0] ==
']') {
2925 scanindex = sscanf(current,
"%d",&index);
2931 char *end = (
char*)(varindex.
Data());
2932 for(
char bracket_level = 0;*end!=0;end++) {
2933 if (*end==
'[') bracket_level++;
2934 if (bracket_level==0 && *end==
']')
break;
2935 if (*end==
']') bracket_level--;
2945 current += strlen(varindex)+1;
2953 current = (
char*)strstr( current,
"[" );
2960 res =
ParseWithLeaf(leaf,leftover,
final,paran_level,castqueue,useLeafCollectionObject,name);
2961 if (res<0)
return res;
2962 if (res>0) action = res;
2992 }
else if (strlen(gcut->
GetVarX())) {
3001 for(
Int_t i2 = 1; i2<
n; i2++) {
3002 if (x[i2] < min) min = x[i2];
3003 if (x[i2] > max) max = x[i2];
3022 Error(
"DefinedVariable",
"Found a TCutG without leaf information (%s)",
3059 while ((leafcur = (
TLeaf*)nextleaf())) {
3076 }
else if (type>60 || type==0) {
3087 if (clonesinfo) {
delete clonesinfo; clonesinfo = 0; }
3109 clones = (
TClonesArray*)clonesinfo->GetLocalValuePointer(leafcur,0);
3111 if (clones) cl = clones->
GetClass();
3153 leafinfo = clonesinfo;
3165 Int_t clones_offset = 0;
3170 else leafinfo->
fNext = sub_clonesinfo;
3171 else leafinfo = sub_clonesinfo;
3177 delete leafinfo; clonesinfo = 0;
3182 if (!clones)
continue;
3189 else if (curelem->GetClassPointer() && curelem->GetClassPointer()->GetCollectionProxy()) {
3243 }
else if (type > 60) {
3302 Error(
"BranchHasMethod",
"A TClonesArray was stored in a branch type no yet support (i.e. neither TBranchObject nor TBranchElement): %s",branch->IsA()->
GetName());
3305 cl = clones ? clones->
GetClass() : 0;
3339 Int_t real_instance = 0;
3374 if (local_index<0) {
3375 Error(
"EvalInstance",
"Index %s is out of bound (%d) in formula %s",
3382 real_instance = local_index *
fCumulSizes[codeindex][1];
3407 if (local_index<0) {
3408 Error(
"EvalInstance",
"Index %s is out of bound (%d) in formula %s",
3428 if (check)
return fNdata[0]+1;
3433 }
while( instance >= virt_accum && local_index<maxloop);
3439 if (local_index==(maxloop-1) && (instance >= virt_accum)) {
3441 if (check)
return fNdata[0]+1;
3447 if (check)
return fNdata[0]+1;
3455 local_index =
fIndexes[codeindex][0];
3482 if (
fIndexes[codeindex][vdim]>=0) {
3485 if (isize!=1 &&
fIndexes[codeindex][vdim]>isize) {
3490 for(
Int_t k=vdim -1; k>0; --k) {
3491 fCumulSizes[codeindex][k] = fCumulSizes[codeindex][k+1]*
fFixedSizes[codeindex][k];
3494 real_instance = local_index *
fCumulSizes[codeindex][1];
3498 for (
Int_t dim = 1; dim < max_dim; dim++) {
3509 if (
fIndexes[codeindex][dim]==-2) {
3516 if (local_index<0 ||
3518 Error(
"EvalInstance",
"Index %s is out of bound (%d/%d) in formula %s",
3526 real_instance += local_index *
fCumulSizes[codeindex][dim+1];
3530 if (
fIndexes[codeindex][max_dim]>=0) {
3531 if (!info) real_instance +=
fIndexes[codeindex][max_dim];
3537 local_index = instance;
3539 if (info && local_index>=
fCumulSizes[codeindex][max_dim]) {
3543 if (
fIndexes[codeindex][max_dim]==-2) {
3549 if (local_index<0 ||
3551 Error(
"EvalInstance",
"Index %s is of out bound (%d/%d) in formula %s",
3559 real_instance += local_index;
3564 return real_instance;
3662 else if (real_instance>=
fNdata[0])
return 0;
3668 if (real_instance) {
3669 Warning(
"EvalObject",
"Not yet implement for kDirect and arrays (for %s).\nPlease contact the developers",
GetName());
3688 const Int_t kMAXSTRINGFOUND = 10;
3689 const char *stringStack[kMAXSTRINGFOUND];
3700 }
else if (real_instance>=
fNdata[0]) {
3713 return stringStack[0];
3716 #define TT_EVAL_INIT \ 3717 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0); \ 3719 const Int_t real_instance = GetRealInstance(instance,0); \ 3721 if (instance==0) fNeedLoading = kTRUE; \ 3722 if (real_instance>=fNdata[0]) return 0; \ 3728 if (fNeedLoading) { \ 3729 fNeedLoading = kFALSE; \ 3730 TBranch *br = leaf->GetBranch(); \ 3731 Long64_t tentry = br->GetTree()->GetReadEntry(); \ 3732 R__LoadBranch(br,tentry,fQuickLoad); \ 3739 if (fLookupType[0]==kDirect) { \ 3740 label = (char*)leaf->GetValuePointer(); \ 3742 label = (char*)GetLeafInfo(0)->GetValuePointer(leaf,instance); \ 3744 Int_t bin = fAxis->FindBin(label); \ 3748 #define TREE_EVAL_INIT \ 3749 const Int_t real_instance = GetRealInstance(instance,0); \ 3751 if (real_instance>=fNdata[0]) return 0; \ 3757 label = (char*)GetLeafInfo(0)->GetValuePointer((TLeaf*)0x0,instance); \ 3758 Int_t bin = fAxis->FindBin(label); \ 3762 #define TT_EVAL_INIT_LOOP \ 3763 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(code); \ 3766 const Int_t real_instance = GetRealInstance(instance,code); \ 3769 TBranch *branch = (TBranch*)fBranches.UncheckedAt(code); \ 3771 Long64_t treeEntry = branch->GetTree()->GetReadEntry(); \ 3772 R__LoadBranch(branch,treeEntry,fQuickLoad); \ 3773 } else if (fDidBooleanOptimization) { \ 3774 branch = leaf->GetBranch(); \ 3775 Long64_t treeEntry = branch->GetTree()->GetReadEntry(); \ 3776 if (branch->GetReadEntry() != treeEntry) branch->GetEntry( treeEntry ); \ 3782 if (fDidBooleanOptimization) { \ 3783 TBranch *br = leaf->GetBranch(); \ 3784 Long64_t treeEntry = br->GetTree()->GetReadEntry(); \ 3785 if (br->GetReadEntry() != treeEntry) br->GetEntry( treeEntry ); \ 3788 if (real_instance>=fNdata[code]) return 0; 3790 #define TREE_EVAL_INIT_LOOP \ 3792 const Int_t real_instance = GetRealInstance(instance,code); \ 3794 if (real_instance>=fNdata[code]) return 0; 3809 for (
int i=1; i<len; ++i) {
3824 for (
int i=1; i<len; ++i) {
3843 }
while (!condval && i<len);
3844 if (!condval && i==len) {
3853 for (; i<len; ++i) {
3875 }
while (!condval && i<len);
3876 if (!condval && i==len) {
3885 for (; i<len; ++i) {
3900 template <
typename T>
T fmod_local(
T x,
T y) {
return fmod(x,y); }
3903 template<
typename T>
inline void SetMethodParam(
TMethodCall *method,
T p) { method->
SetParam(p); }
3917 if( !strncmp(
fExpr[op],
"0x", 2) || !strncmp(
fExpr[op],
"0X", 2) ) {
3919 sscanf(
fExpr[op],
"%llx", &val );
3934 template<
typename T>
3945 return leaf->GetTypedValue<
T>(real_instance);
3996 const Int_t kMAXSTRINGFOUND = 10;
3997 const char *stringStackLocal[kMAXSTRINGFOUND];
3998 const char **stringStack = stringStackArg?stringStackArg:stringStackLocal;
4014 if (newaction==
kConstant) { pos++; tab[pos-1] = GetConstant<T>(oper &
kTFOperMask);
continue; }
4018 case kEnd :
return tab[0];
4019 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4020 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4021 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4022 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4023 else tab[pos-1] /= tab[pos];
4028 tab[pos-1] =
T(int1 % int2);
4048 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
4057 case kfmod : pos--; tab[pos-1] = fmod_local(tab[pos-1],tab[pos]);
continue;
4058 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4059 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
4062 case kstrstr : pos2 -= 2; pos++;
if (strstr(stringStack[pos2],stringStack[pos2+1])) tab[pos-1]=1;
4066 case kmin : pos--; tab[pos-1] = std::min(tab[pos-1],tab[pos]);
continue;
4067 case kmax : pos--; tab[pos-1] = std::max(tab[pos-1],tab[pos]);
continue;
4069 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
4070 else {tab[pos-1] = 0;}
4073 if (dexp < -700) {tab[pos-1] = 0;
continue;}
4074 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
4078 else {tab[pos-1] = 0;}
4084 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
4087 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4090 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
4093 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
4097 case kEqual : pos--; tab[pos-1] = (tab[pos-1] == tab[pos]) ? 1 : 0;
continue;
4098 case kNotEqual : pos--; tab[pos-1] = (tab[pos-1] != tab[pos]) ? 1 : 0;
continue;
4099 case kLess : pos--; tab[pos-1] = (tab[pos-1] < tab[pos]) ? 1 : 0;
continue;
4100 case kGreater : pos--; tab[pos-1] = (tab[pos-1] > tab[pos]) ? 1 : 0;
continue;
4101 case kLessThan : pos--; tab[pos-1] = (tab[pos-1] <= tab[pos]) ? 1 : 0;
continue;
4102 case kGreaterThan: pos--; tab[pos-1] = (tab[pos-1] >= tab[pos]) ? 1 : 0;
continue;
4103 case kNot : tab[pos-1] = (tab[pos-1] != 0) ? 0 : 1;
continue;
4105 case kStringEqual : pos2 -= 2; pos++;
if (!strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1;
4108 case kStringNotEqual: pos2 -= 2; pos++;
if (strcmp(stringStack[pos2+1],stringStack[pos2])) tab[pos-1]=1;
4133 pos2++; stringStack[pos2-1] = (
char*)
fExpr[i].Data();
4147 int op = param % 10;
4149 if (op == 1 && (!tab[pos-1]) ) {
4158 }
else if (op == 2 && tab[pos-1] ) {
4169 int toskip = param / 10;
4180 int fno = param / 1000;
4181 int nargs = param % 1000;
4189 UInt_t argloc = pos-nargs;
4190 for(
Int_t j=0;j<nargs;j++,argloc++,pos--) {
4191 SetMethodParam(method, tab[argloc]);
4214 switch (lookupType) {
4221 case kIteration: tab[pos++] = instance;
continue;
4229 GetTypedValue<T>(leaf,real_instance);
continue; }
4231 GetTypedValue<T>((
TLeaf*)0x0,real_instance);
continue; }
4236 default: tab[pos++] = 0;
continue;
4245 tab[pos++] = gcut->
IsInside(xcut,ycut);
4271 tab[pos] = param; pos++;
4289 T param = FindMin<T>(primary,condition);
4291 tab[pos] = param; pos++;
4298 T param = FindMax<T>(primary,condition);
4300 tab[pos] = param; pos++;
4310 if (instance < primary->
GetNdata()) {
4316 tab[pos] = param; pos++;
4330 if (instance < primary->
GetNdata()) {
4368 if (real_instance>=
fNdata[string_code])
return 0;
4390 template double TTreeFormula::EvalInstance<double> (int,
char const**);
4391 template long double TTreeFormula::EvalInstance<long double> (int,
char const**);
4392 template long long TTreeFormula::EvalInstance<long long> (int,
char const**);
4458 Warning(
"GetValueFromMethod",
"No streamer info for branch %s.", branch->
GetName());
4468 thisobj = *((
char**) (address + offset));
4518 Warning(
"GetValuePointerFromMethod",
"No streamer info for branch %s.", branch->
GetName());
4528 thisobj = *((
char**) (address + offset));
4711 if (indexname[strlen(indexname)-1] ==
'_' ) {
4723 if (bid < 0)
return kFALSE;
4786 const int kMAXLENGTH = 1024;
4787 static char value[kMAXLENGTH];
4790 for (
int i = 0; i < kMAXLENGTH-1; i++)
4792 value[kMAXLENGTH-1] = 0;
4793 }
else if (mode == -1) {
4795 }
else if (mode == 0) {
4798 const char * val = 0;
4801 }
else if (instance<
fNdata[0]) {
4813 val = ((
TTreeFormula*)
this)->EvalStringInstance(instance);
4817 val = ((
TTreeFormula*)
this)->EvalStringInstance(instance);
4821 strlcpy(value, val, kMAXLENGTH);
4825 value[kMAXLENGTH-1] = 0;
4830 if (real_instance<
fNdata[0]) {
4831 Ssiz_t len = strlen(decform);
4832 Char_t outputSizeLevel = 1;
4835 switch (decform[len-2]) {
4838 outputSizeLevel = 2;
4839 if (len>3 && tolower(decform[len-3])==
'l') {
4840 outputSizeLevel = 3;
4844 case 'h': outputSizeLevel = 0;
break;
4847 switch(decform[len-1]) {
4852 switch (outputSizeLevel) {
4866 switch (outputSizeLevel) {
4881 switch (outputSizeLevel) {
4886 expo = strchr(value,
'e');
4891 expo = strchr(value,
'e');
4896 UInt_t declen = atoi(decform);
4897 if (strlen(value)>declen) {
4898 UInt_t off = strlen(value)-declen;
4899 char *start = expo - off;
4900 UInt_t vlen = strlen(expo);
4908 if (isalpha(decform[strlen(decform)-1])) {
4909 TString short_decform(decform);
4932 for(
UInt_t dim=0; dim<max_dim ;++dim) {
4942 for(
Int_t k=0; k <=
n; ++k) {
4955 if (!axis) {
fAxis = 0;
return;}
5045 for (
Int_t i=0;i<nleaves;i++) {
5128 Int_t last_code = -1;
5130 for(TDimensionInfo * info; (info = (TDimensionInfo*)next()); ) {
5131 if (last_code!=info->fCode) {
5136 last_code = info->fCode;