AliRoot Core  3dc7879 (3dc7879)
AliTreePlayer.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
16 
17 
18 
19 #include "TStatToolkit.h"
20 #include "Riostream.h"
21 #include <iostream>
22 #include "TSystem.h"
23 #include "TNamed.h"
24 #include "TFile.h"
25 #include "TTree.h"
26 #include "TPRegexp.h"
27 #include "TFriendElement.h"
28 #include "AliExternalInfo.h"
29 #include "TTreeFormula.h"
30 #include "TTreeFormulaManager.h"
31 #include "AliTreePlayer.h"
32 #include "TEntryList.h"
33 #include "THn.h"
34 #include "TLegend.h"
35 #include "TBufferJSON.h"
36 #include <sstream>
37 #include <bitset>
38 #include "TTimeStamp.h"
39 using namespace std;
40 ClassImp(AliTreePlayer)
41 ClassImp(AliTreeFormulaF)
42 
43 
45 AliTreeFormulaF::AliTreeFormulaF() : TTreeFormula(), fTextArray(NULL), fFormatArray(NULL), fFormulaArray(NULL),fValue(""),fDebug(0) {
46 }
47 
52 AliTreeFormulaF::AliTreeFormulaF(const char *name, const char *formula, TTree *tree, Int_t debug):
53  TTreeFormula(), fTextArray(NULL), fFormatArray(NULL), fFormulaArray(NULL), fValue(""), fDebug(debug) {
54  SetName(name);
55  SetTitle(formula);
56  SetTree(tree);
57  Compile(formula);
58  SetBit(kIsCharacter);
59 
60 }
61 
64  delete fTextArray;
65  delete fFormulaArray;
66  delete fFormatArray;
67 }
68 
73 Int_t AliTreeFormulaF::Compile(const char *expression) {
74  TTree *tree = GetTree();
75  TString fquery = expression;
76  //
77  // 1. GetList of %format{variables} to query
78  // format: TStringf
79  // variable: TTreeFormula
80  // 3. GetFormatted string
81  //
82  //Int_t sLength = fquery.Length(); // original format string
83  //Int_t iVar = 0;
84  //Int_t varBegin = -1;
86  fFormatArray = new TObjArray;
87  fTextArray = new TObjArray;
88  Int_t nVars = 0;
89  Int_t lastI = 0;
90  Int_t iChar = 0;
91  for (iChar = 0; iChar < fquery.Length(); iChar++) {
92  if (fquery[iChar] != '{') continue;
93  Int_t delta0 = 1, deltaf = 0;
94  for (delta0 = 1; delta0 + iChar < fquery.Length(); delta0++) if (fquery[iChar + delta0] == '}') break;
95  for (deltaf = -1; deltaf + iChar >= 0; deltaf--) if (fquery[iChar + deltaf] == '%') break;
96  TString stext(fquery(lastI, iChar + deltaf - lastI));
97  TString sformat(fquery(iChar + deltaf + 1, -(deltaf + 1)));
98  TString sformula(fquery(iChar + 1, delta0 - 1));
99  if (fDebug&4) {
100  printf("%d\t%d\t%d\n", iChar, deltaf, delta0);
101  printf("%d\t%s\t%s\t%s\n", nVars, stext.Data(), sformat.Data(), sformula.Data());
102  }
103  fFormatArray->AddAtAndExpand(new TObjString(sformat.Data()), nVars);
104  fTextArray->AddAtAndExpand(new TObjString(stext.Data()), nVars);
105  fFormulaArray->AddAtAndExpand(new TTreeFormula(sformula.Data(), sformula.Data(), tree), nVars);
106  nVars++;
107  lastI = iChar + delta0 + 1;
108  }
109  TString stext(fquery(lastI, fquery.Length() - lastI));
110  fTextArray->AddAtAndExpand(new TObjString(stext.Data()), nVars);
111  return 0;
112 }
113 
117 char *AliTreeFormulaF::PrintValue(Int_t mode) const {
118  PrintValue(mode, 0, "");
119  return NULL;
120 }
121 
131 char *AliTreeFormulaF::PrintValue(Int_t mode, Int_t instance, const char *decform) const {
132  std::stringstream stream;
133  Int_t nVars = fFormulaArray->GetEntries();
134  for (Int_t iVar = 0; iVar <= nVars; iVar++) {
135  stream << fTextArray->At(iVar)->GetName();
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;
138  if (iVar < nVars) {
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");
141  if (isHex) { // TODO check 64bits/32 bits
142  char buffer[64];
143  Int_t value=treeFormula->EvalInstance();
144  //sprintf(format,"%s",fFormatArray->At(iVar)->GetName());
145  sprintf(buffer,"%X",(Int_t)value);
146  stream<<buffer;
147  continue;
148  }
149  if ((fFormatArray->At(iVar)->GetName()[0]=='b')) { //TODO parse number of bits
150  Long64_t value=treeFormula->EvalInstance();
151  bitset<32> b(value);
152  stream<<b.to_string();
153  continue;
154  }
155  if ((fFormatArray->At(iVar)->GetName()[0]=='t')) { //TODO use formats
156  Long64_t value=treeFormula->EvalInstance64();
157  TTimeStamp stamp(value);
158  stream<<stamp.AsString("s");
159  continue;
160  }
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;
164  }
165  }
166  //const_cast<AliTreeFormulaF*>(this)->fValue=TString(stream.str().data()); /// TODO check compliation of mutable in old c++
167  fValue=stream.str().data();
168  return (char *) fValue.Data();
169 }
172  if (fFormulaArray==NULL) return;
173  return;
174  Int_t nVars = fFormulaArray->GetEntries();
175  for (Int_t iVar = 0; iVar <= nVars; iVar++) {
176  TTreeFormula *treeFormula = (TTreeFormula *) fFormulaArray->At(iVar);
177  treeFormula->UpdateFormulaLeaves();
178  }
179 }
180 
184 AliTreePlayer::AliTreePlayer(const char *name, const char *title)
185  :TNamed(name, title)
186 {
187  //
188  //
189 }
190 
191 
192 
199 
210 TObjArray * AliTreePlayer::selectMetadata(TTree * tree, TString query, Int_t verbose, TString *idList){
211  /*
212  query - case sensitive matching is done using Contains method (e.g N(Axis)<=N(xis) )
213  - WILL be case insesitive
214  */
215  //
216  // 1. Parse query and map query to TFormula selection
217  //
218  TObjArray *queryArray=query.Tokenize("[=]");
219  TObjArray *varArray=0;
220  TVectorD vecParam;
221  TFormula *pFormula=0;
222  if (queryArray->GetEntries()>1) {
223  TString stringFormula="";
224  varArray = TString(queryArray->At(1)->GetName()).Tokenize("\"&|!()[]+-/"); //find variable list
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()); // Logic should be improved - to match only "full strings"
230  vecParam[ivar]=1;
231  }
232  pFormula= new TFormula("printMetadataFromula",stringFormula.Data());
233  if (verbose&0x2) pFormula->Print();
234  }
235  //
236  if (queryArray->GetEntriesFast()<=0 ){
237  return 0;
238  }else{
239  if (queryArray->GetEntriesFast()>2) {
240  return 0;
241  }
242  }
243  //
244  // 2.) Find selected data and add the to the list
245  //
246  TObjArray * metaData = (TObjArray*)tree->GetUserInfo()->FindObject("metaTable");
247  Int_t entries = metaData->GetEntries();
248  TObjArray *selected = new TObjArray(entries);
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;
256  }
257  isSelected=pFormula->EvalPar(vecParam.GetMatrixArray());
258  if (verbose&0x2){
259  vecParam.GetMatrixArray();
260  }
261  }
262  if (isSelected){
263  selected->AddLast(metaData->At(ientry));
264  if (idList){
265  TString id=metaData->At(ientry)->GetName();
266  id.Remove(id.Last('.'),id.Length());
267  if (id.Length()>0) {
268  (*idList) += id;
269  (*idList) +=":";
270  }
271  }
272  if (verbose&0x1){
273  printf("%s:%s:%d\n",metaData->At(ientry)->GetName(),metaData->At(ientry)->GetTitle(),isSelected);
274  }
275  }
276  }
277  if (idList!=NULL){
278  delete selected;
279  return NULL;
280  }
281  return selected;
282 }
283 
284 
295 
310 TObjArray * AliTreePlayer::selectTreeInfo(TTree* tree, TString query,Int_t verbose){
311  // 1.) Make a TFormula replacing logical operands with values
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);
316  }
317  queryArray->Compress();
318  formulaEntries=queryArray->GetEntries();
319  if (formulaEntries<=0){
320  ::Error("selectTreeInfo","Empty or wrong selection %s", query.Data());
321  return 0;
322  }
323 
324  TString stringFormula=query;
325  TVectorD formValue(formulaEntries); // boolen or weight value
326  TVectorF formType(formulaEntries); // type of formula - name or metadata
327  TVectorF formExact(formulaEntries); // type of formula - exact or contain
328  TObjArray formMatch(formulaEntries); // string to match
329  TObjArray formMatchType(formulaEntries); // type to match
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()); // Logic should be improved - to match only "full strings"
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());
339  tokenArray->Print();
340  queryArray->Print();
341  delete tokenArray;
342  delete queryArray;
343  return 0;
344  }
345  formMatch[ivar]=tokenArray->At(1);
346  formMatchType[ivar]=tokenArray->At(0);
347  TString queryType(tokenArray->At(0)->GetName());
348  queryType.ToLower();
349  formType[ivar]=1;
350  if (queryType.Contains(".name",TString::kIgnoreCase)){
351  formType[ivar]=0;
352  }
353  if (formName.Contains(":")){
354  formExact[ivar]=0;
355  }else{
356  formExact[ivar]=1;
357  }
358  }
359  //
360  TFormula *pFormula= new TFormula("printMetadataFormula",stringFormula.Data());
361  if (verbose&0x4){
362  ::Info("selectTreeInfo","Formula:");
363  pFormula->Print();
364  ::Info("selectTreeInfo","Query array:");
365  queryArray->Print();
366  ::Info("selectTreeInfo","To match array:");
367  formMatch.Print();
368  ::Info("selectTreeInfo","Exact type:");
369  formExact.Print();
370  }
371  //
372  // 2.) array loop and evaluate filters
373  //
374  TObjArray *selected = new TObjArray(10000); // TODO: we should get upper limit estimate from
375  Int_t nTrees=1;
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++){
382  // TTree::GetListOfAliases() is a TList
383  // TTree::GetListOfBranches is a TObjArray
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++){ // to be rewritten to TSeqColection iterator
390  TString elemName(elemList->At(ientry)->GetName());
391  //
392  for (Int_t icheck=0; icheck<formulaEntries; icheck++){ // check logical expression
393  formValue[icheck]=0;
394  if (formType[icheck]==0){ // check the name
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);
397  }
398  if (formType[icheck]==1){ // check corresponding metadata
399  TObject* metaObject = TStatToolkit::GetMetadata(cTree,TString::Format("%s%s",elemName.Data(), formMatchType.UncheckedAt(icheck)->GetName()).Data());
400  if (metaObject){
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);
404  }
405  }
406  }
407  Bool_t isSelected=pFormula->EvalPar(formValue.GetMatrixArray());
408  if (isSelected){
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());
412  }
413  }
414  }
415  }
416  return selected;
417 }
418 
419 
427 TString AliTreePlayer::printSelectedTreeInfo(TTree *tree, TString infoType, TString regExpFriend, TString regExpTag,
428  Int_t verbose) {
429  /*
430  Example usage:
431  AliExternalInfo info;
432  TTree * treeTPC = info.GetTree("QA.TPC","LHC15o","cpass1_pass1","QA.TRD;QA.TPC;QA.TOC;QA.TOF;Logbook");
433 
434  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch alias","","MIP",1);
435  -- print infoType ="branches or alias" containing regExpTag == MIP in the master tree
436  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch","QA.TRD","Eff",1);
437  -- print infoType ="branches" containing regExpTag == Eff in the QA.TRD tree
438  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch",".*","run",1)
439  -- print infoType ="branches" containing regExpTag == Eff in the all friend trees
440  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch",".*","^run$",1)
441  -- print infoType ="branches" containing regExpTag == run in the all friend trees
442 
443  In case arrays or function should be selected - use aliases:
444  treeTPC->SetAlias("meanMIPvsSectorArray","meanMIPvsSector.fElements")'
445  treeTPC->SetAlias("runTypeName","runType.GetName()")
446  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch alias",".*","meanMIPvsSectorArray",1); ==> meanMIPvsSectorArray
447  AliTreePlayer::printSelectedTreeInfo(treeTPC,"branch alias ",".*","Name$",1) ==> runTypeName
448  */
449  TString result = "";
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;
457  if (itree == 0) {
458  currentTree = tree;
459  if (pregExpFriend.Match(currentTree->GetName()) == 0) continue;
460  } else {
461  if (pregExpFriend.Match(treeFriends->At(itree - 1)->GetName()) == 0) continue;
462  currentTree = ((TFriendElement * )(treeFriends->At(itree - 1)))->GetTree();
463  }
464 
465  if (verbose & 0x1) {
466  ::Info("printSelectedTreeInfo", "tree %s selected", currentTree->GetName());
467  }
468  for (Int_t iDataType = 0; iDataType < 3; iDataType++) {
469  if (infoType.Contains(dataTypes[iDataType], TString::kIgnoreCase) == 0) continue;
470  TList *selList = 0;
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"));
475 
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;
480  if (verbose & 0x1) {
481  ::Info(" printSelectedTreeInfo", "%s.%s", currentTree->GetName(), selList->At(iEntry)->GetName());
482  }
483  if (result.Length() > 0) result += ":";
484  if (itree > 0) {
485  result += treeFriends->At(itree - 1)->GetName();
486  result += ".";
487  }
488  result += selList->At(iEntry)->GetName();
489  }
490  }
491  }
492  return result;
493 }
494 
504 Int_t AliTreePlayer::selectWhatWhereOrderBy(TTree * tree, TString what, TString where, TString /*orderBy*/, Int_t firstentry, Int_t nentries, TString outputFormat, TString outputName){
505  //
506  // Select entry similar to the SQL select
507  // tree instead - SQL FROM statement used
508  // - it is supposed that all information is contained in the tree and related friend trees
509  // - build tree with friends done in separate function
510  // what -
511  // code inspired by the TTreePlay::Scan but another treatment of arrays needed
512  // but wih few changes realted to different output formatting
513  // NOTICE:
514  // for the moment not all parameters used
515  // Example usage:
516  /*
517  AliTreePlayer::selectWhatWhereOrderBy(treeTPC,"run:Logbook.run:meanMIP:meanMIPele:meanMIPvsSector.fElements:fitMIP.fElements","meanMIP>0", "", 0,10,"html","qatpc.html");
518  */
519 
520  if (tree==NULL || tree->GetPlayer()==NULL){
521  ::Error("AliTreePlayer::selectWhatWhereOrderBy","Input tree not defiend");
522  return -1;
523  }
524  // limit number of entries - shorter version of the TTreePlayer::GetEntriesToProcess - but not fully correct ()
525  if (firstentry +nentries >tree->GetEntriesFriend()) nentries=tree->GetEntriesFriend()-firstentry;
526  if (tree->GetEntryList()){ //
527  if (tree->GetEntryList()->GetN()<nentries) nentries=tree->GetEntryList()->GetN();
528  }
529  //
530  Int_t tnumber = -1;
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;
535 
536  //
537  FILE *default_fp = stdout;
538  if (outputName.Length()>0){
539  default_fp=fopen (outputName.Data(),"w");
540  }
541  TObjArray *fArray=what.Tokenize(":");
542  Int_t nCols=fArray->GetEntries();
543  TObjArray *fFormulaList = new TObjArray(nCols+1);
544  TTreeFormula ** rFormulaList = new TTreeFormula*[nCols+1];
545  TObjString **printFormatList = new TObjString*[nCols]; // how to format variables
546  TObjString **columnNameList = new TObjString*[nCols];
547  TObjString **outputFormatList = new TObjString*[nCols]; // root header formatting
548  Bool_t isIndex[nCols];
549  Bool_t isParent[nCols];
550  TClass* isClass[nCols]; // is object
551  TPRegexp indexPattern("^%I"); // pattern for index
552  TPRegexp parentPattern("^%P"); // pattern for parent index
553  for (Int_t iCol=0; iCol<nCols; iCol++){
554  isClass[iCol]=NULL;
555  rFormulaList[iCol]=NULL;
556  TObjArray * arrayDesc = TString(fArray->At(iCol)->GetName()).Tokenize(";");
557  if (arrayDesc->GetEntries()<=0) {
558  ::Error("AliTreePlayer::selectWhatWhereOrderBy","Invalid descriptor %s", arrayDesc->At(iCol)->GetName());
559  //return -1;
560  }
561  TString fieldName=arrayDesc->At(0)->GetName(); // variable content
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());
565  }
566  }
567  if (fieldName.Contains(indexPattern)){ // variable is index
568  isIndex[iCol]=kTRUE;
569  indexPattern.Substitute(fieldName,"");
570  }else{
571  isIndex[iCol]=kFALSE;
572  }
573  if (fieldName.Contains(parentPattern)){ // variable is parent
574  isParent[iCol]=kTRUE;
575  parentPattern.Substitute(fieldName,"");
576  }else{
577  isParent[iCol]=kFALSE;
578  }
579  TTreeFormula * formula = NULL;
580  TNamed* htmlTag=TStatToolkit::GetMetadata(tree,(fieldName+".html").Data());
581  Bool_t isFormulaF= (fieldName[0]=='#') || htmlTag!=NULL;
582 
583  if (!isFormulaF) {
584  formula=new TTreeFormula(fieldName.Data(), fieldName.Data(), tree);
585  }else {
586  TString fstring = fieldName;
587  if (htmlTag) {
588  fstring=htmlTag->GetTitle();
589  } else {
590  fieldName.Replace(0, 1, "");
591  if (tree->GetAlias(fieldName.Data())) {
592  fstring = tree->GetAlias(fieldName.Data());
593  }
594  }
595  formula=new AliTreeFormulaF(fieldName.Data(), fstring.Data(), tree);
596  }
597 
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;
601  }
602  TString printFormat=""; // printing format - column 1 - use default if not specified
603  TString colName=arrayDesc->At(0)->GetName(); // variable name in ouptut - column 2 - using defaut ("variable name") as in input
604  TString outputFormat=""; // output column format specification for TLeaf (see also reading using TTree::ReadFile)
605  if (arrayDesc->At(1)!=NULL){ // format
606  printFormat=arrayDesc->At(1)->GetName();
607  }else{
608  if (formula->IsInteger()) {
609  printFormat="1.20";
610  }else{
611  printFormat="1.20";
612  }
613  }
614  if (arrayDesc->At(2)!=NULL) {
615  colName=arrayDesc->At(2)->GetName();
616  }else{
617  colName=arrayDesc->At(0)->GetName();
618  }
619  //colName = (arrayDesc->GetEntries()>1) ? arrayDesc->At(2)->GetName() : arrayDesc->At(0)->GetName();
620  if (arrayDesc->At(3)!=NULL){ //outputFormat (for csv)
621  outputFormat= arrayDesc->At(3)->GetName();
622  }else{
623  outputFormat="/D";
624  if (formula->IsInteger()) outputFormat="/I";
625  if (formula->IsString()) outputFormat="/C";
626  }
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);
632  }
633  TTreeFormula *select = new TTreeFormula("Selection",where.Data(),tree);
634  fFormulaList->AddLast(select);
635  rFormulaList[nCols]=select;
636 
637 
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; // TODO - check of needed for AliTreeFormulaF
643  // if ->GetManager()->GetMultiplicity()>0 mean there is at minimum one array
644  switch( rFormulaList[iCol]->GetManager()->GetMultiplicity() ) {
645  case 1:
646  case 2:
647  hasArray = kTRUE;
648  forceDim = kTRUE;
649  break;
650  case -1:
651  forceDim = kTRUE;
652  break;
653  case 0:
654  break;
655  }
656  }
657 
658 
659  // print header
660  if (isHTML){
661  fprintf(default_fp,"%s", "<table class=\"display\" cellspacing=\"0\" width=\"100%\">\n"); // add metadata info
662  fprintf(default_fp,"\t<thead class=\"header\">\n"); // add metadata info
663  fprintf(default_fp,"\t<tr>\n"); // add metadata info
664  for (Int_t iCol=0; iCol<nCols; iCol++){
665  TNamed *tHeadName = TStatToolkit::GetMetadata(tree,TString(columnNameList[iCol]->GetName())+".thead");
666  TNamed *tooltipName = TStatToolkit::GetMetadata(tree,TString(columnNameList[iCol]->GetName())+".tooltip");
667  TString sthName=(tHeadName!=NULL) ? tHeadName->GetTitle() : columnNameList[iCol]->GetName();
668  TNamed *descriptionName = TStatToolkit::GetMetadata(tree,TString(columnNameList[iCol]->GetName())+".headerTooltip");
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()); // add metadata info
673 // if (tooltipName==NULL){
674 // fprintf(default_fp, "\t\t<th>%s</th>\n", sthName.Data()); // add metadata info
675 // }else {
676 // fprintf(default_fp, "\t\t<th class=\"tooltip\" data-tooltip=\"%s\">%s</th>\n", tooltipName->GetTitle(), sthName.Data()); // add metadata info
677 // }
678  }
679  fprintf(default_fp,"\t</tr>\n"); // add metadata info
680  fprintf(default_fp,"\t</thead>\n"); // add metadata info
681  //
682  fprintf(default_fp,"\t<tfoot class=\"header\">\n"); // add metadata info
683  fprintf(default_fp,"\t<tr>\n"); // add metadata info
684  for (Int_t iCol=0; iCol<nCols; iCol++){
685  fprintf(default_fp,"\t\t<th>%s</th>\n",columnNameList[iCol]->GetName()); // add metadata info
686  }
687  fprintf(default_fp,"\t</tr>\n"); // add metadata info
688  fprintf(default_fp,"\t</tfoot>\n"); // add metadata info
689  fprintf(default_fp,"\t<tbody>\n"); // add metadata info
690  }
691  if (isCSV && outputFormat.Contains("csvroot")){
692  // add header info
693  for (Int_t iCol=0; iCol<nCols; iCol++){
694  fprintf(default_fp,"%s%s",columnNameList[iCol]->GetName(), outputFormatList[iCol]->GetName());
695  if (iCol<nCols-1) {
696  fprintf(default_fp,":");
697  }else{
698  fprintf(default_fp,"\n"); // add metadata info
699  }
700  }
701  }
702  if (isJSON&&!isElastic){
703  fprintf(default_fp,"{\n\t \"tree\": [\n "); // add metadata info
704  }
705 
706  Int_t selected=0;
707  for (Int_t ientry=firstentry; ientry<firstentry+nentries; ientry++){
708  Int_t entryNumber = tree->GetEntryNumber(ientry);
709  if (entryNumber < 0) break;
710  Long64_t localEntry = tree->LoadTree(entryNumber);
711  //
712  if (tnumber != tree->GetTreeNumber()) {
713  tnumber = tree->GetTreeNumber();
714  for(Int_t iCol=0;iCol<nCols;iCol++) {
715  rFormulaList[iCol]->UpdateFormulaLeaves();
716  }
717  select->UpdateFormulaLeaves();
718  }
719  if (select) {
720  // if (select->EvalInstance(inst) == 0) {
721  if (select->EvalInstance(0) == 0) { // for the moment simplified version of selection - not treating "array" selection
722  continue;
723  }
724  }
725  selected++;
726  // if json out
727  if (isJSON){
728  if (selected>1){
729  if (isElastic) {
730  fprintf(default_fp,"}\n{\"index\":{\"_id\": \"");
731  }
732  else{
733  fprintf(default_fp,"},\n{\n");
734  }
735  }else{
736  if (isElastic){
737  fprintf(default_fp,"{\"index\":{\"_id\": \"");
738  }else{
739  fprintf(default_fp,"{\n");
740  }
741  }
742  for (Int_t icol=0; icol<nCols; icol++){
743  TString obuffer="";
744  if (isClass[icol]){
745  const char*bname=rFormulaList[icol]->GetName();
746  TBranch *br = tree->GetBranch(bname);
747  br->GetEntry(entryNumber); // not sure if the entry is loaded
748  void **ppobject=(void**)br->GetAddress();
749  if (ppobject) {
750  obuffer = TBufferJSON::ConvertToJSON(*ppobject, isClass[icol]);
751  if (isElastic) obuffer.ReplaceAll("\n","");
752  //fprintf(default_fp,"%s",clbuffer.Data());
753  }
754  }
755  if (rFormulaList[icol]->GetTree()==NULL) continue;
756  Int_t nData=rFormulaList[icol]->GetNdata();
757  if (isJSON==kFALSE){
758  fprintf(default_fp,"\t\"%s\":",rFormulaList[icol]->GetName());
759  }else{
760  if (isIndex[icol]==kFALSE && isParent[icol]==kFALSE){
761  TString fieldName(rFormulaList[icol]->GetName());
762  if (isElastic) {
763  if (isClass[icol]) fieldName.Remove(fieldName.Length() - 1);
764  fieldName.ReplaceAll(".", "%_");
765  }
766  if (icol>0 && isIndex[icol-1]==kFALSE && isParent[icol-1]==kFALSE ){
767  fprintf(default_fp,"\t,\"%s\":",fieldName.Data());
768  }else{
769  fprintf(default_fp,"\t\"%s\":",fieldName.Data());
770  }
771  }
772  }
773  if (nData<=1){
774  if ((isIndex[icol]==kFALSE)&&(isParent[icol]==kFALSE)){
775  if (isClass[icol]!=NULL){
776  fprintf(default_fp,"%s",obuffer.Data());
777  }else {
778  if ( (isElastic || isJSON) && rFormulaList[icol]->IsString()) {
779  fprintf(default_fp, "\t\"%s\"",
780  rFormulaList[icol]->PrintValue(0, 0, printFormatList[icol]->GetName()));
781  } else {
782  fprintf(default_fp, "\t%s",
783  rFormulaList[icol]->PrintValue(0, 0, printFormatList[icol]->GetName()));
784  }
785  }
786  }
787  if (isIndex[icol]){
788  fprintf(default_fp,"%s",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
789  if (isIndex[icol+1]){
790  fprintf(default_fp,".");
791  }else
792  if (isParent[icol+1]==kFALSE){
793  fprintf(default_fp,"\"}}\n{");
794  }
795  }
796  if (isParent[icol]==kTRUE){
797  fprintf(default_fp,"\", \"parent\": \"%s\"}}\n{",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
798  }
799  }else{
800  fprintf(default_fp,"\t[");
801  for (Int_t iData=0; iData<nData;iData++){
802  fprintf(default_fp,"%f",rFormulaList[icol]->EvalInstance(iData));
803  if (iData<nData-1) {
804  fprintf(default_fp,",");
805  } else{
806  fprintf(default_fp,"]");
807  }
808  }
809  }
810  // if (icol<nCols-1 && (isIndex[icol]==kFALSE && isParent[icol]==kFALSE) ) fprintf(default_fp,",");
811  //fprintf(default_fp,"\n");
812  }
813  }
814 
815  //
816  if (isHTML){
817  fprintf(default_fp,"<tr>\n");
818  for (Int_t icol=0; icol<nCols; icol++){
819  Int_t nData=rFormulaList[icol]->GetNdata();
820  if (nData<=1){
821  fprintf(default_fp,"\t<td>%s</td>",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
822  }else{
823  fprintf(default_fp,"\t<td>");
824  for (Int_t iData=0; iData<nData;iData++){
825  fprintf(default_fp,"%f",rFormulaList[icol]->EvalInstance(iData));
826  if (iData<nData-1) {
827  fprintf(default_fp,",");
828  }else{
829  fprintf(default_fp,"</td>");
830  }
831  }
832  }
833  fprintf(default_fp,"\n");
834  }
835  fprintf(default_fp,"</tr>\n");
836  }
837  //
838  if (isCSV){
839  for (Int_t icol=0; icol<nCols; icol++){ // formula loop
840  Int_t nData=rFormulaList[icol]->GetNdata();
841  if (nData<=1){
842  fprintf(default_fp,"%s\t",rFormulaList[icol]->PrintValue(0,0,printFormatList[icol]->GetName()));
843  }else{
844  for (Int_t iData=0; iData<nData;iData++){ // array loo
845  fprintf(default_fp,"%f",rFormulaList[icol]->EvalInstance(iData));
846  if (iData<nData-1) {
847  fprintf(default_fp,",");
848  }else{
849  fprintf(default_fp,"\t");
850  }
851  }
852  }
853  }
854  fprintf(default_fp,"\n");
855  }
856  }
857  if (isJSON) fprintf(default_fp,"}\t]\n}\n");
858  if (isHTML){
859  fprintf(default_fp,"\t</tbody>"); // add metadata info
860  fprintf(default_fp,"</table>"); // add metadata info
861  }
862 
863  if (default_fp!=stdout) fclose (default_fp);
864  return selected;
865 }
866 
867 
871 Int_t AliTreePlayer::GetStatType(const TString &stat){
872 
873  if(!stat.CompareTo("median",TString::kIgnoreCase)){
874  return kMedian;
875  } else if(!stat.CompareTo("medianLeft",TString::kIgnoreCase)){
876  return kMedianLeft;
877  } else if(!stat.CompareTo("medianRight",TString::kIgnoreCase)){
878  return kMedianRight;
879  } else if(!stat.CompareTo("RMS",TString::kIgnoreCase)){
880  return kRMS;
881  } else if(!stat.CompareTo("Mean",TString::kIgnoreCase)){
882  return kMean;
883  }else if(!stat.CompareTo("Max",TString::kIgnoreCase)){
884  return kMax;
885  }else if(!stat.CompareTo("Min",TString::kIgnoreCase)){
886  return kMin;
887  } else if(stat.BeginsWith("LTMRMS",TString::kIgnoreCase)){ // Least trimmed RMS, argument is LTMRMS0.95 or similar
888  return kLTMRMS;
889  } else if(stat.BeginsWith("LTM",TString::kIgnoreCase)){ // Least trimmed mean, argument is LTM0.95 or similar
890  return kLTM;
891  } else {
892  ::Error("GetStatType()","Cannot decode string \"%s\"."
893  " Use one of \"median\", \"medianLeft\", \"medianRight\", \"RMS\", or \"Mean\". "
894  " Also supported is \"LTM\", or \"LTMRMS\", which should be succeeded by a float like"
895  " \"LTM0.95\" or an integer (interpreted as percentage) like \"LTMRMS95\" to specify "
896  " the fraction of data to be kept."
897  " Use a colon separated list like \"median:medianLeft:medianRight:RMS\""
898  " as the fifth argument to the AddStatInfo().",stat.Data());
899  return kUndef;
900  }
901 }
909 void AliTreePlayer::AddStatInfo(TTree* treeLeft, TTree * treeRight , const TString refQuery, Double_t deltaT,
910  const TString statString,
911  Int_t maxEntries){
912 
913  //
914  // 1.) Get variables from the right tree, sort them according to the coordinate
915  //
916  Int_t entries = treeRight->Draw(refQuery.Data(),"","goffpara",maxEntries);
917  if(entries<1){
918  ::Error("AddStatInfo","No matching entries for query");
919  return;
920  }else if (entries>treeRight->GetEstimate()){
921  treeRight->SetEstimate(entries*2);
922  entries = treeRight->Draw(refQuery.Data(),"","goffpara",maxEntries);
923  }
924  Int_t * indexArr = new Int_t[entries];
925  TMath::Sort(entries, treeRight->GetV1(), indexArr,kFALSE);
926  Double_t * coordArray = new Double_t[entries];
927  for (Int_t icoord=0; icoord<entries; icoord++) coordArray[icoord]=treeRight->GetV1()[indexArr[icoord]];
928  //
929  // 2.) Attach the median,.. of the variables to the left tree
930  //
931  // The first token is the coordinate
932  TString var;
933  Ssiz_t from=0;
934  if(!refQuery.Tokenize(var,from,":")){
935  ::Error("AddStatInfo","Cannot tokenize query \'%s\'. Use colon separated list"
936  ,refQuery.Data());
937  delete[]indexArr;indexArr=0;
938  delete[]coordArray;coordArray=0;
939  return;
940  }
941  Int_t entriesCoord = treeLeft->GetEntries();
942  TBranch * br = treeLeft->GetBranch(var.Data());
943  Int_t coordValue;
944  br->SetAddress(&coordValue);
945  //TLeaf *coordLeaf = (TLeaf*)(br->GetListOfLeaves()->At(0));
946 
947  while(refQuery.Tokenize(var,from,":")){
948  // var="valueAnodeRaw.fElements[0]";
949  TString stat;
950  Ssiz_t fromStat=0;
951  while(statString.Tokenize(stat,fromStat,":")){
952  // stat = "median"; stat="medianLeft"; stat="medianRight";
953  // Int_t statType=TStatToolkit::GetStatType(stat);
954  Int_t statType=GetStatType(stat);
955  if(statType==kUndef)continue;
956  //printf("\n\n\n--- StatType %d ---\n\n\n\n",statType);
957 
958  // In case of LMS or LMR determine the fraction
959  Float_t frac=0.;
960  if(statType==kLTM || statType==kLTMRMS){ // stat="LTM0.95" or "LTMRMS0.95" similar
961  TString tmp= stat;
962  tmp.ReplaceAll("LTMRMS","");
963  tmp.ReplaceAll("LTM","");
964  frac = tmp.Atof(); // atof returns 0.0 on error
965  if(frac>1)frac/=100.; // allows "LTM95" for 95%
966  }
967 
968  // Determine the offset in coordinate to the left and right
969  Double_t leftOffset=-1e99,rightOffset=-1e99;
970  if(statType==kMedian||statType==kRMS || statType==kMean
971  || statType==kLTM || statType==kLTMRMS || statType==kMin || statType==kMax ){ // symmetric
972  leftOffset=-deltaT;rightOffset=deltaT;
973  } else if(statType==kMedianLeft){ //left
974  leftOffset=-2.*deltaT;rightOffset=0.;
975  } else if(statType==kMedianRight){ //right
976  leftOffset=0.;rightOffset=2.*deltaT;
977  }
978 
979  TString brName=Form("%s_%s",var.Data(),stat.Data());
980  brName.ReplaceAll("[","_");
981  brName.ReplaceAll("]","_");
982  brName.ReplaceAll(".","_");
983  Double_t statValue=0;
984  if (treeLeft->GetDirectory()) treeLeft->GetDirectory()->cd();
985  TBranch *brToFill = treeLeft->Branch(brName.Data(),&statValue, (brName+"/D").Data());
986  TVectorD dvalues(entries);
987 
988  for (Int_t icoord=0; icoord<entriesCoord; icoord++){
989  // Int_t icoord=0
990  br->GetEntry(icoord);
991  Double_t startCoord=coordValue+leftOffset;
992  Double_t endCoord =coordValue+rightOffset;
993  //Double_t startCoord=coordLeaf->GetValue()+leftOffset;
994  //Double_t endCoord =coordLeaf->GetValue()+rightOffset;
995 
996  // Binary search finds last element smaller or equal
997  Int_t index0=BinarySearchSmaller(entries, coordArray, startCoord)+1;
998  Int_t index1=TMath::BinarySearch(entries, coordArray, endCoord) +1;
999  statValue=0;
1000  if (index1>=0 && index0>=0){
1001  //if (values.capacity()<index1-index0) values.reserve(1.5*(index1-index0)); //resize of needed
1002  if (index1-index0<=0){
1003  index0--;
1004  index1++;
1005  if (index0<0) index0=0;
1006  if (index1>=entries) index1=entries-1;
1007  }
1008  for (Int_t i=0; i<index1-index0; i++){
1009  dvalues[i]=treeRight->GetV2()[indexArr[i+index0]];
1010  }
1011  // Calculate
1012  if(statType==kMedian||statType==kMedianLeft||statType==kMedianRight){
1013  statValue=TMath::Median(index1-index0, dvalues.GetMatrixArray());
1014  } else if(statType==kRMS){
1015  statValue=TMath::RMS(index1-index0, dvalues.GetMatrixArray());
1016  } else if(statType==kMean){
1017  statValue=TMath::Mean(index1-index0, dvalues.GetMatrixArray());
1018  }else if(statType==kMin){
1019  statValue=TMath::MinElement(index1-index0, dvalues.GetMatrixArray());
1020  }else if(statType==kMax){
1021  statValue=TMath::MaxElement(index1-index0, dvalues.GetMatrixArray());
1022  } else if(statType==kLTM){
1023  TVectorD params(7);
1024  try {
1025  TStatToolkit::LTMUnbinned(index1 - index0, dvalues.GetMatrixArray(), params, frac);
1026  }
1027  catch (int e)
1028  {
1029  cout << "TStatToolkit::LTMUnbinned. Catch Exception Nr. " << e << '\n';
1030  continue;
1031  }
1032  statValue = params[1];
1033  } else if(statType==kLTMRMS){
1034  TVectorD params(7);
1035  try {
1036  TStatToolkit::LTMUnbinned(index1 - index0, dvalues.GetMatrixArray(), params, frac);
1037  }
1038  catch (int e)
1039  {
1040  cout << "TStatToolkit::LTMUnbinned. Catch Exception Nr. " << e << '\n';
1041  continue;
1042  }
1043  statValue = params[2];
1044  } else{
1045  ::Error("AddStatInfo()","String %s StatType %d not implemented",stat.Data(),statType);
1046  }
1047  }
1048  brToFill->Fill();
1049  } // Loop over coordinates
1050  brToFill->FlushBaskets();
1051  } // Loop over stat types
1052  } // Loop over variables
1053  treeLeft->Write();
1054  delete[]indexArr;indexArr=0;
1055  delete[]coordArray;coordArray=0;
1056 
1057 }
1058 
1059 
1082 
1092 
1118 TObjArray * AliTreePlayer::MakeHistograms(TTree * tree, TString hisString, TString defaultCut, Int_t firstEntry, Int_t lastEntry, Int_t chunkSize, Int_t verbose){
1119  // Algorithm:
1120  // 1.) Analyze formula, create minimal formula expression
1121  // 2.) Event loop
1122  // 3.) Filling of histograms
1123  //
1124 
1125  const Int_t kMaxDim=10;
1126  Int_t entriesAll=tree->GetEntries();
1127  if (chunkSize<=0) chunkSize=entriesAll;
1128  if (lastEntry>entriesAll) lastEntry=entriesAll;
1129  if (verbose&0x7){
1130  ::Info("AliTreePlayer::MakeHistograms","firstEntry %d", firstEntry);
1131  ::Info("AliTreePlayer::MakeHistograms","lastEntry %d", lastEntry);
1132  ::Info("AliTreePlayer::MakeHistograms","entriesAll %d", entriesAll);
1133  }
1134  //
1135  TObjArray *hisDescriptionList=hisString.Tokenize(";");
1136  Int_t nHistograms = hisDescriptionList->GetEntries();
1137  TObjArray * hisArray = new TObjArray(nHistograms);
1138  TObjArray * hisDescriptionArray=new TObjArray(nHistograms); // OWNER
1139  TObjArray * hisFormulaArray=new TObjArray(nHistograms); // array of TFomula arrays - Not OWNER
1140  TObjArray * hisWeightArray=new TObjArray(nHistograms); // array of TFomula arrays - Not OWNER
1141  TArrayI hisDims(nHistograms);
1142  //
1143  Int_t nExpressions=hisString.CountChar(':')+hisString.CountChar(';')+1;
1144  TObjArray * formulaArray = new TObjArray(nExpressions); // array of all expressions - OWNER
1145  TString queryString = "";
1146  Int_t hisSizeFull=0;
1147  //
1148  // 1.) Analyze formula, book list of TObjString
1149  //
1150  Bool_t isOK=kTRUE;
1151  for (Int_t iHis=0; iHis<nHistograms; iHis++){
1152  TString hisDescription = hisDescriptionList->At(iHis)->GetName();
1153  Int_t hisIndex=hisDescription.Index(">>");
1154  if (hisIndex<=0) {
1155  isOK=kFALSE;
1156  ::Error("AliTreePlayer::MakeHistograms","Invalid expression %s",hisDescription.Data());
1157  break;
1158  }else{
1159  hisDescriptionArray->AddAtAndExpand(new TObjString(((hisDescriptionList->At(iHis)->GetName()))+(hisIndex+2)),iHis);
1160  }
1161  hisDescription.Remove(hisIndex);
1162  TObjArray *hisDimArray=hisDescription.Tokenize(":");
1163  Int_t nDims=hisDimArray->GetEntries();
1164  if (nDims<=0){
1165  isOK=kFALSE;
1166  ::Error("AliTreePlayer::MakeHistograms","Invalid description %s",hisDescription.Data());
1167  delete hisDimArray;
1168  break;
1169  }
1170  TObjArray * varArray = new TObjArray(nDims);
1171  if (hisDimArray->At(nDims-1)->GetName()[0]=='#'){
1172  TString formulaName=&((hisDimArray->At(nDims-1)->GetName())[1]);
1173  nDims-=1;
1174  TObjString *tFormula = new TObjString(formulaName.Data());
1175  hisWeightArray->AddAt(tFormula,iHis);
1176  if (formulaArray->FindObject(formulaName.Data())==NULL){
1177  formulaArray->AddLast(tFormula);
1178  varArray->AddAt(tFormula,nDims);
1179  }
1180  }
1181  for (Int_t iDim=0; iDim<nDims;iDim++){
1182  TObjString *tFormula = (TObjString*) (formulaArray->FindObject(hisDimArray->At(iDim)->GetName()));
1183  if (tFormula==NULL){
1184  tFormula = new TObjString(hisDimArray->At(iDim)->GetName());
1185  formulaArray->AddLast(tFormula);
1186  }
1187  varArray->AddAt(tFormula,iDim);
1188  }
1189  hisFormulaArray->AddAt(varArray,iHis);
1190  hisDims[iHis]=nDims;
1191  delete hisDimArray;
1192  }
1193  queryString="";
1194  Int_t nFormulas=formulaArray->GetEntries();
1195  for (Int_t iFor=0; iFor<nFormulas; iFor++){
1196  queryString+=formulaArray->At(iFor)->GetName();
1197  queryString+=":";
1198  }
1199  queryString+=formulaArray->At(nFormulas-1)->GetName();
1200  if (verbose&0x2) hisDescriptionArray->Print();
1201  if (verbose&0x4) formulaArray->Print();
1202  //
1203  // 2.) Event loop
1204  //
1205  Int_t tNumber=-1;
1206  for (Int_t bEntry=firstEntry; bEntry<lastEntry; bEntry+=chunkSize){ // chunks loop
1207  Int_t toQuery=TMath::Min(chunkSize, lastEntry-bEntry);
1208  Int_t qLength = tree->Draw(queryString,defaultCut,"goffpara",toQuery, bEntry); // query varaibles
1209  if (qLength>tree->GetEstimate()){
1210  tree->SetEstimate(qLength*1.5);
1211  qLength = tree->Draw(queryString,defaultCut,"goffpara",chunkSize, bEntry);
1212  }
1213 
1214  // 2.2 fill histograms if not yet done
1215  if (hisArray->GetEntriesFast()==0){ // book histograms if not yet done
1216  for (Int_t iHis=0; iHis<nHistograms; iHis++){
1217  if (hisDescriptionArray->At(iHis)==NULL){
1218  ::Error("AliTreePlayer::MakeHistograms", "Empty description %d",iHis);
1219  continue;
1220  }
1221  TString hisDescription= hisDescriptionArray->At(iHis)->GetName();
1222  TString varDecription=hisDescriptionList->At(iHis)->GetName();
1223  TObjArray * descriptionArray=hisDescription.Tokenize("(,)");
1224  TObjArray * varArray= TString(hisDescriptionList->At(iHis)->GetName()).Tokenize(":");
1225  Int_t nLength=descriptionArray->GetEntries();
1226  if ((nLength-1)/3 < hisDims[iHis]){
1227  ::Error("AliTreePlayer::MakeHistograms", "Histogram dimension Mismatch %s", hisDescriptionArray->At(iHis)->GetName());
1228  return NULL;
1229  }
1230  if (varArray->GetEntries()<hisDims[iHis]){
1231  ::Error("AliTreePlayer::MakeHistograms", "Variable mismatch %s", hisDescriptionArray->At(iHis)->GetName());
1232  return NULL;
1233  }
1234  TString hName(descriptionArray->At(0)->GetName());
1235  THnBase * his = 0;
1236  Int_t nBins[kMaxDim];
1237  Double_t xMin[kMaxDim], xMax[kMaxDim];
1238  for (Int_t iDim=0; iDim<hisDims[iHis]; iDim++){
1239  nBins[iDim]= TString(descriptionArray->At(3*iDim+1)->GetName()).Atoi();
1240  if (descriptionArray->At(3*iDim+2)->GetName()[0]!='%'){
1241  xMin[iDim]= TString(descriptionArray->At(3*iDim+2)->GetName()).Atof();
1242  }else{
1243  if (descriptionArray->At(3*iDim+2)->GetName()[1]=='A'){ // %A - alias describing range
1244  TTreeFormula falias("falias",&(descriptionArray->At(3*iDim+2)->GetName()[2]),tree);
1245  xMin[iDim]=falias.EvalInstance();
1246  }
1247  }
1248  if (descriptionArray->At(3*iDim+3)->GetName()[0]!='%'){
1249  xMax[iDim]= TString(descriptionArray->At(3*iDim+3)->GetName()).Atof();
1250  }else{
1251  if (descriptionArray->At(3*iDim+3)->GetName()[1]=='A'){ // %A - alias describing range
1252  TTreeFormula falias("falias",&(descriptionArray->At(3*iDim+3)->GetName()[2]),tree);
1253  xMax[iDim]=falias.EvalInstance();
1254  }
1255  }
1256  if (xMax[iDim]<=xMin[iDim]){
1257  ::Error("AliTreePlayer::MakeHistograms","Invalid hstogram range specification for histogram %s: %s\t%s",hisDescription.Data(), \
1258  descriptionArray->At(3*iDim+2)->GetName(), descriptionArray->At(3*iDim+3)->GetName() );
1259  }
1260  }
1261  THnF * phis = new THnF(hName.Data(),hName.Data(), hisDims[iHis],nBins, xMin,xMax);
1262  hisArray->AddAt(phis,iHis);
1263  if (verbose&0x1) {
1264  ::Info("AliTreePlayer::MakeHistograms","%s: size=%lld",hisDescription.Data(), phis->GetNbins());
1265  }
1266  hisSizeFull+= phis->GetNbins();
1267  for (Int_t iDim=0;iDim<hisDims[iHis]; iDim++){
1268  phis->GetAxis(iDim)->SetName(varArray->At(iDim)->GetName());
1269  phis->GetAxis(iDim)->SetTitle(varArray->At(iDim)->GetName());
1270  TNamed *axisTitle=TStatToolkit::GetMetadata(tree,TString::Format("%s.AxisTitle",varArray->At(iDim)->GetName()).Data());
1271  if (axisTitle) phis->GetAxis(iDim)->SetTitle(axisTitle->GetTitle());
1272  }
1273  }
1274  if (verbose&0x1) {
1275  ::Info("AliTreePlayer::MakeHistograms","Total size=%d",hisSizeFull);
1276  }
1277  }
1278  // 2.3 fill histograms
1279  if (tree->GetVal(0)==NULL){
1280  ::Error(" AliTreePlayer::MakeHistograms","Info not available"); // TODO - fix the logic
1281  continue;
1282  }
1283  Double_t values[kMaxDim];
1284  for (Int_t iHis=0; iHis<nHistograms; iHis++){
1285  Int_t indeces[kMaxDim+1];
1286  TObjArray *formulaArrayHis = (TObjArray*) (hisFormulaArray->At(iHis));
1287  for (Int_t iVec=0; iVec<formulaArrayHis->GetEntriesFast(); iVec++){
1288  indeces[iVec]= formulaArray->IndexOf(formulaArray->FindObject(formulaArrayHis->At(iVec)->GetName()));
1289  }
1290  Int_t indexW=-1;
1291  if (hisWeightArray->GetEntriesFast()>=iHis){
1292  if (hisWeightArray->UncheckedAt(iHis)!=NULL){
1293  if (hisWeightArray->UncheckedAt(iHis)->GetName()){
1294  indexW= formulaArray->IndexOf(formulaArray->FindObject(hisWeightArray->UncheckedAt(iHis)->GetName()));
1295  }else{
1296  ::Error("xxx","Problem to find %s", hisWeightArray->UncheckedAt(iHis)->GetName());
1297  }
1298  }
1299  }
1300  THnBase * his = (THnBase*) hisArray->UncheckedAt(iHis);
1301  for (Int_t cEvent=0; cEvent<qLength; cEvent++){
1302  for (Int_t iDim=0; iDim<hisDims[iHis]; iDim++){
1303  if (tree->GetVal(indeces[iDim])==NULL){
1304  ::Error(" AliTreePlayer::MakeHistograms","Info %d not avaliable",iDim); // TODO - fix the logic
1305  continue;
1306  }
1307  values[iDim]=tree->GetVal(indeces[iDim])[cEvent];
1308  }
1309  Double_t weight=(indexW<0)? 1: tree->GetVal(indexW)[cEvent];
1310  if (weight>0) his->Fill(values,weight);
1311  }
1312  }
1313  }
1314  //
1315  delete hisDescriptionArray;
1316  delete formulaArray;
1317  return hisArray;
1318 
1319 }
1320 
1321 
1322 
1323 
1324 TPad * AliTreePlayer::DrawHistograms(TPad * pad, TObjArray * hisArray, TString drawExpression, TObjArray *keepArray, Int_t verbose){
1325  //
1326  //
1327  // Example usage:
1328  /*
1329  TPad *pad= 0; TString drawExpression="";
1330  drawExpression="[1,1,1]:"
1331  drawExpression+="hisPtAll(0,10)(0)(errpl);hisPtITS(0,10)(0)(err);hisPtPhiThetaAll(0,10,-3.2,3.2,-1.2,1.2)(0)(err):";
1332  drawExpression+="hisAlpha(-3.2,3.2)(0)(errpl);hisPtPhiThetaAll(0,10,-3.2,3.2,-1.2,1.2)(1)(err):";
1333  drawExpression+="hisTgl(-1,1)(0)(errpl);hisPtPhiThetaAll(0,10,-3.2,3.2,-1.2,1.2)(2)(err):";
1334  pad = AliTreePlayer::DrawHistograms(0,hisArray,drawExpression);
1335  */
1336  TString projType[8]={"f-mean","f-rms","f-ltm","f-ltmsigma","f-gmean","f-grms","f-median","f-gmean"};
1337 
1338  TObjArray *drawList=drawExpression.Tokenize(":");
1339  // structure pad
1340  TString padDescription=drawList->At(0)->GetName();
1341  if (pad==NULL){
1342  static Int_t counter=0;
1343  pad = new TCanvas(TString::Format("canvasCounter%d",counter).Data(), drawExpression,1000,800);
1344  counter++;
1345  }
1346  // divide pads
1347  Int_t nPads=0, nRows=0;
1348  TObjArray *padRows=padDescription.Tokenize("[](),");
1349  nRows=padRows->GetEntries();
1350  for (Int_t iRow=0; iRow<nRows; iRow++){
1351  Int_t nCols=TString(padRows->At(iRow)->GetName()).Atoi();
1352  for (Int_t iCol=0; iCol<nCols; iCol++){
1353  pad->cd();
1354  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));
1355  newPad->Draw();
1356  nPads++;
1357  newPad->SetNumber(nPads);
1358  }
1359  }
1360  delete padRows;
1361  //
1362  //
1363  TPRegexp isPadOption("^%O");
1364  Bool_t isLogY=kFALSE;
1365  for (Int_t iPad=0; iPad<nPads; iPad++){
1366  Int_t nGraphs=0, nHistos=0;
1367  if (drawList->At(iPad+1)==NULL) break;
1368  //TVirtualPad *cPad =
1369  TVirtualPad *cPad = pad->cd(iPad+1);
1370  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));
1371  legend->SetNColumns(2);
1372  legend->SetBorderSize(0);
1373  TString padSetup=drawList->At(iPad+1)->GetName();
1374  TString padOption="";
1375  Bool_t isTimeX=kFALSE, isTimeY=kFALSE;
1376 
1377  if (padSetup.Contains(isPadOption)){
1378  padOption=TString(&padSetup[2]);
1379  padOption.Remove(padOption.First(";"));
1380  padOption.ToLower();
1381  if (padOption.Contains("logy")) {
1382  pad->cd(iPad+1)->SetLogy();
1383  isLogY=kTRUE;
1384  }
1385  if (padOption.Contains("logx")) {
1386  pad->cd(iPad+1)->SetLogx();
1387  }
1388  if (padOption.Contains("gridy")) pad->cd(iPad+1)->SetGridy();
1389  if (padOption.Contains("gridx")) pad->cd(iPad+1)->SetGridx();
1390  if (padOption.Contains("timex")) isTimeX=kTRUE;
1391  if (padOption.Contains("timey")) isTimeY=kTRUE;
1392  padSetup.Remove(0,padSetup.First(';')+1);
1393  }
1394 
1395  TObjArray * padDrawList= padSetup.Tokenize(";");
1396  Double_t hisMin=0, hisMax=-1;
1397  TH1 * hisToDraw=0;
1398  TGraphErrors * grToDraw=0;
1399  //
1400  for (Int_t ihis=0; ihis<padDrawList->GetEntries(); ihis++){
1401  TObjArray *hisDescription= TString(padDrawList->At(ihis)->GetName()).Tokenize("()");
1402  THn * his = (THn*)hisArray->FindObject(hisDescription->At(0)->GetName());
1403  if (his==NULL) continue;
1404  if (verbose&0x4){
1405  ::Info("AliTreePlayer::DrawHistograms","Pad %d. Processing his %s",iPad, hisDescription->At(0)->GetName());
1406  }
1407  Int_t ndim=his->GetNdimensions();
1408  TString rangeDescription(hisDescription->At(1)->GetName());
1409  Int_t ndimRange= (rangeDescription.CountChar(','));
1410  if (ndimRange>0) ndimRange=ndimRange/2+1;
1411  if (ndimRange>0){
1412  TObjArray *rangeArray=rangeDescription.Tokenize(",");
1413  for (Int_t iDim=0; iDim<ndimRange; iDim++){
1414  if (rangeArray->At(iDim*2)->GetName()[0]=='U') {
1415  Double_t min=TString(&(rangeArray->At(iDim*2)->GetName()[1])).Atof();
1416  Double_t max=TString(&(rangeArray->At(iDim*2+1)->GetName()[1])).Atof();
1417  if (verbose&0x8){
1418  ::Info("AliTreePlayer::DrawHistograms","Pad %d. %s.GetAxis(%d).SetRangeUser(%f,%f).",iPad,hisDescription->At(0)->GetName(), iDim, min,max);
1419  }
1420  his->GetAxis(iDim)->SetRangeUser(min,max);
1421  }else{
1422  Int_t min=TString((rangeArray->At(iDim*2)->GetName())).Atoi();
1423  Int_t max=TString((rangeArray->At(iDim*2+1)->GetName())).Atoi();
1424  if (verbose&0x8){
1425  ::Info("AliTreePlayer::DrawHistograms","Pad %d. %s.GetAxis(%d).SetRange(%d,%d).",iPad,hisDescription->At(0)->GetName(), iDim, min,max);
1426  }
1427  his->GetAxis(iDim)->SetRange(min,max);
1428  }
1429  }
1430  delete rangeArray;
1431  }
1432  TString drawOption = hisDescription->At(3)->GetName();
1433  drawOption.ToLower();
1434  TString projString=hisDescription->At(2)->GetName();
1435  Int_t nDims = projString.CountChar(',')+1;
1436  TH1 * hProj =0;
1437  TGraphErrors*gr=0;
1438  //
1439  if (nDims==1) {
1440  hProj=his->Projection(projString.Atoi());
1441  //hProj->SetName(Form("Pad%d_His%d",iPad,nHistos)); //
1442  nHistos++;
1443  }
1444  if (nDims==2) {
1445  Int_t dim0 = projString.Atoi();
1446  Int_t dim1 = TString(&(projString[2])).Atoi();
1447  TH2* his2D =his->Projection(dim0,dim1);
1448  for (Int_t iProj=0; iProj<8; iProj++){
1449  if (drawOption.Contains(projType[iProj])){
1450  gr=TStatToolkit::MakeStat1D(his2D,0,1.0,iProj,21+ihis,ihis+1);
1451  //gr->SetName(Form("gr_Pad%d_Graph%d",iPad,nGraphs)); //
1452  nGraphs++;
1453  // gr->SetTitle(Form("gr_Pad%d_Graph%d",iPad,nGraphs)); //
1454  gr->SetTitle(padDrawList->At(ihis)->GetName());
1455  gr->GetXaxis()->SetTitle(his2D->GetXaxis()->GetTitle());
1456  gr->GetYaxis()->SetTitle(his2D->GetYaxis()->GetTitle());
1457  drawOption.ReplaceAll(projType[iProj].Data(),"");
1458  }
1459  }
1460  delete his2D;
1461  }
1462  if (gr){
1463  Double_t grMinI=TMath::MinElement(gr->GetN(),gr->GetY())-3.*TMath::Median(gr->GetN(),gr->GetEY());
1464  Double_t grMaxI=TMath::MaxElement(gr->GetN(),gr->GetY())+3.*TMath::Median(gr->GetN(),gr->GetEY());
1465  if (hisMax<hisMin) {hisMin=grMinI; hisMax=grMaxI;}
1466  if (hisMax<grMaxI) hisMax=grMaxI;
1467  if (hisMin>grMinI) hisMin=grMinI;
1468  if (ihis==0) {
1469  grToDraw = gr;
1470  gr->Draw((drawOption+"a").Data());
1471  legend->AddEntry(gr,"","p");
1472  }
1473  else{
1474  gr->Draw(drawOption.Data());
1475  legend->AddEntry(gr,"", "p");
1476  }
1477  if (keepArray) keepArray->AddLast(gr);
1478  }
1479  if (hProj){
1480  hProj->SetMarkerColor(ihis+1);
1481  hProj->SetLineColor(ihis+1);
1482  hProj->SetMarkerStyle(21+ihis);
1483  if (keepArray) keepArray->AddLast(hProj);
1484  //
1485  if (hisMax<hisMin) {
1486  hisMin=hProj->GetMinimum();
1487  hisMax=hProj->GetMaximum();
1488  }
1489  if (hisMax<hProj->GetMaximum()) hisMax=hProj->GetMaximum();
1490  if (hisMin>hProj->GetMinimum()) hisMin=hProj->GetMinimum();
1491  if (ihis==0) {
1492  hisToDraw = hProj;
1493  hProj->Draw((TString(hisDescription->At(3)->GetName())+"").Data());
1494  legend->AddEntry(hProj);
1495  }
1496  else{
1497  hProj->Draw((TString(hisDescription->At(3)->GetName())+"same").Data());
1498  legend->AddEntry(hProj);
1499  }
1500  }
1501  }
1502  pad->cd(iPad+1);
1503  if (hisToDraw!=NULL){
1504  hisToDraw->SetMaximum(hisMax+(hisMax-hisMin)/2.);
1505  if (hisMin<=0) hisMin=TMath::Min(0.01, hisMax*0.01);
1506  hisToDraw->SetMinimum(hisMin);
1507  if (isLogY){
1508  hisToDraw->SetMaximum(hisMax*TMath::Max(10.,(hisMax/hisMin)/4.));
1509  }
1510 
1511  if ((verbose&0x8)>0){
1512  ::Info("AliTreePlayer::DrawHistograms:","Pad %d. %s SetMinimum(%f). SetMaximum(%f)",iPad,padDrawList->At(0)->GetName(), hisMin,hisMax+(hisMax-hisMin)/2.);
1513  }
1514  if (isTimeX) hisToDraw->GetXaxis()->SetTimeDisplay(1);
1515  if (isTimeY) hisToDraw->GetYaxis()->SetTimeDisplay(1);
1516  pad->cd(iPad+1)->Modified();
1517  pad->cd(iPad+1)->Update();
1518  legend->Draw("same");
1519  }
1520  if (grToDraw!=NULL){
1521  grToDraw->SetMaximum(hisMax+(hisMax-hisMin)/2.);
1522  grToDraw->SetMinimum(hisMin-(hisMax-hisMin)/3.);
1523  if (isTimeX) grToDraw->GetXaxis()->SetTimeDisplay(1);
1524  if (isTimeY) grToDraw->GetYaxis()->SetTimeDisplay(1);
1525 
1526  if ((verbose&0x8)>0){
1527  ::Info("AliTreePlayer::DrawHistograms:","Pad %d. %s SetMinimum(%f). SetMaximum(%f)",iPad,padDrawList->At(0)->GetName(), hisMax+(hisMax-hisMin)/2.,hisMin-(hisMax-hisMin)/3.);
1528  }
1529 
1530  pad->cd(iPad+1)->Modified();
1531  pad->cd(iPad+1)->Update();
1532  legend->Draw("same");
1533  }
1534  pad->cd(iPad+1);
1535  }
1536  return pad;
1537 
1538 }
1539 
1540 
1551 void AliTreePlayer::MakeCacheTree(TTree * tree, TString varList, TString outFile, TString outTree, TCut selection, Int_t nEntries, Int_t firstEntry){
1552  TTreeSRedirector *pcstream = new TTreeSRedirector(outFile,"recreate");
1553  if (tree->GetEstimate()<tree->GetEntries()) tree->SetEstimate(tree->GetEntries());
1554  Int_t entries=0;
1555  if (firstEntry>=0 && nEntries>0) {
1556  entries = tree->Draw(varList.Data(),selection,"goffpara",nEntries,firstEntry);
1557  }else{
1558  entries = tree->Draw(varList.Data(),selection,"goffpara");
1559  }
1560  TObjArray * varName=varList.Tokenize(":");
1561  const Int_t nVars=varName->GetEntries();
1562  Double_t vars[nVars];
1563  TTree *treeOut=NULL;
1564  for (Int_t iPoint=0; iPoint <entries; iPoint++){
1565  for (Int_t iVar=0; iVar<nVars; iVar++){
1566  vars[iVar]=tree->GetVal(iVar)[iPoint];
1567  if (iPoint==0) (*pcstream)<<outTree.Data()<<TString::Format("%s=",varName->At(iVar)->GetName()).Data()<<vars[iVar];
1568  }
1569  if (iPoint==0) {
1570  (*pcstream)<<outTree.Data()<<"\n";
1571  treeOut=((*pcstream)<<outTree.Data()).GetTree();
1572  }else{
1573  treeOut->Fill();
1574  }
1575  }
1576  delete pcstream;
1577 }
1578 
1587 TTree* AliTreePlayer::LoadTrees(const char *inputDataList, const char *chRegExp, const char *chNotReg, TString inputFileSelection, TString axisAlias, TString axisTitle) {
1588  //
1589  TPRegexp regExp(chRegExp);
1590  TPRegexp notReg(chNotReg);
1591  TObjArray *regExpArray = inputFileSelection.Tokenize(":");
1592  TObjArray *residualMapList = gSystem->GetFromPipe(inputDataList).Tokenize("\n");
1593  Int_t nFiles = residualMapList->GetEntries();
1594  TTree *treeBase = 0;
1595  TObjArray *arrayAxisAlias = axisAlias.Tokenize(":");
1596  TObjArray *arrayAxisTitle = axisTitle.Tokenize(":");
1597  std::map<string,string> tagValue;
1599  Int_t nSelected=0;
1600  for (Int_t iFile = 0; iFile < nFiles; iFile++) {
1601  tagValue.clear();
1603  for (Int_t jFile=iFile;jFile<nFiles; jFile++){
1604  TString name = residualMapList->At(jFile)->GetName();
1605  if (name[0]=='#') {
1606  Int_t first=name.First(":");
1607  TString tag=name(1,name.First(":")-1);
1608  TString value=name(name.First(":")+1,name.Length());
1609  tagValue[tag.Data()]=value.Data();
1610  }else{
1611  iFile=jFile;
1612  break;
1613  }
1614  }
1615  TString fileName = residualMapList->At(iFile)->GetName();
1616  Bool_t isSelected = kTRUE;
1617  // check if the file was selected
1618  if (regExpArray->GetEntries() > 0) {
1619  isSelected = kFALSE;
1620  for (Int_t entry = 0; entry < regExpArray->GetEntries(); entry++) {
1621  TPRegexp reg(regExpArray->At(entry)->GetName());
1622  if (reg.Match(fileName)) isSelected |= kTRUE;
1623  }
1624  }
1625  if (!isSelected) continue;
1626  ::Info("LoadTrees","Load file\t%s", fileName.Data());
1627  TString description = "";
1628  TFile *finput = TFile::Open(fileName.Data());
1629  if (finput == NULL) {
1630  ::Error("MakeResidualDistortionReport", "Invalid file name %s", fileName.Data());
1631  continue;
1632  }
1633  TList *keys = finput->GetListOfKeys();
1634  Int_t isLegend = kFALSE;
1636  for (Int_t iKey = 0; iKey < keys->GetEntries(); iKey++) {
1637  if (regExp.Match(keys->At(iKey)->GetName()) == 0) continue; // is selected
1638  if (notReg.Match(keys->At(iKey)->GetName()) != 0) continue; // is rejected
1639  TTree *tree = (TTree *) finput->Get(keys->At(iKey)->GetName()); // better to use dynamic cast
1640  if (treeBase == NULL) {
1641  TFile *finput2 = TFile::Open(fileName.Data());
1642  treeBase = (TTree *) finput2->Get(keys->At(iKey)->GetName());
1643  }
1644  TString fileTitle=tagValue["Title"];
1645  if (fileTitle.Length()){
1646  treeBase->AddFriend(tree, TString::Format("%s.%s", fileTitle.Data(), keys->At(iKey)->GetName()).Data());
1647  }else{
1648  treeBase->AddFriend(tree, TString::Format("%s", keys->At(iKey)->GetName()).Data());
1649  }
1650  Int_t entriesF = tree->GetEntries();
1651  Int_t entriesB = treeBase->GetEntries();
1652  if (entriesB == entriesF) {
1653  ::Info("InitMapTree", "%s\t%s.%s:\t%d\t%d", treeBase->GetName(), fileName.Data(), keys->At(iKey)->GetName(), entriesB, entriesF);
1654  } else {
1655  ::Error("InitMapTree", "%s\t%s.%s:\t%d\t%d", treeBase->GetName(), fileName.Data(), keys->At(iKey)->GetName(), entriesB, entriesF);
1656  }
1657  }
1659  }
1660  if (treeBase) {
1661  for (Int_t iAxis = 0; iAxis < arrayAxisAlias->GetEntries(); iAxis++) {
1662  treeBase->SetAlias(arrayAxisAlias->At(iAxis)->GetName(), TString::Format("%s%dCenter", arrayAxisAlias->At(iAxis)->GetName(), iAxis + 1).Data());
1663  TStatToolkit::AddMetadata(treeBase, TString::Format("%s.AxisTitle", arrayAxisAlias->At(iAxis)->GetName()).Data(), arrayAxisTitle->At(iAxis)->GetName());
1664  }
1665  }
1666  return treeBase;
1667 }
1668 
Int_t fDebug
current cache value of the formula
Definition: AliTreePlayer.h:89
static TString printSelectedTreeInfo(TTree *tree, TString infoType, TString regExpFriend, TString regExpTag, Int_t verbose)
TBrowser b
Definition: RunAnaESD.C:12
TNamed * GetMetadata(TTree *tree, const char *vartagName, TString *prefix=0, Bool_t fullMatch=kFALSE)
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
TFile * Open(const char *filename, Long64_t &nevents)
static TPad * DrawHistograms(TPad *pad, TObjArray *hisArray, TString drawExpression, TObjArray *keepArray=0, Int_t verbose=0)
TObjArray * fFormulaArray
array of format strings to draw
Definition: AliTreePlayer.h:87
#define TObjArray
static TObjArray * selectTreeInfo(TTree *tree, TString query, Int_t verbose)
static TTree * LoadTrees(const char *inputDataList, const char *chRegExp, const char *chNotReg, TString inputFileSelection, TString axisAlias, TString axisTitle)
LoadTrees and and append friend trees.
THashList * AddMetadata(TTree *, const char *vartagName, const char *varTagValue)
static Int_t GetStatType(const TString &stat)
TObjArray * fFormatArray
array of text inputs
Definition: AliTreePlayer.h:86
TTreeSRedirector * pcstream
strP3 Tokenize("+") -> Print()
TObjArray * hisArray
virtual char * PrintValue(Int_t mode=0) const
virtual Int_t Compile(const char *expression="")
Helper class for AliTreePlayer - formatted string to query tree Example usageExample: Construct direc...
Definition: AliTreePlayer.h:74
TString fileName(const char *dir, int runNumber, const char *da, int i, const char *type)
TStatToolkit stat
Definition: AnalyzeLaser.C:5
Set of functions to extend functionality of the TTreePlayer.
Definition: AliTreePlayer.h:94
TTree * tree
static TObjArray * selectMetadata(TTree *tree, TString query, Int_t verbose, TString *idList=NULL)
TGraph * gr
Definition: CalibTime.C:25
static TObjArray * MakeHistograms(TTree *tree, TString hisString, TString defaultCut, Int_t firstEntry, Int_t lastEntry, Int_t chunkSize=-1, Int_t verbose=1)
TGraphErrors * MakeStat1D(TH2 *his, Int_t deltaBin, Double_t fraction, Int_t returnType, Int_t markerStyle, Int_t markerColor)
AliTreeFormulaF()
Default constructor.
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)
TObjArray * fTextArray
Definition: AliTreePlayer.h:85
Int_t nBins
TString fValue
array of TFormulas
Definition: AliTreePlayer.h:88
virtual void UpdateFormulaLeaves()
static void MakeCacheTree(TTree *tree, TString varList, TString outFile, TString outTree, TCut selection, Int_t nEntries=-1, Int_t firstEntry=0)
Fill tree with information specified in varList of TTreeFormulas Used to cache CPU consuming formulas...
Int_t * LTMUnbinned(int np, const T *arr, TVectorT< T > &params, Float_t keep=1.0)
Definition: TStatToolkit.h:629
TTree * GetTree(Int_t ievent)
Int_t debug