TTreeFormulaManager.cxx

Go to the documentation of this file.
00001 // @(#)root/treeplayer:$Id: TTreeFormulaManager.cxx 35756 2010-09-27 01:30:22Z pcanal $
00002 // Author: Philippe Canal   20/03/02
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al.        *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 
00013 #include "TTreeFormulaManager.h"
00014 
00015 #include "TArrayI.h"
00016 #include "TError.h"
00017 #include "TLeafElement.h"
00018 
00019 
00020 ClassImp(TTreeFormulaManager)
00021 
00022 //________________________________________________________________________________
00023 //
00024 //     A TreeFormulaManager is used to coordinate one or more TTreeFormula objecs
00025 //
00026 //  In particular it makes sure that the dimensions and size of all the formulas
00027 //  is properly coordinated.
00028 //
00029 
00030 
00031 //______________________________________________________________________________
00032 TTreeFormulaManager::TTreeFormulaManager() : TObject()
00033 {
00034 //*-*-*-*-*-*-*-*-*-*-*Tree FormulaManger default constructor*-*-*-*-*-*-*-*-*-*
00035 //*-*                  ======================================
00036 
00037    fMultiplicity = 0;
00038    fMultiVarDim  = kFALSE;
00039    fNeedSync     = kFALSE;
00040    fNdata = 1;
00041 
00042    for(Int_t i=0; i<kMAXFORMDIM+1; i++) {
00043       fVarDims[i] = 0;
00044       fCumulUsedSizes[i] = 1;
00045       fUsedSizes[i] = 1;
00046       fVirtUsedSizes[i] = 1;
00047    }
00048    fCumulUsedVarDims = 0;
00049 }
00050 
00051 
00052 //______________________________________________________________________________
00053 TTreeFormulaManager::~TTreeFormulaManager()
00054 {
00055 //*-*-*-*-*-*-*-*-*-*-*Tree FormulaManager default destructor*-*-*-*-*-*-*-*-*-*
00056 //*-*                  ======================================
00057 
00058    for (int l = 0; l<kMAXFORMDIM; l++) {
00059       if (fVarDims[l]) delete fVarDims[l];
00060       fVarDims[l] = 0;
00061    }
00062    if (fCumulUsedVarDims) delete fCumulUsedVarDims;
00063 }
00064 
00065 //______________________________________________________________________________
00066 void TTreeFormulaManager::Remove(TTreeFormula* adding)
00067 {
00068    // Remove a formula from this manager
00069 
00070    fFormulas.Remove(adding);
00071 }
00072 
00073 //______________________________________________________________________________
00074 void TTreeFormulaManager::Add(TTreeFormula* adding)
00075 {
00076   // Add a new formula to the list of formulas managed
00077   // The manager of the formula will be changed and the old one will be deleted
00078   // if it is empty.
00079 
00080    TTreeFormulaManager * old = adding->fManager;
00081 
00082    if (old) {
00083       if (old==this) {
00084          if (fFormulas.FindObject(adding)) return;
00085       } else {
00086          old->fFormulas.Remove(adding);
00087          if (old->fFormulas.GetLast()==-1) delete adding->fManager;
00088       }
00089    }
00090 
00091    if (adding->TestBit(TTreeFormula::kNeedEntries)) {
00092       SetBit(TTreeFormula::kNeedEntries);
00093    }
00094 
00095    fFormulas.Add(adding);
00096    adding->fManager = this;
00097    fNeedSync = kTRUE;
00098 }
00099 
00100 //______________________________________________________________________________
00101 void TTreeFormulaManager::AddVarDims(Int_t virt_dim)
00102 {
00103    // Add a variable dimension
00104 
00105    if (!fVarDims[virt_dim]) fVarDims[virt_dim] = new TArrayI;
00106 }
00107 
00108 //______________________________________________________________________________
00109 void TTreeFormulaManager::CancelDimension(Int_t virt_dim)
00110 {
00111    // Cancel a dimension.  This is usually called when an out-of-bounds index
00112    // is used.
00113 
00114    fCumulUsedSizes[virt_dim] = 0;
00115 
00116 }
00117 
00118 //______________________________________________________________________________
00119 void TTreeFormulaManager::EnableMultiVarDims()
00120 {
00121    // Set the manager as handling a formula with multiple variable dimensions
00122 
00123    fMultiVarDim = kTRUE;
00124    if (!fCumulUsedVarDims) fCumulUsedVarDims = new TArrayI;
00125 
00126 }
00127 
00128 //______________________________________________________________________________
00129 Int_t TTreeFormulaManager::GetNdata(Bool_t forceLoadDim)
00130 {
00131 //*-*-*-*-*-*-*-*Return number of available instances in the formulas*-*-*-*-*-*
00132 //*-*            ====================================================
00133 //
00134 
00135    Int_t k;
00136 
00137    // new version of GetNData:
00138    // Possible problem: we only allow one variable dimension so far.
00139    if (fMultiplicity==0) return fNdata;
00140 
00141    if (fMultiplicity==2) return fNdata; // CumulUsedSizes[0];
00142 
00143    // We have at least one leaf with a variable size:
00144 
00145    // Reset the registers.
00146    for(k=0; k<=kMAXFORMDIM; k++) {
00147       fUsedSizes[k] = TMath::Abs(fVirtUsedSizes[k]);
00148       if (fVarDims[k]) {
00149          for(Int_t i0=0;i0<fVarDims[k]->GetSize();i0++) {
00150             fVarDims[k]->AddAt(0,i0);
00151          }
00152       }
00153    }
00154    if (fCumulUsedVarDims) {
00155       for(Int_t i0=0;i0<fCumulUsedVarDims->GetSize();++i0) {
00156          fCumulUsedVarDims->AddAt(0,i0);
00157       }
00158    }
00159 
00160    TTreeFormula* current = 0;
00161 
00162    Int_t size = fFormulas.GetLast()+1;
00163 
00164    for(Int_t i=0; i<size; i++) {
00165 
00166       current = (TTreeFormula*)fFormulas.UncheckedAt(i);
00167       if (current->fMultiplicity!=1 && !current->fHasCast) continue;
00168       if (!current->LoadCurrentDim() ) {
00169          if (forceLoadDim) {
00170             for(Int_t j=i+1; j<size; j++) {
00171                current = (TTreeFormula*)fFormulas.UncheckedAt(j);
00172                if (current->fMultiplicity!=1 && !current->fHasCast) continue;
00173                current->LoadCurrentDim();
00174             }
00175          }
00176          fNdata = 0;
00177          return 0;
00178       }
00179    }
00180 
00181    if (fMultiplicity==-1) { fNdata = 1; return fCumulUsedSizes[0]; }
00182 
00183    Int_t overall = 1;
00184    if (!fMultiVarDim) {
00185       for (k = kMAXFORMDIM; (k >= 0) ; k--) {
00186          if (fUsedSizes[k]>=0) {
00187             overall *= fUsedSizes[k];
00188             fCumulUsedSizes[k] = overall;
00189          } else {
00190             Error("GetNdata","a dimension is still negative!");
00191          }
00192       }
00193    } else {
00194       overall = 0; // Since we work with additions in this section
00195       if (fCumulUsedVarDims && fUsedSizes[0]>fCumulUsedVarDims->GetSize()) fCumulUsedVarDims->Set(fUsedSizes[0]);
00196       for(Int_t i = 0; i < fUsedSizes[0]; i++) {
00197          Int_t local_overall = 1;
00198          for (k = kMAXFORMDIM; (k > 0) ; k--) {
00199             if (fVarDims[k]) {
00200                Int_t index = fVarDims[k]->At(i);
00201                if (fCumulUsedVarDims && fCumulUsedVarDims->At(i)==1 && index) index = 1;
00202                if (fUsedSizes[k]==1 || (index!=1 && index<fUsedSizes[k]))
00203                   local_overall *= index;
00204                else local_overall *= fUsedSizes[k];
00205             } else {
00206                local_overall *= fUsedSizes[k];
00207             }
00208          }
00209          // a negative value indicates that this value of the primary index
00210          // will lead to an invalid index; So we skip it.
00211          if (fCumulUsedVarDims->At(i)<0) fCumulUsedVarDims->AddAt(0,i);
00212          else {
00213             fCumulUsedVarDims->AddAt(local_overall,i);
00214             overall += local_overall;
00215          }
00216       }
00217    }
00218    fNdata = overall;
00219    return overall;
00220 
00221 }
00222 
00223 //______________________________________________________________________________
00224 Bool_t TTreeFormulaManager::Sync()
00225 {
00226    // Synchronize all the formulae.
00227 
00228    if (!fNeedSync) return true;
00229 
00230    TTreeFormula* current = 0;
00231    Bool_t hasCast = kFALSE;
00232 
00233    fMultiplicity = 0;
00234    // We do not use an intermediary variable because ResetDimensions
00235    // might add more formulas (TCutG).
00236    for(Int_t i=0; i<fFormulas.GetLast()+1; i++) {
00237       current = (TTreeFormula*)fFormulas.UncheckedAt(i);
00238 
00239       hasCast |= current->fHasCast;
00240 
00241       // We probably need to reset the formula's dimension
00242 
00243       current->ResetDimensions();
00244       switch (current->GetMultiplicity()) {
00245       case 0:
00246          // nothing to do
00247          break;
00248       case 1:
00249          fMultiplicity = 1;
00250          break;
00251       case 2:
00252          if (fMultiplicity!=1) fMultiplicity = 2;
00253          break;
00254       default:
00255         Error("Sync","Unexpected case!");
00256       }
00257 
00258 
00259    } // end of for each formulas
00260 
00261    // For now we keep fCumulUsedSizes sign aware.
00262    // This will be reset properly (if needed) by GetNdata.
00263    fCumulUsedSizes[kMAXFORMDIM] = fUsedSizes[kMAXFORMDIM];
00264    for (Int_t k = kMAXFORMDIM; (k > 0) ; k--) {
00265       if (fUsedSizes[k-1]>=0) {
00266          fCumulUsedSizes[k-1] = fUsedSizes[k-1] * fCumulUsedSizes[k];
00267       } else {
00268          fCumulUsedSizes[k-1] = - TMath::Abs(fCumulUsedSizes[k]);
00269       }
00270    }
00271 
00272    // Now that we know the virtual dimension we know if a loop over EvalInstance
00273    // is needed or not.
00274    if (fCumulUsedSizes[0]==1 && fMultiplicity>0) {
00275       // Case where even though we have an array.  We know that they will always
00276       // only be one element.
00277       fMultiplicity -= 2;
00278    } else if (fCumulUsedSizes[0]<0 && fMultiplicity==2) {
00279       // Case of a fixed length array that have one of its indices given
00280       // by a variable.
00281       fMultiplicity = 1;
00282    } else if (fMultiplicity==0 && hasCast) {
00283       fMultiplicity = -1;
00284    }
00285 
00286    switch(fMultiplicity) {
00287       case 0: fNdata = 1; break;
00288       case 2: fNdata = fCumulUsedSizes[0]; break;
00289       default: fNdata = 0;
00290    }
00291    fNeedSync = kFALSE;
00292 
00293    return true;
00294 }
00295 
00296 //______________________________________________________________________________
00297 void TTreeFormulaManager::UpdateFormulaLeaves()
00298 {
00299    // this function could be called TTreePlayer::UpdateFormulaLeaves, itself
00300    // called by TChain::LoadTree when a new Tree is loaded.
00301    // Because Trees in a TChain may have a different list of leaves, one
00302    // must update the leaves numbers in the TTreeFormula used by the TreePlayer.
00303 
00304    // A safer alternative would be to recompile the whole thing .... However
00305    // currently compile HAS TO be called from the constructor!
00306 
00307    Int_t size = fFormulas.GetLast()+1;
00308 
00309    for(Int_t i=0; i<size; i++) {
00310 
00311       TTreeFormula *current = (TTreeFormula*)fFormulas.UncheckedAt(i);
00312       current->UpdateFormulaLeaves();
00313 
00314    }
00315 
00316 }
00317 
00318 //______________________________________________________________________________
00319 void TTreeFormulaManager::UpdateUsedSize(Int_t &virt_dim, Int_t vsize)
00320 {
00321    // Reload the array sizes
00322 
00323    if (vsize<0)
00324       fVirtUsedSizes[virt_dim] = -1 * TMath::Abs(fVirtUsedSizes[virt_dim]);
00325    else
00326       if ( TMath::Abs(fVirtUsedSizes[virt_dim])==1
00327           || (vsize < TMath::Abs(fVirtUsedSizes[virt_dim]) ) ) {
00328          // Absolute values represent the min of all real dimensions
00329          // that are known.  The fact that it is negatif indicates
00330          // that one of the leaf has a variable size for this
00331          // dimensions.
00332          if (fVirtUsedSizes[virt_dim] < 0) {
00333             fVirtUsedSizes[virt_dim] = -1 * vsize;
00334          } else {
00335             fVirtUsedSizes[virt_dim] = vsize;
00336          }
00337       }
00338    fUsedSizes[virt_dim] = fVirtUsedSizes[virt_dim];
00339    virt_dim++;
00340 
00341 }

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