RooTreeDataStore.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooTreeDataStore.cxx 34064 2010-06-22 15:05:19Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooTreeDataStore is the abstract base class for data collection that
00021 // use a TTree as internal storage mechanism
00022 // END_HTML
00023 //
00024 
00025 #include "RooFit.h"
00026 #include "RooMsgService.h"
00027 #include "RooTreeDataStore.h"
00028 
00029 #include "Riostream.h"
00030 #include "TTree.h"
00031 #include "TChain.h"
00032 #include "TDirectory.h"
00033 #include "TROOT.h"
00034 #include "RooFormulaVar.h"
00035 #include "RooRealVar.h"
00036 #include "RooHistError.h"
00037 
00038 #include <iomanip>
00039 using namespace std ;
00040 
00041 ClassImp(RooTreeDataStore)
00042 ;
00043 
00044 
00045 Int_t RooTreeDataStore::_defTreeBufSize = 4096 ;
00046 
00047 
00048 
00049 //_____________________________________________________________________________
00050 RooTreeDataStore::RooTreeDataStore() :
00051   _tree(0),
00052   _cacheTree(0),
00053   _cacheOwner(0),
00054   _defCtor(kTRUE),
00055   _wgtVar(0),
00056   _extWgtArray(0),
00057   _extWgtErrLoArray(0),
00058   _extWgtErrHiArray(0),
00059   _extSumW2Array(0),
00060   _curWgt(1),
00061   _curWgtErrLo(0),
00062   _curWgtErrHi(0),
00063   _curWgtErr(0)
00064 {
00065 }
00066 
00067 
00068 
00069 //_____________________________________________________________________________
00070 RooTreeDataStore::RooTreeDataStore(TTree* t, const RooArgSet& vars, const char* wgtVarName) :
00071   RooAbsDataStore("blah","blah",varsNoWeight(vars,wgtVarName)),
00072   _tree(t),
00073   _cacheTree(0),
00074   _cacheOwner(0),
00075   _defCtor(kTRUE),
00076   _varsww(vars),
00077   _wgtVar(weightVar(vars,wgtVarName)),
00078   _extWgtArray(0),
00079   _curWgt(1)
00080 {
00081   // Constructor to facilitate reading of legacy RooDataSets
00082 }
00083 
00084 
00085 
00086 
00087 //_____________________________________________________________________________
00088 RooTreeDataStore::RooTreeDataStore(const char* name, const char* title, const RooArgSet& vars, const char* wgtVarName) :
00089   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
00090   _tree(0),
00091   _cacheTree(0), 
00092   _cacheOwner(0),
00093   _defCtor(kFALSE),
00094   _varsww(vars),
00095   _wgtVar(weightVar(vars,wgtVarName)),
00096   _extWgtArray(0),
00097   _extWgtErrLoArray(0),
00098   _extWgtErrHiArray(0),
00099   _extSumW2Array(0),
00100   _curWgt(1),
00101   _curWgtErrLo(0),
00102   _curWgtErrHi(0),
00103   _curWgtErr(0)
00104 {
00105   initialize() ;  
00106 }
00107 
00108 
00109 
00110 
00111 //_____________________________________________________________________________
00112 RooTreeDataStore::RooTreeDataStore(const char* name, const char* title, const RooArgSet& vars, TTree& t, const RooFormulaVar& select, const char* wgtVarName) :
00113   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
00114   _tree(0),
00115   _cacheTree(0),
00116   _cacheOwner(0),
00117   _defCtor(kFALSE),
00118   _varsww(vars),
00119   _wgtVar(weightVar(vars,wgtVarName)),
00120   _extWgtArray(0),
00121   _extWgtErrLoArray(0),
00122   _extWgtErrHiArray(0),
00123   _extSumW2Array(0),
00124   _curWgt(1),
00125   _curWgtErrLo(0),
00126   _curWgtErrHi(0),
00127   _curWgtErr(0)
00128 {
00129   initialize() ;  
00130   loadValues(&t,&select) ;
00131 }
00132 
00133 
00134 
00135 //_____________________________________________________________________________
00136 RooTreeDataStore::RooTreeDataStore(const char* name, const char* title, const RooArgSet& vars, TTree& t, const char* selExpr, const char* wgtVarName) :
00137   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
00138   _tree(0),
00139   _cacheTree(0),
00140   _cacheOwner(0),
00141   _defCtor(kFALSE),
00142   _varsww(vars),
00143   _wgtVar(weightVar(vars,wgtVarName)),
00144   _extWgtArray(0),
00145   _extWgtErrLoArray(0),
00146   _extWgtErrHiArray(0),
00147   _extSumW2Array(0),
00148   _curWgt(1),
00149   _curWgtErrLo(0),
00150   _curWgtErrHi(0),
00151   _curWgtErr(0)
00152 {
00153   initialize() ;  
00154 
00155   if (selExpr && *selExpr) {
00156     // Create a RooFormulaVar cut from given cut expression
00157     RooFormulaVar select(selExpr,selExpr,_vars) ;
00158     loadValues(&t,&select);
00159   } else {
00160     loadValues(&t);
00161   }
00162 }
00163 
00164 
00165 
00166 //_____________________________________________________________________________
00167 RooTreeDataStore::RooTreeDataStore(const char* name, const char* title, const RooArgSet& vars, const RooAbsDataStore& tds, const RooFormulaVar& select, const char* wgtVarName) :
00168   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
00169   _tree(0),
00170   _cacheTree(0),
00171   _cacheOwner(0),
00172   _defCtor(kFALSE),
00173   _varsww(vars),
00174   _wgtVar(weightVar(vars,wgtVarName)),
00175   _extWgtArray(0),
00176   _extWgtErrLoArray(0),
00177   _extWgtErrHiArray(0),
00178   _extSumW2Array(0),
00179   _curWgt(1),
00180   _curWgtErrLo(0),
00181   _curWgtErrHi(0),
00182   _curWgtErr(0)
00183 {
00184   initialize() ;  
00185   loadValues(&tds,&select) ;
00186 }
00187 
00188 
00189 
00190 //_____________________________________________________________________________
00191 RooTreeDataStore::RooTreeDataStore(const char* name, const char* title, const RooArgSet& vars, const RooAbsDataStore& ads, const char* selExpr, const char* wgtVarName) :
00192   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)),
00193   _tree(0),
00194   _cacheTree(0),
00195   _cacheOwner(0),
00196   _defCtor(kFALSE),
00197   _varsww(vars),
00198   _wgtVar(weightVar(vars,wgtVarName)),
00199   _extWgtArray(0),
00200   _extWgtErrLoArray(0),
00201   _extWgtErrHiArray(0),
00202   _extSumW2Array(0),
00203   _curWgt(1),
00204   _curWgtErrLo(0),
00205   _curWgtErrHi(0),
00206   _curWgtErr(0)
00207 {
00208   initialize() ;  
00209 
00210   if (selExpr && *selExpr) {
00211     // Create a RooFormulaVar cut from given cut expression
00212     RooFormulaVar select(selExpr,selExpr,_vars) ;
00213     loadValues(&ads,&select);
00214   } else {
00215     loadValues(&ads);
00216   }
00217 }
00218 
00219 
00220 
00221 
00222 //_____________________________________________________________________________
00223 RooTreeDataStore::RooTreeDataStore(const char *name, const char *title, RooAbsDataStore& tds, 
00224                          const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
00225                          Int_t nStart, Int_t nStop, Bool_t /*copyCache*/, const char* wgtVarName) :
00226   RooAbsDataStore(name,title,varsNoWeight(vars,wgtVarName)), _defCtor(kFALSE),
00227   _varsww(vars),
00228   _wgtVar(weightVar(vars,wgtVarName)),
00229   _extWgtArray(0),
00230   _extWgtErrLoArray(0),
00231   _extWgtErrHiArray(0),
00232   _extSumW2Array(0),
00233   _curWgt(1),
00234   _curWgtErrLo(0),
00235   _curWgtErrHi(0),
00236   _curWgtErr(0)
00237 {
00238 
00239   // WVE NEED TO ADJUST THIS FOR WEIGHTS
00240 
00241   // Protected constructor for internal use only
00242   _tree = 0 ;
00243   _cacheTree = 0 ;
00244   createTree(name,title) ;
00245 
00246   // Deep clone cutVar and attach clone to this dataset
00247   RooFormulaVar* cloneVar = 0;
00248   if (cutVar) {    
00249     cloneVar = (RooFormulaVar*) cutVar->cloneTree() ;
00250     cloneVar->attachDataStore(tds) ;
00251   }
00252 
00253   // Constructor from existing data set with list of variables that preserves the cache
00254   initialize();
00255 
00256   attachCache(0,((RooTreeDataStore&)tds)._cachedVars) ;
00257 
00258   // WVE copy values of cached variables here!!!
00259   _cacheTree->CopyEntries(((RooTreeDataStore&)tds)._cacheTree) ;
00260   _cacheOwner = 0 ;
00261   
00262   loadValues(&tds,cloneVar,cutRange,nStart,nStop);
00263 
00264   if (cloneVar) delete cloneVar ;
00265 }
00266 
00267 
00268 
00269 //_____________________________________________________________________________
00270 RooArgSet RooTreeDataStore::varsNoWeight(const RooArgSet& allVars, const char* wgtName) 
00271 {
00272   // Utility function for constructors
00273   // Return RooArgSet that is copy of allVars minus variable matching wgtName if specified
00274 
00275   RooArgSet ret(allVars) ;
00276   if(wgtName) {
00277     RooAbsArg* wgt = allVars.find(wgtName) ;
00278     if (wgt) {
00279       ret.remove(*wgt,kTRUE,kTRUE) ;
00280     }
00281   }
00282   return ret ;
00283 }
00284 
00285 
00286 
00287 //_____________________________________________________________________________
00288 RooRealVar* RooTreeDataStore::weightVar(const RooArgSet& allVars, const char* wgtName) 
00289 {
00290   // Utility function for constructors
00291   // Return pointer to weight variable if it is defined
00292 
00293   if(wgtName) {
00294     RooRealVar* wgt = dynamic_cast<RooRealVar*>(allVars.find(wgtName)) ;
00295     return wgt ;
00296   } 
00297   return 0 ;
00298 }
00299 
00300 
00301 
00302 
00303 //_____________________________________________________________________________
00304 void RooTreeDataStore::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVarsIn) 
00305 {
00306   // Initialize cache of dataset: attach variables of cache ArgSet
00307   // to the corresponding TTree branches
00308 
00309   // iterate over the cache variables for this dataset
00310   _cachedVars.removeAll() ;
00311   TIterator* iter = cachedVarsIn.createIterator() ;
00312   RooAbsArg *var;
00313   while((0 != (var= (RooAbsArg*)iter->Next()))) {    
00314     var->attachToTree(*_cacheTree,_defTreeBufSize) ;
00315     _cachedVars.add(*var) ;
00316   }
00317   delete iter ;
00318   _cacheOwner = newOwner ;
00319 
00320 }
00321 
00322 
00323 
00324 
00325 
00326 
00327 //_____________________________________________________________________________
00328 RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const char* newname) :
00329   RooAbsDataStore(other,newname),
00330   _tree(0),
00331   _cacheTree(0),
00332   _defCtor(kFALSE),
00333   _varsww(other._varsww),
00334   _wgtVar(other._wgtVar),
00335   _extWgtArray(other._extWgtArray),
00336   _extWgtErrLoArray(other._extWgtErrLoArray),
00337   _extWgtErrHiArray(other._extWgtErrHiArray),
00338   _extSumW2Array(other._extSumW2Array),
00339   _curWgt(other._curWgt),
00340   _curWgtErrLo(other._curWgtErrLo),
00341   _curWgtErrHi(other._curWgtErrHi),
00342   _curWgtErr(other._curWgtErr)
00343 {
00344   initialize() ;  
00345   loadValues(&other) ;
00346 }
00347 
00348 
00349 //_____________________________________________________________________________
00350 RooTreeDataStore::RooTreeDataStore(const RooTreeDataStore& other, const RooArgSet& vars, const char* newname) :
00351   RooAbsDataStore(other,varsNoWeight(vars,other._wgtVar?other._wgtVar->GetName():0),newname),
00352   _tree(0),
00353   _cacheTree(0),
00354   _defCtor(kFALSE),
00355   _varsww(vars),
00356   _wgtVar(other._wgtVar?weightVar(vars,other._wgtVar->GetName()):0),
00357   _extWgtArray(other._extWgtArray),
00358   _extWgtErrLoArray(other._extWgtErrLoArray),
00359   _extWgtErrHiArray(other._extWgtErrHiArray),
00360   _extSumW2Array(other._extSumW2Array),
00361   _curWgt(other._curWgt),
00362   _curWgtErrLo(other._curWgtErrLo),
00363   _curWgtErrHi(other._curWgtErrHi),
00364   _curWgtErr(other._curWgtErr)
00365 {
00366   initialize() ;  
00367   loadValues(&other) ;
00368 }
00369 
00370 
00371 
00372 
00373 //_____________________________________________________________________________
00374 RooTreeDataStore::~RooTreeDataStore()
00375 {
00376   // Destructor
00377   if (_tree) {
00378     delete _tree ;
00379   }
00380   if (_cacheTree) {
00381     delete _cacheTree ;
00382   }
00383 }
00384 
00385 
00386 
00387 //_____________________________________________________________________________
00388 void RooTreeDataStore::initialize() 
00389 {
00390   // One-time initialization common to all constructor forms.  Attach
00391   // variables of internal ArgSet to the corresponding TTree branches
00392 
00393   // Recreate (empty) cache tree
00394   createTree(GetName(),GetTitle()) ;
00395 
00396   // Attach each variable to the dataset
00397   TIterator* iter = _varsww.createIterator() ;
00398   RooAbsArg *var;
00399   while((0 != (var= (RooAbsArg*)iter->Next()))) {
00400     var->attachToTree(*_tree,_defTreeBufSize) ;
00401   }
00402   delete iter ;
00403 }
00404 
00405 
00406 
00407 
00408 
00409 //_____________________________________________________________________________
00410 void RooTreeDataStore::createTree(const char* name, const char* title)
00411 {
00412   // Create TTree object that lives in memory, independent of current
00413   // location of gDirectory
00414 
00415   TString pwd(gDirectory->GetPath()) ;
00416   TString memDir(gROOT->GetName()) ;
00417   memDir.Append(":/") ;
00418   Bool_t notInMemNow= (pwd!=memDir) ;
00419 
00420   // cout << "RooTreeData::createTree pwd=" << pwd << " memDir=" << memDir << " notInMemNow = " << (notInMemNow?"T":"F") << endl ;
00421 
00422   if (notInMemNow) {
00423     gDirectory->cd(memDir) ;
00424   }
00425 
00426   if (!_tree) {
00427     _tree = new TTree(name,title) ;
00428     _tree->SetDirectory(0) ;
00429     gDirectory->RecursiveRemove(_tree) ;
00430   }
00431   if (!_cacheTree) {
00432     _cacheTree = new TTree(name,title) ;
00433     _cacheTree->SetDirectory(0) ;
00434     gDirectory->RecursiveRemove(_cacheTree) ;
00435   }
00436 
00437   if (notInMemNow) {
00438     gDirectory->cd(pwd) ;
00439   }
00440   
00441 }
00442 
00443 
00444 
00445 
00446 //_____________________________________________________________________________
00447 void RooTreeDataStore::loadValues(const TTree *t, const RooFormulaVar* select, const char* /*rangeName*/, Int_t /*nStart*/, Int_t /*nStop*/) 
00448 {
00449   // Load values from tree 't' into this data collection, optionally
00450   // selecting events using 'select' RooFormulaVar
00451   //
00452   // The source tree 't' is first clone as not disturb its branch
00453   // structure when retrieving information from it.
00454 
00455   // Clone source tree
00456   // WVE Clone() crashes on trees, CloneTree() crashes on tchains :-(
00457 
00458   // Change directory to memory dir before cloning tree to avoid ROOT errors
00459   TString pwd(gDirectory->GetPath()) ;
00460   TString memDir(gROOT->GetName()) ;
00461   memDir.Append(":/") ;
00462   Bool_t notInMemNow= (pwd!=memDir) ;
00463 
00464   if (notInMemNow) {
00465     gDirectory->cd(memDir) ;
00466   }
00467 
00468   TTree* tClone ;
00469   if (dynamic_cast<const TChain*>(t)) {
00470     tClone = (TTree*) t->Clone() ; 
00471   } else {
00472     tClone = ((TTree*)t)->CloneTree() ;
00473   }
00474 
00475   // Change directory back to original directory
00476   tClone->SetDirectory(0) ;
00477 
00478   if (notInMemNow) {
00479     gDirectory->cd(pwd) ;
00480   }
00481     
00482   // Clone list of variables  
00483   RooArgSet *sourceArgSet = (RooArgSet*) _varsww.snapshot(kFALSE) ;
00484   
00485   // Attach args in cloned list to cloned source tree
00486   TIterator* sourceIter =  sourceArgSet->createIterator() ;
00487   RooAbsArg* sourceArg = 0;
00488   while ((sourceArg=(RooAbsArg*)sourceIter->Next())) {
00489     sourceArg->attachToTree(*tClone,_defTreeBufSize) ;
00490   }
00491 
00492   // Redirect formula servers to sourceArgSet
00493   RooFormulaVar* selectClone(0) ;
00494   if (select) {
00495     selectClone = (RooFormulaVar*) select->cloneTree() ;
00496     selectClone->recursiveRedirectServers(*sourceArgSet) ;
00497 
00498     RooArgSet branchList ;
00499     selectClone->branchNodeServerList(&branchList) ;
00500     TIterator* iter = branchList.createIterator() ;
00501     RooAbsArg* arg ;
00502     while((arg=(RooAbsArg*)iter->Next())) {
00503       arg->setOperMode(RooAbsArg::ADirty) ;
00504     }
00505     delete iter ;
00506   }
00507 
00508   // Loop over events in source tree   
00509   RooAbsArg* destArg = 0;
00510   TIterator* destIter = _varsww.createIterator() ;
00511   Int_t numInvalid(0) ;
00512   Int_t nevent= (Int_t)tClone->GetEntries();
00513   for(Int_t i=0; i < nevent; ++i) {
00514     Int_t entryNumber=tClone->GetEntryNumber(i);
00515     if (entryNumber<0) break;
00516     tClone->GetEntry(entryNumber,1);
00517  
00518     // Copy from source to destination
00519      destIter->Reset() ;
00520      sourceIter->Reset() ;
00521      Bool_t allOK(kTRUE) ;
00522      while ((destArg = (RooAbsArg*)destIter->Next())) {              
00523        sourceArg = (RooAbsArg*) sourceIter->Next() ;
00524        destArg->copyCache(sourceArg) ;
00525        sourceArg->copyCache(destArg) ;
00526        if (!destArg->isValid()) {
00527          numInvalid++ ;
00528          allOK=kFALSE ;
00529          break ;
00530        }       
00531      }   
00532 
00533      // Does this event pass the cuts?
00534      if (!allOK || (selectClone && selectClone->getVal()==0)) {
00535        continue ; 
00536      }
00537 
00538      fill() ;
00539   }
00540   delete destIter ;
00541 
00542   if (numInvalid>0) {
00543     coutI(Eval) << "RooTreeDataStore::loadValues(" << GetName() << ") Ignored " << numInvalid << " out of range events" << endl ;
00544   }
00545   
00546   SetTitle(t->GetTitle());
00547 
00548   delete sourceIter ;
00549   delete sourceArgSet ;
00550   delete selectClone ;
00551   delete tClone ;
00552 }
00553 
00554 
00555 
00556 
00557 
00558 
00559 //_____________________________________________________________________________
00560 void RooTreeDataStore::loadValues(const RooAbsDataStore *ads, const RooFormulaVar* select, 
00561                                   const char* rangeName, Int_t nStart, Int_t nStop)  
00562 {
00563   // Load values from dataset 't' into this data collection, optionally
00564   // selecting events using 'select' RooFormulaVar
00565   //
00566 
00567   // Redirect formula servers to source data row
00568   RooFormulaVar* selectClone(0) ;
00569   if (select) {
00570     selectClone = (RooFormulaVar*) select->cloneTree() ;
00571     selectClone->recursiveRedirectServers(*ads->get()) ;
00572 
00573     RooArgSet branchList ;
00574     selectClone->branchNodeServerList(&branchList) ;
00575     TIterator* iter = branchList.createIterator() ;
00576     RooAbsArg* arg ;
00577     while((arg=(RooAbsArg*)iter->Next())) {
00578       arg->setOperMode(RooAbsArg::ADirty) ;
00579     }
00580     delete iter ;
00581   }
00582 
00583   // Force RDS internal initialization
00584   ads->get(0) ;
00585 
00586   // Loop over events in source tree   
00587   RooAbsArg* arg = 0;
00588   TIterator* destIter = _varsww.createIterator() ;
00589   Int_t nevent = nStop < ads->numEntries() ? nStop : ads->numEntries() ;
00590   Bool_t allValid ;
00591 
00592   for(Int_t i=nStart; i < nevent ; ++i) {
00593     ads->get(i) ;
00594 
00595     // Does this event pass the cuts?
00596     if (selectClone && selectClone->getVal()==0) {
00597       continue ; 
00598     }
00599 
00600     
00601     _varsww.assignValueOnly(((RooTreeDataStore*)ads)->_varsww) ;
00602     destIter->Reset() ;
00603     // Check that all copied values are valid
00604     allValid=kTRUE ;
00605     while((arg=(RooAbsArg*)destIter->Next())) {
00606       if (!arg->isValid() || (rangeName && !arg->inRange(rangeName))) {
00607         //cout << "arg " << arg->GetName() << " is not valid" << endl ;
00608         //arg->Print("v") ;
00609         allValid=kFALSE ;
00610         break ;
00611       }
00612     }
00613     //cout << "RooTreeData::loadValues(" << GetName() << ") allValid = " << (allValid?"T":"F") << endl ;
00614     if (!allValid) {
00615       continue ;
00616     }
00617     
00618     _cachedVars = ((RooTreeDataStore*)ads)->_cachedVars ;
00619     fill() ;
00620    }
00621   delete destIter ;
00622   
00623   delete selectClone ;
00624   SetTitle(ads->GetTitle());
00625 }
00626 
00627 
00628 
00629 //_____________________________________________________________________________
00630 Bool_t RooTreeDataStore::valid() const 
00631 {
00632   // Return true if currently loaded coordinate is considered valid within
00633   // the current range definitions of all observables
00634   return kTRUE ;
00635 }
00636 
00637 
00638 
00639 
00640 //_____________________________________________________________________________
00641 Int_t RooTreeDataStore::fill()
00642 {
00643    // Interface function to TTree::Fill
00644    return _tree->Fill() ;
00645 }
00646  
00647 
00648 
00649 //_____________________________________________________________________________
00650 const RooArgSet* RooTreeDataStore::get(Int_t index) const 
00651 {
00652   // Load the n-th data point (n='index') in memory
00653   // and return a pointer to the internal RooArgSet
00654   // holding its coordinates.
00655 
00656   checkInit() ;
00657 
00658   Int_t ret = ((RooTreeDataStore*)this)->GetEntry(index, 1) ;
00659 
00660   if(!ret) return 0;
00661 
00662   if (_doDirtyProp) {
00663     // Raise all dirty flags 
00664     _iterator->Reset() ;
00665     RooAbsArg* var = 0;
00666     while ((var=(RooAbsArg*)_iterator->Next())) {
00667       var->setValueDirty() ; // This triggers recalculation of all clients
00668     } 
00669     
00670     _cacheIter->Reset() ;
00671     while ((var=(RooAbsArg*)_cacheIter->Next())) {
00672       var->setValueDirty()  ; // This triggers recalculation of all clients, but doesn't recalculate self
00673       var->clearValueDirty() ; 
00674     } 
00675   }
00676   
00677   // Update current weight cache
00678   if (_extWgtArray) {
00679 
00680     // If external array is specified use that  
00681     _curWgt = _extWgtArray[index] ;
00682     _curWgtErrLo = _extWgtErrLoArray[index] ;
00683     _curWgtErrHi = _extWgtErrHiArray[index] ;
00684     _curWgtErr   = sqrt(_extSumW2Array[index]) ;
00685 
00686   } else if (_wgtVar) {
00687 
00688     // Otherwise look for weight variable
00689     _curWgt = _wgtVar->getVal() ;
00690     _curWgtErrLo = _wgtVar->getAsymErrorLo() ;
00691     _curWgtErrHi = _wgtVar->getAsymErrorHi() ;
00692     _curWgtErr   = _wgtVar->hasAsymError() ? ((_wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo())/2)  : _wgtVar->getError() ;
00693 
00694   } else {
00695 
00696     // Otherwise return 1 
00697     _curWgt=1.0 ;
00698     _curWgtErrLo = 0 ;
00699     _curWgtErrHi = 0 ;
00700     _curWgtErr = 0 ;
00701     
00702   }
00703 
00704   return &_vars;
00705 }
00706 
00707 
00708 
00709 //_____________________________________________________________________________
00710 Double_t RooTreeDataStore::weight(Int_t index) const 
00711 {
00712   // Return the weight of the n-th data point (n='index') in memory
00713   get(index) ;
00714   return weight() ;
00715 }
00716 
00717 
00718 
00719 //_____________________________________________________________________________
00720 Double_t RooTreeDataStore::weight() const 
00721 {
00722   // Return the weight of the n-th data point (n='index') in memory
00723   return _curWgt ;
00724 }
00725 
00726 
00727 //_____________________________________________________________________________
00728 Double_t RooTreeDataStore::weightError(RooAbsData::ErrorType etype) const 
00729 {
00730   if (_extWgtArray) {
00731 
00732     // We have a weight array, use that info
00733 
00734     // Return symmetric error on current bin calculated either from Poisson statistics or from SumOfWeights
00735     Double_t lo,hi ;
00736     weightError(lo,hi,etype) ;
00737     return (lo+hi)/2 ;
00738 
00739    } else if (_wgtVar) {
00740 
00741     // We have a a weight variable, use that info
00742     if (_wgtVar->hasAsymError()) {
00743       return ( _wgtVar->getAsymErrorHi() - _wgtVar->getAsymErrorLo() ) / 2 ;
00744     } else {
00745       return _wgtVar->getError() ;    
00746     }
00747 
00748   } else {
00749 
00750     // We have no weights
00751     return 0 ;
00752 
00753   }
00754 }
00755 
00756 
00757 
00758 //_____________________________________________________________________________
00759 void RooTreeDataStore::weightError(Double_t& lo, Double_t& hi, RooAbsData::ErrorType etype) const
00760 {
00761   if (_extWgtArray) {
00762     
00763     // We have a weight array, use that info
00764     switch (etype) {
00765       
00766     case RooAbsData::Auto:
00767       throw string(Form("RooDataHist::weightError(%s) weight type Auto not allowed here",GetName())) ;
00768       break ;
00769       
00770     case RooAbsData::Poisson:
00771       // Weight may be preset or precalculated    
00772       if (_curWgtErrLo>=0) {
00773         lo = _curWgtErrLo ;
00774         hi = _curWgtErrHi ;
00775         return ;
00776       }
00777       
00778       // Otherwise Calculate poisson errors
00779       Double_t ym,yp ;  
00780       RooHistError::instance().getPoissonInterval(Int_t(weight()+0.5),ym,yp,1) ;
00781       lo = weight()-ym ;
00782       hi = yp-weight() ;
00783       return ;
00784       
00785     case RooAbsData::SumW2:
00786       lo = _curWgtErr ;
00787       hi = _curWgtErr ;
00788       return ;
00789       
00790     case RooAbsData::None:
00791       lo = 0 ;
00792       hi = 0 ;
00793       return ;
00794     }    
00795     
00796   } else if (_wgtVar) {
00797 
00798     // We have a a weight variable, use that info
00799     if (_wgtVar->hasAsymError()) {
00800       hi = _wgtVar->getAsymErrorHi() ;
00801       lo = _wgtVar->getAsymErrorLo() ;
00802     } else {
00803       hi = _wgtVar->getError() ;
00804       lo = _wgtVar->getError() ;
00805     }  
00806 
00807   } else {
00808 
00809     // We are unweighted
00810     lo=0 ;
00811     hi=0 ;
00812 
00813   }
00814 }
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 //_____________________________________________________________________________
00823 Bool_t RooTreeDataStore::changeObservableName(const char* from, const char* to) 
00824 {
00825   // Change name of internal observable named 'from' into 'to'
00826 
00827   // Find observable to be changed
00828   RooAbsArg* var = _vars.find(from) ;
00829 
00830   // Check that we found it
00831   if (!var) {
00832     coutE(InputArguments) << "RooTreeDataStore::changeObservableName(" << GetName() << " no observable " << from << " in this dataset" << endl ;
00833     return kTRUE ;
00834   }
00835 
00836   // Process name change
00837   TString oldBranchName = var->cleanBranchName() ;
00838   var->SetName(to) ;  
00839 
00840   // Change the branch name as well 
00841   if (_tree->GetBranch(oldBranchName.Data())) {
00842 
00843     // Simple case varName = branchName
00844     _tree->GetBranch(oldBranchName.Data())->SetName(var->cleanBranchName().Data()) ;
00845 
00846     // Process any error branch if existing
00847     if (_tree->GetBranch(Form("%s_err",oldBranchName.Data()))) {
00848       _tree->GetBranch(Form("%s_err",oldBranchName.Data()))->SetName(Form("%s_err",var->cleanBranchName().Data())) ;
00849     }
00850     if (_tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))) {
00851       _tree->GetBranch(Form("%s_aerr_lo",oldBranchName.Data()))->SetName(Form("%s_aerr_lo",var->cleanBranchName().Data())) ;
00852     }
00853     if (_tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))) {
00854       _tree->GetBranch(Form("%s_aerr_hi",oldBranchName.Data()))->SetName(Form("%s_aerr_hi",var->cleanBranchName().Data())) ;
00855     }
00856 
00857   } else {
00858 
00859     // Native category case branchNames = varName_idx and varName_lbl
00860     if (_tree->GetBranch(Form("%s_idx",oldBranchName.Data()))) {
00861       _tree->GetBranch(Form("%s_idx",oldBranchName.Data()))->SetName(Form("%s_idx",var->cleanBranchName().Data())) ;
00862     }
00863     if (_tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))) {
00864       _tree->GetBranch(Form("%s_lbl",oldBranchName.Data()))->SetName(Form("%s_lb",var->cleanBranchName().Data())) ;
00865     }
00866     
00867   }
00868 
00869   return kFALSE ;
00870 }
00871 
00872   
00873 
00874 //_____________________________________________________________________________
00875 RooAbsArg* RooTreeDataStore::addColumn(RooAbsArg& newVar, Bool_t adjustRange)
00876 {
00877   // Add a new column to the data set which holds the pre-calculated values
00878   // of 'newVar'. This operation is only meaningful if 'newVar' is a derived
00879   // value.
00880   //
00881   // The return value points to the added element holding 'newVar's value
00882   // in the data collection. The element is always the corresponding fundamental
00883   // type of 'newVar' (e.g. a RooRealVar if 'newVar' is a RooFormulaVar)
00884   //
00885   // Note: This function is explicitly NOT intended as a speed optimization
00886   //       opportunity for the user. Components of complex PDFs that can be
00887   //       precalculated with the dataset are automatically identified as such
00888   //       and will be precalculated when fitting to a dataset
00889   // 
00890   //       By forcibly precalculating functions with non-trivial Jacobians,
00891   //       or functions of multiple variables occurring in the data set,
00892   //       using addColumn(), you may alter the outcome of the fit. 
00893   //
00894   //       Only in cases where such a modification of fit behaviour is intentional, 
00895   //       this function should be used. 
00896 
00897   checkInit() ;
00898 
00899   // Create a fundamental object of the right type to hold newVar values
00900   RooAbsArg* valHolder= newVar.createFundamental();
00901   // Sanity check that the holder really is fundamental
00902   if(!valHolder->isFundamental()) {
00903     coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
00904          << valHolder->GetName() << "\"" << endl;
00905     return 0;
00906   }
00907 
00908   // Clone variable and attach to cloned tree 
00909   RooAbsArg* newVarClone = newVar.cloneTree() ;
00910   newVarClone->recursiveRedirectServers(_vars,kFALSE) ;
00911 
00912   // Attach value place holder to this tree
00913   ((RooAbsArg*)valHolder)->attachToTree(*_tree,_defTreeBufSize) ;
00914   _vars.add(*valHolder) ;
00915   _varsww.add(*valHolder) ;
00916 
00917   // Fill values of of placeholder
00918   for (int i=0 ; i<GetEntries() ; i++) {
00919     get(i) ;
00920 
00921     newVarClone->syncCache(&_vars) ;
00922     valHolder->copyCache(newVarClone) ;
00923     valHolder->fillTreeBranch(*_tree) ;
00924   }
00925 
00926 
00927   if (adjustRange) {
00928 //     // Set range of valHolder to (just) bracket all values stored in the dataset
00929 //     Double_t vlo,vhi ;
00930 //     RooRealVar* rrvVal = dynamic_cast<RooRealVar*>(valHolder) ;
00931 //     if (rrvVal) {
00932 //       getRange(*rrvVal,vlo,vhi,0.05) ;
00933 //       rrvVal->setRange(vlo,vhi) ;  
00934 //     }
00935   }
00936 
00937   delete newVarClone ;  
00938   return valHolder ;
00939 }
00940 
00941 
00942 
00943 //_____________________________________________________________________________
00944 RooArgSet* RooTreeDataStore::addColumns(const RooArgList& varList)
00945 {
00946   // Utility function to add multiple columns in one call
00947   // See addColumn() for details
00948 
00949   TIterator* vIter = varList.createIterator() ;
00950   RooAbsArg* var ;
00951 
00952   checkInit() ;
00953 
00954   TList cloneSetList ;
00955   RooArgSet cloneSet ;
00956   RooArgSet* holderSet = new RooArgSet ;
00957 
00958   while((var=(RooAbsArg*)vIter->Next())) {
00959     // Create a fundamental object of the right type to hold newVar values
00960     RooAbsArg* valHolder= var->createFundamental();
00961     holderSet->add(*valHolder) ;
00962 
00963     // Sanity check that the holder really is fundamental
00964     if(!valHolder->isFundamental()) {
00965       coutE(InputArguments) << GetName() << "::addColumn: holder argument is not fundamental: \""
00966            << valHolder->GetName() << "\"" << endl;
00967       return 0;
00968     }
00969     
00970     // Clone variable and attach to cloned tree 
00971     RooArgSet* newVarCloneList = (RooArgSet*) RooArgSet(*var).snapshot() ;  
00972     if (!newVarCloneList) {
00973       coutE(InputArguments) << "RooTreeDataStore::RooTreeData(" << GetName() 
00974                             << ") Couldn't deep-clone variable " << var->GetName() << ", abort." << endl ;
00975       return 0 ;
00976     }
00977     RooAbsArg* newVarClone = newVarCloneList->find(var->GetName()) ;   
00978     newVarClone->recursiveRedirectServers(_vars,kFALSE) ;
00979     newVarClone->recursiveRedirectServers(*holderSet,kFALSE) ;
00980 
00981     cloneSetList.Add(newVarCloneList) ;
00982     cloneSet.add(*newVarClone) ;
00983 
00984     // Attach value place holder to this tree
00985     ((RooAbsArg*)valHolder)->attachToTree(*_tree,_defTreeBufSize) ;
00986     _vars.addOwned(*valHolder) ;
00987   }
00988   delete vIter ;
00989 
00990 
00991   TIterator* cIter = cloneSet.createIterator() ;
00992   TIterator* hIter = holderSet->createIterator() ;
00993   RooAbsArg *cloneArg, *holder ;
00994   // Fill values of of placeholder
00995   for (int i=0 ; i<GetEntries() ; i++) {
00996     get(i) ;
00997 
00998     cIter->Reset() ;
00999     hIter->Reset() ;
01000     while((cloneArg=(RooAbsArg*)cIter->Next())) {
01001       holder = (RooAbsArg*)hIter->Next() ;
01002 
01003       cloneArg->syncCache(&_vars) ;
01004       holder->copyCache(cloneArg) ;
01005       holder->fillTreeBranch(*_tree) ;
01006     }
01007   }
01008   
01009   delete cIter ;
01010   delete hIter ;
01011 
01012   cloneSetList.Delete() ;
01013   return holderSet ;
01014 }
01015 
01016 
01017 
01018 
01019 //_____________________________________________________________________________
01020 RooAbsDataStore* RooTreeDataStore::merge(const RooArgSet& allVars, list<RooAbsDataStore*> dstoreList)
01021 {
01022   // Merge columns of supplied data set(s) with this data set.  All
01023   // data sets must have equal number of entries.  In case of
01024   // duplicate columns the column of the last dataset in the list
01025   // prevails
01026     
01027   RooTreeDataStore* mergedStore = new RooTreeDataStore("merged","merged",allVars) ;
01028 
01029   Int_t nevt = dstoreList.front()->numEntries() ;
01030   for (int i=0 ; i<nevt ; i++) {
01031 
01032     // Cope data from self
01033     mergedStore->_vars = *get(i) ;
01034       
01035     // Copy variables from merge sets
01036     for (list<RooAbsDataStore*>::iterator iter = dstoreList.begin() ; iter!=dstoreList.end() ; iter++) {
01037       const RooArgSet* partSet = (*iter)->get(i) ;
01038       mergedStore->_vars = *partSet ;
01039     }
01040 
01041     mergedStore->fill() ;
01042   }
01043   return mergedStore ;
01044 }
01045 
01046 
01047 
01048 
01049 
01050 //_____________________________________________________________________________
01051 void RooTreeDataStore::append(RooAbsDataStore& other) 
01052 {
01053   Int_t nevt = other.numEntries() ;
01054   for (int i=0 ; i<nevt ; i++) {  
01055     _vars = *other.get(i) ;
01056     if (_wgtVar) {
01057       _wgtVar->setVal(other.weight()) ;
01058     }
01059     
01060     fill() ;
01061   }
01062 }
01063 
01064 
01065 
01066 //_____________________________________________________________________________
01067 Int_t RooTreeDataStore::numEntries() const 
01068 {
01069   return _tree->GetEntries() ;
01070 }
01071 
01072 
01073 
01074 //_____________________________________________________________________________
01075 void RooTreeDataStore::reset() 
01076 {
01077   Reset() ;
01078 }
01079 
01080 
01081 
01082 //_____________________________________________________________________________
01083 void RooTreeDataStore::cacheArgs(const RooAbsArg* owner, RooArgSet& newVarSet, const RooArgSet* nset) 
01084 {
01085   // Cache given RooAbsArgs with this tree: The tree is
01086   // given direct write access of the args internal cache
01087   // the args values is pre-calculated for all data points
01088   // in this data collection. Upon a get() call, the
01089   // internal cache of 'newVar' will be loaded with the
01090   // precalculated value and it's dirty flag will be cleared.
01091 
01092   checkInit() ;
01093 
01094   _cacheOwner = owner ;
01095 
01096   TIterator *iter = newVarSet.createIterator() ;
01097   RooAbsArg *arg ;
01098 
01099   Bool_t doTreeFill = (_cachedVars.getSize()==0) ;
01100     
01101   while ((arg=(RooAbsArg*)iter->Next())) {
01102     // Attach original newVar to this tree
01103     arg->attachToTree(*_cacheTree,_defTreeBufSize) ;
01104     arg->redirectServers(_vars) ;
01105     _cachedVars.add(*arg) ;
01106   }
01107   
01108   // Refill regular and cached variables of current tree from clone
01109   for (int i=0 ; i<GetEntries() ; i++) {
01110     get(i) ;
01111     
01112     // Evaluate the cached variables and store the results
01113     iter->Reset() ;
01114     while ((arg=(RooAbsArg*)iter->Next())) {
01115       arg->setValueDirty() ;
01116       arg->syncCache(nset) ;
01117       if (!doTreeFill) {
01118         arg->fillTreeBranch(*_cacheTree) ;
01119       }
01120     }
01121 
01122     if (doTreeFill) {
01123       _cacheTree->Fill() ;
01124     }
01125   }
01126 
01127   delete iter ;
01128 }
01129 
01130 
01131 
01132 
01133 //_____________________________________________________________________________
01134 void RooTreeDataStore::setArgStatus(const RooArgSet& set, Bool_t active) 
01135 {
01136   // Activate or deactivate the branch status of the TTree branch associated
01137   // with the given set of dataset observables
01138 
01139   TIterator* iter = set.createIterator() ;
01140   RooAbsArg* arg ;
01141   while ((arg=(RooAbsArg*)iter->Next())) {
01142     RooAbsArg* depArg = _vars.find(arg->GetName()) ;
01143     if (!depArg) {
01144       coutE(InputArguments) << "RooTreeDataStore::setArgStatus(" << GetName() 
01145                             << ") dataset doesn't contain variable " << arg->GetName() << endl ;
01146       continue ;
01147     }
01148     depArg->setTreeBranchStatus(*_tree,active) ;
01149   }
01150   delete iter ;
01151 }
01152 
01153 
01154 
01155 //_____________________________________________________________________________
01156 void RooTreeDataStore::resetCache() 
01157 {
01158   // Remove tree with values of cached observables
01159   // and clear list of cached observables
01160 
01161   // Empty list of cached functions
01162   _cachedVars.removeAll() ;
01163 
01164   // Delete & recreate cache tree 
01165   delete _cacheTree ;
01166   _cacheTree = 0 ;
01167   createTree(GetName(),GetTitle()) ;
01168 
01169   return ;
01170 }
01171 
01172 
01173 //_____________________________________________________________________________
01174 void RooTreeDataStore::checkInit() const
01175 {
01176   if (_defCtor) {
01177     const_cast<RooTreeDataStore*>(this)->initialize() ;
01178     _defCtor = kFALSE ;    
01179   }
01180 }
01181 
01182 
01183 
01184 
01185 
01186 //_____________________________________________________________________________
01187 Stat_t RooTreeDataStore::GetEntries() const
01188 {
01189    // Interface function to TTree::GetEntries
01190    return _tree->GetEntries() ;
01191 }
01192  
01193 
01194 //_____________________________________________________________________________
01195 void RooTreeDataStore::Reset(Option_t* option)
01196 {
01197    // Interface function to TTree::Reset
01198    _tree->Reset(option) ;
01199 }
01200  
01201 
01202 //_____________________________________________________________________________
01203 Int_t RooTreeDataStore::Fill()
01204 {
01205    // Interface function to TTree::Fill
01206    return _tree->Fill() ;
01207 }
01208  
01209 
01210 //_____________________________________________________________________________
01211 Int_t RooTreeDataStore::GetEntry(Int_t entry, Int_t getall)
01212 {
01213    // Interface function to TTree::GetEntry
01214    Int_t ret1 = _tree->GetEntry(entry,getall) ; 
01215    if (!ret1) return 0 ;
01216    _cacheTree->GetEntry(entry,getall) ; 
01217    return ret1 ;
01218 }
01219 
01220 
01221 //_____________________________________________________________________________
01222 void RooTreeDataStore::Draw(Option_t* option) 
01223 { 
01224   _tree->Draw(option) ; 
01225 }
01226 
01227 //______________________________________________________________________________
01228 void RooTreeDataStore::Streamer(TBuffer &R__b)
01229 {
01230    // Stream an object of class RooTreeDataStore.
01231 
01232    if (R__b.IsReading()) {
01233       R__b.ReadClassBuffer(RooTreeDataStore::Class(),this);
01234       initialize() ;
01235    } else {
01236       R__b.WriteClassBuffer(RooTreeDataStore::Class(),this);
01237    }
01238 }
01239 

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