TTreeTableInterface.cxx

Go to the documentation of this file.
00001 // Author: Roel Aaij 15/08/2007
00002 
00003 /*************************************************************************
00004  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00005  * All rights reserved.                                                  *
00006  *                                                                       *
00007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00009  *************************************************************************/
00010 
00011 #include "TClass.h"
00012 #include "Riostream.h"
00013 #include "TSystem.h"
00014 #include "TEnv.h"
00015 #include "TGResourcePool.h"
00016 #include "TTreeTableInterface.h"
00017 #include "TTreeFormula.h"
00018 #include "TError.h"
00019 #include "TTree.h"
00020 #include "TEntryList.h"
00021 #include "TSelectorDraw.h"
00022 #include "TTreeFormulaManager.h"
00023 #include "TTreeFormula.h"
00024 
00025 ClassImp(TTreeTableInterface)
00026 
00027 //////////////////////////////////////////////////////////////////////////
00028 //                                                                      //
00029 // TTreeTableInterface.                                                 //
00030 //                                                                      //
00031 // TTreeTableInterface is used to interface to data that is stored in a //
00032 // TTree. When the interface is created, an expression can be           //
00033 // specified. This expression will define the columns to be shown.      //
00034 //                                                                      //
00035 // A selection criterium can also be specified. A TEntryList will be    //
00036 // created and applied to the TTree using this criterium.               //
00037 // a new TEntryList to use can be specified using SetEntryList.         //
00038 // TGTable->Update() will need to be called to show the effects.        //
00039 //                                                                      //
00040 // WARNING: Do not apply an entrylist to the tree in any other way than //
00041 // through the interface, this will have undefined consequences.        //
00042 //                                                                      //
00043 // Columns can be manipulated using the appropriate methods. A          //
00044 // TGTable->Update is always needed afterwards to make the table aware  //
00045 // of the changes.                                                      //
00046 //                                                                      //
00047 //////////////////////////////////////////////////////////////////////////
00048 
00049 //______________________________________________________________________________
00050 TTreeTableInterface::TTreeTableInterface (TTree *tree, const char *varexp,
00051    const char *selection, Option_t *option, Long64_t nentries,
00052    Long64_t firstentry)
00053    : TVirtualTableInterface(), fTree(tree), fFormulas(0), fEntry(0),
00054      fNEntries(nentries), fFirstEntry(firstentry), fManager(0), fSelect(0), fSelector(0), fInput(0),
00055      fForceDim(kFALSE), fEntries(0), fNRows(0), fNColumns(0)
00056 {
00057    // TTreeTableInterface constructor.
00058 
00059    if (fTree == 0) {
00060       Error("TTreeTableInterface", "No tree supplied");
00061       return;
00062    }
00063 
00064    fFormulas= new TList();
00065    fSelector = new TSelectorDraw();
00066    fInput = new TList();
00067    fInput->Add(new TNamed("varexp",""));
00068    fInput->Add(new TNamed("selection",""));
00069    fSelector->SetInputList(fInput);
00070    fEntry=fFirstEntry;
00071 
00072    TString opt = option;
00073 
00074    if (nentries == 0) {
00075       fNEntries = fTree->GetEntries();
00076       Info("TTreeTableInterface", "nentries was 0, setting to maximum number"
00077            " available in the tree");
00078    }
00079 
00080    // Do stuff with opt.Contains() and options
00081    SetVariablesExpression(varexp);
00082    SetSelection(selection);
00083 
00084    if (fNRows == 0) {
00085       Warning ("TTreeTableInterface::TTreeTableInterface", "nrows = 0");
00086    }
00087    if (fNColumns == 0) {
00088       Warning ("TTreeTableInterface::TTreeTableInterface", "ncolumns = 0");
00089    }
00090 }
00091 
00092 //______________________________________________________________________________
00093 TTreeTableInterface::~TTreeTableInterface()
00094 {
00095    // TTreeTableInterface destructor.
00096 
00097    fFormulas->Delete();
00098    delete fFormulas;
00099    delete fInput;
00100    delete fSelector;
00101 
00102    if (fTree) fTree->SetEntryList(0);
00103    delete fEntries;
00104 }
00105 
00106 //______________________________________________________________________________
00107 void TTreeTableInterface::SetVariablesExpression(const char *varexp)
00108 {
00109    // Compile the variables expression from the given varexp.
00110 
00111    // FIXME check if enough protection against wrong expressions is in place
00112 
00113    Bool_t allvar = kFALSE;
00114 
00115    if (varexp) {
00116       if (!strcmp(varexp, "*")) { allvar = kTRUE; }
00117    } else {
00118       // if varexp is empty, take all available leaves as a column
00119       allvar = kTRUE;
00120    }
00121 
00122    if (allvar) {
00123       TObjArray *leaves = fTree->GetListOfLeaves();
00124       UInt_t nleaves = leaves->GetEntries();
00125       if (!nleaves) {
00126          Error("TTreeTableInterface", "No leaves in Tree");
00127          return;
00128       }
00129       fNColumns = nleaves;
00130       for (UInt_t ui = 0; ui < fNColumns; ui++) {
00131          TLeaf *lf = (TLeaf*)leaves->At(ui);
00132          fFormulas->Add(new TTreeFormula("Var1", lf->GetName(), fTree));
00133       }
00134       // otherwise select only the specified columns
00135    } else {
00136       std::vector<TString> cnames;
00137       fNColumns = fSelector->SplitNames(varexp,cnames);
00138 
00139       // Create the TreeFormula objects corresponding to each column
00140       for (UInt_t ui = 0; ui < fNColumns; ui++) {
00141          fFormulas->Add(new TTreeFormula("Var1", cnames[ui].Data(), fTree));
00142       }
00143    }
00144 }
00145 
00146 //______________________________________________________________________________
00147 void TTreeTableInterface::SetSelection(const char *selection)
00148 {
00149    // Set the selection expression.
00150 
00151    // FIXME verify functionality
00152    if (fSelect) {
00153       fFormulas->Remove(fSelect);
00154       delete fSelect;
00155       fSelect = 0;
00156    }
00157    if (selection && strlen(selection)) {
00158       fSelect = new TTreeFormula("Selection", selection, fTree);
00159       fFormulas->Add(fSelect);
00160    }
00161 
00162    if (fManager) {
00163       for (Int_t i = 0; i <= fFormulas->LastIndex(); i++) {
00164          fManager->Remove((TTreeFormula*)fFormulas->At(i));
00165       }
00166    }
00167 
00168    // SyncFormulas() will update the formula manager if needed
00169    SyncFormulas();
00170    InitEntries();
00171 }
00172 
00173 //______________________________________________________________________________
00174 void TTreeTableInterface::SyncFormulas()
00175 {
00176    // Sync the formulas using the TTreeFormulaManager.
00177 
00178    // FIXME verify functionality
00179 
00180    Int_t i = 0;
00181    if (fFormulas->LastIndex() >= 0) {
00182       if (fSelect) {
00183          if (fSelect->GetManager()->GetMultiplicity() > 0 ) {
00184             if (!fManager) fManager = new TTreeFormulaManager;
00185             for (i = 0; i <= fFormulas->LastIndex(); i++) {
00186                fManager->Add((TTreeFormula*)fFormulas->At(i));
00187             }
00188             fManager->Sync();
00189          }
00190       }
00191       for (i = 0; i < fFormulas->LastIndex(); i++) {
00192          TTreeFormula *form = ((TTreeFormula*)fFormulas->At(i));
00193          switch (form->GetManager()->GetMultiplicity()) {
00194             case  1:
00195             case  2:
00196             case -1:
00197                fForceDim = kTRUE;
00198                break;
00199             case  0:
00200                break;
00201          }
00202       }
00203    }
00204 }
00205 
00206 //______________________________________________________________________________
00207 void TTreeTableInterface::InitEntries()
00208 {
00209    // Initialise the TEntryList with the entries that match the
00210    // selection criterium.
00211 
00212    TEntryList *entrylist = new TEntryList(fTree);
00213 
00214    UInt_t ui = 0;
00215    Int_t i = 0;
00216 
00217    Long64_t notSkipped = 0;
00218    Int_t tnumber = -1;
00219    Long64_t entry = fFirstEntry;
00220    Int_t entriesToDisplay = fNEntries;
00221 
00222    while (entriesToDisplay != 0){
00223 //       entryNumber = fTree->GetEntryNumber(entry);
00224 //       if(entryNumber < 0) break;
00225       Long64_t localEntry = fTree->LoadTree(entry);
00226       if (localEntry < 0) break;
00227       if (tnumber != fTree->GetTreeNumber()) {
00228          tnumber = fTree->GetTreeNumber();
00229          if (fManager) fManager->UpdateFormulaLeaves();
00230          else {
00231             for(i = 0; i < fFormulas->LastIndex(); i++)
00232                ((TTreeFormula*)fFormulas->At(ui))->UpdateFormulaLeaves();
00233          }
00234       }
00235       Int_t ndata = 1;
00236       if (fForceDim){
00237          if (fManager)
00238             ndata = fManager->GetNdata(kTRUE);
00239          else {
00240             for (ui = 0; ui < fNColumns; ui++){
00241                if (ndata < ((TTreeFormula*)fFormulas->At(ui))->GetNdata())
00242                    ndata = ((TTreeFormula*)fFormulas->At(ui))->GetNdata();
00243             }
00244             if (fSelect && fSelect->GetNdata() == 0)
00245                ndata = 0;
00246          }
00247       }
00248       Bool_t skip = kFALSE;
00249 
00250       // Loop over the instances of the selection condition
00251       for (Int_t inst = 0; inst < ndata; inst++){
00252          if (fSelect){
00253             if (fSelect->EvalInstance(inst) == 0){
00254                skip = kTRUE;
00255                entry++;
00256             }
00257          }
00258       }
00259       if (!skip){
00260          entrylist->Enter(entry);
00261          notSkipped++;
00262          entriesToDisplay--;
00263          entry++;
00264       }
00265    }
00266    SetEntryList(entrylist);
00267 }
00268 
00269 //______________________________________________________________________________
00270 Double_t TTreeTableInterface::GetValue(UInt_t row, UInt_t column)
00271 {
00272    // Return the value of row,column. If the position does not exist
00273    // or does not contain a number, 0 is returned.
00274 
00275    static UInt_t prow = 0;
00276 
00277    if (row < fNRows) {
00278       Long64_t entry = 0;
00279       if (row == prow + 1) {
00280          entry = fEntries->Next();
00281       } else {
00282          entry = fEntries->GetEntry(row);
00283       }
00284       prow = row;
00285       fTree->LoadTree(entry);
00286    } else {
00287       Error("TTreeTableInterface", "Row requested does not exist");
00288       return 0;
00289    }
00290    if (column < fNColumns) {
00291       TTreeFormula *formula = (TTreeFormula *)fFormulas->At(column);
00292       if (!formula->IsString()) {
00293          return (Double_t)formula->EvalInstance();
00294       } else {
00295          Warning("TTreeTableInterface::GetValue", "Value requested is a "
00296                  "string, returning 0.");
00297          return 0;
00298       }
00299    } else {
00300       Error("TTreeTableInterface", "Column requested does not exist");
00301       return 0;
00302    }
00303 }
00304 
00305 //______________________________________________________________________________
00306 const char *TTreeTableInterface::GetValueAsString(UInt_t row, UInt_t column)
00307 {
00308    // Return the content of row,column as string to use in a
00309    // TGTableCell label.
00310 
00311    static UInt_t prow = 0;
00312 
00313    if (row < fNRows) {
00314       Long64_t entry = 0;
00315       if (row == prow + 1) {
00316          entry = fEntries->Next();
00317       } else {
00318          entry = fEntries->GetEntry(row);
00319       }
00320       prow = row;
00321       fTree->LoadTree(entry);
00322    } else {
00323       Error("TTreeTableInterface", "Row requested does not exist");
00324       return 0;
00325    }
00326    if (column < fNColumns) {
00327       TTreeFormula *formula = (TTreeFormula *)fFormulas->At(column);
00328       if(formula->IsString()) {
00329          return Form("%s", formula->EvalStringInstance());
00330       } else {
00331          return Form("%5.2f", (Double_t)formula->EvalInstance());
00332       }
00333    } else {
00334       Error("TTreeTableInterface", "Column requested does not exist");
00335       return 0;
00336    }
00337 }
00338 
00339 //______________________________________________________________________________
00340 const char *TTreeTableInterface::GetRowHeader(UInt_t row)
00341 {
00342    // Return a string to use as a label for rowheader at column.
00343 
00344    if (row < fNRows) {
00345       return Form("%lld", fEntries->GetEntry(row));
00346    } else {
00347       Error("TTreeTableInterface", "Row requested does not exist");
00348       return "";
00349    }
00350 }
00351 
00352 //______________________________________________________________________________
00353 const char *TTreeTableInterface::GetColumnHeader(UInt_t column)
00354 {
00355    // Return a string to use as a label for columnheader at column.
00356 
00357    TTreeFormula *formula = (TTreeFormula *)fFormulas->At(column);
00358    if (column < fNColumns) {
00359       return formula->GetTitle();
00360    } else {
00361       Error("TTreeTableInterface", "Column requested does not exist");
00362       return "";
00363    }
00364 }
00365 
00366 //______________________________________________________________________________
00367 UInt_t TTreeTableInterface::GetNColumns()
00368 {
00369    // Return the amount of column available.
00370 
00371    return fNColumns;
00372 }
00373 
00374 //______________________________________________________________________________
00375 UInt_t TTreeTableInterface::GetNRows()
00376 {
00377    // Return the amount of rows in the Tree.
00378 
00379    return fNRows;
00380 }
00381 
00382 //______________________________________________________________________________
00383 void TTreeTableInterface::AddColumn(const char *expression, UInt_t position)
00384 {
00385    // Add column according ot expression at position,
00386    // TGTable->Update() is needed afterwards to apply the change to
00387    // the TGTable.
00388 
00389    TString onerow = expression;
00390 
00391    if (onerow.Contains(':')) {
00392       Error("TTreeTableInterface::AddColumn", "Only 1 expression allowed.");
00393       return;
00394    }
00395 
00396    // Create the TreeFormula objects corresponding to the new expression
00397    TTreeFormula *formula = new TTreeFormula("Var1", expression, fTree);
00398    fFormulas->AddAt(formula, position);
00399 
00400    if (fManager) {
00401       fManager->Add(formula);
00402       fManager->Sync();
00403    }
00404    fNColumns++;
00405 }
00406 
00407 //______________________________________________________________________________
00408 void TTreeTableInterface::AddColumn(TTreeFormula *formula, UInt_t position)
00409 {
00410    // Add column with formula at position, TGTable->Update() is needed
00411    // afterwards to apply the change to the TGTable.
00412 
00413    if (position > fNColumns) {
00414       Error("TTreeTableInterface::AddColumn", "Please specify a "
00415             "valid position.");
00416       return;
00417    }
00418    fFormulas->AddAt(formula, position);
00419    if (fManager) {
00420       fManager->Add(formula);
00421       fManager->Sync();
00422    }
00423    fNColumns++;
00424 }
00425 
00426 //______________________________________________________________________________
00427 void TTreeTableInterface::RemoveColumn(UInt_t position)
00428 {
00429    // Remove column at position, TGTable->Update() is needed
00430    // afterwards to apply the change to the TGTable.
00431 
00432    if (position >= fNColumns) {
00433       Error("TTreeTableInterface::RemoveColumn", "Please specify a "
00434             "valid column.");
00435       return;
00436    } else if (fNColumns == 1) {
00437       Error("TTreeTableInterface::RemoveColumn", "Can't remove last column");
00438       return;
00439    }
00440 
00441    TTreeFormula *formula = (TTreeFormula *)fFormulas->RemoveAt(position);
00442    if (fManager) {
00443       fManager->Remove(formula);
00444       fManager->Sync();
00445    }
00446 
00447    if (formula) delete formula;
00448    fNColumns--;
00449 }
00450 
00451 //______________________________________________________________________________
00452 void TTreeTableInterface::SetFormula(TTreeFormula *formula, UInt_t position)
00453 {
00454    // Set the TTreeFormula of position to formula.
00455 
00456    if (position >= fNColumns) {
00457       Error("TTreeTableInterface::SetFormula", "Please specify a "
00458             "valid position.");
00459       return;
00460    }
00461    TTreeFormula *form = (TTreeFormula *)fFormulas->RemoveAt(position);
00462    if (fSelect) {
00463       fManager->Remove(form);
00464    }
00465    if (form) delete form;
00466    fFormulas->AddAt(formula, position);
00467    if (fManager) {
00468       fManager->Add(formula);
00469       fManager->Sync();
00470    }
00471 
00472 }
00473 
00474 //______________________________________________________________________________
00475 void TTreeTableInterface::SetEntryList(TEntryList *entrylist)
00476 {
00477    // Set the currently active entrylist.
00478 
00479    // Untested
00480    if (fEntries) delete fEntries;
00481    fEntries = entrylist;
00482    fNRows = fEntries->GetN();
00483    fTree->SetEntryList(entrylist);
00484 }

Generated on Tue Jul 5 15:43:13 2011 for ROOT_528-00b_version by  doxygen 1.5.1