RooAbsData.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAbsData.cxx 36274 2010-10-11 08:05:03Z 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 // RooAbsData is the common abstract base class for binned and unbinned
00021 // datasets. The abstract interface defines plotting and tabulating entry
00022 // points for its contents and provides an iterator over its elements
00023 // (bins for binned data sets, data points for unbinned datasets).
00024 // END_HTML
00025 //
00026 //
00027 
00028 #include "RooFit.h"
00029 #include "Riostream.h"
00030 
00031 #include "TClass.h"
00032 #include "TMath.h"
00033 
00034 #include "RooAbsData.h"
00035 #include "RooAbsData.h"
00036 #include "RooFormulaVar.h"
00037 #include "RooCmdConfig.h"
00038 #include "RooAbsRealLValue.h"
00039 #include "RooMsgService.h"
00040 #include "RooMultiCategory.h"
00041 #include "Roo1DTable.h"
00042 #include "RooAbsDataStore.h"
00043 
00044 #include "RooRealVar.h"
00045 #include "RooGlobalFunc.h"
00046 #include "RooPlot.h"
00047 #include "RooCurve.h"
00048 #include "RooHist.h"
00049 
00050 #include "TMatrixDSym.h"
00051 #include "TPaveText.h"
00052 #include "TH1.h"
00053 #include "TH2.h"
00054 #include "TH3.h"
00055 
00056 
00057 ClassImp(RooAbsData)
00058 ;
00059 
00060 
00061 //_____________________________________________________________________________
00062 RooAbsData::RooAbsData() 
00063 {
00064   // Default constructor
00065   _dstore = 0 ;
00066   _iterator = _vars.createIterator() ;
00067   _cacheIter = _cachedVars.createIterator() ;
00068 }
00069 
00070 
00071 
00072 //_____________________________________________________________________________
00073 RooAbsData::RooAbsData(const char *name, const char *title, const RooArgSet& vars, RooAbsDataStore* dstore) :
00074   TNamed(name,title), _vars("Dataset Variables"), _cachedVars("Cached Variables"), _dstore(dstore)
00075 {
00076   // Constructor from a set of variables. Only fundamental elements of vars
00077   // (RooRealVar,RooCategory etc) are stored as part of the dataset
00078 
00079   // clone the fundamentals of the given data set into internal buffer
00080   TIterator* iter = vars.createIterator() ;
00081   RooAbsArg *var;
00082   while((0 != (var= (RooAbsArg*)iter->Next()))) {
00083     if (!var->isFundamental()) {
00084       coutE(InputArguments) << "RooAbsDataStore::initialize(" << GetName() 
00085                             << "): Data set cannot contain non-fundamental types, ignoring " 
00086                             << var->GetName() << endl ;
00087     } else {
00088       _vars.addClone(*var);
00089     }
00090   }
00091   delete iter ;
00092 
00093   // reconnect any paramaterized ranges to internal dataset observables
00094   iter = _vars.createIterator() ;
00095   while((0 != (var= (RooAbsArg*)iter->Next()))) {
00096     var->attachDataSet(*this) ;
00097   } 
00098   delete iter ;
00099 
00100   _iterator= _vars.createIterator();
00101   _cacheIter = _cachedVars.createIterator() ;
00102 }
00103 
00104 
00105 
00106 //_____________________________________________________________________________
00107 RooAbsData::RooAbsData(const RooAbsData& other, const char* newname) : 
00108   TNamed(newname?newname:other.GetName(),other.GetTitle()), 
00109   RooPrintable(other), _vars(),
00110   _cachedVars("Cached Variables")
00111 {
00112   // Copy constructor
00113 
00114   _vars.addClone(other._vars) ;
00115 
00116   // reconnect any paramaterized ranges to internal dataset observables
00117   TIterator* iter = _vars.createIterator() ;
00118   RooAbsArg* var ;
00119   while((0 != (var= (RooAbsArg*)iter->Next()))) {
00120     var->attachDataSet(*this) ;
00121   } 
00122   delete iter ;
00123 
00124 
00125   _iterator= _vars.createIterator();
00126   _cacheIter = _cachedVars.createIterator() ;
00127 
00128   _dstore = other._dstore->clone(_vars,newname?newname:other.GetName()) ;
00129   
00130 }
00131 
00132 
00133 
00134 //_____________________________________________________________________________
00135 RooAbsData::~RooAbsData() 
00136 {
00137   // Destructor
00138   
00139   // delete owned contents.
00140   delete _dstore ;
00141   delete _iterator ;
00142   delete _cacheIter ;
00143 }
00144 
00145 
00146 
00147 //_____________________________________________________________________________
00148 Bool_t RooAbsData::changeObservableName(const char* from, const char* to)
00149 {
00150   return _dstore->changeObservableName(from,to) ;
00151 }
00152 
00153 
00154 
00155 
00156 
00157 //_____________________________________________________________________________
00158 void RooAbsData::fill()
00159 {
00160   _dstore->fill() ;
00161 }
00162 
00163 
00164 
00165 
00166 
00167 //_____________________________________________________________________________
00168 Int_t RooAbsData::numEntries() const
00169 {
00170   return _dstore->numEntries() ;
00171 }
00172 
00173 
00174 
00175 
00176 
00177 //_____________________________________________________________________________
00178 void RooAbsData::reset()
00179 {
00180   _dstore->reset() ;
00181 }
00182 
00183 
00184 
00185 
00186 //_____________________________________________________________________________
00187 const RooArgSet* RooAbsData::get(Int_t index) const 
00188 {
00189   checkInit() ;
00190   return _dstore->get(index) ;
00191 }
00192 
00193 
00194 
00195 
00196 //_____________________________________________________________________________
00197 void RooAbsData::cacheArgs(const RooAbsArg* cacheOwner, RooArgSet& varSet, const RooArgSet* nset) 
00198 {
00199   // Internal method -- Cache given set of functions with data
00200   _dstore->cacheArgs(cacheOwner,varSet,nset) ;
00201 }
00202 
00203 
00204 
00205 
00206 
00207 //_____________________________________________________________________________
00208 void RooAbsData::resetCache() 
00209 {
00210   // Internal method -- Remove cached function values
00211   _dstore->resetCache() ;
00212   _cachedVars.removeAll() ;
00213 }
00214 
00215 
00216 
00217 //_____________________________________________________________________________
00218 void RooAbsData::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVars) 
00219 {
00220   // Internal method -- Attach dataset copied with cache contents to copied instances of functions
00221   _dstore->attachCache(newOwner, cachedVars) ;
00222 }
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 //_____________________________________________________________________________
00232 void RooAbsData::setArgStatus(const RooArgSet& set, Bool_t active) 
00233 {
00234   _dstore->setArgStatus(set,active) ;
00235 }
00236 
00237 
00238 
00239 
00240 //_____________________________________________________________________________
00241 void RooAbsData::setDirtyProp(Bool_t flag) 
00242 { 
00243   // Control propagation of dirty flags from observables in dataset
00244   _dstore->setDirtyProp(flag) ; 
00245 }
00246 
00247   
00248 
00249 
00250 
00251 
00252 //_____________________________________________________________________________
00253 RooAbsData* RooAbsData::reduce(const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,const RooCmdArg& arg4,
00254                                const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) 
00255 {
00256   // Create a reduced copy of this dataset. The caller takes ownership of the returned dataset
00257   //
00258   // The following optional named arguments are accepted
00259   //
00260   //   SelectVars(const RooArgSet& vars) -- Only retain the listed observables in the output dataset
00261   //   Cut(const char* expression)       -- Only retain event surviving the given cut expression
00262   //   Cut(const RooFormulaVar& expr)    -- Only retain event surviving the given cut formula
00263   //   CutRange(const char* name)        -- Only retain events inside range with given name. Multiple CutRange
00264   //                                        arguments may be given to select multiple ranges
00265   //   EventRange(int lo, int hi)        -- Only retain events with given sequential event numbers
00266   //   Name(const char* name)            -- Give specified name to output dataset
00267   //   Title(const char* name)           -- Give specified title to output dataset
00268   //
00269 
00270   // Define configuration for this method
00271   RooCmdConfig pc(Form("RooAbsData::reduce(%s)",GetName())) ;
00272   pc.defineString("name","Name",0,"") ;
00273   pc.defineString("title","Title",0,"") ;
00274   pc.defineString("cutRange","CutRange",0,"") ;
00275   pc.defineString("cutSpec","CutSpec",0,"") ;
00276   pc.defineObject("cutVar","CutVar",0,0) ;
00277   pc.defineInt("evtStart","EventRange",0,0) ;
00278   pc.defineInt("evtStop","EventRange",1,2000000000) ;
00279   pc.defineObject("varSel","SelectVars",0,0) ;
00280   pc.defineMutex("CutVar","CutSpec") ;
00281 
00282   // Process & check varargs 
00283   pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
00284   if (!pc.ok(kTRUE)) {
00285     return 0 ;
00286   }
00287 
00288   // Extract values from named arguments
00289   const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
00290   const char* cutSpec = pc.getString("cutSpec",0,kTRUE) ;
00291   RooFormulaVar* cutVar = static_cast<RooFormulaVar*>(pc.getObject("cutVar",0)) ;
00292   Int_t nStart = pc.getInt("evtStart",0) ;
00293   Int_t nStop = pc.getInt("evtStop",2000000000) ;
00294   RooArgSet* varSet = static_cast<RooArgSet*>(pc.getObject("varSel")) ;
00295   const char* name = pc.getString("name",0,kTRUE) ;
00296   const char* title = pc.getString("title",0,kTRUE) ;
00297 
00298   // Make sure varSubset doesn't contain any variable not in this dataset
00299   RooArgSet varSubset ;
00300   if (varSet) {
00301     varSubset.add(*varSet) ;
00302     TIterator* iter = varSubset.createIterator() ;
00303     RooAbsArg* arg ;
00304     while((arg=(RooAbsArg*)iter->Next())) {
00305       if (!_vars.find(arg->GetName())) {
00306         coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable " 
00307                               << arg->GetName() << " not in dataset, ignored" << endl ;
00308         varSubset.remove(*arg) ;
00309       }
00310     }
00311     delete iter ;    
00312   } else {
00313     varSubset.add(*get()) ;
00314   }
00315 
00316   RooAbsData* ret = 0 ;
00317   if (cutSpec) {
00318 
00319     RooFormulaVar cutVarTmp(cutSpec,cutSpec,*get()) ;
00320     ret =  reduceEng(varSubset,&cutVarTmp,cutRange,nStart,nStop,kFALSE) ;      
00321 
00322   } else if (cutVar) {
00323 
00324     ret = reduceEng(varSubset,cutVar,cutRange,nStart,nStop,kFALSE) ;
00325 
00326   } else {
00327 
00328     ret = reduceEng(varSubset,0,cutRange,nStart,nStop,kFALSE) ;
00329 
00330   }
00331   
00332   if (!ret) return 0 ;
00333 
00334   if (name) {
00335     ret->SetName(name) ;
00336   }
00337   if (title) {
00338     ret->SetTitle(title) ;
00339   }
00340 
00341   return ret ;
00342 }
00343 
00344 
00345 
00346 //_____________________________________________________________________________
00347 RooAbsData* RooAbsData::reduce(const char* cut) 
00348 { 
00349   // Create a subset of the data set by applying the given cut on the data points.
00350   // The cut expression can refer to any variable in the data set. For cuts involving 
00351   // other variables, such as intermediate formula objects, use the equivalent 
00352   // reduce method specifying the as a RooFormulVar reference.
00353 
00354   RooFormulaVar cutVar(cut,cut,*get()) ;
00355   return reduceEng(*get(),&cutVar,0,0,2000000000,kFALSE) ;
00356 }
00357 
00358 
00359 
00360 //_____________________________________________________________________________
00361 RooAbsData* RooAbsData::reduce(const RooFormulaVar& cutVar) 
00362 {
00363   // Create a subset of the data set by applying the given cut on the data points.
00364   // The 'cutVar' formula variable is used to select the subset of data points to be 
00365   // retained in the reduced data collection.
00366 
00367   return reduceEng(*get(),&cutVar,0,0,2000000000,kFALSE) ;
00368 }
00369 
00370 
00371 
00372 //_____________________________________________________________________________
00373 RooAbsData* RooAbsData::reduce(const RooArgSet& varSubset, const char* cut) 
00374 {
00375   // Create a subset of the data set by applying the given cut on the data points
00376   // and reducing the dimensions to the specified set.
00377   // 
00378   // The cut expression can refer to any variable in the data set. For cuts involving 
00379   // other variables, such as intermediate formula objects, use the equivalent 
00380   // reduce method specifying the as a RooFormulVar reference.
00381 
00382   // Make sure varSubset doesn't contain any variable not in this dataset
00383   RooArgSet varSubset2(varSubset) ;
00384   TIterator* iter = varSubset.createIterator() ;
00385   RooAbsArg* arg ;
00386   while((arg=(RooAbsArg*)iter->Next())) {
00387     if (!_vars.find(arg->GetName())) {
00388       coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable " 
00389                             << arg->GetName() << " not in dataset, ignored" << endl ;
00390       varSubset2.remove(*arg) ;
00391     }
00392   }
00393   delete iter ;
00394 
00395   if (cut && strlen(cut)>0) {
00396     RooFormulaVar cutVar(cut,cut,*get()) ;
00397     return reduceEng(varSubset2,&cutVar,0,0,2000000000,kFALSE) ;      
00398   } 
00399   return reduceEng(varSubset2,0,0,0,2000000000,kFALSE) ;
00400 }
00401 
00402 
00403 
00404 //_____________________________________________________________________________
00405 RooAbsData* RooAbsData::reduce(const RooArgSet& varSubset, const RooFormulaVar& cutVar) 
00406 {
00407   // Create a subset of the data set by applying the given cut on the data points
00408   // and reducing the dimensions to the specified set.
00409   // 
00410   // The 'cutVar' formula variable is used to select the subset of data points to be 
00411   // retained in the reduced data collection.
00412 
00413   // Make sure varSubset doesn't contain any variable not in this dataset
00414   RooArgSet varSubset2(varSubset) ;
00415   TIterator* iter = varSubset.createIterator() ;
00416   RooAbsArg* arg ;
00417   while((arg=(RooAbsArg*)iter->Next())) {
00418     if (!_vars.find(arg->GetName())) {
00419       coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable " 
00420                             << arg->GetName() << " not in dataset, ignored" << endl ;
00421       varSubset2.remove(*arg) ;
00422     }
00423   }
00424   delete iter ;
00425 
00426   return reduceEng(varSubset2,&cutVar,0,0,2000000000,kFALSE) ;
00427 }
00428 
00429 
00430 
00431 //_____________________________________________________________________________
00432 Double_t RooAbsData::weightError(ErrorType) const 
00433 { 
00434   // Return error on current weight (dummy implementation returning zero)
00435   return 0 ; 
00436 } 
00437 
00438 
00439 
00440 //_____________________________________________________________________________
00441 void RooAbsData::weightError(Double_t& lo, Double_t& hi, ErrorType) const 
00442 { 
00443   // Return asymmetric error on weight. (Dummy implementation returning zero)
00444   lo=0 ; hi=0 ; 
00445 } 
00446 
00447 
00448 
00449 //_____________________________________________________________________________
00450 RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
00451                             const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5, 
00452                             const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
00453 {
00454   // Plot dataset on specified frame. By default an unbinned dataset will use the default binning of
00455   // the target frame. A binned dataset will by default retain its intrinsic binning.
00456   //
00457   // The following optional named arguments can be used to modify the default behavior
00458   //
00459   // Data representation options
00460   // ---------------------------
00461   // Asymmetry(const RooCategory& c) -- Show the asymmetry of the daya in given two-state category [F(+)-F(-)] / [F(+)+F(-)]. 
00462   //                                    Category must have two states with indices -1 and +1 or three states with indeces -1,0 and +1.
00463   // DataError(RooAbsData::EType)    -- Select the type of error drawn: Poisson (default) draws asymmetric Poisson
00464   //                                    confidence intervals. SumW2 draws symmetric sum-of-weights error
00465   // Binning(double xlo, double xhi, -- Use specified binning to draw dataset
00466   //                      int nbins)
00467   // Binning(const RooAbsBinning&)   -- Use specified binning to draw dataset
00468   // Binning(const char* name)       -- Use binning with specified name to draw dataset
00469   // RefreshNorm(Bool_t flag)        -- Force refreshing for PDF normalization information in frame.
00470   //                                    If set, any subsequent PDF will normalize to this dataset, even if it is
00471   //                                    not the first one added to the frame. By default only the 1st dataset
00472   //                                    added to a frame will update the normalization information
00473   // Rescale(Double_t factor)        -- Apply global rescaling factor to histogram
00474   //
00475   // Histogram drawing options
00476   // -------------------------
00477   // DrawOption(const char* opt)     -- Select ROOT draw option for resulting TGraph object
00478   // LineStyle(Int_t style)          -- Select line style by ROOT line style code, default is solid
00479   // LineColor(Int_t color)          -- Select line color by ROOT color code, default is black
00480   // LineWidth(Int_t width)          -- Select line with in pixels, default is 3
00481   // MarkerStyle(Int_t style)        -- Select the ROOT marker style, default is 21
00482   // MarkerColor(Int_t color)        -- Select the ROOT marker color, default is black
00483   // MarkerSize(Double_t size)       -- Select the ROOT marker size
00484   // XErrorSize(Double_t frac)       -- Select size of X error bar as fraction of the bin width, default is 1
00485   //
00486   //
00487   // Misc. other options
00488   // -------------------
00489   // Name(const chat* name)          -- Give curve specified name in frame. Useful if curve is to be referenced later
00490   // Invisble(Bool_t flag)           -- Add curve to frame, but do not display. Useful in combination AddTo()
00491   // AddTo(const char* name,         -- Add constructed histogram to already existing histogram with given name and relative weight factors
00492   // double_t wgtSelf, double_t wgtOther)
00493   // 
00494   //                                    
00495   RooLinkedList l ;
00496   l.Add((TObject*)&arg1) ;  l.Add((TObject*)&arg2) ;  
00497   l.Add((TObject*)&arg3) ;  l.Add((TObject*)&arg4) ;
00498   l.Add((TObject*)&arg5) ;  l.Add((TObject*)&arg6) ;  
00499   l.Add((TObject*)&arg7) ;  l.Add((TObject*)&arg8) ;
00500   return plotOn(frame,l) ;  
00501 }
00502 
00503 
00504 
00505 
00506 //_____________________________________________________________________________
00507 TH1 *RooAbsData::createHistogram(const char* varNameList, Int_t xbins, Int_t ybins, Int_t zbins) const
00508 {
00509   // Create and fill a ROOT histogram TH1,TH2 or TH3 with the values of this dataset for the variables with given names
00510   // The range of each observable that is histogrammed is always automatically calculated from the distribution in
00511   // the dataset. The number of bins can be controlled using the [xyz]bins parameters. For a greater degree of control
00512   // use the createHistogram() method below with named arguments
00513   //
00514   // The caller takes ownership of the returned histogram
00515 
00516   // Parse list of variable names
00517   char buf[1024] ;
00518   strlcpy(buf,varNameList,1024) ;
00519   char* varName = strtok(buf,",:") ;
00520   
00521   RooRealVar* xvar = (RooRealVar*) get()->find(varName) ;
00522   if (!xvar) {
00523     coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
00524     return 0 ;
00525   }
00526   varName = strtok(0,",") ; 
00527   RooRealVar* yvar = varName ? (RooRealVar*) get()->find(varName) : 0 ;
00528   if (varName && !yvar) {
00529     coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
00530     return 0 ;
00531   }
00532   varName = strtok(0,",") ;  
00533   RooRealVar* zvar = varName ? (RooRealVar*) get()->find(varName) : 0 ;
00534   if (varName && !zvar) {
00535     coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
00536     return 0 ;
00537   }
00538 
00539   // Construct list of named arguments to pass to the implementation version of createHistogram()
00540 
00541   RooLinkedList argList ; 
00542   if (xbins<=0  || !xvar->hasMax() || !xvar->hasMin() ) {
00543     argList.Add(RooFit::AutoBinning(xbins==0?xvar->numBins():abs(xbins)).Clone()) ;
00544   } else {
00545     argList.Add(RooFit::Binning(xbins).Clone()) ;
00546   }
00547  
00548   if (yvar) {        
00549     if (ybins<=0 || !yvar->hasMax() || !yvar->hasMin() ) {
00550       argList.Add(RooFit::YVar(*yvar,RooFit::AutoBinning(ybins==0?yvar->numBins():abs(ybins))).Clone()) ;
00551     } else {
00552       argList.Add(RooFit::YVar(*yvar,RooFit::Binning(ybins)).Clone()) ;
00553     }
00554   }
00555 
00556   if (zvar) {    
00557     if (zbins<=0 || !zvar->hasMax() || !zvar->hasMin() ) {
00558       argList.Add(RooFit::ZVar(*zvar,RooFit::AutoBinning(zbins==0?zvar->numBins():abs(zbins))).Clone()) ;
00559     } else {
00560       argList.Add(RooFit::ZVar(*zvar,RooFit::Binning(zbins)).Clone()) ;
00561     }
00562   }
00563 
00564 
00565 
00566   // Call implementation function
00567   TH1* result = createHistogram(GetName(),*xvar,argList) ;
00568 
00569   // Delete temporary list of RooCmdArgs 
00570   argList.Delete() ;
00571 
00572   return result ;
00573 }
00574 
00575 
00576 
00577 //_____________________________________________________________________________
00578 TH1 *RooAbsData::createHistogram(const char *name, const RooAbsRealLValue& xvar,
00579                                  const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
00580                                  const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const 
00581 {
00582   // Create and fill a ROOT histogram TH1,TH2 or TH3 with the values of this dataset. 
00583   //
00584   // This function accepts the following arguments
00585   //
00586   // name -- Name of the ROOT histogram
00587   // xvar -- Observable to be mapped on x axis of ROOT histogram
00588   //
00589   // AutoBinning(Int_t nbins, Double_y margin)    -- Automatically calculate range with given added fractional margin, set binning to nbins
00590   // AutoSymBinning(Int_t nbins, Double_y margin) -- Automatically calculate range with given added fractional margin, 
00591   //                                                 with additional constraint that mean of data is in center of range, set binning to nbins
00592   // Binning(const char* name)                    -- Apply binning with given name to x axis of histogram
00593   // Binning(RooAbsBinning& binning)              -- Apply specified binning to x axis of histogram
00594   // Binning(int nbins, double lo, double hi)     -- Apply specified binning to x axis of histogram
00595   //
00596   // YVar(const RooAbsRealLValue& var,...)    -- Observable to be mapped on y axis of ROOT histogram
00597   // ZVar(const RooAbsRealLValue& var,...)    -- Observable to be mapped on z axis of ROOT histogram
00598   //
00599   // The YVar() and ZVar() arguments can be supplied with optional Binning() Auto(Sym)Range() arguments to control the binning of the Y and Z axes, e.g.
00600   // createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
00601   //
00602   // The caller takes ownership of the returned histogram
00603 
00604   RooLinkedList l ;
00605   l.Add((TObject*)&arg1) ;  l.Add((TObject*)&arg2) ;  
00606   l.Add((TObject*)&arg3) ;  l.Add((TObject*)&arg4) ;
00607   l.Add((TObject*)&arg5) ;  l.Add((TObject*)&arg6) ;  
00608   l.Add((TObject*)&arg7) ;  l.Add((TObject*)&arg8) ;
00609 
00610   return createHistogram(name,xvar,l) ;
00611 }
00612 
00613 
00614 //_____________________________________________________________________________
00615 TH1 *RooAbsData::createHistogram(const char *name, const RooAbsRealLValue& xvar, const RooLinkedList& argListIn) const
00616 {
00617   // Internal method that implements histogram filling
00618   RooLinkedList argList(argListIn) ;
00619   
00620   // Define configuration for this method
00621   RooCmdConfig pc(Form("RooAbsData::createHistogram(%s)",GetName())) ;
00622   pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
00623   pc.defineString("cutString","CutSpec",0,"") ;
00624   pc.defineObject("yvar","YVar",0,0) ;
00625   pc.defineObject("zvar","ZVar",0,0) ;
00626   pc.allowUndefined() ;
00627   
00628   // Process & check varargs 
00629   pc.process(argList) ;
00630   if (!pc.ok(kTRUE)) {
00631     return 0 ;
00632   }
00633 
00634   const char* cutSpec = pc.getString("cutString",0,kTRUE) ;
00635   const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
00636 
00637   RooArgList vars(xvar) ;
00638   RooAbsArg* yvar = static_cast<RooAbsArg*>(pc.getObject("yvar")) ;
00639   if (yvar) {
00640     vars.add(*yvar) ;
00641   }
00642   RooAbsArg* zvar = static_cast<RooAbsArg*>(pc.getObject("zvar")) ;
00643   if (zvar) {
00644     vars.add(*zvar) ;
00645   }
00646 
00647   pc.stripCmdList(argList,"CutRange,CutSpec") ;
00648 
00649   // Swap Auto(Sym)RangeData with a Binning command
00650   RooLinkedList ownedCmds ;
00651   RooCmdArg* autoRD = (RooCmdArg*) argList.find("AutoRangeData") ;
00652   if (autoRD) {
00653     Double_t xmin,xmax ;
00654     getRange((RooRealVar&)xvar,xmin,xmax,autoRD->getDouble(0),autoRD->getInt(0)) ;
00655     RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRD->getInt(1),xmin,xmax).Clone() ;
00656     ownedCmds.Add(bincmd) ;
00657     argList.Replace(autoRD,bincmd) ;
00658   }
00659 
00660   if (yvar) {
00661     RooCmdArg* autoRDY = (RooCmdArg*) ((RooCmdArg*)argList.find("YVar"))->subArgs().find("AutoRangeData") ;
00662     if (autoRDY) {
00663       Double_t ymin,ymax ;
00664       getRange((RooRealVar&)(*yvar),ymin,ymax,autoRDY->getDouble(0),autoRDY->getInt(0)) ;
00665       RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRDY->getInt(1),ymin,ymax).Clone() ;
00666       //ownedCmds.Add(bincmd) ;
00667       ((RooCmdArg*)argList.find("YVar"))->subArgs().Replace(autoRDY,bincmd) ;
00668       delete autoRDY ;
00669     }
00670   }
00671 
00672   if (zvar) {
00673     RooCmdArg* autoRDZ = (RooCmdArg*) ((RooCmdArg*)argList.find("ZVar"))->subArgs().find("AutoRangeData") ;
00674     if (autoRDZ) {
00675       Double_t zmin,zmax ;
00676       getRange((RooRealVar&)(*zvar),zmin,zmax,autoRDZ->getDouble(0),autoRDZ->getInt(0)) ;
00677       RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRDZ->getInt(1),zmin,zmax).Clone() ;
00678       //ownedCmds.Add(bincmd) ;
00679       ((RooCmdArg*)argList.find("ZVar"))->subArgs().Replace(autoRDZ,bincmd) ;
00680       delete autoRDZ ;
00681     }
00682   }
00683 
00684 
00685   TH1* histo = xvar.createHistogram(name,argList) ;
00686   fillHistogram(histo,vars,cutSpec,cutRange) ;
00687 
00688   ownedCmds.Delete() ;
00689 
00690   return histo ;
00691 }
00692 
00693 
00694 
00695 
00696 //_____________________________________________________________________________
00697 Roo1DTable* RooAbsData::table(const RooArgSet& catSet, const char* cuts, const char* opts) const 
00698 {
00699   // Construct table for product of categories in catSet
00700   RooArgSet catSet2 ;
00701 
00702   string prodName("(") ;
00703   TIterator* iter = catSet.createIterator() ;
00704   RooAbsArg* arg ;
00705   while((arg=(RooAbsArg*)iter->Next())) {
00706     if (dynamic_cast<RooAbsCategory*>(arg)) {
00707       catSet2.add(*arg) ;
00708       if (prodName.length()>1) {
00709         prodName += " x " ;
00710       }
00711       prodName += arg->GetName() ;
00712     } else {
00713       coutW(InputArguments) << "RooAbsData::table(" << GetName() << ") non-RooAbsCategory input argument " << arg->GetName() << " ignored" << endl ;
00714     }
00715   }
00716   prodName += ")" ;
00717   delete iter ;
00718 
00719   RooMultiCategory tmp(prodName.c_str(),prodName.c_str(),catSet2) ;
00720   return table(tmp,cuts,opts) ;
00721 }
00722 
00723 
00724 
00725 
00726 //_____________________________________________________________________________
00727 void RooAbsData::printName(ostream& os) const 
00728 {
00729   // Print name of dataset
00730 
00731   os << GetName() ;
00732 }
00733 
00734 
00735 
00736 //_____________________________________________________________________________
00737 void RooAbsData::printTitle(ostream& os) const 
00738 {
00739   // Print title of dataset
00740   os << GetTitle() ;
00741 }
00742 
00743 
00744 
00745 //_____________________________________________________________________________
00746 void RooAbsData::printClassName(ostream& os) const 
00747 {
00748   // Print class name of dataset
00749   os << IsA()->GetName() ;
00750 }
00751 
00752 
00753 
00754 //_____________________________________________________________________________
00755 void RooAbsData::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
00756 {
00757   _dstore->printMultiline(os,contents,verbose,indent) ;
00758 }
00759 
00760 
00761 
00762 
00763 //_____________________________________________________________________________
00764 Int_t RooAbsData::defaultPrintContents(Option_t* /*opt*/) const 
00765 {
00766   // Define default print options, for a given print style
00767 
00768   return kName|kClassName|kArgs|kValue ;
00769 }
00770 
00771 
00772 
00773 //_____________________________________________________________________________
00774 Double_t RooAbsData::standMoment(RooRealVar &var, Double_t order, const char* cutSpec, const char* cutRange) const 
00775 {
00776   // Calculate standardized moment < (X - <X>)^n > / sigma^n,  where n = order.
00777   // 
00778   // If cutSpec and/or cutRange are specified
00779   // the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
00780   // and/or are inside the range named 'cutRange'
00781 
00782   // Hardwire invariant answer for first and second moment
00783   if (order==1) return 0 ;
00784   if (order==2) return 1 ;
00785 
00786   return moment(var,order,cutSpec,cutRange) / TMath::Power(sigma(var,cutSpec,cutRange),order) ; 
00787 }
00788 
00789 
00790 
00791 //_____________________________________________________________________________
00792 Double_t RooAbsData::moment(RooRealVar &var, Double_t order, const char* cutSpec, const char* cutRange) const 
00793 {
00794   // Calculate moment < (X - <X>)^n > where n = order.
00795   // 
00796   // If cutSpec and/or cutRange are specified
00797   // the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
00798   // and/or are inside the range named 'cutRange'
00799 
00800   Double_t offset = order>1 ? moment(var,1,cutSpec,cutRange) : 0 ;
00801   return moment(var,order,offset,cutSpec,cutRange) ;
00802 
00803 }
00804 
00805 
00806 
00807 
00808 
00809 //_____________________________________________________________________________
00810 Double_t RooAbsData::moment(RooRealVar &var, Double_t order, Double_t offset, const char* cutSpec, const char* cutRange) const
00811 {
00812   // Return the 'order'-ed moment of observable 'var' in this dataset. If offset is non-zero it is subtracted
00813   // from the values of 'var' prior to the moment calculation. If cutSpec and/or cutRange are specified
00814   // the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
00815   // and/or are inside the range named 'cutRange'
00816 
00817   // Lookup variable in dataset
00818   RooRealVar *varPtr= (RooRealVar*) _vars.find(var.GetName());
00819   if(0 == varPtr) {
00820     coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << endl ;
00821     return 0;
00822   }
00823 
00824   // Check if found variable is of type RooRealVar
00825   if (!dynamic_cast<RooRealVar*>(varPtr)) {
00826     coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << endl ;
00827     return 0;
00828   }
00829 
00830   // Check if dataset is not empty
00831   if(sumEntries() == 0.) {
00832     coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") WARNING: empty dataset" << endl ;
00833     return 0;
00834   }
00835 
00836   // Setup RooFormulaVar for cutSpec if it is present
00837   RooFormula* select = 0 ;
00838   if (cutSpec) {
00839     select = new RooFormula("select",cutSpec,*get()) ;
00840   }
00841 
00842 
00843   // Calculate requested moment
00844   Double_t sum(0);
00845   const RooArgSet* vars ;
00846   for(Int_t index= 0; index < numEntries(); index++) {
00847     vars = get(index) ;
00848     if (select && select->eval()==0) continue ;
00849     if (cutRange && vars->allInRange(cutRange)) continue ;
00850     
00851     sum+= weight() * TMath::Power(varPtr->getVal() - offset,order);
00852   }
00853   return sum/sumEntries();
00854 }
00855 
00856 
00857 
00858 
00859 //_____________________________________________________________________________
00860 RooRealVar* RooAbsData::dataRealVar(const char* methodname, RooRealVar& extVar) const 
00861 {
00862   // Internal method to check if given RooRealVar maps to a RooRealVar in this dataset
00863 
00864   // Lookup variable in dataset
00865   RooRealVar *xdata = (RooRealVar*) _vars.find(extVar.GetName());
00866   if(!xdata) {
00867     coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not in data" << endl ;
00868     return 0;
00869   }
00870   // Check if found variable is of type RooRealVar
00871   if (!dynamic_cast<RooRealVar*>(xdata)) {
00872     coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not of type RooRealVar in data" << endl ;
00873     return 0;
00874   }
00875   return xdata;
00876 }
00877 
00878 
00879 //_____________________________________________________________________________
00880 Double_t RooAbsData::corrcov(RooRealVar &x,RooRealVar &y, const char* cutSpec, const char* cutRange, Bool_t corr) const 
00881 {
00882   // Internal method to calculate single correlation and covariance elements
00883 
00884   // Lookup variable in dataset
00885   RooRealVar *xdata = dataRealVar(corr?"correlation":"covariance",x) ;
00886   RooRealVar *ydata = dataRealVar(corr?"correlation":"covariance",y) ;
00887   if (!xdata||!ydata) return 0 ;
00888 
00889   // Check if dataset is not empty
00890   if(sumEntries() == 0.) {
00891     coutW(InputArguments) << "RooDataSet::" << (corr?"correlation":"covariance") << "(" << GetName() << ") WARNING: empty dataset, returning zero" << endl ;
00892     return 0;
00893   }
00894 
00895   // Setup RooFormulaVar for cutSpec if it is present
00896   RooFormula* select = cutSpec ? new RooFormula("select",cutSpec,*get()) : 0 ;
00897 
00898   // Calculate requested moment
00899   Double_t xysum(0),xsum(0),ysum(0),x2sum(0),y2sum(0);
00900   const RooArgSet* vars ;
00901   for(Int_t index= 0; index < numEntries(); index++) {
00902     vars = get(index) ;
00903     if (select && select->eval()==0) continue ;
00904     if (cutRange && vars->allInRange(cutRange)) continue ;
00905 
00906     xysum += weight()*xdata->getVal()*ydata->getVal() ;
00907     xsum += weight()*xdata->getVal() ;
00908     ysum += weight()*ydata->getVal() ;
00909     if (corr) {
00910       x2sum += weight()*xdata->getVal()*xdata->getVal() ;
00911       y2sum += weight()*ydata->getVal()*ydata->getVal() ;
00912     }
00913   }
00914 
00915   // Normalize entries
00916   xysum/=sumEntries() ;
00917   xsum/=sumEntries() ;
00918   ysum/=sumEntries() ;
00919   if (corr) {
00920     x2sum/=sumEntries() ;
00921     y2sum/=sumEntries() ;
00922   }
00923 
00924   // Cleanup
00925   if (select) delete select ;
00926 
00927   // Return covariance or correlation as requested
00928   if (corr) {
00929     return (xysum-xsum*ysum)/(sqrt(x2sum-(xsum*xsum))*sqrt(y2sum-(ysum*ysum))) ;
00930   } else {
00931     return (xysum-xsum*ysum);
00932   }
00933 }
00934 
00935 
00936 
00937 //_____________________________________________________________________________
00938 TMatrixDSym* RooAbsData::corrcovMatrix(const RooArgList& vars, const char* cutSpec, const char* cutRange, Bool_t corr) const 
00939 {
00940   // Return covariance matrix from data for given list of observables
00941 
00942   RooArgList varList ;
00943   TIterator* iter = vars.createIterator() ;
00944   RooRealVar* var ;
00945   while((var=(RooRealVar*)iter->Next())) {
00946     RooRealVar* datavar = dataRealVar("covarianceMatrix",*var) ;
00947     if (!datavar) {
00948       delete iter ;
00949       return 0 ;
00950     } 
00951     varList.add(*datavar) ;
00952   }
00953   delete iter ;
00954 
00955 
00956   // Check if dataset is not empty
00957   if(sumEntries() == 0.) {
00958     coutW(InputArguments) << "RooDataSet::covariance(" << GetName() << ") WARNING: empty dataset, returning zero" << endl ;
00959     return 0;
00960   }
00961 
00962   // Setup RooFormulaVar for cutSpec if it is present
00963   RooFormula* select = cutSpec ? new RooFormula("select",cutSpec,*get()) : 0 ;
00964 
00965   iter = varList.createIterator() ;
00966   TIterator* iter2 = varList.createIterator() ;
00967 
00968   TMatrixDSym xysum(varList.getSize()) ;
00969   vector<double> xsum(varList.getSize()) ;
00970   vector<double> x2sum(varList.getSize()) ;
00971 
00972   // Calculate <x_i> and <x_i y_j>
00973   for(Int_t index= 0; index < numEntries(); index++) {
00974     const RooArgSet* dvars = get(index) ;
00975     if (select && select->eval()==0) continue ;
00976     if (cutRange && dvars->allInRange(cutRange)) continue ;
00977 
00978     RooRealVar* varx, *vary ;
00979     iter->Reset() ;
00980     Int_t ix=0,iy=0 ;
00981     while((varx=(RooRealVar*)iter->Next())) {
00982       xsum[ix] += weight()*varx->getVal() ;
00983       if (corr) {
00984         x2sum[ix] += weight()*varx->getVal()*varx->getVal() ;
00985       } 
00986 
00987       *iter2=*iter ; iy=ix ;
00988       vary=varx ;
00989       while(vary) {
00990         xysum(ix,iy) += weight()*varx->getVal()*vary->getVal() ;
00991         xysum(iy,ix) = xysum(ix,iy) ;
00992         iy++ ;
00993         vary=(RooRealVar*)iter2->Next() ;
00994       }
00995       ix++ ;
00996     }
00997     
00998   }
00999 
01000   // Normalize sums 
01001   for (Int_t ix=0 ; ix<varList.getSize() ; ix++) {
01002     xsum[ix] /= sumEntries() ;
01003     if (corr) {
01004       x2sum[ix] /= sumEntries() ;
01005     }
01006     for (Int_t iy=0 ; iy<varList.getSize() ; iy++) {      
01007       xysum(ix,iy) /= sumEntries() ;
01008     }
01009   }    
01010 
01011   // Calculate covariance matrix
01012   TMatrixDSym* C = new TMatrixDSym(varList.getSize()) ;
01013   for (Int_t ix=0 ; ix<varList.getSize() ; ix++) {
01014     for (Int_t iy=0 ; iy<varList.getSize() ; iy++) {      
01015       (*C)(ix,iy) = xysum(ix,iy)-xsum[ix]*xsum[iy] ;
01016       if (corr) {
01017         (*C)(ix,iy) /= sqrt((x2sum[ix]-(xsum[ix]*xsum[ix]))*(x2sum[iy]-(xsum[iy]*xsum[iy]))) ;
01018       }
01019     }    
01020   }
01021 
01022   if (select) delete select ;
01023   delete iter ;
01024   delete iter2 ;
01025 
01026   return C ;
01027 }
01028 
01029 
01030 
01031 //_____________________________________________________________________________
01032 RooRealVar* RooAbsData::meanVar(RooRealVar &var, const char* cutSpec, const char* cutRange) const
01033 {
01034   // Create a RooRealVar containing the mean of observable 'var' in
01035   // this dataset.  If cutSpec and/or cutRange are specified the
01036   // moment is calculated on the subset of the data which pass the C++
01037   // cut specification expression 'cutSpec' and/or are inside the
01038   // range named 'cutRange'
01039   
01040   // Create a new variable with appropriate strings. The error is calculated as
01041   // RMS/Sqrt(N) which is generally valid.
01042 
01043   // Create holder variable for mean
01044   TString name(var.GetName()),title("Mean of ") ;
01045   name.Append("Mean");
01046   title.Append(var.GetTitle());
01047   RooRealVar *meanv= new RooRealVar(name,title,0) ;
01048   meanv->setConstant(kFALSE) ;
01049 
01050   // Adjust plot label
01051   TString label("<") ;
01052   label.Append(var.getPlotLabel());
01053   label.Append(">");
01054   meanv->setPlotLabel(label.Data());
01055 
01056   // fill in this variable's value and error
01057   Double_t meanVal=moment(var,1,0,cutSpec,cutRange) ;
01058   Double_t N(sumEntries(cutSpec,cutRange)) ;
01059 
01060   Double_t rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
01061   meanv->setVal(meanVal) ;
01062   meanv->setError(N > 0 ? rmsVal/sqrt(N) : 0);
01063 
01064   return meanv;
01065 }
01066 
01067 
01068 
01069 //_____________________________________________________________________________
01070 RooRealVar* RooAbsData::rmsVar(RooRealVar &var, const char* cutSpec, const char* cutRange) const
01071 {
01072   // Create a RooRealVar containing the RMS of observable 'var' in
01073   // this dataset.  If cutSpec and/or cutRange are specified the
01074   // moment is calculated on the subset of the data which pass the C++
01075   // cut specification expression 'cutSpec' and/or are inside the
01076   // range named 'cutRange'
01077 
01078   // Create a new variable with appropriate strings. The error is calculated as
01079   // RMS/(2*Sqrt(N)) which is only valid if the variable has a Gaussian distribution.
01080 
01081   // Create RMS value holder
01082   TString name(var.GetName()),title("RMS of ") ;
01083   name.Append("RMS");
01084   title.Append(var.GetTitle());
01085   RooRealVar *rms= new RooRealVar(name,title,0) ;
01086   rms->setConstant(kFALSE) ;
01087 
01088   // Adjust plot label
01089   TString label(var.getPlotLabel());
01090   label.Append("_{RMS}");
01091   rms->setPlotLabel(label);
01092 
01093   // Fill in this variable's value and error
01094   Double_t meanVal(moment(var,1,0,cutSpec,cutRange)) ;
01095   Double_t N(sumEntries());
01096   Double_t rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
01097   rms->setVal(rmsVal) ;
01098   rms->setError(rmsVal/sqrt(2*N));
01099 
01100   return rms;
01101 }
01102 
01103 
01104 //_____________________________________________________________________________
01105 RooPlot* RooAbsData::statOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2, 
01106                             const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5, 
01107                             const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
01108 {
01109   // Add a box with statistics information to the specified frame. By default a box with the
01110   // event count, mean and rms of the plotted variable is added.
01111   //
01112   // The following optional named arguments are accepted
01113   //
01114   //   What(const char* whatstr)          -- Controls what is printed: "N" = count, "M" is mean, "R" is RMS.
01115   //   Format(const char* optStr)         -- Classing [arameter formatting options, provided for backward compatibility
01116   //   Format(const char* what,...)       -- Parameter formatting options, details given below
01117   //   Label(const chat* label)           -- Add header label to parameter box
01118   //   Layout(Double_t xmin,              -- Specify relative position of left,right side of box and top of box. Position of 
01119   //       Double_t xmax, Double_t ymax)     bottom of box is calculated automatically from number lines in box
01120   //   Cut(const char* expression)        -- Apply given cut expression to data when calculating statistics
01121   //   CutRange(const char* rangeName)    -- Only consider events within given range when calculating statistics. Multiple
01122   //                                         CutRange() argument may be specified to combine ranges
01123   //
01124   // The Format(const char* what,...) has the following structure
01125   //
01126   //   const char* what          -- Controls what is shown. "N" adds name, "E" adds error, 
01127   //                                "A" shows asymmetric error, "U" shows unit, "H" hides the value
01128   //   FixedPrecision(int n)     -- Controls precision, set fixed number of digits
01129   //   AutoPrecision(int n)      -- Controls precision. Number of shown digits is calculated from error 
01130   //                                + n specified additional digits (1 is sensible default)
01131   //   VerbatimName(Bool_t flag) -- Put variable name in a \verb+   + clause.
01132   //
01133 
01134   // Stuff all arguments in a list
01135   RooLinkedList cmdList;
01136   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
01137   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
01138   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
01139   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
01140 
01141   // Select the pdf-specific commands 
01142   RooCmdConfig pc(Form("RooTreeData::statOn(%s)",GetName())) ;
01143   pc.defineString("what","What",0,"MNR") ;
01144   pc.defineString("label","Label",0,"") ;
01145   pc.defineDouble("xmin","Layout",0,0.65) ;
01146   pc.defineDouble("xmax","Layout",1,0.99) ;
01147   pc.defineInt("ymaxi","Layout",0,Int_t(0.95*10000)) ;
01148   pc.defineString("formatStr","Format",0,"NELU") ;
01149   pc.defineInt("sigDigit","Format",0,2) ;
01150   pc.defineInt("dummy","FormatArgs",0,0) ;
01151   pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
01152   pc.defineString("cutString","CutSpec",0,"") ;
01153   pc.defineMutex("Format","FormatArgs") ;
01154 
01155   // Process and check varargs 
01156   pc.process(cmdList) ;
01157   if (!pc.ok(kTRUE)) {
01158     return frame ;
01159   }
01160 
01161   const char* label = pc.getString("label") ;
01162   Double_t xmin = pc.getDouble("xmin") ;
01163   Double_t xmax = pc.getDouble("xmax") ;
01164   Double_t ymax = pc.getInt("ymaxi") / 10000. ;
01165   const char* formatStr = pc.getString("formatStr") ;
01166   Int_t sigDigit = pc.getInt("sigDigit") ;  
01167   const char* what = pc.getString("what") ;
01168 
01169   const char* cutSpec = pc.getString("cutString",0,kTRUE) ;
01170   const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
01171 
01172   if (pc.hasProcessed("FormatArgs")) {
01173     RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
01174     return statOn(frame,what,label,0,0,xmin,xmax,ymax,cutSpec,cutRange,formatCmd) ;
01175   } else {
01176     return statOn(frame,what,label,sigDigit,formatStr,xmin,xmax,ymax,cutSpec,cutRange) ;
01177   }
01178 }
01179 
01180 
01181 
01182 //_____________________________________________________________________________
01183 RooPlot* RooAbsData::statOn(RooPlot* frame, const char* what, const char *label, Int_t sigDigits,
01184                              Option_t *options, Double_t xmin, Double_t xmax, Double_t ymax, 
01185                              const char* cutSpec, const char* cutRange, const RooCmdArg* formatCmd) 
01186 {
01187   // Implementation back-end of statOn() mehtod with named arguments
01188 
01189   Bool_t showLabel= (label != 0 && strlen(label) > 0);
01190 
01191   TString whatStr(what) ;
01192   whatStr.ToUpper() ;
01193   Bool_t showN = whatStr.Contains("N") ;
01194   Bool_t showR = whatStr.Contains("R") ;
01195   Bool_t showM = whatStr.Contains("M") ;
01196   Int_t nPar= 0;
01197   if (showN) nPar++ ;
01198   if (showR) nPar++ ;
01199   if (showM) nPar++ ;
01200 
01201   // calculate the box's size
01202   Double_t dy(0.06), ymin(ymax-nPar*dy);
01203   if(showLabel) ymin-= dy;
01204 
01205   // create the box and set its options
01206   TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
01207   if(!box) return 0;
01208   box->SetName(Form("%s_statBox",GetName())) ;
01209   box->SetFillColor(0);
01210   box->SetBorderSize(1);
01211   box->SetTextAlign(12);
01212   box->SetTextSize(0.04F);
01213   box->SetFillStyle(1001);
01214 
01215   // add formatted text for each statistic
01216   RooRealVar N("N","Number of Events",sumEntries(cutSpec,cutRange));
01217   N.setPlotLabel("Entries") ;
01218   RooRealVar *meanv= meanVar(*(RooRealVar*)frame->getPlotVar(),cutSpec,cutRange);
01219   meanv->setPlotLabel("Mean") ;
01220   RooRealVar *rms= rmsVar(*(RooRealVar*)frame->getPlotVar(),cutSpec,cutRange);
01221   rms->setPlotLabel("RMS") ;
01222   TString *rmsText, *meanText, *NText ;
01223   if (options) {
01224     rmsText= rms->format(sigDigits,options);
01225     meanText= meanv->format(sigDigits,options);
01226     NText= N.format(sigDigits,options);
01227   } else {
01228     rmsText= rms->format(*formatCmd);
01229     meanText= meanv->format(*formatCmd);
01230     NText= N.format(*formatCmd);
01231   }
01232   if (showR) box->AddText(rmsText->Data());
01233   if (showM) box->AddText(meanText->Data());
01234   if (showN) box->AddText(NText->Data());
01235 
01236   // cleanup heap memory
01237   delete NText;
01238   delete meanText;
01239   delete rmsText;
01240   delete meanv;
01241   delete rms;
01242 
01243   // add the optional label if specified
01244   if(showLabel) box->AddText(label);
01245 
01246   frame->addObject(box) ;
01247   return frame ;
01248 }
01249 
01250 
01251 
01252 
01253 //_____________________________________________________________________________
01254 TH1 *RooAbsData::fillHistogram(TH1 *hist, const RooArgList &plotVars, const char *cuts, const char* cutRange) const
01255 {
01256   // Loop over columns of our tree data and fill the input histogram. Returns a pointer to the
01257   // input histogram, or zero in case of an error. The input histogram can be any TH1 subclass, and
01258   // therefore of arbitrary dimension. Variables are matched with the (x,y,...) dimensions of the input
01259   // histogram according to the order in which they appear in the input plotVars list.
01260 
01261   // Do we have a valid histogram to use?
01262   if(0 == hist) {
01263     coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: no valid histogram to fill" << endl;
01264     return 0;
01265   }
01266 
01267   // Check that the number of plotVars matches the input histogram's dimension
01268   Int_t hdim= hist->GetDimension();
01269   if(hdim != plotVars.getSize()) {
01270     coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: plotVars has the wrong dimension" << endl;
01271     return 0;
01272   }
01273 
01274   // Check that the plot variables are all actually RooAbsReal's and print a warning if we do not
01275   // explicitly depend on one of them. Clone any variables that we do not contain directly and
01276   // redirect them to use our event data.
01277   RooArgSet plotClones,localVars;
01278   for(Int_t index= 0; index < plotVars.getSize(); index++) {
01279     const RooAbsArg *var= plotVars.at(index);
01280     const RooAbsReal *realVar= dynamic_cast<const RooAbsReal*>(var);
01281     if(0 == realVar) {
01282       coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot plot variable \"" << var->GetName()
01283            << "\" of type " << var->ClassName() << endl;
01284       return 0;
01285     }
01286     RooAbsArg *found= _vars.find(realVar->GetName());
01287     if(!found) {
01288       RooAbsArg *clone= plotClones.addClone(*realVar,kTRUE); // do not complain about duplicates
01289       assert(0 != clone);
01290       if(!clone->dependsOn(_vars)) {
01291         coutW(InputArguments) << ClassName() << "::" << GetName()
01292              << ":fillHistogram: WARNING: data does not contain variable: " << realVar->GetName() << endl;
01293       }
01294       else {
01295         clone->recursiveRedirectServers(_vars);
01296       }
01297       localVars.add(*clone);
01298     }
01299     else {
01300       localVars.add(*found);
01301     }
01302   }
01303 
01304   // Create selection formula if selection cuts are specified
01305   RooFormula* select = 0;
01306   if(0 != cuts && strlen(cuts)) {
01307     select=new RooFormula(cuts,cuts,_vars);
01308     if (!select || !select->ok()) {
01309       coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: invalid cuts \"" << cuts << "\"" << endl;
01310       delete select;
01311       return 0 ;
01312     }
01313   }
01314   
01315   // Lookup each of the variables we are binning in our tree variables
01316   const RooAbsReal *xvar = 0;
01317   const RooAbsReal *yvar = 0;
01318   const RooAbsReal *zvar = 0;
01319   switch(hdim) {
01320   case 3:
01321     zvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(2)->GetName()));
01322     assert(0 != zvar);
01323     // fall through to next case...
01324   case 2:
01325     yvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(1)->GetName()));
01326     assert(0 != yvar);
01327     // fall through to next case...
01328   case 1:
01329     xvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(0)->GetName()));
01330     assert(0 != xvar);
01331     break;
01332   default:
01333     coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot fill histogram with "
01334          << hdim << " dimensions" << endl;
01335     break;
01336   }
01337 
01338   // Parse cutRange specification
01339   vector<string> cutVec ;
01340   if (cutRange && strlen(cutRange)>0) {
01341     if (strchr(cutRange,',')==0) {
01342       cutVec.push_back(cutRange) ;
01343     } else {
01344       char* buf = new char[strlen(cutRange)+1] ;
01345       strlcpy(buf,cutRange,strlen(cutRange)+1) ;
01346       const char* oneRange = strtok(buf,",") ;
01347       while(oneRange) {
01348         cutVec.push_back(oneRange) ;
01349         oneRange = strtok(0,",") ;
01350       }
01351       delete[] buf ;
01352     }
01353   }
01354 
01355   // Loop over events and fill the histogram  
01356   Int_t nevent= numEntries() ; //(Int_t)_tree->GetEntries();
01357   for(Int_t i=0; i < nevent; ++i) {
01358 
01359     //Int_t entryNumber= _tree->GetEntryNumber(i);
01360     //if (entryNumber<0) break;
01361     get(i);
01362 
01363     // Apply expression based selection criteria
01364     if (select && select->eval()==0) {
01365       continue ;
01366     }
01367 
01368 
01369     // Apply range based selection criteria
01370     Bool_t selectByRange = kTRUE ;
01371     if (cutRange) {
01372       _iterator->Reset() ;
01373       RooAbsArg* arg ;
01374       while((arg=(RooAbsArg*)_iterator->Next())) {
01375         Bool_t selectThisArg = kFALSE ;
01376         UInt_t icut ;
01377         for (icut=0 ; icut<cutVec.size() ; icut++) {
01378           if (arg->inRange(cutVec[icut].c_str())) {
01379             selectThisArg = kTRUE ;
01380             break ;
01381           }
01382         }
01383         if (!selectThisArg) {
01384           selectByRange = kFALSE ;
01385           break ;
01386         }
01387       }
01388     }
01389 
01390     if (!selectByRange) {
01391       // Go to next event in loop over events
01392       continue ;
01393     }
01394 
01395     Int_t bin(0);
01396     switch(hdim) {
01397     case 1:
01398       bin= hist->FindBin(xvar->getVal());
01399       hist->Fill(xvar->getVal(),weight()) ;
01400       break;
01401     case 2:
01402       bin= hist->FindBin(xvar->getVal(),yvar->getVal());
01403       static_cast<TH2*>(hist)->Fill(xvar->getVal(),yvar->getVal(),weight()) ;
01404       break;
01405     case 3:
01406       bin= hist->FindBin(xvar->getVal(),yvar->getVal(),zvar->getVal());
01407       static_cast<TH3*>(hist)->Fill(xvar->getVal(),yvar->getVal(),zvar->getVal(),weight()) ;
01408       break;
01409     default:
01410       assert(hdim < 3);
01411       break;
01412     }
01413 
01414     Double_t error2 = TMath::Power(hist->GetBinError(bin),2)-TMath::Power(weight(),2)  ;
01415     Double_t we = weightError(RooAbsData::SumW2) ;
01416 
01417 
01418     if (we==0) we = weight() ;
01419     error2 += TMath::Power(we,2) ;
01420     //hist->AddBinContent(bin,weight());
01421     hist->SetBinError(bin,sqrt(error2)) ;
01422 
01423     //cout << "RooTreeData::fillHistogram() bin = " << bin << " weight() = " << weight() << " we = " << we << endl ;
01424 
01425   }
01426 
01427   if(0 != select) delete select;
01428 
01429   return hist;
01430 }
01431 
01432 
01433 
01434 //_____________________________________________________________________________
01435 TList* RooAbsData::split(const RooAbsCategory& splitCat, Bool_t createEmptyDataSets) const
01436 {
01437   // Split dataset into subsets based on states of given splitCat in this dataset.
01438   // A TList of RooDataSets is returned in which each RooDataSet is named
01439   // after the state name of splitCat of which it contains the dataset subset.
01440   // The observables splitCat itself is no longer present in the sub datasets.
01441   // If createEmptyDataSets is kFALSE (default) this method only creates datasets for states 
01442   // which have at least one entry The caller takes ownership of the returned list and its contents
01443 
01444   // Sanity check
01445   if (!splitCat.dependsOn(*get())) {
01446     coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") ERROR category " << splitCat.GetName() 
01447          << " doesn't depend on any variable in this dataset" << endl ;
01448     return 0 ;
01449   }
01450 
01451   // Clone splitting category and attach to self
01452   RooAbsCategory* cloneCat =0;
01453   RooArgSet* cloneSet = 0;
01454   if (splitCat.isDerived()) {
01455     cloneSet = (RooArgSet*) RooArgSet(splitCat).snapshot(kTRUE) ;
01456     if (!cloneSet) {
01457       coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") Couldn't deep-clone splitting category, abort." << endl ;
01458       return 0 ;
01459     }
01460     cloneCat = (RooAbsCategory*) cloneSet->find(splitCat.GetName()) ;
01461     cloneCat->attachDataSet(*this) ;
01462   } else {
01463     cloneCat = dynamic_cast<RooAbsCategory*>(get()->find(splitCat.GetName())) ;
01464     if (!cloneCat) {
01465       coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") ERROR category " << splitCat.GetName() 
01466            << " is fundamental and does not appear in this dataset" << endl ;
01467       return 0 ;      
01468     }
01469   }
01470 
01471   // Split a dataset in a series of subsets, each corresponding
01472   // to a state of splitCat
01473   TList* dsetList = new TList ;
01474 
01475   // Construct set of variables to be included in split sets = full set - split category
01476   RooArgSet subsetVars(*get()) ;
01477   if (splitCat.isDerived()) {
01478     RooArgSet* vars = splitCat.getVariables() ;
01479     subsetVars.remove(*vars,kTRUE,kTRUE) ;
01480     delete vars ;
01481   } else {
01482     subsetVars.remove(splitCat,kTRUE,kTRUE) ;
01483   }
01484 
01485   // If createEmptyDataSets is true, prepopulate with empty sets corresponding to all states
01486   if (createEmptyDataSets) {
01487     TIterator* stateIter = cloneCat->typeIterator() ;
01488     RooCatType* state ;
01489     while ((state=(RooCatType*)stateIter->Next())) {
01490       RooAbsData* subset = emptyClone(state->GetName(),state->GetName(),&subsetVars) ;
01491       dsetList->Add((RooAbsArg*)subset) ;    
01492     }
01493   }
01494 
01495   
01496   // Loop over dataset and copy event to matching subset
01497   Int_t i ;
01498   for (i=0 ; i<numEntries() ; i++) {
01499     const RooArgSet* row =  get(i) ;
01500     RooAbsData* subset = (RooAbsData*) dsetList->FindObject(cloneCat->getLabel()) ;
01501     if (!subset) {
01502       subset = emptyClone(cloneCat->getLabel(),cloneCat->getLabel(),&subsetVars) ;
01503       dsetList->Add((RooAbsArg*)subset) ;
01504     }
01505     subset->add(*row,weight()) ;
01506   }
01507 
01508   delete cloneSet ;
01509   return dsetList ;
01510 }
01511 
01512 
01513 
01514 //_____________________________________________________________________________
01515 RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooLinkedList& argList) const
01516 {
01517   // Plot dataset on specified frame. By default an unbinned dataset will use the default binning of
01518   // the target frame. A binned dataset will by default retain its intrinsic binning.
01519   //
01520   // The following optional named arguments can be used to modify the default behavior
01521   //
01522   // Data representation options
01523   // ---------------------------
01524   // Asymmetry(const RooCategory& c) -- Show the asymmetry of the data in given two-state category [F(+)-F(-)] / [F(+)+F(-)]. 
01525   //                                    Category must have two states with indices -1 and +1 or three states with indeces -1,0 and +1.
01526   // Efficiency(const RooCategory& c)-- Show the efficiency F(acc)/[F(acc)+F(rej)]. Category must have two states with indices 0 and 1
01527   // DataError(RooAbsData::EType)    -- Select the type of error drawn: 
01528   //                                     - Auto(default) results in Poisson for unweighted data and SumW2 for weighted data
01529   //                                     - Poisson draws asymmetric Poisson confidence intervals. 
01530   //                                     - SumW2 draws symmetric sum-of-weights error ( sum(w)^2/sum(w^2) )
01531   //                                     - None draws no error bars
01532   // Binning(double xlo, double xhi, -- Use specified binning to draw dataset
01533   //                      int nbins)
01534   // Binning(const RooAbsBinning&)   -- Use specified binning to draw dataset
01535   // Binning(const char* name)       -- Use binning with specified name to draw dataset
01536   // RefreshNorm(Bool_t flag)        -- Force refreshing for PDF normalization information in frame.
01537   //                                    If set, any subsequent PDF will normalize to this dataset, even if it is
01538   //                                    not the first one added to the frame. By default only the 1st dataset
01539   //                                    added to a frame will update the normalization information
01540   // Rescale(Double_t f)             -- Rescale drawn histogram by given factor
01541   //
01542   // Histogram drawing options
01543   // -------------------------
01544   // DrawOption(const char* opt)     -- Select ROOT draw option for resulting TGraph object
01545   // LineStyle(Int_t style)          -- Select line style by ROOT line style code, default is solid
01546   // LineColor(Int_t color)          -- Select line color by ROOT color code, default is black
01547   // LineWidth(Int_t width)          -- Select line with in pixels, default is 3
01548   // MarkerStyle(Int_t style)        -- Select the ROOT marker style, default is 21
01549   // MarkerColor(Int_t color)        -- Select the ROOT marker color, default is black
01550   // MarkerSize(Double_t size)       -- Select the ROOT marker size
01551   // FillStyle(Int_t style)          -- Select fill style, default is filled. 
01552   // FillColor(Int_t color)          -- Select fill color by ROOT color code
01553   // XErrorSize(Double_t frac)       -- Select size of X error bar as fraction of the bin width, default is 1
01554   //
01555   //
01556   // Misc. other options
01557   // -------------------
01558   // Name(const chat* name)          -- Give curve specified name in frame. Useful if curve is to be referenced later
01559   // Invisble()                      -- Add curve to frame, but do not display. Useful in combination AddTo()
01560   // AddTo(const char* name,         -- Add constructed histogram to already existing histogram with given name and relative weight factors
01561   // double_t wgtSelf, double_t wgtOther)
01562   // 
01563   //                                    
01564   //
01565 
01566   // New experimental plotOn() with varargs...
01567 
01568   // Define configuration for this method
01569   RooCmdConfig pc(Form("RooTreeData::plotOn(%s)",GetName())) ;
01570   pc.defineString("drawOption","DrawOption",0,"P") ;
01571   pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
01572   pc.defineString("cutString","CutSpec",0,"") ;
01573   pc.defineString("histName","Name",0,"") ;
01574   pc.defineObject("cutVar","CutVar",0) ;
01575   pc.defineObject("binning","Binning",0) ;
01576   pc.defineString("binningName","BinningName",0,"") ;
01577   pc.defineInt("nbins","BinningSpec",0,100) ;
01578   pc.defineDouble("xlo","BinningSpec",0,0) ;
01579   pc.defineDouble("xhi","BinningSpec",1,1) ;
01580   pc.defineObject("asymCat","Asymmetry",0) ;
01581   pc.defineObject("effCat","Efficiency",0) ;
01582   pc.defineInt("lineColor","LineColor",0,-999) ;
01583   pc.defineInt("lineStyle","LineStyle",0,-999) ;
01584   pc.defineInt("lineWidth","LineWidth",0,-999) ;
01585   pc.defineInt("markerColor","MarkerColor",0,-999) ;
01586   pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
01587   pc.defineDouble("markerSize","MarkerSize",0,-999) ;
01588   pc.defineInt("fillColor","FillColor",0,-999) ;
01589   pc.defineInt("fillStyle","FillStyle",0,-999) ;
01590   pc.defineInt("errorType","DataError",0,(Int_t)RooAbsData::Auto) ;
01591   pc.defineInt("histInvisible","Invisible",0,0) ;
01592   pc.defineInt("refreshFrameNorm","RefreshNorm",0,1) ;
01593   pc.defineString("addToHistName","AddTo",0,"") ;
01594   pc.defineDouble("addToWgtSelf","AddTo",0,1.) ;
01595   pc.defineDouble("addToWgtOther","AddTo",1,1.) ;
01596   pc.defineDouble("xErrorSize","XErrorSize",0,1.) ;
01597   pc.defineDouble("scaleFactor","Rescale",0,1.) ;
01598   pc.defineMutex("DataError","Asymmetry","Efficiency") ;
01599   pc.defineMutex("Binning","BinningName","BinningSpec") ;
01600 
01601   // Process & check varargs 
01602   pc.process(argList) ;
01603   if (!pc.ok(kTRUE)) {
01604     return frame ;
01605   }
01606 
01607   PlotOpt o ;
01608 
01609   // Extract values from named arguments
01610   o.drawOptions = pc.getString("drawOption") ;
01611   o.cuts = pc.getString("cutString") ;
01612   if (pc.hasProcessed("Binning")) {
01613     o.bins = (RooAbsBinning*) pc.getObject("binning") ;
01614   } else if (pc.hasProcessed("BinningName")) {
01615     o.bins = &frame->getPlotVar()->getBinning(pc.getString("binningName")) ;
01616   } else if (pc.hasProcessed("BinningSpec")) {
01617     Double_t xlo = pc.getDouble("xlo") ;
01618     Double_t xhi = pc.getDouble("xhi") ;
01619     o.bins = new RooUniformBinning((xlo==xhi)?frame->getPlotVar()->getMin():xlo,
01620                                    (xlo==xhi)?frame->getPlotVar()->getMax():xhi,pc.getInt("nbins")) ;
01621   }
01622   const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
01623   const RooAbsCategoryLValue* effCat = (const RooAbsCategoryLValue*) pc.getObject("effCat") ;
01624   o.etype = (RooAbsData::ErrorType) pc.getInt("errorType") ;
01625   o.histInvisible = pc.getInt("histInvisible") ;
01626   o.xErrorSize = pc.getDouble("xErrorSize") ;
01627   o.cutRange = pc.getString("cutRange",0,kTRUE) ;
01628   o.histName = pc.getString("histName",0,kTRUE) ;
01629   o.addToHistName = pc.getString("addToHistName",0,kTRUE) ;
01630   o.addToWgtSelf = pc.getDouble("addToWgtSelf") ;
01631   o.addToWgtOther = pc.getDouble("addToWgtOther") ;
01632   o.refreshFrameNorm = pc.getInt("refreshFrameNorm") ;
01633   o.scaleFactor = pc.getDouble("scaleFactor") ;
01634 
01635   // Map auto error type to actual type
01636   if (o.etype == Auto) {
01637     o.etype = isNonPoissonWeighted() ? SumW2 : Poisson ;    
01638     if (o.etype == SumW2) {
01639       coutI(InputArguments) << "RooAbsData::plotOn(" << GetName() 
01640                             << ") INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors" << endl ;
01641     }
01642   }
01643   
01644   if (o.addToHistName && !frame->findObject(o.addToHistName,RooHist::Class())) {
01645     coutE(InputArguments) << "RooAbsData::plotOn(" << GetName() << ") cannot find existing histogram " << o.addToHistName 
01646                           << " to add to in RooPlot" << endl ;
01647     return frame ;
01648   }
01649 
01650   RooPlot* ret ;
01651   if (!asymCat && !effCat) {
01652     ret = plotOn(frame,o) ;
01653   } else if (asymCat) {
01654     ret = plotAsymOn(frame,*asymCat,o) ;    
01655   } else {
01656     ret = plotEffOn(frame,*effCat,o) ;    
01657   }
01658 
01659   Int_t lineColor   = pc.getInt("lineColor") ;
01660   Int_t lineStyle   = pc.getInt("lineStyle") ;
01661   Int_t lineWidth   = pc.getInt("lineWidth") ;
01662   Int_t markerColor = pc.getInt("markerColor") ;
01663   Int_t markerStyle = pc.getInt("markerStyle") ;
01664   Size_t markerSize  = pc.getDouble("markerSize") ;
01665   Int_t fillColor = pc.getInt("fillColor") ;
01666   Int_t fillStyle = pc.getInt("fillStyle") ;
01667   if (lineColor!=-999) ret->getAttLine()->SetLineColor(lineColor) ;
01668   if (lineStyle!=-999) ret->getAttLine()->SetLineStyle(lineStyle) ;
01669   if (lineWidth!=-999) ret->getAttLine()->SetLineWidth(lineWidth) ;
01670   if (markerColor!=-999) ret->getAttMarker()->SetMarkerColor(markerColor) ;
01671   if (markerStyle!=-999) ret->getAttMarker()->SetMarkerStyle(markerStyle) ;
01672   if (markerSize!=-999) ret->getAttMarker()->SetMarkerSize(markerSize) ;
01673   if (fillColor!=-999) ret->getAttFill()->SetFillColor(fillColor) ;
01674   if (fillStyle!=-999) ret->getAttFill()->SetFillStyle(fillStyle) ;
01675 
01676   if (pc.hasProcessed("BinningSpec")) {
01677     delete o.bins ;
01678   }
01679 
01680   return ret ;
01681 }
01682 
01683 
01684 
01685 //_____________________________________________________________________________
01686 RooPlot *RooAbsData::plotOn(RooPlot *frame, PlotOpt o) const 
01687 {
01688   // Create and fill a histogram of the frame's variable and append it to the frame.
01689   // The frame variable must be one of the data sets dimensions.
01690   //
01691   // The plot range and the number of plot bins is determined by the parameters
01692   // of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins())
01693   // 
01694   // The optional cut string expression can be used to select the events to be plotted.
01695   // The cut specification may refer to any variable contained in the data set
01696   //
01697   // The drawOptions are passed to the TH1::Draw() method
01698 
01699   if(0 == frame) {
01700     coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << endl;
01701     return 0;
01702   }
01703   RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
01704   if(0 == var) {
01705     coutE(Plotting) << ClassName() << "::" << GetName()
01706          << ":plotOn: frame does not specify a plot variable" << endl;
01707     return 0;
01708   }
01709 
01710   // create and fill a temporary histogram of this variable
01711   TString histName(GetName());
01712   histName.Append("_plot");
01713   TH1F *hist ;
01714     if (o.bins) {
01715     hist= static_cast<TH1F*>(var->createHistogram(histName.Data(), RooFit::AxisLabel("Events"), RooFit::Binning(*o.bins))) ;
01716   } else {
01717     hist= var->createHistogram(histName.Data(), "Events", 
01718                                frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(), frame->GetNbinsX());
01719   }
01720 
01721   // Keep track of sum-of-weights error
01722   hist->Sumw2() ;
01723 
01724   if(0 == fillHistogram(hist,RooArgList(*var),o.cuts,o.cutRange)) {
01725     coutE(Plotting) << ClassName() << "::" << GetName()
01726          << ":plotOn: fillHistogram() failed" << endl;
01727     return 0;
01728   }
01729 
01730   // If frame has no predefined bin width (event density) it will be adjusted to 
01731   // our histograms bin width so we should force that bin width here
01732   Double_t nomBinWidth ;
01733   if (frame->getFitRangeNEvt()==0 && o.bins) {
01734     nomBinWidth = o.bins->averageBinWidth() ;
01735   } else {
01736     nomBinWidth = o.bins ? frame->getFitRangeBinW() : 0 ;
01737   }
01738 
01739   // convert this histogram to a RooHist object on the heap
01740   RooHist *graph= new RooHist(*hist,nomBinWidth,1,o.etype,o.xErrorSize,o.correctForBinWidth,o.scaleFactor); 
01741   if(0 == graph) {
01742     coutE(Plotting) << ClassName() << "::" << GetName()
01743          << ":plotOn: unable to create a RooHist object" << endl;
01744     delete hist;
01745     return 0;
01746   }  
01747 
01748   // If the dataset variable has a wide range than the plot variable,
01749   // calculate the number of entries in the dataset in the plot variable fit range
01750   RooAbsRealLValue* dataVar = (RooAbsRealLValue*) _vars.find(var->GetName()) ;
01751   Double_t nEnt(sumEntries()) ;
01752   if (dataVar->getMin()<var->getMin() || dataVar->getMax()>var->getMax()) {
01753     RooAbsData* tmp = ((RooAbsData*)this)->reduce(*var) ;
01754     nEnt = tmp->sumEntries() ;
01755     delete tmp ;
01756   }
01757 
01758   // Store the number of entries before the cut, if any was made
01759   if ((o.cuts && strlen(o.cuts)) || o.cutRange) {
01760     coutI(Plotting) << "RooTreeData::plotOn: plotting " << hist->GetSum() << " events out of " << nEnt << " total events" << endl ;
01761     graph->setRawEntries(nEnt) ;
01762   }
01763 
01764   // Add self to other hist if requested
01765   if (o.addToHistName) {
01766     RooHist* otherGraph = static_cast<RooHist*>(frame->findObject(o.addToHistName,RooHist::Class())) ;
01767 
01768     if (!graph->hasIdenticalBinning(*otherGraph)) {
01769       coutE(Plotting) << "RooTreeData::plotOn: ERROR Histogram to be added to, '" << o.addToHistName << "',has different binning" << endl ;
01770       delete graph ;
01771       return frame ;
01772     }
01773 
01774     RooHist* sumGraph = new RooHist(*graph,*otherGraph,o.addToWgtSelf,o.addToWgtOther,o.etype) ;
01775     delete graph ;
01776     graph = sumGraph ;
01777   }  
01778 
01779   // Rename graph if requested
01780   if (o.histName) {
01781     graph->SetName(o.histName) ;
01782   } else {
01783     TString hname(Form("h_%s",GetName())) ;
01784     if (o.cutRange && strlen(o.cutRange)>0) {
01785       hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
01786     } 
01787     if (o.cuts && strlen(o.cuts)>0) {
01788       hname.Append(Form("_Cut[%s]",o.cuts)) ;
01789     } 
01790     graph->SetName(hname.Data()) ;
01791   }
01792   
01793   // initialize the frame's normalization setup, if necessary
01794   frame->updateNormVars(_vars);
01795 
01796 
01797   // add the RooHist to the specified plot
01798   frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
01799 
01800 
01801 
01802   // cleanup
01803   delete hist;
01804 
01805   return frame;  
01806 }
01807 
01808 
01809 
01810 
01811 //_____________________________________________________________________________
01812 RooPlot* RooAbsData::plotAsymOn(RooPlot* frame, const RooAbsCategoryLValue& asymCat, PlotOpt o) const 
01813 {
01814   // Create and fill a histogram with the asymmetry N[+] - N[-] / ( N[+] + N[-] ),
01815   // where N(+/-) is the number of data points with asymCat=+1 and asymCat=-1 
01816   // as function of the frames variable. The asymmetry category 'asymCat' must
01817   // have exactly 2 (or 3) states defined with index values +1,-1 (and 0)
01818   // 
01819   // The plot range and the number of plot bins is determined by the parameters
01820   // of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins())
01821   // 
01822   // The optional cut string expression can be used to select the events to be plotted.
01823   // The cut specification may refer to any variable contained in the data set
01824   //
01825   // The drawOptions are passed to the TH1::Draw() method
01826 
01827   if(0 == frame) {
01828     coutE(Plotting) << ClassName() << "::" << GetName() << ":plotAsymOn: frame is null" << endl;
01829     return 0;
01830   }
01831   RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
01832   if(0 == var) {
01833     coutE(Plotting) << ClassName() << "::" << GetName()
01834          << ":plotAsymOn: frame does not specify a plot variable" << endl;
01835     return 0;
01836   }
01837 
01838   // create and fill temporary histograms of this variable for each state
01839   TString hist1Name(GetName()),hist2Name(GetName());
01840   hist1Name.Append("_plot1");
01841   TH1F *hist1, *hist2 ;
01842   hist2Name.Append("_plot2");
01843 
01844   if (o.bins) {
01845     hist1= var->createHistogram(hist1Name.Data(), "Events", *o.bins) ;
01846     hist2= var->createHistogram(hist2Name.Data(), "Events", *o.bins) ;
01847   } else {
01848     hist1= var->createHistogram(hist1Name.Data(), "Events", 
01849                                 frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
01850                                 frame->GetNbinsX());
01851     hist2= var->createHistogram(hist2Name.Data(), "Events", 
01852                                 frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
01853                                 frame->GetNbinsX());
01854   }
01855 
01856   assert(0 != hist1 && 0 != hist2);
01857 
01858   TString cuts1,cuts2 ;
01859   if (o.cuts && strlen(o.cuts)) {
01860     cuts1 = Form("(%s)&&(%s>0)",o.cuts,asymCat.GetName());
01861     cuts2 = Form("(%s)&&(%s<0)",o.cuts,asymCat.GetName());
01862   } else {
01863     cuts1 = Form("(%s>0)",asymCat.GetName());
01864     cuts2 = Form("(%s<0)",asymCat.GetName());
01865   }
01866 
01867   if(0 == fillHistogram(hist1,RooArgList(*var),cuts1.Data(),o.cutRange) ||
01868      0 == fillHistogram(hist2,RooArgList(*var),cuts2.Data(),o.cutRange)) {
01869     coutE(Plotting) << ClassName() << "::" << GetName()
01870          << ":plotAsymOn: createHistogram() failed" << endl;
01871     return 0;
01872   }
01873 
01874   // convert this histogram to a RooHist object on the heap
01875   RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,kFALSE,o.scaleFactor);
01876   graph->setYAxisLabel(Form("Asymmetry in %s",asymCat.GetName())) ;
01877 
01878   // initialize the frame's normalization setup, if necessary
01879   frame->updateNormVars(_vars);
01880 
01881   // Rename graph if requested
01882   if (o.histName) {
01883     graph->SetName(o.histName) ;
01884   } else {
01885     TString hname(Form("h_%s_Asym[%s]",GetName(),asymCat.GetName())) ;
01886     if (o.cutRange && strlen(o.cutRange)>0) {
01887       hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
01888     } 
01889     if (o.cuts && strlen(o.cuts)>0) {
01890       hname.Append(Form("_Cut[%s]",o.cuts)) ;
01891     } 
01892     graph->SetName(hname.Data()) ;
01893   }
01894 
01895   // add the RooHist to the specified plot
01896   frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
01897 
01898   // cleanup
01899   delete hist1;
01900   delete hist2;
01901 
01902   return frame;  
01903 }
01904 
01905 
01906 
01907 //_____________________________________________________________________________
01908 RooPlot* RooAbsData::plotEffOn(RooPlot* frame, const RooAbsCategoryLValue& effCat, PlotOpt o) const 
01909 {
01910   // Create and fill a histogram with the effiency N[1] / ( N[1] + N[0] ),
01911   // where N(1/0) is the number of data points with effCat=1 and effCat=0
01912   // as function of the frames variable. The efficiency category 'effCat' must
01913   // have exactly 2 +1 and 0.
01914   // 
01915   // The plot range and the number of plot bins is determined by the parameters
01916   // of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins())
01917   // 
01918   // The optional cut string expression can be used to select the events to be plotted.
01919   // The cut specification may refer to any variable contained in the data set
01920   //
01921   // The drawOptions are passed to the TH1::Draw() method
01922 
01923   if(0 == frame) {
01924     coutE(Plotting) << ClassName() << "::" << GetName() << ":plotEffOn: frame is null" << endl;
01925     return 0;
01926   }
01927   RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
01928   if(0 == var) {
01929     coutE(Plotting) << ClassName() << "::" << GetName()
01930          << ":plotEffOn: frame does not specify a plot variable" << endl;
01931     return 0;
01932   }
01933 
01934   // create and fill temporary histograms of this variable for each state
01935   TString hist1Name(GetName()),hist2Name(GetName());
01936   hist1Name.Append("_plot1");
01937   TH1F *hist1, *hist2 ;
01938   hist2Name.Append("_plot2");
01939 
01940   if (o.bins) {
01941     hist1= var->createHistogram(hist1Name.Data(), "Events", *o.bins) ;
01942     hist2= var->createHistogram(hist2Name.Data(), "Events", *o.bins) ;
01943   } else {
01944     hist1= var->createHistogram(hist1Name.Data(), "Events", 
01945                                 frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
01946                                 frame->GetNbinsX());
01947     hist2= var->createHistogram(hist2Name.Data(), "Events", 
01948                                 frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
01949                                 frame->GetNbinsX());
01950   }
01951 
01952   assert(0 != hist1 && 0 != hist2);
01953 
01954   TString cuts1,cuts2 ;
01955   if (o.cuts && strlen(o.cuts)) {
01956     cuts1 = Form("(%s)&&(%s==1)",o.cuts,effCat.GetName());
01957     cuts2 = Form("(%s)&&(%s==0)",o.cuts,effCat.GetName());
01958   } else {
01959     cuts1 = Form("(%s==1)",effCat.GetName());
01960     cuts2 = Form("(%s==0)",effCat.GetName());
01961   }
01962 
01963   if(0 == fillHistogram(hist1,RooArgList(*var),cuts1.Data(),o.cutRange) ||
01964      0 == fillHistogram(hist2,RooArgList(*var),cuts2.Data(),o.cutRange)) {
01965     coutE(Plotting) << ClassName() << "::" << GetName()
01966          << ":plotEffOn: createHistogram() failed" << endl;
01967     return 0;
01968   }
01969 
01970   // convert this histogram to a RooHist object on the heap
01971   RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,kTRUE);
01972   graph->setYAxisLabel(Form("Efficiency of %s=%s",effCat.GetName(),effCat.lookupType(1)->GetName())) ;
01973 
01974   // initialize the frame's normalization setup, if necessary
01975   frame->updateNormVars(_vars);
01976 
01977   // Rename graph if requested
01978   if (o.histName) {
01979     graph->SetName(o.histName) ;
01980   } else {
01981     TString hname(Form("h_%s_Eff[%s]",GetName(),effCat.GetName())) ;
01982     if (o.cutRange && strlen(o.cutRange)>0) {
01983       hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
01984     } 
01985     if (o.cuts && strlen(o.cuts)>0) {
01986       hname.Append(Form("_Cut[%s]",o.cuts)) ;
01987     } 
01988     graph->SetName(hname.Data()) ;
01989   }
01990 
01991   // add the RooHist to the specified plot
01992   frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
01993 
01994   // cleanup
01995   delete hist1;
01996   delete hist2;
01997 
01998   return frame;  
01999 }
02000 
02001 
02002 //_____________________________________________________________________________
02003 Roo1DTable* RooAbsData::table(const RooAbsCategory& cat, const char* cuts, const char* /*opts*/) const
02004 {
02005   // Create and fill a 1-dimensional table for given category column
02006   // This functions is the equivalent of plotOn() for category dimensions. 
02007   //
02008   // The optional cut string expression can be used to select the events to be tabulated
02009   // The cut specification may refer to any variable contained in the data set
02010   //
02011   // The option string is currently not used
02012 
02013   // First see if var is in data set 
02014   RooAbsCategory* tableVar = (RooAbsCategory*) _vars.find(cat.GetName()) ;
02015   RooArgSet *tableSet = 0;
02016   Bool_t ownPlotVar(kFALSE) ;
02017   if (!tableVar) {
02018     if (!cat.dependsOn(_vars)) {
02019       coutE(Plotting) << "RooTreeData::Table(" << GetName() << "): Argument " << cat.GetName() 
02020            << " is not in dataset and is also not dependent on data set" << endl ;
02021       return 0 ; 
02022     }
02023 
02024     // Clone derived variable 
02025     tableSet = (RooArgSet*) RooArgSet(cat).snapshot(kTRUE) ;
02026     if (!tableSet) {
02027       coutE(Plotting) << "RooTreeData::table(" << GetName() << ") Couldn't deep-clone table category, abort." << endl ;
02028       return 0 ;
02029     }
02030     tableVar = (RooAbsCategory*) tableSet->find(cat.GetName()) ;
02031     ownPlotVar = kTRUE ;    
02032 
02033     //Redirect servers of derived clone to internal ArgSet representing the data in this set
02034     tableVar->recursiveRedirectServers(_vars) ;
02035   }
02036 
02037   TString tableName(GetName()) ;
02038   if (cuts && strlen(cuts)) {
02039     tableName.Append("(") ;
02040     tableName.Append(cuts) ;
02041     tableName.Append(")") ;    
02042   }
02043   Roo1DTable* table2 = tableVar->createTable(tableName) ;
02044 
02045   // Make cut selector if cut is specified
02046   RooFormulaVar* cutVar = 0;
02047   if (cuts && strlen(cuts)) {
02048     cutVar = new RooFormulaVar("cutVar",cuts,_vars) ;
02049   }
02050 
02051   // Dump contents   
02052   Int_t nevent= numEntries() ;
02053   for(Int_t i=0; i < nevent; ++i) {
02054     get(i);
02055 
02056     if (cutVar && cutVar->getVal()==0) continue ;
02057     
02058     table2->fill(*tableVar,weight()) ;
02059   }
02060 
02061   if (ownPlotVar) delete tableSet ;
02062   if (cutVar) delete cutVar ;
02063 
02064   return table2 ;
02065 }
02066 
02067 
02068 //_____________________________________________________________________________
02069 Bool_t RooAbsData::getRange(RooRealVar& var, Double_t& lowest, Double_t& highest, Double_t marginFrac, Bool_t symMode) const 
02070 {
02071   // Fill Doubles 'lowest' and 'highest' with the lowest and highest value of
02072   // observable 'var' in this dataset. If the return value is kTRUE and error
02073   // occurred
02074 
02075   // Lookup variable in dataset
02076   RooRealVar *varPtr= (RooRealVar*) _vars.find(var.GetName());
02077   if(0 == varPtr) {
02078     coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << endl ;
02079     return kTRUE;
02080   }
02081 
02082   // Check if found variable is of type RooRealVar
02083   if (!dynamic_cast<RooRealVar*>(varPtr)) {
02084     coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << endl ;
02085     return kTRUE;
02086   }
02087 
02088   // Check if dataset is not empty
02089   if(sumEntries() == 0.) {
02090     coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") WARNING: empty dataset" << endl ;
02091     return kTRUE;
02092   }
02093 
02094   // Look for highest and lowest value 
02095   lowest = RooNumber::infinity() ;
02096   highest = -RooNumber::infinity() ;
02097   for (Int_t i=0 ; i<numEntries() ; i++) {
02098     get(i) ;
02099     if (varPtr->getVal()<lowest) {
02100       lowest = varPtr->getVal() ;
02101     }
02102     if (varPtr->getVal()>highest) {
02103       highest = varPtr->getVal() ;
02104     }
02105   }  
02106 
02107   if (marginFrac>0) {
02108     if (symMode==kFALSE) {
02109 
02110       Double_t margin = marginFrac*(highest-lowest) ;    
02111       lowest -= margin ;
02112       highest += margin ; 
02113       if (lowest<var.getMin()) lowest = var.getMin() ;
02114       if (highest>var.getMax()) highest = var.getMax() ;
02115 
02116     } else {
02117 
02118       Double_t mom1 = moment(var,1) ;
02119       Double_t delta = ((highest-mom1)>(mom1-lowest)?(highest-mom1):(mom1-lowest))*(1+marginFrac) ;
02120       lowest = mom1-delta ;
02121       highest = mom1+delta ;
02122       if (lowest<var.getMin()) lowest = var.getMin() ;
02123       if (highest>var.getMax()) highest = var.getMax() ;
02124 
02125     }
02126   }
02127   
02128   return kFALSE ;
02129 }
02130 
02131 
02132 
02133 
02134 //_____________________________________________________________________________
02135 void RooAbsData::optimizeReadingWithCaching(RooAbsArg& arg, const RooArgSet& cacheList, const RooArgSet& keepObsList)
02136 {
02137   // Prepare dataset for use with cached constant terms listed in
02138   // 'cacheList' of expression 'arg'. Deactivate tree branches
02139   // for any dataset observable that is either not used at all,
02140   // or is used exclusively by cached branch nodes.
02141 
02142   RooArgSet pruneSet ;
02143 
02144   // Add unused observables in this dataset to pruneSet
02145   pruneSet.add(*get()) ;
02146   RooArgSet* usedObs = arg.getObservables(*this) ;
02147   pruneSet.remove(*usedObs,kTRUE,kTRUE) ;
02148 
02149   // Add observables exclusively used to calculate cached observables to pruneSet
02150   TIterator* vIter = get()->createIterator() ;
02151   RooAbsArg *var ;
02152   while ((var=(RooAbsArg*) vIter->Next())) {
02153     if (allClientsCached(var,cacheList)) {
02154       pruneSet.add(*var) ;
02155     }
02156   }
02157   delete vIter ;
02158 
02159 
02160   if (pruneSet.getSize()!=0) {
02161 
02162     // Go over all used observables and check if any of them have parameterized
02163     // ranges in terms of pruned observables. If so, remove those observable
02164     // from the pruning list
02165     TIterator* uIter = usedObs->createIterator() ;
02166     RooAbsArg* obs ;
02167     while((obs=(RooAbsArg*)uIter->Next())) {
02168       RooRealVar* rrv = dynamic_cast<RooRealVar*>(obs) ;
02169       if (rrv && !rrv->getBinning().isShareable()) {
02170         RooArgSet depObs ;
02171         RooAbsReal* loFunc = rrv->getBinning().lowBoundFunc() ;
02172         RooAbsReal* hiFunc = rrv->getBinning().highBoundFunc() ;
02173         if (loFunc) {
02174           loFunc->leafNodeServerList(&depObs,0,kTRUE) ;
02175         }
02176         if (hiFunc) {
02177           hiFunc->leafNodeServerList(&depObs,0,kTRUE) ;
02178         }
02179         if (depObs.getSize()>0) {
02180           pruneSet.remove(depObs,kTRUE,kTRUE) ;
02181         }
02182       }
02183     }
02184     delete uIter ;
02185   }
02186 
02187 
02188   // Remove all observables in keep list from prune list
02189   pruneSet.remove(keepObsList,kTRUE,kTRUE) ;
02190 
02191   if (pruneSet.getSize()!=0) {
02192     
02193     // Deactivate tree branches here
02194     cxcoutI(Optimization) << "RooTreeData::optimizeReadingForTestStatistic(" << GetName() << "): Observables " << pruneSet
02195                             << " in dataset are either not used at all, orserving exclusively p.d.f nodes that are now cached, disabling reading of these observables for TTree" << endl ;
02196     setArgStatus(pruneSet,kFALSE) ;
02197   }
02198 
02199   delete usedObs ;
02200   
02201 }
02202 
02203 
02204 //_____________________________________________________________________________
02205 Bool_t RooAbsData::allClientsCached(RooAbsArg* var, const RooArgSet& cacheList)
02206 {
02207   // Utility function that determines if all clients of object 'var'
02208   // appear in given list of cached nodes.
02209 
02210   Bool_t ret(kTRUE), anyClient(kFALSE) ;
02211 
02212   TIterator* cIter = var->valueClientIterator() ;    
02213   RooAbsArg* client ;
02214   while ((client=(RooAbsArg*) cIter->Next())) {
02215     anyClient = kTRUE ;
02216     if (!cacheList.find(client->GetName())) {
02217       // If client is not cached recurse
02218       ret &= allClientsCached(client,cacheList) ;
02219     }
02220   }
02221   delete cIter ;
02222   
02223   return anyClient?ret:kFALSE ;
02224 }
02225 
02226 
02227 
02228 
02229 //_____________________________________________________________________________
02230 void RooAbsData::checkInit() const
02231 { 
02232   _dstore->checkInit() ; 
02233 }
02234 
02235 
02236 //_____________________________________________________________________________
02237 void RooAbsData::Draw(Option_t* option) 
02238 { 
02239   // Forward draw command to data store
02240   if (_dstore) _dstore->Draw(option) ; 
02241 }
02242 
02243 
02244 
02245 //_____________________________________________________________________________
02246 Bool_t RooAbsData::hasFilledCache() const 
02247 { 
02248   return _dstore->hasFilledCache() ; 
02249 }
02250 
02251 
02252 //_____________________________________________________________________________
02253 const TTree* RooAbsData::tree() const 
02254 { 
02255   return _dstore->tree() ; 
02256 }

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