20 #include "Riostream.h" 27 #include "TFriendElement.h" 29 #include "TTreeFormula.h" 30 #include "TTreeFormulaManager.h" 32 #include "TEntryList.h" 35 #include "TBufferJSON.h" 39 #include "TTimeStamp.h" 54 TTreeFormula(), fTextArray(NULL), fFormatArray(NULL), fFormulaArray(NULL), fValue(
""), fDebug(debug) {
76 TString fquery = expression;
83 Int_t sLength = fquery.Length();
92 for (iChar = 0; iChar < fquery.Length(); iChar++) {
93 if (fquery[iChar] !=
'{')
continue;
94 Int_t delta0 = 1, deltaf = 0;
95 for (delta0 = 1; delta0 + iChar < fquery.Length(); delta0++)
if (fquery[iChar + delta0] ==
'}')
break;
96 for (deltaf = -1; deltaf + iChar >= 0; deltaf--)
if (fquery[iChar + deltaf] ==
'%')
break;
97 TString stext(fquery(lastI, iChar + deltaf - lastI));
98 TString sformat(fquery(iChar + deltaf + 1, -(deltaf + 1)));
99 TString sformula(fquery(iChar + 1, delta0 - 1));
101 printf(
"%d\t%d\t%d\n", iChar, deltaf, delta0);
102 printf(
"%d\t%s\t%s\t%s\n", nVars, stext.Data(), sformat.Data(), sformula.Data());
104 fFormatArray->AddAtAndExpand(
new TObjString(sformat.Data()), nVars);
105 fTextArray->AddAtAndExpand(
new TObjString(stext.Data()), nVars);
106 fFormulaArray->AddAtAndExpand(
new TTreeFormula(sformula.Data(), sformula.Data(),
tree), nVars);
108 lastI = iChar + delta0 + 1;
110 TString stext(fquery(lastI, fquery.Length() - lastI));
111 fTextArray->AddAtAndExpand(
new TObjString(stext.Data()), nVars);
131 std::stringstream stream;
133 const char *format=NULL;
134 for (Int_t iVar = 0; iVar <= nVars; iVar++) {
136 if (
fDebug&2) cout<<
"T"<<iVar<<
"\t\t"<<
fTextArray->At(iVar)->GetName()<<endl;
137 if (
fDebug&4) cout<<
"F"<<iVar<<
"\t\t"<<stream.str().data()<<endl;
139 TTreeFormula *treeFormula = (TTreeFormula *)
fFormulaArray->At(iVar);
140 Bool_t isHex=TString(
fFormatArray->At(iVar)->GetName()).Contains(
"x") || TString(
fFormatArray->At(iVar)->GetName()).Contains(
"X");
143 Int_t value=treeFormula->EvalInstance();
145 sprintf(buffer,
"%X",(Int_t)value);
150 Long64_t value=treeFormula->EvalInstance();
152 stream<<b.to_string();
156 Long64_t value=treeFormula->EvalInstance64();
157 TTimeStamp stamp(value);
158 stream<<stamp.AsString(
"s");
161 TString value=treeFormula->PrintValue(0, instance,
fFormatArray->At(iVar)->GetName());
162 stream << value.Data();
163 if (
fDebug&&1) cout<<
"F"<<iVar<<
"\t\t"<<value.Data()<<
"\t"<<
fFormatArray->At(iVar)->GetName()<<endl;
167 fValue=stream.str().data();
168 return (
char *)
fValue.Data();
175 for (Int_t iVar = 0; iVar <= nVars; iVar++) {
176 TTreeFormula *treeFormula = (TTreeFormula *)
fFormulaArray->At(iVar);
177 treeFormula->UpdateFormulaLeaves();
218 TObjArray *queryArray=query.Tokenize(
"[=]");
221 TFormula *pFormula=0;
222 if (queryArray->GetEntries()>1) {
223 TString stringFormula=
"";
224 varArray = TString(queryArray->At(1)->GetName()).
Tokenize(
"\"&|!()[]+-/");
225 vecParam.ResizeTo(varArray->GetEntriesFast());
226 stringFormula=queryArray->At(1)->GetName();
227 stringFormula.ReplaceAll(
"\"",
"");
228 for (Int_t ivar=0; ivar<varArray->GetEntriesFast(); ivar++){
229 stringFormula.ReplaceAll(varArray->At(ivar)->GetName(),TString::Format(
"x[%d]",ivar).Data());
232 pFormula=
new TFormula(
"printMetadataFromula",stringFormula.Data());
233 if (verbose&0x2) pFormula->Print();
236 if (queryArray->GetEntriesFast()<=0 ){
239 if (queryArray->GetEntriesFast()>2) {
247 Int_t entries = metaData->GetEntries();
249 for (Int_t ientry=0;ientry<entries; ientry++){
250 TString index=metaData->At(ientry)->GetName();
251 if (strstr(metaData->At(ientry)->GetName(),queryArray->At(0)->GetName())==NULL)
continue;
252 Bool_t isSelected=kTRUE;
253 if (queryArray->GetEntriesFast()>1){
254 for (Int_t ipar=0; ipar< vecParam.GetNrows(); ipar++){
255 vecParam[ipar]=strstr(metaData->At(ientry)->GetTitle(),varArray->At(ipar)->GetName())!=NULL;
257 isSelected=pFormula->EvalPar(vecParam.GetMatrixArray());
259 vecParam.GetMatrixArray();
263 selected->AddLast(metaData->At(ientry));
265 TString
id=metaData->At(ientry)->GetName();
266 id.Remove(
id.Last(
'.'),
id.Length());
273 printf(
"%s:%s:%d\n",metaData->At(ientry)->GetName(),metaData->At(ientry)->GetTitle(),isSelected);
312 TObjArray *queryArray=query.Tokenize(
"&|()!");
313 Int_t formulaEntries=queryArray->GetEntries();
314 for (Int_t i=0;i<formulaEntries; i++){
315 if (TString(queryArray->At(i)->GetName()).ReplaceAll(
" ",
"").Length()<=0) queryArray->RemoveAt(i);
317 queryArray->Compress();
318 formulaEntries=queryArray->GetEntries();
319 if (formulaEntries<=0){
320 ::Error(
"selectTreeInfo",
"Empty or wrong selection %s", query.Data());
324 TString stringFormula=query;
326 TVectorF formType(formulaEntries);
327 TVectorF formExact(formulaEntries);
330 for (Int_t ivar=0; ivar<formulaEntries; ivar++){
331 TString formName=queryArray->At(ivar)->GetName();
332 stringFormula.ReplaceAll(queryArray->At(ivar)->GetName(),TString::Format(
"x[%d]",ivar).Data());
333 formName.ReplaceAll(
" ",
"");
334 formName.ReplaceAll(
"\t",
"");
335 TObjArray *tokenArray=formName.Tokenize(
"[=:]");
336 if (tokenArray->GetEntries()<2){
337 ::Error(
"selectTreeInfo",
"Wrong subformula %s",formName.Data());
338 ::Error(
"selectTreeInfo",
"Full formula was %s",query.Data());
345 formMatch[ivar]=tokenArray->At(1);
346 formMatchType[ivar]=tokenArray->At(0);
347 TString queryType(tokenArray->At(0)->GetName());
350 if (queryType.Contains(
".name",TString::kIgnoreCase)){
353 if (formName.Contains(
":")){
360 TFormula *pFormula=
new TFormula(
"printMetadataFormula",stringFormula.Data());
362 ::Info(
"selectTreeInfo",
"Formula:");
364 ::Info(
"selectTreeInfo",
"Query array:");
366 ::Info(
"selectTreeInfo",
"To match array:");
368 ::Info(
"selectTreeInfo",
"Exact type:");
376 if (tree->GetListOfFriends()!=NULL) nTrees+=tree->GetListOfFriends()->GetEntries();
377 for (Int_t iTree=0; iTree<nTrees; iTree++){
378 TTree * cTree =
tree;
379 if (iTree>0) cTree=tree->GetFriend(tree->GetListOfFriends()->At(iTree-1)->GetName());
380 if (cTree==NULL)
continue;
381 for (Int_t itype=0; itype<2; itype++){
384 TSeqCollection* elemList=0;
385 if (itype==0) elemList=cTree->GetListOfBranches();
386 if (itype==1) elemList=cTree->GetListOfAliases();
387 if (elemList==NULL)
continue;
388 Int_t elemEntries=elemList->GetEntries();
389 for (Int_t ientry=0; ientry<elemEntries; ientry++){
390 TString elemName(elemList->At(ientry)->GetName());
392 for (Int_t icheck=0; icheck<formulaEntries; icheck++){
394 if (formType[icheck]==0){
395 if (formExact[icheck]==1) formValue[icheck]=(elemName==formMatch.At(icheck)->GetName());
396 if (formExact[icheck]==0) formValue[icheck]=(strstr(elemName.Data(),formMatch.UncheckedAt(icheck)->GetName())!=NULL);
398 if (formType[icheck]==1){
399 TObject* metaObject =
TStatToolkit::GetMetadata(cTree,TString::Format(
"%s%s",elemName.Data(), formMatchType.UncheckedAt(icheck)->GetName()).Data());
401 TString metaName(metaObject->GetTitle());
402 if (formExact[icheck]==1) formValue[icheck]=(metaName==formMatch.At(icheck)->GetName());
403 if (formExact[icheck]==0) formValue[icheck]=(strstr(metaName.Data(),formMatch.UncheckedAt(icheck)->GetName())!=NULL);
407 Bool_t isSelected=pFormula->EvalPar(formValue.GetMatrixArray());
409 if (iTree==0) selected->AddLast(
new TObjString(elemList->At(ientry)->GetName()));
410 if (iTree>0) selected->AddLast(
new TObjString(TString::Format(
"%s.%s",tree->GetListOfFriends()->At(iTree-1)->GetName(),elemList->At(ientry)->GetName())));
411 if (verbose&0x1)
printf(
"%s\n",elemName.Data());
450 TList *treeFriends = tree->GetListOfFriends();
451 Int_t ntrees = 1 + ((treeFriends != NULL) ? treeFriends->GetEntries() : 0);
452 TPRegexp pregExpFriend = regExpFriend;
453 TPRegexp pregExpTag = regExpTag;
454 const char *dataTypes[3] = {
"branch",
"alias",
"metaData"};
455 for (Int_t itree = 0; itree < ntrees; itree++) {
456 TTree *currentTree = 0;
459 if (pregExpFriend.Match(currentTree->GetName()) == 0)
continue;
461 if (pregExpFriend.Match(treeFriends->At(itree - 1)->GetName()) == 0)
continue;
462 currentTree = ((TFriendElement * )(treeFriends->At(itree - 1)))->GetTree();
466 ::Info(
"printSelectedTreeInfo",
"tree %s selected", currentTree->GetName());
468 for (Int_t iDataType = 0; iDataType < 3; iDataType++) {
469 if (infoType.Contains(dataTypes[iDataType], TString::kIgnoreCase) == 0)
continue;
471 if (iDataType == 0) selList = (TList *) currentTree->GetListOfBranches();
472 if (iDataType == 1) selList = (TList *) currentTree->GetListOfAliases();
473 if (iDataType == 2 && tree->GetUserInfo())
474 selList = (TList * )(currentTree->GetUserInfo()->FindObject(
"metaTable"));
476 if (selList == NULL)
continue;
477 Int_t selListEntries = selList->GetEntries();
478 for (Int_t iEntry = 0; iEntry < selListEntries; iEntry++) {
479 if (pregExpTag.Match(selList->At(iEntry)->GetName()) <= 0)
continue;
481 ::Info(
" printSelectedTreeInfo",
"%s.%s", currentTree->GetName(), selList->At(iEntry)->GetName());
483 if (result.Length() > 0) result +=
":";
485 result += treeFriends->At(itree - 1)->GetName();
488 result += selList->At(iEntry)->GetName();
520 if (tree==NULL || tree->GetPlayer()==NULL){
521 ::Error(
"AliTreePlayer::selectWhatWhereOrderBy",
"Input tree not defiend");
525 if (firstentry +nentries >tree->GetEntriesFriend()) nentries=tree->GetEntriesFriend()-firstentry;
526 if (tree->GetEntryList()){
527 if (tree->GetEntryList()->GetN()<nentries) nentries=tree->GetEntryList()->GetN();
531 Bool_t isHTML=outputFormat.Contains(
"html",TString::kIgnoreCase );
532 Bool_t isCSV=outputFormat.Contains(
"csv",TString::kIgnoreCase);
533 Bool_t isElastic=outputFormat.Contains(
"elastic",TString::kIgnoreCase);
534 Bool_t isJSON=outputFormat.Contains(
"json",TString::kIgnoreCase)||isElastic;
537 FILE *default_fp = stdout;
538 if (outputName.Length()>0){
539 default_fp=fopen (outputName.Data(),
"w");
542 Int_t nCols=fArray->GetEntries();
544 TTreeFormula ** rFormulaList =
new TTreeFormula*[nCols+1];
545 TObjString **printFormatList =
new TObjString*[nCols];
546 TObjString **columnNameList =
new TObjString*[nCols];
547 TObjString **outputFormatList =
new TObjString*[nCols];
548 Bool_t isIndex[nCols];
549 Bool_t isParent[nCols];
550 TClass* isClass[nCols];
551 TPRegexp indexPattern(
"^%I");
552 TPRegexp parentPattern(
"^%P");
553 for (Int_t iCol=0; iCol<nCols; iCol++){
555 rFormulaList[iCol]=NULL;
557 if (arrayDesc->GetEntries()<=0) {
558 ::Error(
"AliTreePlayer::selectWhatWhereOrderBy",
"Invalid descriptor %s", arrayDesc->At(iCol)->GetName());
561 TString fieldName=arrayDesc->At(0)->GetName();
562 if (tree->GetBranch(fieldName.Data())){
563 if (TString(tree->GetBranch(fieldName.Data())->GetClassName()).Length()>0) {
564 isClass[iCol]=TClass::GetClass(tree->GetBranch(fieldName.Data())->GetClassName());
567 if (fieldName.Contains(indexPattern)){
569 indexPattern.Substitute(fieldName,
"");
571 isIndex[iCol]=kFALSE;
573 if (fieldName.Contains(parentPattern)){
574 isParent[iCol]=kTRUE;
575 parentPattern.Substitute(fieldName,
"");
577 isParent[iCol]=kFALSE;
579 TTreeFormula * formula = NULL;
581 Bool_t isFormulaF= (fieldName[0]==
'#') || htmlTag!=NULL;
584 formula=
new TTreeFormula(fieldName.Data(), fieldName.Data(),
tree);
586 TString fstring = fieldName;
588 fstring=htmlTag->GetTitle();
590 fieldName.Replace(0, 1,
"");
591 if (tree->GetAlias(fieldName.Data())) {
592 fstring = tree->GetAlias(fieldName.Data());
598 if (formula->GetTree()==NULL){
599 ::Error(
"AliTreePlayer::selectWhatWhereOrderBy",
"Invalid formula %s, parsed from the original string %s",fieldName.Data(),what.Data());
600 if (isJSON==kFALSE)
return -1;
602 TString printFormat=
"";
603 TString colName=arrayDesc->At(0)->GetName();
604 TString outputFormat=
"";
605 if (arrayDesc->At(1)!=NULL){
606 printFormat=arrayDesc->At(1)->GetName();
608 if (formula->IsInteger()) {
614 if (arrayDesc->At(2)!=NULL) {
615 colName=arrayDesc->At(2)->GetName();
617 colName=arrayDesc->At(0)->GetName();
620 if (arrayDesc->At(3)!=NULL){
621 outputFormat= arrayDesc->At(3)->GetName();
624 if (formula->IsInteger()) outputFormat=
"/I";
625 if (formula->IsString()) outputFormat=
"/C";
627 fFormulaList->AddAt(formula,iCol);
628 rFormulaList[iCol]=formula;
629 printFormatList[iCol]=
new TObjString(printFormat);
630 outputFormatList[iCol]=
new TObjString(outputFormat);
631 columnNameList[iCol]=
new TObjString(colName);
633 TTreeFormula *select =
new TTreeFormula(
"Selection",where.Data(),
tree);
634 fFormulaList->AddLast(select);
635 rFormulaList[nCols]=select;
638 Bool_t hasArray = kFALSE;
639 Bool_t forceDim = kFALSE;
640 for (Int_t iCol=0; iCol<nCols; iCol++){
641 if (rFormulaList[iCol]!=NULL) rFormulaList[iCol]->UpdateFormulaLeaves();
642 if (rFormulaList[iCol]->GetManager()==NULL)
continue;
644 switch( rFormulaList[iCol]->GetManager()->GetMultiplicity() ) {
661 fprintf(default_fp,
"<table class=\"display\" cellspacing=\"0\" width=\"100%\">\n");
662 fprintf(default_fp,
"\t<thead class=\"header\">\n");
663 fprintf(default_fp,
"\t<tr>\n");
664 for (Int_t iCol=0; iCol<nCols; iCol++){
667 TString sthName=(tHeadName!=NULL) ? tHeadName->GetTitle() : columnNameList[iCol]->GetName();
669 fprintf(default_fp,
"\t\t<th");
670 if (tooltipName!=0) fprintf(default_fp,
" class=\"tooltip\" data-tooltip=\"%s\"", tooltipName->GetTitle());
671 if (descriptionName!=0) fprintf(default_fp,
" title=\"%s\"", descriptionName->GetTitle());
672 fprintf(default_fp,
">%s</th>\n", sthName.Data());
679 fprintf(default_fp,
"\t</tr>\n");
680 fprintf(default_fp,
"\t</thead>\n");
682 fprintf(default_fp,
"\t<tfoot class=\"header\">\n");
683 fprintf(default_fp,
"\t<tr>\n");
684 for (Int_t iCol=0; iCol<nCols; iCol++){
685 fprintf(default_fp,
"\t\t<th>%s</th>\n",columnNameList[iCol]->GetName());
687 fprintf(default_fp,
"\t</tr>\n");
688 fprintf(default_fp,
"\t</tfoot>\n");
689 fprintf(default_fp,
"\t<tbody>\n");
693 for (Int_t iCol=0; iCol<nCols; iCol++){
694 fprintf(default_fp,
"%s%s",columnNameList[iCol]->GetName(), outputFormatList[iCol]->GetName());
696 fprintf(default_fp,
":");
698 fprintf(default_fp,
"\n");
704 for (Int_t ientry=firstentry; ientry<firstentry+nentries; ientry++){
705 Int_t entryNumber = tree->GetEntryNumber(ientry);
706 if (entryNumber < 0)
break;
707 Long64_t localEntry = tree->LoadTree(entryNumber);
709 if (tnumber != tree->GetTreeNumber()) {
710 tnumber = tree->GetTreeNumber();
711 for(Int_t iCol=0;iCol<nCols;iCol++) {
712 rFormulaList[iCol]->UpdateFormulaLeaves();
714 select->UpdateFormulaLeaves();
718 if (select->EvalInstance(0) == 0) {
727 fprintf(default_fp,
"}\n{\"index\":{\"_id\": \"");
730 fprintf(default_fp,
"},\n{\n");
734 fprintf(default_fp,
"{\"index\":{\"_id\": \"");
736 fprintf(default_fp,
"{{\n");
739 for (Int_t icol=0; icol<nCols; icol++){
742 const char*bname=rFormulaList[icol]->GetName();
743 TBranch *br = tree->GetBranch(bname);
744 br->GetEntry(entryNumber);
745 void **ppobject=(
void**)br->GetAddress();
747 obuffer = TBufferJSON::ConvertToJSON(*ppobject, isClass[icol]);
748 if (isElastic) obuffer.ReplaceAll(
"\n",
"");
752 if (rFormulaList[icol]->
GetTree()==NULL)
continue;
753 Int_t nData=rFormulaList[icol]->GetNdata();
754 if (isElastic==kFALSE){
755 fprintf(default_fp,
"\t\"%s\":",rFormulaList[icol]->GetName());
757 if (isIndex[icol]==kFALSE && isParent[icol]==kFALSE){
758 TString fieldName(rFormulaList[icol]->GetName());
759 if (isClass[icol]) fieldName.Remove(fieldName.Length()-1);
760 fieldName.ReplaceAll(
".",
"%_");
761 if (icol>0 && isIndex[icol-1]==kFALSE && isParent[icol-1]==kFALSE ){
762 fprintf(default_fp,
"\t,\"%s\":",fieldName.Data());
764 fprintf(default_fp,
"\t\"%s\":",fieldName.Data());
769 if ((isIndex[icol]==kFALSE)&&(isParent[icol]==kFALSE)){
770 if (isClass[icol]!=NULL){
771 fprintf(default_fp,
"%s",obuffer.Data());
773 if (isElastic && rFormulaList[icol]->IsString()) {
774 fprintf(default_fp,
"\t\"%s\"",
775 rFormulaList[icol]->PrintValue(0, 0, printFormatList[icol]->GetName()));
777 fprintf(default_fp,
"\t%s",
778 rFormulaList[icol]->PrintValue(0, 0, printFormatList[icol]->GetName()));
783 fprintf(default_fp,
"%s",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
784 if (isIndex[icol+1]){
785 fprintf(default_fp,
".");
787 if (isParent[icol+1]==kFALSE){
788 fprintf(default_fp,
"\"}}\n{");
791 if (isParent[icol]==kTRUE){
792 fprintf(default_fp,
"\", \"parent\": \"%s\"}}\n{",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
795 fprintf(default_fp,
"\t[");
796 for (Int_t iData=0; iData<nData;iData++){
797 fprintf(default_fp,
"%f",rFormulaList[icol]->EvalInstance(iData));
799 fprintf(default_fp,
",");
801 fprintf(default_fp,
"]");
812 fprintf(default_fp,
"<tr>\n");
813 for (Int_t icol=0; icol<nCols; icol++){
814 Int_t nData=rFormulaList[icol]->GetNdata();
816 fprintf(default_fp,
"\t<td>%s</td>",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
818 fprintf(default_fp,
"\t<td>");
819 for (Int_t iData=0; iData<nData;iData++){
820 fprintf(default_fp,
"%f",rFormulaList[icol]->EvalInstance(iData));
822 fprintf(default_fp,
",");
824 fprintf(default_fp,
"</td>");
828 fprintf(default_fp,
"\n");
830 fprintf(default_fp,
"</tr>\n");
834 for (Int_t icol=0; icol<nCols; icol++){
835 Int_t nData=rFormulaList[icol]->GetNdata();
837 fprintf(default_fp,
"%s\t",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
839 for (Int_t iData=0; iData<nData;iData++){
840 fprintf(default_fp,
"%f",rFormulaList[icol]->EvalInstance(iData));
842 fprintf(default_fp,
",");
844 fprintf(default_fp,
"\t");
849 fprintf(default_fp,
"\n");
852 if (isJSON) fprintf(default_fp,
"}\n");
854 fprintf(default_fp,
"\t</tbody>");
855 fprintf(default_fp,
"</table>");
858 if (default_fp!=stdout) fclose (default_fp);
868 if(!stat.CompareTo(
"median",TString::kIgnoreCase)){
870 }
else if(!stat.CompareTo(
"medianLeft",TString::kIgnoreCase)){
872 }
else if(!stat.CompareTo(
"medianRight",TString::kIgnoreCase)){
874 }
else if(!stat.CompareTo(
"RMS",TString::kIgnoreCase)){
876 }
else if(!stat.CompareTo(
"Mean",TString::kIgnoreCase)){
878 }
else if(!stat.CompareTo(
"Max",TString::kIgnoreCase)){
880 }
else if(!stat.CompareTo(
"Min",TString::kIgnoreCase)){
882 }
else if(stat.BeginsWith(
"LTMRMS",TString::kIgnoreCase)){
884 }
else if(stat.BeginsWith(
"LTM",TString::kIgnoreCase)){
887 ::Error(
"GetStatType()",
"Cannot decode string \"%s\"." 888 " Use one of \"median\", \"medianLeft\", \"medianRight\", \"RMS\", or \"Mean\". " 889 " Also supported is \"LTM\", or \"LTMRMS\", which should be succeeded by a float like" 890 " \"LTM0.95\" or an integer (interpreted as percentage) like \"LTMRMS95\" to specify " 891 " the fraction of data to be kept." 892 " Use a colon separated list like \"median:medianLeft:medianRight:RMS\"" 893 " as the fifth argument to the AddStatInfo().",stat.Data());
905 const TString statString,
911 Int_t entries = treeRight->Draw(refQuery.Data(),
"",
"goffpara",maxEntries);
913 ::Error(
"AddStatInfo",
"No matching entries for query");
915 }
else if (entries>treeRight->GetEstimate()){
916 treeRight->SetEstimate(entries*2);
917 entries = treeRight->Draw(refQuery.Data(),
"",
"goffpara",maxEntries);
919 Int_t * indexArr =
new Int_t[entries];
920 TMath::Sort(entries, treeRight->GetV1(), indexArr,kFALSE);
921 Double_t * coordArray =
new Double_t[entries];
922 for (Int_t icoord=0; icoord<entries; icoord++) coordArray[icoord]=treeRight->GetV1()[indexArr[icoord]];
929 if(!refQuery.Tokenize(var,from,
":")){
930 ::Error(
"AddStatInfo",
"Cannot tokenize query \'%s\'. Use colon separated list" 932 delete[]indexArr;indexArr=0;
933 delete[]coordArray;coordArray=0;
936 Int_t entriesCoord = treeLeft->GetEntries();
937 TBranch * br = treeLeft->GetBranch(var.Data());
939 br->SetAddress(&coordValue);
942 while(refQuery.Tokenize(var,from,
":")){
946 while(statString.Tokenize(stat,fromStat,
":")){
950 if(statType==
kUndef)
continue;
957 tmp.ReplaceAll(
"LTMRMS",
"");
958 tmp.ReplaceAll(
"LTM",
"");
960 if(frac>1)frac/=100.;
964 Double_t leftOffset=-1e99,rightOffset=-1e99;
967 leftOffset=-deltaT;rightOffset=deltaT;
969 leftOffset=-2.*deltaT;rightOffset=0.;
971 leftOffset=0.;rightOffset=2.*deltaT;
974 TString brName=Form(
"%s_%s",var.Data(),stat.Data());
975 brName.ReplaceAll(
"[",
"_");
976 brName.ReplaceAll(
"]",
"_");
977 brName.ReplaceAll(
".",
"_");
978 Double_t statValue=0;
979 if (treeLeft->GetDirectory()) treeLeft->GetDirectory()->cd();
980 TBranch *brToFill = treeLeft->Branch(brName.Data(),&statValue, (brName+
"/D").Data());
983 for (Int_t icoord=0; icoord<entriesCoord; icoord++){
985 br->GetEntry(icoord);
986 Double_t startCoord=coordValue+leftOffset;
987 Double_t endCoord =coordValue+rightOffset;
993 Int_t index1=TMath::BinarySearch(entries, coordArray, endCoord) +1;
995 if (index1>=0 && index0>=0){
997 if (index1-index0<=0){
1000 if (index0<0) index0=0;
1001 if (index1>=entries) index1=entries-1;
1003 for (Int_t i=0; i<index1-index0; i++){
1004 dvalues[i]=treeRight->GetV2()[indexArr[i+index0]];
1008 statValue=TMath::Median(index1-index0, dvalues.GetMatrixArray());
1009 }
else if(statType==
kRMS){
1010 statValue=TMath::RMS(index1-index0, dvalues.GetMatrixArray());
1011 }
else if(statType==
kMean){
1012 statValue=TMath::Mean(index1-index0, dvalues.GetMatrixArray());
1013 }
else if(statType==
kMin){
1014 statValue=TMath::MinElement(index1-index0, dvalues.GetMatrixArray());
1015 }
else if(statType==
kMax){
1016 statValue=TMath::MaxElement(index1-index0, dvalues.GetMatrixArray());
1017 }
else if(statType==
kLTM){
1024 cout <<
"TStatToolkit::LTMUnbinned. Catch Exception Nr. " << e <<
'\n';
1027 statValue = params[1];
1035 cout <<
"TStatToolkit::LTMUnbinned. Catch Exception Nr. " << e <<
'\n';
1038 statValue = params[2];
1040 ::Error(
"AddStatInfo()",
"String %s StatType %d not implemented",stat.Data(),statType);
1045 brToFill->FlushBaskets();
1049 delete[]indexArr;indexArr=0;
1050 delete[]coordArray;coordArray=0;
1120 const Int_t kMaxDim=10;
1121 Int_t entriesAll=tree->GetEntriesFast();
1122 if (chunkSize<=0) chunkSize=entriesAll;
1123 if (lastEntry>entriesAll) lastEntry=entriesAll;
1125 TObjArray *hisDescriptionList=hisString.Tokenize(
";");
1126 Int_t nHistograms = hisDescriptionList->GetEntries();
1131 TArrayI hisDims(nHistograms);
1133 Int_t nExpressions=hisString.CountChar(
':')+hisString.CountChar(
';')+1;
1135 TString queryString =
"";
1136 Int_t hisSizeFull=0;
1141 for (Int_t iHis=0; iHis<nHistograms; iHis++){
1142 TString hisDescription = hisDescriptionList->At(iHis)->GetName();
1143 Int_t hisIndex=hisDescription.Index(
">>");
1146 ::Error(
"AliTreePlayer::MakeHistograms",
"Invalid expression %s",hisDescription.Data());
1149 hisDescriptionArray->AddAtAndExpand(
new TObjString(((hisDescriptionList->At(iHis)->GetName()))+(hisIndex+2)),iHis);
1151 hisDescription.Remove(hisIndex);
1152 TObjArray *hisDimArray=hisDescription.Tokenize(
":");
1153 Int_t nDims=hisDimArray->GetEntries();
1156 ::Error(
"AliTreePlayer::MakeHistograms",
"Invalid description %s",hisDescription.Data());
1161 if (hisDimArray->At(nDims-1)->GetName()[0]==
'#'){
1162 TString formulaName=&((hisDimArray->At(nDims-1)->GetName())[1]);
1164 TObjString *tFormula =
new TObjString(formulaName.Data());
1165 hisWeightArray->AddAt(tFormula,iHis);
1166 if (formulaArray->FindObject(formulaName.Data())==NULL){
1167 formulaArray->AddLast(tFormula);
1168 varArray->AddAt(tFormula,nDims);
1171 for (Int_t iDim=0; iDim<nDims;iDim++){
1172 TObjString *tFormula = (TObjString*) (formulaArray->FindObject(hisDimArray->At(iDim)->GetName()));
1173 if (tFormula==NULL){
1174 tFormula =
new TObjString(hisDimArray->At(iDim)->GetName());
1175 formulaArray->AddLast(tFormula);
1177 varArray->AddAt(tFormula,iDim);
1179 hisFormulaArray->AddAt(varArray,iHis);
1180 hisDims[iHis]=nDims;
1184 Int_t nFormulas=formulaArray->GetEntries();
1185 for (Int_t iFor=0; iFor<nFormulas; iFor++){
1186 queryString+=formulaArray->At(iFor)->GetName();
1189 queryString+=formulaArray->At(nFormulas-1)->GetName();
1190 if (verbose&0x2) hisDescriptionArray->Print();
1191 if (verbose&0x4) formulaArray->Print();
1196 for (Int_t bEntry=firstEntry; bEntry<lastEntry; bEntry+=chunkSize){
1198 Int_t toQuery=TMath::Min(chunkSize, lastEntry-bEntry);
1199 Int_t qLength = tree->Draw(queryString,defaultCut,
"goffpara",toQuery, bEntry);
1200 if (qLength>tree->GetEstimate()){
1201 tree->SetEstimate(qLength*1.5);
1202 qLength = tree->Draw(queryString,defaultCut,
"goffpara",chunkSize, bEntry);
1206 if (hisArray->GetEntriesFast()==0){
1207 for (Int_t iHis=0; iHis<nHistograms; iHis++){
1208 if (hisDescriptionArray->At(iHis)==NULL){
1209 ::Error(
"AliTreePlayer::MakeHistograms",
"Empty description %d",iHis);
1212 TString hisDescription= hisDescriptionArray->At(iHis)->GetName();
1213 TString varDecription=hisDescriptionList->At(iHis)->GetName();
1214 TObjArray * descriptionArray=hisDescription.Tokenize(
"(,)");
1215 TObjArray * varArray= TString(hisDescriptionList->At(iHis)->GetName()).
Tokenize(
":");
1216 Int_t nLength=descriptionArray->GetEntries();
1217 if ((nLength-1)/3 < hisDims[iHis]){
1218 ::Error(
"AliTreePlayer::MakeHistograms",
"Histogram dimension Mismatch %s", hisDescriptionArray->At(iHis)->GetName());
1221 if (varArray->GetEntries()<hisDims[iHis]){
1222 ::Error(
"AliTreePlayer::MakeHistograms",
"Variable mismatch %s", hisDescriptionArray->At(iHis)->GetName());
1225 TString hName(descriptionArray->At(0)->GetName());
1227 Int_t
nBins[kMaxDim];
1228 Double_t xMin[kMaxDim], xMax[kMaxDim];
1229 for (Int_t iDim=0; iDim<hisDims[iHis]; iDim++){
1230 nBins[iDim]= TString(descriptionArray->At(3*iDim+1)->GetName()).Atoi();
1231 if (descriptionArray->At(3*iDim+2)->GetName()[0]!=
'%'){
1232 xMin[iDim]= TString(descriptionArray->At(3*iDim+2)->GetName()).Atof();
1234 if (descriptionArray->At(3*iDim+2)->GetName()[1]==
'A'){
1235 TTreeFormula falias(
"falias",&(descriptionArray->At(3*iDim+2)->GetName()[2]),tree);
1236 xMin[iDim]=falias.EvalInstance();
1239 if (descriptionArray->At(3*iDim+3)->GetName()[0]!=
'%'){
1240 xMax[iDim]= TString(descriptionArray->At(3*iDim+3)->GetName()).Atof();
1242 if (descriptionArray->At(3*iDim+3)->GetName()[1]==
'A'){
1243 TTreeFormula falias(
"falias",&(descriptionArray->At(3*iDim+3)->GetName()[2]),tree);
1244 xMax[iDim]=falias.EvalInstance();
1247 if (xMax[iDim]<=xMin[iDim]){
1248 ::Error(
"AliTreePlayer::MakeHistograms",
"Invalid hstogram range specification for histogram %s: %s\t%s",hisDescription.Data(), \
1249 descriptionArray->At(3*iDim+2)->GetName(), descriptionArray->At(3*iDim+3)->GetName() );
1252 THnF * phis =
new THnF(hName.Data(),hName.Data(), hisDims[iHis],
nBins, xMin,xMax);
1253 hisArray->AddAt(phis,iHis);
1256 ::Info(
"AliTreePlayer::MakeHistograms",
"%s: size=%lld",hisDescription.Data(), phis->GetNbins());
1258 hisSizeFull+= phis->GetNbins();
1259 for (Int_t iDim=0;iDim<hisDims[iHis]; iDim++){
1260 phis->GetAxis(iDim)->SetName(varArray->At(iDim)->GetName());
1261 phis->GetAxis(iDim)->SetTitle(varArray->At(iDim)->GetName());
1263 if (axisTitle) phis->GetAxis(iDim)->SetTitle(axisTitle->GetTitle());
1267 ::Info(
"AliTreePlayer::MakeHistograms",
"Total size=%d",hisSizeFull);
1271 if (tree->GetVal(0)==NULL){
1272 ::Error(
" AliTreePlayer::MakeHistograms",
"Info not available");
1275 Double_t values[kMaxDim];
1276 for (Int_t iHis=0; iHis<nHistograms; iHis++){
1277 Int_t indeces[kMaxDim+1];
1279 for (Int_t iVec=0; iVec<formulaArrayHis->GetEntriesFast(); iVec++){
1280 indeces[iVec]= formulaArray->IndexOf(formulaArray->FindObject(formulaArrayHis->At(iVec)->GetName()));
1283 if (hisWeightArray->GetEntriesFast()>=iHis){
1284 if (hisWeightArray->UncheckedAt(iHis)!=NULL){
1285 if (hisWeightArray->UncheckedAt(iHis)->GetName()){
1286 indexW= formulaArray->IndexOf(formulaArray->FindObject(hisWeightArray->UncheckedAt(iHis)->GetName()));
1288 ::Error(
"xxx",
"Problem to find %s", hisWeightArray->UncheckedAt(iHis)->GetName());
1292 THnBase * his = (THnBase*) hisArray->UncheckedAt(iHis);
1293 for (Int_t cEvent=0; cEvent<qLength; cEvent++){
1294 for (Int_t iDim=0; iDim<hisDims[iHis]; iDim++){
1295 if (tree->GetVal(indeces[iDim])==NULL){
1296 ::Error(
" AliTreePlayer::MakeHistograms",
"Info %d not avaliable",iDim);
1299 values[iDim]=tree->GetVal(indeces[iDim])[cEvent];
1301 Double_t weight=(indexW<0)? 1: tree->GetVal(indexW)[cEvent];
1302 if (weight>0) his->Fill(values,weight);
1308 delete hisDescriptionArray;
1309 delete formulaArray;
1329 TString projType[8]={
"f-mean",
"f-rms",
"f-ltm",
"f-ltmsigma",
"f-gmean",
"f-grms",
"f-median",
"f-gmean"};
1331 TObjArray *drawList=drawExpression.Tokenize(
":");
1333 TString padDescription=drawList->At(0)->GetName();
1335 static Int_t counter=0;
1336 pad =
new TCanvas(TString::Format(
"canvasCounter%d",counter).Data(), drawExpression,1000,800);
1340 Int_t nPads=0, nRows=0;
1341 TObjArray *padRows=padDescription.Tokenize(
"[](),");
1342 nRows=padRows->GetEntries();
1343 for (Int_t iRow=0; iRow<nRows; iRow++){
1344 Int_t nCols=TString(padRows->At(iRow)->GetName()).Atoi();
1345 for (Int_t iCol=0; iCol<nCols; iCol++){
1347 TPad * newPad=
new TPad(Form(
"pad%d",nPads),Form(
"pad%d",nPads),iCol/Double_t(nCols),(nRows-iRow-1)/Double_t(nRows),(iCol+1)/Double_t(nCols),(nRows-iRow)/Double_t(nRows));
1350 newPad->SetNumber(nPads);
1356 TPRegexp isPadOption(
"^%O");
1357 Bool_t isLogY=kFALSE;
1358 for (Int_t iPad=0; iPad<nPads; iPad++){
1359 Int_t nGraphs=0, nHistos=0;
1360 if (drawList->At(iPad+1)==NULL)
break;
1362 TVirtualPad *cPad = pad->cd(iPad+1);
1363 TLegend * legend =
new TLegend(cPad->GetLeftMargin()+0.02,0.7,1-cPad->GetRightMargin()-0.02 ,1-cPad->GetTopMargin()-0.02, TString::Format(
"Pad%d",iPad));
1364 legend->SetNColumns(2);
1365 legend->SetBorderSize(0);
1366 TString padSetup=drawList->At(iPad+1)->GetName();
1367 TString padOption=
"";
1368 Bool_t isTimeX=kFALSE, isTimeY=kFALSE;
1370 if (padSetup.Contains(isPadOption)){
1371 padOption=TString(&padSetup[2]);
1372 padOption.Remove(padOption.First(
";"));
1373 padOption.ToLower();
1374 if (padOption.Contains(
"logy")) {
1375 pad->cd(iPad+1)->SetLogy();
1378 if (padOption.Contains(
"logx")) {
1379 pad->cd(iPad+1)->SetLogx();
1381 if (padOption.Contains(
"gridy")) pad->cd(iPad+1)->SetGridy();
1382 if (padOption.Contains(
"gridx")) pad->cd(iPad+1)->SetGridx();
1383 if (padOption.Contains(
"timex")) isTimeX=kTRUE;
1384 if (padOption.Contains(
"timey")) isTimeY=kTRUE;
1385 padSetup.Remove(0,padSetup.First(
';')+1);
1388 TObjArray * padDrawList= padSetup.Tokenize(
";");
1389 Double_t hisMin=0, hisMax=-1;
1391 TGraphErrors * grToDraw=0;
1393 for (Int_t ihis=0; ihis<padDrawList->GetEntries(); ihis++){
1394 TObjArray *hisDescription= TString(padDrawList->At(ihis)->GetName()).
Tokenize(
"()");
1395 THn * his = (THn*)hisArray->FindObject(hisDescription->At(0)->GetName());
1396 if (his==NULL)
continue;
1398 ::Info(
"AliTreePlayer::DrawHistograms",
"Pad %d. Processing his %s",iPad, hisDescription->At(0)->GetName());
1400 Int_t ndim=his->GetNdimensions();
1401 TString rangeDescription(hisDescription->At(1)->GetName());
1402 Int_t ndimRange= (rangeDescription.CountChar(
','));
1403 if (ndimRange>0) ndimRange=ndimRange/2+1;
1405 TObjArray *rangeArray=rangeDescription.Tokenize(
",");
1406 for (Int_t iDim=0; iDim<ndimRange; iDim++){
1407 if (rangeArray->At(iDim*2)->GetName()[0]==
'U') {
1408 Double_t min=TString(&(rangeArray->At(iDim*2)->GetName()[1])).Atof();
1409 Double_t max=TString(&(rangeArray->At(iDim*2+1)->GetName()[1])).Atof();
1411 ::Info(
"AliTreePlayer::DrawHistograms",
"Pad %d. %s.GetAxis(%d).SetRangeUser(%f,%f).",iPad,hisDescription->At(0)->GetName(), iDim, min,max);
1413 his->GetAxis(iDim)->SetRangeUser(min,max);
1415 Int_t min=TString((rangeArray->At(iDim*2)->GetName())).Atoi();
1416 Int_t max=TString((rangeArray->At(iDim*2+1)->GetName())).Atoi();
1418 ::Info(
"AliTreePlayer::DrawHistograms",
"Pad %d. %s.GetAxis(%d).SetRange(%d,%d).",iPad,hisDescription->At(0)->GetName(), iDim, min,max);
1420 his->GetAxis(iDim)->SetRange(min,max);
1425 TString drawOption = hisDescription->At(3)->GetName();
1426 drawOption.ToLower();
1427 TString projString=hisDescription->At(2)->GetName();
1428 Int_t nDims = projString.CountChar(
',')+1;
1433 hProj=his->Projection(projString.Atoi());
1438 Int_t dim0 = projString.Atoi();
1439 Int_t dim1 = TString(&(projString[2])).Atoi();
1440 TH2* his2D =his->Projection(dim0,dim1);
1441 for (Int_t iProj=0; iProj<8; iProj++){
1442 if (drawOption.Contains(projType[iProj])){
1447 gr->SetTitle(padDrawList->At(ihis)->GetName());
1448 gr->GetXaxis()->SetTitle(his2D->GetXaxis()->GetTitle());
1449 gr->GetYaxis()->SetTitle(his2D->GetYaxis()->GetTitle());
1450 drawOption.ReplaceAll(projType[iProj].Data(),
"");
1456 Double_t grMinI=TMath::MinElement(gr->GetN(),gr->GetY())-3.*TMath::Median(gr->GetN(),gr->GetEY());
1457 Double_t grMaxI=TMath::MaxElement(gr->GetN(),gr->GetY())+3.*TMath::Median(gr->GetN(),gr->GetEY());
1458 if (hisMax<hisMin) {hisMin=grMinI; hisMax=grMaxI;}
1459 if (hisMax<grMaxI) hisMax=grMaxI;
1460 if (hisMin>grMinI) hisMin=grMinI;
1463 gr->Draw((drawOption+
"a").Data());
1464 legend->AddEntry(gr,
"",
"p");
1467 gr->Draw(drawOption.Data());
1468 legend->AddEntry(gr,
"",
"p");
1470 if (keepArray) keepArray->AddLast(gr);
1473 hProj->SetMarkerColor(ihis+1);
1474 hProj->SetLineColor(ihis+1);
1475 hProj->SetMarkerStyle(21+ihis);
1476 if (keepArray) keepArray->AddLast(hProj);
1478 if (hisMax<hisMin) {
1479 hisMin=hProj->GetMinimum();
1480 hisMax=hProj->GetMaximum();
1482 if (hisMax<hProj->GetMaximum()) hisMax=hProj->GetMaximum();
1483 if (hisMin>hProj->GetMinimum()) hisMin=hProj->GetMinimum();
1486 hProj->Draw((TString(hisDescription->At(3)->GetName())+
"").Data());
1487 legend->AddEntry(hProj);
1490 hProj->Draw((TString(hisDescription->At(3)->GetName())+
"same").Data());
1491 legend->AddEntry(hProj);
1496 if (hisToDraw!=NULL){
1497 hisToDraw->SetMaximum(hisMax+(hisMax-hisMin)/2.);
1498 if (hisMin<=0) hisMin=TMath::Min(0.01, hisMax*0.01);
1499 hisToDraw->SetMinimum(hisMin);
1501 hisToDraw->SetMaximum(hisMax*TMath::Max(10.,(hisMax/hisMin)/4.));
1504 if ((verbose&0x8)>0){
1505 ::Info(
"AliTreePlayer::DrawHistograms:",
"Pad %d. %s SetMinimum(%f). SetMaximum(%f)",iPad,padDrawList->At(0)->GetName(), hisMin,hisMax+(hisMax-hisMin)/2.);
1507 if (isTimeX) hisToDraw->GetXaxis()->SetTimeDisplay(1);
1508 if (isTimeY) hisToDraw->GetYaxis()->SetTimeDisplay(1);
1509 pad->cd(iPad+1)->Modified();
1510 pad->cd(iPad+1)->Update();
1511 legend->Draw(
"same");
1513 if (grToDraw!=NULL){
1514 grToDraw->SetMaximum(hisMax+(hisMax-hisMin)/2.);
1515 grToDraw->SetMinimum(hisMin-(hisMax-hisMin)/3.);
1516 if (isTimeX) grToDraw->GetXaxis()->SetTimeDisplay(1);
1517 if (isTimeY) grToDraw->GetYaxis()->SetTimeDisplay(1);
1519 if ((verbose&0x8)>0){
1520 ::Info(
"AliTreePlayer::DrawHistograms:",
"Pad %d. %s SetMinimum(%f). SetMaximum(%f)",iPad,padDrawList->At(0)->GetName(), hisMax+(hisMax-hisMin)/2.,hisMin-(hisMax-hisMin)/3.);
1523 pad->cd(iPad+1)->Modified();
1524 pad->cd(iPad+1)->Update();
1525 legend->Draw(
"same");
1547 if (tree->GetEstimate()<tree->GetEntries()) tree->SetEstimate(tree->GetEntries());
1548 Int_t entries=tree->Draw(varList.Data(),selection,
"goffpara");
1549 TObjArray * varName=varList.Tokenize(
":");
1550 const Int_t nVars=varName->GetEntries();
1551 Double_t vars[nVars];
1552 TTree *treeOut=NULL;
1553 for (Int_t iPoint=0; iPoint <entries; iPoint++){
1554 for (Int_t iVar=0; iVar<nVars; iVar++){
1555 vars[iVar]=tree->GetVal(iVar)[iPoint];
1556 if (iPoint==0) (*pcstream)<<outTree.Data()<<TString::Format(
"%s=",varName->At(iVar)->GetName()).Data()<<vars[iVar];
1559 (*pcstream)<<outTree.Data()<<
"\n";
1560 treeOut=((*pcstream)<<outTree.Data()).
GetTree();
static TString printSelectedTreeInfo(TTree *tree, TString infoType, TString regExpFriend, TString regExpTag, Int_t verbose)
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
static TPad * DrawHistograms(TPad *pad, TObjArray *hisArray, TString drawExpression, TObjArray *keepArray=0, Int_t verbose=0)
static TObjArray * selectTreeInfo(TTree *tree, TString query, Int_t verbose)
static Int_t GetStatType(const TString &stat)
TTreeSRedirector * pcstream
strP3 Tokenize("+") -> Print()
Set of functions to extend functionality of the TTreePlayer.
static TObjArray * selectMetadata(TTree *tree, TString query, Int_t verbose, TString *idList=NULL)
static TObjArray * MakeHistograms(TTree *tree, TString hisString, TString defaultCut, Int_t firstEntry, Int_t lastEntry, Int_t chunkSize=-1, Int_t verbose=1)
static Long64_t BinarySearchSmaller(Long64_t n, const T *array, T value)
static Int_t selectWhatWhereOrderBy(TTree *tree, TString what, TString where, TString orderBy, Int_t firstentry, Int_t nentries, TString outputFormat, TString outputName)
static void AddStatInfo(TTree *treeLeft, TTree *treeRight, const TString refQuery, Double_t deltaT, const TString statString="median:medianLeft:medianRight:RMS:Mean:LTM0.60:LTMRMS0.60:Max:Min", Int_t maxEntries=100000000)
static void AddStamp(const char *sname, Int_t id0=-1, Int_t id1=-1, Int_t id2=-1, Int_t id3=-1)
class TVectorT< Double_t > TVectorD
TTree * GetTree(Int_t ievent)
static void MakeCacheTree(TTree *tree, TString varList, TString outFile, TString outTree, TCut selection)