RooDataSet.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooDataSet.cxx 37128 2010-11-30 22:24:50Z 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 // RooDataSet is a container class to hold unbinned data. Each data point
00021 // in N-dimensional space is represented by a RooArgSet of RooRealVar, RooCategory 
00022 // or RooStringVar objects 
00023 // END_HTML
00024 //
00025 
00026 #include "RooFit.h"
00027 
00028 #include "Riostream.h"
00029 #include "Riostream.h"
00030 #include <fstream>
00031 #include "TTree.h"
00032 #include "TH2.h"
00033 #include "TDirectory.h"
00034 #include "RooDataSet.h"
00035 #include "RooPlot.h"
00036 #include "RooAbsReal.h"
00037 #include "Roo1DTable.h"
00038 #include "RooCategory.h"
00039 #include "RooFormulaVar.h"
00040 #include "RooArgList.h"
00041 #include "RooAbsRealLValue.h"
00042 #include "RooRealVar.h"
00043 #include "RooDataHist.h"
00044 #include "RooMsgService.h"
00045 #include "RooCmdConfig.h"
00046 #include "RooHist.h"
00047 #include "TROOT.h"
00048 #include "TFile.h"
00049 #include "RooTreeDataStore.h"
00050 #include "RooCompositeDataStore.h"
00051 #include "RooTreeData.h"
00052 
00053 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
00054 char* operator+( streampos&, char* );
00055 #endif
00056 
00057 ClassImp(RooDataSet)
00058 ;
00059 
00060 
00061 //_____________________________________________________________________________
00062 RooDataSet::RooDataSet() : _wgtVar(0) 
00063 {
00064   // Default constructor for persistence
00065 }
00066 
00067 
00068 
00069 
00070 
00071 //_____________________________________________________________________________
00072 RooDataSet::RooDataSet(const char* name, const char* title, const RooArgSet& vars, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
00073                        const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8)  :
00074   RooAbsData(name,title,RooArgSet(vars,(RooAbsArg*)RooCmdConfig::decodeObjOnTheFly("RooDataSet::RooDataSet", "IndexCat",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)))
00075 {
00076   // Construct an unbinned dataset from a RooArgSet defining the dimensions of the data space. Optionally, data
00077   // can be imported at the time of construction.
00078   //
00079   // This constructor takes the following optional arguments
00080   //
00081   // Import(TTree*)              -- Import contents of given TTree. Only braches of the TTree that have names
00082   //                                corresponding to those of the RooAbsArgs that define the RooDataSet are
00083   //                                imported. 
00084   // ImportFromFile(const char* fileName, const char* treeName) -- Import tree with given name from file with given name.
00085   //
00086   // Import(RooDataSet&)         -- Import contents of given RooDataSet. Only observables that are common with
00087   //                                the definition of this dataset will be imported
00088   //
00089   // Index(RooCategory&)         -- Prepare import of datasets into a N+1 dimensional RooDataSet
00090   //                                where the extra discrete dimension labels the source of the imported histogram.
00091   //                              
00092   // Import(const char*,         -- Import a dataset to be associated with the given state name of the index category
00093   //              RooDataSet&)      specified in Index(). If the given state name is not yet defined in the index
00094   //                                category it will be added on the fly. The import command can be specified
00095   //                                multiple times. 
00096   //
00097   // Link(const char*, RooDataSet&) -- Link contents of supplied RooDataSet to this dataset for given index category state name.
00098   //                                   In this mode, no data is copied and the linked dataset must be remain live for the duration
00099   //                                   of this dataset. Note that link is active for both reading and writing, so modifications
00100   //                                   to the aggregate dataset will also modify its components. Link() and Import() are mutually exclusive.
00101   //
00102   // Import(map<string,RooDataSet*>&) -- As above, but allows specification of many imports in a single operation
00103   // Link(map<string,RooDataSet*>&)   -- As above, but allows specification of many links in a single operation
00104   //
00105   //                              
00106   // Cut(const char*)            -- Apply the given cut specification when importing data
00107   // Cut(RooFormulaVar&)         
00108   //
00109   // CutRange(const char*)       -- Only accept events in the observable range with the given name
00110   //
00111   // WeightVar(const char*)      -- Interpret the given variable as event weight rather than as observable
00112   // WeightVar(const RooAbsArg&) 
00113   //
00114   // StoreError(const RooArgSet&)     -- Store symmetric error along with value for given subset of observables
00115   // StoreAsymError(const RooArgSet&) -- Store asymmetric error along with value for given subset of observables
00116   //
00117 
00118   // Define configuration for this method
00119   RooCmdConfig pc(Form("RooDataSet::ctor(%s)",GetName())) ;
00120   pc.defineObject("impTree","ImportTree",0) ;
00121   pc.defineObject("impData","ImportData",0) ;
00122   pc.defineObject("indexCat","IndexCat",0) ;
00123   pc.defineObject("impSliceData","ImportDataSlice",0,0,kTRUE) ; // array
00124   pc.defineString("impSliceState","ImportDataSlice",0,"",kTRUE) ; // array
00125   pc.defineObject("lnkSliceData","LinkDataSlice",0,0,kTRUE) ; // array
00126   pc.defineString("lnkSliceState","LinkDataSlice",0,"",kTRUE) ; // array
00127   pc.defineString("cutSpec","CutSpec",0,"") ; 
00128   pc.defineObject("cutVar","CutVar",0) ;
00129   pc.defineString("cutRange","CutRange",0,"") ;
00130   pc.defineString("wgtVarName","WeightVarName",0,"") ;
00131   pc.defineString("fname","ImportFromFile",0,"") ;
00132   pc.defineString("tname","ImportFromFile",1,"") ;
00133   pc.defineObject("wgtVar","WeightVar",0) ;
00134   pc.defineObject("dummy1","ImportDataSliceMany",0) ;
00135   pc.defineObject("dummy2","LinkDataSliceMany",0) ;
00136   pc.defineSet("errorSet","StoreError",0) ;
00137   pc.defineSet("asymErrSet","StoreAsymError",0) ;
00138   pc.defineMutex("ImportTree","ImportData","ImportDataSlice","LinkDataSlice","ImportFromFile") ;
00139   pc.defineMutex("CutSpec","CutVar") ;
00140   pc.defineMutex("WeightVarName","WeightVar") ;
00141   pc.defineDependency("ImportDataSlice","IndexCat") ;
00142   pc.defineDependency("LinkDataSlice","IndexCat") ;
00143 
00144   
00145   RooLinkedList l ;
00146   l.Add((TObject*)&arg1) ;  l.Add((TObject*)&arg2) ;  
00147   l.Add((TObject*)&arg3) ;  l.Add((TObject*)&arg4) ;
00148   l.Add((TObject*)&arg5) ;  l.Add((TObject*)&arg6) ;  
00149   l.Add((TObject*)&arg7) ;  l.Add((TObject*)&arg8) ;
00150 
00151   // Process & check varargs 
00152   pc.process(l) ;
00153   if (!pc.ok(kTRUE)) {
00154     assert(0) ;
00155     return ;
00156   }
00157 
00158   // Extract relevant objects
00159   TTree* impTree = static_cast<TTree*>(pc.getObject("impTree")) ;
00160   RooDataSet* impData = static_cast<RooDataSet*>(pc.getObject("impData")) ;
00161   RooFormulaVar* cutVar = static_cast<RooFormulaVar*>(pc.getObject("cutVar")) ;
00162   const char* cutSpec = pc.getString("cutSpec","",kTRUE) ;
00163   const char* cutRange = pc.getString("cutRange","",kTRUE) ;
00164   const char* wgtVarName = pc.getString("wgtVarName","",kTRUE) ;
00165   RooRealVar* wgtVar = static_cast<RooRealVar*>(pc.getObject("wgtVar")) ;
00166   const char* impSliceNames = pc.getString("impSliceState","",kTRUE) ;
00167   const RooLinkedList& impSliceData = pc.getObjectList("impSliceData") ;
00168   const char* lnkSliceNames = pc.getString("lnkSliceState","",kTRUE) ;
00169   const RooLinkedList& lnkSliceData = pc.getObjectList("lnkSliceData") ;
00170   RooCategory* indexCat = static_cast<RooCategory*>(pc.getObject("indexCat")) ;
00171   RooArgSet* errorSet = pc.getSet("errorSet") ;
00172   RooArgSet* asymErrorSet = pc.getSet("asymErrSet") ;
00173   const char* fname = pc.getString("fname") ;
00174   const char* tname = pc.getString("tname") ;
00175 
00176   // Case 1 --- Link multiple dataset as slices
00177   if (lnkSliceNames) {
00178 
00179     // Make import mapping if index category is specified
00180     map<string,RooAbsData*> hmap ;  
00181     if (indexCat) {
00182       char tmp[1024] ;
00183       strlcpy(tmp,lnkSliceNames,1024) ;
00184       char* token = strtok(tmp,",") ;
00185       TIterator* hiter = lnkSliceData.MakeIterator() ;
00186       while(token) {
00187         hmap[token] = (RooAbsData*) hiter->Next() ;
00188         token = strtok(0,",") ;
00189       }
00190       delete hiter ;
00191     }
00192     
00193     // Lookup name of weight variable if it was specified by object reference
00194     if (wgtVar) {
00195       // coverity[UNUSED_VALUE]
00196       wgtVarName = wgtVar->GetName() ;
00197     }
00198         
00199     appendToDir(this,kTRUE) ;
00200     
00201     // Initialize RooDataSet with optional weight variable
00202     initialize(0) ;
00203     
00204     map<string,RooAbsDataStore*> storeMap ;
00205     RooCategory* icat = (RooCategory*) (indexCat ? _vars.find(indexCat->GetName()) : 0 ) ;
00206     if (!icat) {
00207       throw std::string("RooDataSet::RooDataSet() ERROR in constructor, cannot find index category") ;
00208     }
00209     for (map<string,RooAbsData*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
00210       // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
00211       if (indexCat && !indexCat->lookupType(hiter->first.c_str())) {
00212         indexCat->defineType(hiter->first.c_str()) ;
00213         coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
00214       }
00215       if (icat && !icat->lookupType(hiter->first.c_str())) {    
00216         icat->defineType(hiter->first.c_str()) ;
00217       }
00218       icat->setLabel(hiter->first.c_str()) ;
00219       storeMap[icat->getLabel()]=hiter->second->store() ;
00220     }
00221 
00222     // Create composite datastore
00223     _dstore = new RooCompositeDataStore(name,title,_vars,*icat,storeMap) ;
00224         
00225   } else {
00226 
00227     if (wgtVar) {
00228       wgtVarName = wgtVar->GetName() ;
00229     }
00230 
00231     // Create empty datastore 
00232     RooTreeDataStore* tstore = new RooTreeDataStore(name,title,_vars,wgtVarName) ;
00233     _dstore = tstore ;
00234     
00235     
00236     // Make import mapping if index category is specified
00237     map<string,RooDataSet*> hmap ;  
00238     if (indexCat) {
00239       char tmp[1024] ;
00240       strlcpy(tmp,impSliceNames,1024) ;
00241       char* token = strtok(tmp,",") ;
00242       TIterator* hiter = impSliceData.MakeIterator() ;
00243       while(token) {
00244         hmap[token] = (RooDataSet*) hiter->Next() ;
00245         token = strtok(0,",") ;
00246       }
00247       delete hiter ;
00248     }
00249     
00250     // process StoreError requests
00251     if (errorSet) {
00252       RooArgSet* intErrorSet = (RooArgSet*) _vars.selectCommon(*errorSet) ;
00253       intErrorSet->setAttribAll("StoreError") ;
00254       TIterator* iter = intErrorSet->createIterator() ;
00255       RooAbsArg* arg ;
00256       while((arg=(RooAbsArg*)iter->Next())) {
00257         arg->attachToTree(tstore->tree()) ;
00258       }
00259       delete iter ;
00260       delete intErrorSet ;
00261     }
00262     if (asymErrorSet) {
00263       RooArgSet* intAsymErrorSet = (RooArgSet*) _vars.selectCommon(*asymErrorSet) ;
00264       intAsymErrorSet->setAttribAll("StoreAsymError") ;
00265       TIterator* iter = intAsymErrorSet->createIterator() ;
00266       RooAbsArg* arg ;
00267       while((arg=(RooAbsArg*)iter->Next())) {
00268         arg->attachToTree(tstore->tree()) ;
00269       }
00270       delete iter ;
00271       delete intAsymErrorSet ;
00272     }
00273     
00274     // Lookup name of weight variable if it was specified by object reference
00275     if (wgtVar) {
00276       wgtVarName = wgtVar->GetName() ;
00277     }
00278     
00279     
00280     appendToDir(this,kTRUE) ;
00281     
00282     // Initialize RooDataSet with optional weight variable
00283     if (wgtVarName && *wgtVarName) {
00284       // Use the supplied weight column
00285       initialize(wgtVarName) ;    
00286     } else {
00287       if (impData && impData->_wgtVar && vars.find(impData->_wgtVar->GetName())) {
00288         // Use the weight column of the source data set
00289         initialize(impData->_wgtVar->GetName()) ;
00290 
00291       } else if (indexCat) {
00292 
00293         RooDataSet* firstDS = hmap.begin()->second ;
00294         if (firstDS->_wgtVar && vars.find(firstDS->_wgtVar->GetName())) {
00295           initialize(firstDS->_wgtVar->GetName()) ;      
00296         } else {
00297           initialize(0) ;
00298         }
00299       } else {
00300         initialize(0) ;
00301       }
00302     }
00303     
00304     // Import one or more datasets with a cut specification
00305     if (cutSpec && *cutSpec) {
00306       
00307       // Create a RooFormulaVar cut from given cut expression
00308       if (indexCat) {
00309 
00310         // Case 2a --- Import multiple RooDataSets as slices with cutspec
00311         RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
00312         for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
00313           // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
00314           if (!indexCat->lookupType(hiter->first.c_str())) {
00315             indexCat->defineType(hiter->first.c_str()) ;
00316             coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
00317           }
00318           if (!icat->lookupType(hiter->first.c_str())) {        
00319             icat->defineType(hiter->first.c_str()) ;
00320           }
00321           icat->setLabel(hiter->first.c_str()) ;
00322           
00323           RooFormulaVar cutVarTmp(cutSpec,cutSpec,hiter->second->_vars) ;
00324           tstore->loadValues(hiter->second->store(),&cutVarTmp,cutRange) ;
00325         }
00326         
00327       } else if (impData) {
00328 
00329         // Case 3a --- Import RooDataSet with cutspec
00330         RooFormulaVar cutVarTmp(cutSpec,cutSpec,impData->_vars) ;
00331         tstore->loadValues(impData->store(),&cutVarTmp,cutRange);
00332       } else if (impTree) {
00333 
00334         // Case 4a --- Import TTree from memory with cutspec
00335         RooFormulaVar cutVarTmp(cutSpec,cutSpec,_vars) ;
00336         tstore->loadValues(impTree,&cutVarTmp,cutRange);      
00337       } else if (fname && strlen(fname)) {
00338 
00339         // Case 5a --- Import TTree from file with cutspec
00340         TFile *f = TFile::Open(fname) ;
00341         if (!f) {
00342           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;      
00343           throw string(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
00344         }
00345         TTree* t = dynamic_cast<TTree*>(f->Get(tname)) ;
00346         if (!t) {
00347           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
00348           throw string(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
00349         }
00350         RooFormulaVar cutVarTmp(cutSpec,cutSpec,_vars) ;
00351         tstore->loadValues(t,&cutVarTmp,cutRange);              
00352         f->Close() ;
00353 
00354       }
00355       
00356       // Import one or more datasets with a cut formula
00357     } else if (cutVar) {
00358       
00359       if (indexCat) {
00360         
00361         // Case 2b --- Import multiple RooDataSets as slices with cutvar
00362 
00363         RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
00364         for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
00365           // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
00366           if (!indexCat->lookupType(hiter->first.c_str())) {
00367             indexCat->defineType(hiter->first.c_str()) ;
00368             coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
00369           }
00370           if (!icat->lookupType(hiter->first.c_str())) {        
00371             icat->defineType(hiter->first.c_str()) ;
00372           }
00373           icat->setLabel(hiter->first.c_str()) ;
00374           tstore->loadValues(hiter->second->store(),cutVar,cutRange) ;
00375         }
00376         
00377         
00378       } else if (impData) {
00379         // Case 3b --- Import RooDataSet with cutvar
00380         tstore->loadValues(impData->store(),cutVar,cutRange);
00381       } else if (impTree) {
00382         // Case 4b --- Import TTree from memory with cutvar
00383         tstore->loadValues(impTree,cutVar,cutRange);
00384       } else if (fname && strlen(fname)) {
00385         // Case 5b --- Import TTree from file with cutvar
00386         TFile *f = TFile::Open(fname) ;
00387         if (!f) {
00388           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;      
00389           throw string(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
00390         }
00391         TTree* t = dynamic_cast<TTree*>(f->Get(tname)) ;
00392         if (!t) {
00393           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
00394           throw string(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
00395         }
00396         tstore->loadValues(t,cutVar,cutRange);          
00397         f->Close() ;
00398       }
00399       
00400       // Import one or more datasets without cuts
00401     } else {
00402       
00403       if (indexCat) {
00404         
00405         RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
00406         for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
00407           // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
00408           if (!indexCat->lookupType(hiter->first.c_str())) {
00409             indexCat->defineType(hiter->first.c_str()) ;
00410             coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
00411           }
00412           if (!icat->lookupType(hiter->first.c_str())) {        
00413             icat->defineType(hiter->first.c_str()) ;
00414           }
00415           icat->setLabel(hiter->first.c_str()) ;
00416           // Case 2c --- Import multiple RooDataSets as slices
00417           tstore->loadValues(hiter->second->store(),0,cutRange) ;
00418         }
00419         
00420         
00421       } else if (impData) {
00422         // Case 3c --- Import RooDataSet
00423         tstore->loadValues(impData->store(),0,cutRange);
00424       } else if (impTree) {
00425         // Case 4c --- Import TTree from memort
00426         tstore->loadValues(impTree,0,cutRange);
00427       } else if (fname && strlen(fname)) {
00428         // Case 5c --- Import TTree from file
00429         TFile *f = TFile::Open(fname) ;
00430         if (!f) {
00431           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;      
00432           throw string(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
00433         }
00434         TTree* t = dynamic_cast<TTree*>(f->Get(tname)) ;
00435         if (!t) {
00436           coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
00437           throw string(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
00438         }
00439         tstore->loadValues(t,0,cutRange);       
00440         f->Close() ;
00441       }
00442     }
00443     
00444   }
00445 }
00446 
00447 
00448 
00449 //_____________________________________________________________________________
00450 RooDataSet::RooDataSet(const char *name, const char *title, const RooArgSet& vars, const char* wgtVarName) :
00451   RooAbsData(name,title,vars)
00452 {
00453   // Constructor of an empty data set from a RooArgSet defining the dimensions
00454   // of the data space.
00455 
00456   _dstore = new RooTreeDataStore(name,title,_vars,wgtVarName) ;
00457 
00458   appendToDir(this,kTRUE) ;
00459   initialize(wgtVarName) ;
00460 }
00461 
00462 
00463 //_____________________________________________________________________________
00464 RooDataSet::RooDataSet(const char *name, const char *title, RooDataSet *dset, 
00465                        const RooArgSet& vars, const char *cuts, const char* wgtVarName) :
00466   RooAbsData(name,title,vars)
00467 {
00468   // Constructor of a data set from (part of) an existing data
00469   // set. The dimensions of the data set are defined by the 'vars'
00470   // RooArgSet, which can be identical to 'dset' dimensions, or a
00471   // subset thereof. The 'cuts' string is an optional RooFormula
00472   // expression and can be used to select the subset of the data
00473   // points in 'dset' to be copied. The cut expression can refer to
00474   // any variable in the source dataset. For cuts involving variables
00475   // other than those contained in the source data set, such as
00476   // intermediate formula objects, use the equivalent constructor
00477   // accepting RooFormulaVar reference as cut specification
00478   //
00479   // For most uses the RooAbsData::reduce() wrapper function, which
00480   // uses this constructor, is the most convenient way to create a
00481   // subset of an existing data
00482   //
00483 
00484   // Initialize datastore
00485   _dstore = new RooTreeDataStore(name,title,_vars,*dset->_dstore,cuts,wgtVarName) ;
00486 
00487   appendToDir(this,kTRUE) ;
00488   
00489   if (wgtVarName) {
00490     // Use the supplied weight column
00491     initialize(wgtVarName) ;    
00492   } else {
00493     if (dset->_wgtVar && vars.find(dset->_wgtVar->GetName())) {
00494       // Use the weight column of the source data set
00495       initialize(dset->_wgtVar->GetName()) ;
00496     } else {
00497       initialize(0) ;
00498     }
00499   }
00500 
00501 }
00502 
00503 
00504 //_____________________________________________________________________________
00505 RooDataSet::RooDataSet(const char *name, const char *title, RooDataSet *dset, 
00506                        const RooArgSet& vars, const RooFormulaVar& cutVar, const char* wgtVarName) :
00507   RooAbsData(name,title,vars)
00508 {
00509   // Constructor of a data set from (part of) an existing data
00510   // set. The dimensions of the data set are defined by the 'vars'
00511   // RooArgSet, which can be identical to 'dset' dimensions, or a
00512   // subset thereof. The 'cutVar' formula variable is used to select
00513   // the subset of data points to be copied.  For subsets without
00514   // selection on the data points, or involving cuts operating
00515   // exclusively and directly on the data set dimensions, the
00516   // equivalent constructor with a string based cut expression is
00517   // recommended.
00518   //
00519   // For most uses the RooAbsData::reduce() wrapper function, which
00520   // uses this constructor, is the most convenient way to create a
00521   // subset of an existing data
00522 
00523   // Initialize datastore
00524   _dstore = new RooTreeDataStore(name,title,_vars,*dset->_dstore,cutVar,wgtVarName) ;
00525 
00526   appendToDir(this,kTRUE) ;
00527 
00528   if (wgtVarName) {
00529     // Use the supplied weight column
00530     initialize(wgtVarName) ;    
00531   } else {
00532     if (dset->_wgtVar && vars.find(dset->_wgtVar->GetName())) {
00533       // Use the weight column of the source data set
00534       initialize(dset->_wgtVar->GetName()) ;
00535     } else {
00536       initialize(0) ;
00537     }
00538   }
00539 }
00540 
00541 
00542 
00543 
00544 //_____________________________________________________________________________
00545 RooDataSet::RooDataSet(const char *name, const char *title, TTree *intree, 
00546                        const RooArgSet& vars, const RooFormulaVar& cutVar, const char* wgtVarName) :
00547   RooAbsData(name,title,vars)
00548 {
00549   // Constructor of a data set from (part of) an ROOT TTRee. The dimensions
00550   // of the data set are defined by the 'vars' RooArgSet. For each dimension
00551   // specified, the TTree must have a branch with the same name. For category
00552   // branches, this branch should contain the numeric index value. Real dimensions
00553   // can be constructed from either 'Double_t' or 'Float_t' tree branches. In the
00554   // latter case, an automatic conversion is applied.
00555   //
00556   // The 'cutVar' formula variable
00557   // is used to select the subset of data points to be copied.
00558   // For subsets without selection on the data points, or involving cuts
00559   // operating exclusively and directly on the data set dimensions, the equivalent
00560   // constructor with a string based cut expression is recommended.
00561 
00562   // Initialize datastore
00563   _dstore = new RooTreeDataStore(name,title,_vars,*intree,cutVar,wgtVarName) ;
00564 
00565   appendToDir(this,kTRUE) ;
00566 
00567   initialize(wgtVarName) ;
00568 }
00569 
00570 
00571 
00572 //_____________________________________________________________________________
00573 RooDataSet::RooDataSet(const char *name, const char *title, TTree *intree, 
00574                        const RooArgSet& vars, const char *selExpr, const char* wgtVarName) :
00575   RooAbsData(name,title,vars)
00576 {
00577   // Constructor of a data set from (part of) an ROOT TTRee. The dimensions
00578   // of the data set are defined by the 'vars' RooArgSet. For each dimension
00579   // specified, the TTree must have a branch with the same name. For category
00580   // branches, this branch should contain the numeric index value. Real dimensions
00581   // can be constructed from either 'Double_t' or 'Float_t' tree branches. In the
00582   // latter case, an automatic conversion is applied.
00583   //
00584   // The 'cuts' string is an optional
00585   // RooFormula expression and can be used to select the subset of the data points 
00586   // in 'dset' to be copied. The cut expression can refer to any variable in the
00587   // vars argset. For cuts involving variables other than those contained in
00588   // the vars argset, such as intermediate formula objects, use the 
00589   // equivalent constructor accepting RooFormulaVar reference as cut specification
00590   //
00591 
00592   // Initialize datastore
00593   _dstore = new RooTreeDataStore(name,title,_vars,*intree,selExpr,wgtVarName) ;
00594 
00595   appendToDir(this,kTRUE) ;
00596 
00597   initialize(wgtVarName) ;
00598 }
00599 
00600 
00601 
00602 //_____________________________________________________________________________
00603 RooDataSet::RooDataSet(RooDataSet const & other, const char* newname) :
00604   RooAbsData(other,newname), RooDirItem()
00605 {
00606   // Copy constructor
00607 
00608   appendToDir(this,kTRUE) ;
00609   initialize(other._wgtVar?other._wgtVar->GetName():0) ;
00610 }
00611 
00612 //_____________________________________________________________________________
00613 RooDataSet::RooDataSet(const char *name, const char *title, RooDataSet *dset, 
00614                        const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
00615                        Int_t nStart, Int_t nStop, Bool_t copyCache, const char* wgtVarName) :
00616   RooAbsData(name,title,vars)
00617 {
00618   // Protected constructor for internal use only
00619 
00620   _dstore = new RooTreeDataStore(name,title,*dset->_dstore,_vars,cutVar,cutRange,nStart,nStop,copyCache,wgtVarName) ;
00621   _cachedVars.add(_dstore->cachedVars()) ;
00622 
00623   appendToDir(this,kTRUE) ;
00624   initialize(dset->_wgtVar?dset->_wgtVar->GetName():0) ;
00625 }
00626 
00627 
00628 //_____________________________________________________________________________
00629 RooArgSet RooDataSet::addWgtVar(const RooArgSet& origVars, const RooAbsArg* wgtVar)
00630 {
00631   // Helper function for constructor that adds optional weight variable to construct
00632   // total set of observables
00633 
00634   RooArgSet tmp(origVars) ;
00635   if (wgtVar) tmp.add(*wgtVar) ;
00636   return tmp ;
00637 }
00638 
00639 
00640 
00641 //_____________________________________________________________________________
00642 RooAbsData* RooDataSet::cacheClone(const RooAbsArg* newCacheOwner, const RooArgSet* newCacheVars, const char* newName) 
00643 {
00644   // Return a clone of this dataset containing only the cached variables
00645 
00646   RooDataSet* dset = new RooDataSet(newName?newName:GetName(),GetTitle(),this,_vars,(RooFormulaVar*)0,0,0,2000000000,kTRUE,_wgtVar?_wgtVar->GetName():0) ;  
00647   //if (_wgtVar) dset->setWeightVar(_wgtVar->GetName()) ;
00648 
00649   RooArgSet* selCacheVars = (RooArgSet*) newCacheVars->selectCommon(dset->_cachedVars) ;
00650   dset->attachCache(newCacheOwner, *selCacheVars) ;
00651   delete selCacheVars ;
00652 
00653   return dset ;
00654 }
00655 
00656 
00657 
00658 //_____________________________________________________________________________
00659 RooAbsData* RooDataSet::emptyClone(const char* newName, const char* newTitle, const RooArgSet* vars) const 
00660 {
00661   // Return an empty clone of this dataset. If vars is not null, only the variables in vars
00662   // are added to the definition of the empty clone
00663 
00664   // If variables are given, be sure to include weight variable if it exists and is not included
00665   RooArgSet vars2 ;
00666   if (vars) {
00667     vars2.add(*vars) ;
00668     if (_wgtVar && !vars2.find(_wgtVar->GetName())) {
00669       vars2.add(*_wgtVar) ;
00670     }
00671   } else {
00672     vars2.add(_vars) ;
00673   }
00674 
00675   RooDataSet* dset = new RooDataSet(newName?newName:GetName(),newTitle?newTitle:GetTitle(),vars2,_wgtVar?_wgtVar->GetName():0) ; 
00676   //if (_wgtVar) dset->setWeightVar(_wgtVar->GetName()) ;
00677   return dset ;
00678 }
00679 
00680 
00681 
00682 //_____________________________________________________________________________
00683 void RooDataSet::initialize(const char* wgtVarName) 
00684 {
00685   // Initialize the dataset. If wgtVarName is not null, interpret the observable
00686   // with that name as event weight
00687 
00688   _varsNoWgt.removeAll() ;
00689   _varsNoWgt.add(_vars) ;
00690   _wgtVar = 0 ;
00691   if (wgtVarName) {
00692     RooAbsArg* wgt = _varsNoWgt.find(wgtVarName) ;
00693     if (!wgt) {
00694       coutW(DataHandling) << "RooDataSet::RooDataSet(" << GetName() << ") WARNING: designated weight variable " 
00695                           << wgtVarName << " not found in set of variables, no weighting will be assigned" << endl ;
00696     } else if (!dynamic_cast<RooRealVar*>(wgt)) {
00697       coutW(DataHandling) << "RooDataSet::RooDataSet(" << GetName() << ") WARNING: designated weight variable " 
00698                           << wgtVarName << " is not of type RooRealVar, no weighting will be assigned" << endl ;
00699     } else {
00700       _varsNoWgt.remove(*wgt) ;
00701       _wgtVar = (RooRealVar*) wgt ;
00702     }
00703   }
00704 }
00705 
00706 
00707 
00708 //_____________________________________________________________________________
00709 RooAbsData* RooDataSet::reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange, 
00710                                   Int_t nStart, Int_t nStop, Bool_t copyCache)
00711 {
00712   // Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods
00713   checkInit() ;
00714 
00715   RooArgSet tmp(varSubset) ;
00716   if (_wgtVar) {
00717     tmp.add(*_wgtVar) ;
00718   }
00719   RooDataSet* ret =  new RooDataSet(GetName(), GetTitle(), this, tmp, cutVar, cutRange, nStart, nStop, copyCache,_wgtVar?_wgtVar->GetName():0) ;
00720   
00721   // WVE - propagate optional weight variable
00722   //       check behaviour in plotting.
00723 //   if (_wgtVar) {
00724 //     ret->setWeightVar(_wgtVar->GetName()) ;
00725 //   }
00726   return ret ;
00727 }
00728 
00729 
00730 
00731 //_____________________________________________________________________________
00732 RooDataSet::~RooDataSet()
00733 {
00734   // Destructor
00735 
00736   removeFromDir(this) ;
00737 }
00738 
00739 
00740 
00741 //_____________________________________________________________________________
00742 RooDataHist* RooDataSet::binnedClone(const char* newName, const char* newTitle) const 
00743 {
00744   // Return binned clone of this dataset
00745 
00746   TString title, name ;
00747   if (newName) {
00748     name = newName ;
00749   } else {
00750     name = Form("%s_binned",GetName()) ;
00751   }
00752   if (newTitle) {
00753     title = newTitle ;
00754   } else {
00755     title = Form("%s_binned",GetTitle()) ;
00756   }
00757 
00758   return new RooDataHist(name,title,*get(),*this) ;
00759 }
00760 
00761 
00762 
00763 //_____________________________________________________________________________
00764 Double_t RooDataSet::weight() const 
00765 {
00766   // Return event weight of current event
00767 
00768   return store()->weight() ; 
00769 }
00770 
00771 
00772 
00773 
00774 //_____________________________________________________________________________
00775 void RooDataSet::weightError(Double_t& lo, Double_t& hi, ErrorType etype) const 
00776 {
00777   store()->weightError(lo,hi,etype) ;
00778 }
00779 
00780 
00781 
00782 //_____________________________________________________________________________
00783 Double_t RooDataSet::weightError(ErrorType etype) const 
00784 {
00785   return store()->weightError(etype) ;
00786 }
00787 
00788 
00789 
00790 //_____________________________________________________________________________
00791 const RooArgSet* RooDataSet::get(Int_t index) const
00792 {
00793   // Return RooArgSet with coordinates of event 'index' 
00794   const RooArgSet* ret  = RooAbsData::get(index) ;
00795   return ret ? &_varsNoWgt : 0 ;
00796 }
00797 
00798 
00799 
00800 //_____________________________________________________________________________
00801 Double_t RooDataSet::sumEntries(const char* cutSpec, const char* cutRange) const 
00802 {
00803   // Return the sum of weights in all entries matching cutSpec (if specified)
00804   // and in named range cutRange (if specified)
00805 
00806   // Setup RooFormulaVar for cutSpec if it is present
00807   RooFormula* select = 0 ;
00808   if (cutSpec) {
00809     select = new RooFormula("select",cutSpec,*get()) ;
00810   }
00811 
00812   // Otherwise sum the weights in the event
00813   Double_t sumw(0) ;
00814   Int_t i ;
00815   for (i=0 ; i<numEntries() ; i++) {
00816     get(i) ;
00817     if (select && select->eval()==0.) continue ;
00818     if (cutRange && !_vars.allInRange(cutRange)) continue ;
00819     sumw += weight() ;
00820   }
00821 
00822   if (select) delete select ;
00823 
00824   return sumw ;  
00825 }
00826 
00827 
00828 
00829 
00830 //_____________________________________________________________________________
00831 Bool_t RooDataSet::isWeighted() const
00832 { 
00833     // Return true if dataset contains weighted events
00834     return store()->isWeighted() ;
00835 }
00836 
00837 
00838 
00839 //_____________________________________________________________________________
00840 Bool_t RooDataSet::isNonPoissonWeighted() const
00841 {
00842   // Returns true if histogram contains bins with entries with a non-integer weight
00843 
00844   // Return false if we have no weights
00845   if (!_wgtVar) return kFALSE ;
00846   
00847   // Now examine individual weights
00848   for (int i=0 ; i<numEntries() ; i++) {
00849     get(i) ;
00850     if (fabs(weight()-Int_t(weight()))>1e-10) return kTRUE ;
00851   }
00852   // If sum of weights is less than number of events there are negative (integer) weights
00853   if (sumEntries()<numEntries()) return kTRUE ;
00854 
00855   return kFALSE ;
00856 }
00857 
00858 
00859 
00860 
00861 //_____________________________________________________________________________
00862 const RooArgSet* RooDataSet::get() const 
00863 { 
00864   // Return a RooArgSet with the coordinates of the current event
00865   return &_varsNoWgt ; 
00866 } 
00867 
00868 
00869 
00870 //_____________________________________________________________________________
00871 void RooDataSet::add(const RooArgSet& data, Double_t wgt, Double_t wgtError) 
00872 {
00873   // Add a data point, with its coordinates specified in the 'data' argset, to the data set. 
00874   // Any variables present in 'data' but not in the dataset will be silently ignored
00875   //
00876   checkInit() ;
00877   _varsNoWgt = data;
00878   if (_wgtVar) {
00879     _wgtVar->setVal(wgt) ;
00880     if (wgtError!=0.) {
00881       _wgtVar->setError(wgtError) ;
00882     }
00883   }
00884   fill();
00885 }
00886 
00887 
00888 
00889 
00890 //_____________________________________________________________________________
00891 void RooDataSet::add(const RooArgSet& indata, Double_t inweight, Double_t weightErrorLo, Double_t weightErrorHi) 
00892 {
00893   // Add a data point, with its coordinates specified in the 'data' argset, to the data set. 
00894   // Any variables present in 'data' but not in the dataset will be silently ignored
00895   //
00896   checkInit() ;
00897 
00898   _varsNoWgt = indata;
00899   if (_wgtVar) {
00900     _wgtVar->setVal(inweight) ;
00901     _wgtVar->setAsymError(weightErrorLo,weightErrorHi) ;
00902   }
00903   fill();
00904 }
00905 
00906 
00907 
00908 
00909 
00910 //_____________________________________________________________________________
00911 void RooDataSet::addFast(const RooArgSet& data, Double_t wgt, Double_t wgtError) 
00912 {
00913   // Add a data point, with its coordinates specified in the 'data' argset, to the data set. 
00914   // Layout and size of input argument data is ASSUMED to be the same as RooArgSet returned
00915   // RooDataSet::get()
00916   //
00917 
00918   checkInit() ;
00919   _varsNoWgt.assignFast(data);
00920   if (_wgtVar) {
00921     _wgtVar->setVal(wgt) ;
00922     if (wgtError!=0.) {
00923       _wgtVar->setError(wgtError) ;
00924     }
00925   }
00926   fill();
00927 }
00928 
00929 
00930 
00931 //_____________________________________________________________________________
00932 Bool_t RooDataSet::merge(RooDataSet* data1, RooDataSet* data2, RooDataSet* data3, 
00933                          RooDataSet* data4, RooDataSet* data5, RooDataSet* data6) 
00934 {
00935   checkInit() ;
00936   list<RooDataSet*> dsetList ;
00937   if (data1) dsetList.push_back(data1) ;
00938   if (data2) dsetList.push_back(data2) ;
00939   if (data3) dsetList.push_back(data3) ;
00940   if (data4) dsetList.push_back(data4) ;
00941   if (data5) dsetList.push_back(data5) ;
00942   if (data6) dsetList.push_back(data6) ;
00943   return merge(dsetList) ;
00944 }
00945 
00946 
00947 
00948 //_____________________________________________________________________________
00949 Bool_t RooDataSet::merge(list<RooDataSet*>dsetList)
00950 {
00951   // Merge columns of supplied data set(s) with this data set.  All
00952   // data sets must have equal number of entries.  In case of
00953   // duplicate columns the column of the last dataset in the list
00954   // prevails
00955 
00956 
00957   checkInit() ;
00958   // Sanity checks: data sets must have the same size
00959   for (list<RooDataSet*>::iterator iter = dsetList.begin() ; iter != dsetList.end() ; iter++) {
00960     if (numEntries()!=(*iter)->numEntries()) {
00961       coutE(InputArguments) << "RooDataSet::merge(" << GetName() << ") ERROR: datasets have different size" << endl ;
00962       return kTRUE ;    
00963     }
00964   }
00965 
00966   // Extend vars with elements of other dataset
00967   list<RooAbsDataStore*> dstoreList ;
00968   for (list<RooDataSet*>::iterator iter = dsetList.begin() ; iter != dsetList.end() ; iter++) {
00969     _vars.addClone((*iter)->_vars,kTRUE) ;
00970     dstoreList.push_back((*iter)->store()) ;
00971   }
00972 
00973   // Merge data stores
00974   RooAbsDataStore* mergedStore = _dstore->merge(_vars,dstoreList) ;
00975   mergedStore->SetName(_dstore->GetName()) ;
00976   mergedStore->SetTitle(_dstore->GetTitle()) ;
00977 
00978   // Replace current data store with merged store
00979   delete _dstore ;
00980   _dstore = mergedStore ;
00981 
00982   initialize(_wgtVar?_wgtVar->GetName():0) ;
00983   return kFALSE ;
00984 }
00985 
00986 
00987 //_____________________________________________________________________________
00988 void RooDataSet::append(RooDataSet& data) 
00989 {
00990   // Add all data points of given data set to this data set.
00991   // Observable in 'data' that are not in this dataset
00992   // with not be transferred
00993   checkInit() ;
00994   _dstore->append(*data._dstore) ;
00995 }
00996 
00997 
00998 
00999 //_____________________________________________________________________________
01000 RooAbsArg* RooDataSet::addColumn(RooAbsArg& var, Bool_t adjustRange) 
01001 {
01002   // Add a column with the values of the given (function) argument
01003   // to this dataset. The function value is calculated for each
01004   // event using the observable values of each event in case the
01005   // function depends on variables with names that are identical
01006   // to the observable names in the dataset
01007 
01008   checkInit() ;
01009   RooAbsArg* ret = _dstore->addColumn(var,adjustRange) ;
01010   _vars.addOwned(*ret) ;
01011   initialize(_wgtVar?_wgtVar->GetName():0) ;
01012   return ret ;
01013 }
01014 
01015 
01016 //_____________________________________________________________________________
01017 RooArgSet* RooDataSet::addColumns(const RooArgList& varList) 
01018 {
01019   // Add a column with the values of the given list of (function)
01020   // argument to this dataset. Each function value is calculated for
01021   // each event using the observable values of the event in case the
01022   // function depends on variables with names that are identical to
01023   // the observable names in the dataset
01024 
01025   checkInit() ;
01026   RooArgSet* ret = _dstore->addColumns(varList) ;  
01027   _vars.addOwned(*ret) ;
01028   initialize(_wgtVar?_wgtVar->GetName():0) ;
01029   return ret ;
01030 }
01031 
01032 
01033 
01034 //_____________________________________________________________________________
01035 TH2F* RooDataSet::createHistogram(const RooAbsRealLValue& var1, const RooAbsRealLValue& var2, const char* cuts, const char *name) const
01036 {
01037   // Create a TH2F histogram of the distribution of the specified variable
01038   // using this dataset. Apply any cuts to select which events are used.
01039   // The variable being plotted can either be contained directly in this
01040   // dataset, or else be a function of the variables in this dataset.
01041   // The histogram will be created using RooAbsReal::createHistogram() with
01042   // the name provided (with our dataset name prepended).
01043   checkInit() ;
01044   return createHistogram(var1, var2, var1.getBins(), var2.getBins(), cuts, name);
01045 }
01046 
01047 
01048 
01049 //_____________________________________________________________________________
01050 TH2F* RooDataSet::createHistogram(const RooAbsRealLValue& var1, const RooAbsRealLValue& var2, 
01051                                   Int_t nx, Int_t ny, const char* cuts, const char *name) const
01052 {
01053   // Create a TH2F histogram of the distribution of the specified variable
01054   // using this dataset. Apply any cuts to select which events are used.
01055   // The variable being plotted can either be contained directly in this
01056   // dataset, or else be a function of the variables in this dataset.
01057   // The histogram will be created using RooAbsReal::createHistogram() with
01058   // the name provided (with our dataset name prepended).
01059 
01060   checkInit() ;
01061   static Int_t counter(0) ;
01062 
01063   Bool_t ownPlotVarX(kFALSE) ;
01064   // Is this variable in our dataset?
01065   RooAbsReal* plotVarX= (RooAbsReal*)_vars.find(var1.GetName());
01066   if(0 == plotVarX) {
01067     // Is this variable a client of our dataset?
01068     if (!var1.dependsOn(_vars)) {
01069       coutE(InputArguments) << GetName() << "::createHistogram: Argument " << var1.GetName() 
01070                             << " is not in dataset and is also not dependent on data set" << endl ;
01071       return 0 ; 
01072     }
01073 
01074     // Clone derived variable 
01075     plotVarX = (RooAbsReal*) var1.Clone()  ;
01076     ownPlotVarX = kTRUE ;
01077 
01078     //Redirect servers of derived clone to internal ArgSet representing the data in this set
01079     plotVarX->redirectServers(const_cast<RooArgSet&>(_vars)) ;
01080   }
01081 
01082   Bool_t ownPlotVarY(kFALSE) ;
01083   // Is this variable in our dataset?
01084   RooAbsReal* plotVarY= (RooAbsReal*)_vars.find(var2.GetName());
01085   if(0 == plotVarY) {
01086     // Is this variable a client of our dataset?
01087     if (!var2.dependsOn(_vars)) {
01088       coutE(InputArguments) << GetName() << "::createHistogram: Argument " << var2.GetName() 
01089                             << " is not in dataset and is also not dependent on data set" << endl ;
01090       return 0 ; 
01091     }
01092 
01093     // Clone derived variable 
01094     plotVarY = (RooAbsReal*) var2.Clone()  ;
01095     ownPlotVarY = kTRUE ;
01096 
01097     //Redirect servers of derived clone to internal ArgSet representing the data in this set
01098     plotVarY->redirectServers(const_cast<RooArgSet&>(_vars)) ;
01099   }
01100 
01101   // Create selection formula if selection cuts are specified
01102   RooFormula* select = 0;
01103   if(0 != cuts && strlen(cuts)) {
01104     select=new RooFormula(cuts,cuts,_vars);
01105     if (!select || !select->ok()) {
01106       delete select;
01107       return 0 ;
01108     }
01109   }
01110   
01111   TString histName(name);
01112   histName.Prepend("_");
01113   histName.Prepend(fName);
01114   histName.Append("_") ;
01115   histName.Append(Form("%08x",counter++)) ;
01116 
01117   // create the histogram
01118   TH2F* histogram=new TH2F(histName.Data(), "Events", nx, var1.getMin(), var1.getMax(), 
01119                                                       ny, var2.getMin(), var2.getMax());
01120   if(!histogram) {
01121     coutE(DataHandling) << fName << "::createHistogram: unable to create a new histogram" << endl;
01122     return 0;
01123   }
01124 
01125   // Dump contents  
01126   Int_t nevent= numEntries() ;
01127   for(Int_t i=0; i < nevent; ++i) 
01128   {
01129     get(i);
01130     
01131     if (select && select->eval()==0) continue ;
01132     histogram->Fill(plotVarX->getVal(), plotVarY->getVal()) ;
01133   }
01134 
01135   if (ownPlotVarX) delete plotVarX ;
01136   if (ownPlotVarY) delete plotVarY ;
01137   if (select) delete select ;
01138 
01139   return histogram ;
01140 }
01141 
01142 
01143 
01144 
01145 
01146 //_____________________________________________________________________________
01147 RooPlot* RooDataSet::plotOnXY(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
01148                               const RooCmdArg& arg3, const RooCmdArg& arg4,
01149                               const RooCmdArg& arg5, const RooCmdArg& arg6,
01150                               const RooCmdArg& arg7, const RooCmdArg& arg8) const 
01151 {
01152   // Special plot method for 'X-Y' datasets used in Chi^2 fitting. These datasets 
01153   // have one observable (X) and have weights (Y) and associated errors.
01154   //
01155   // Contents options
01156   // ---------------------
01157   // YVar(RooRealVar& var)           -- Designate specified observable as 'y' variable
01158   //                                    If not specified, the event weight will be the y variable
01159   // Histogram drawing options
01160   // -------------------------
01161   // DrawOption(const char* opt)     -- Select ROOT draw option for resulting TGraph object
01162   // LineStyle(Int_t style)          -- Select line style by ROOT line style code, default is solid
01163   // LineColor(Int_t color)          -- Select line color by ROOT color code, default is black
01164   // LineWidth(Int_t width)          -- Select line with in pixels, default is 3
01165   // MarkerStyle(Int_t style)        -- Select the ROOT marker style, default is 21
01166   // MarkerColor(Int_t color)        -- Select the ROOT marker color, default is black
01167   // MarkerSize(Double_t size)       -- Select the ROOT marker size
01168   // Rescale(Double_t factor)        -- Apply global rescaling factor to histogram
01169   //
01170   //
01171   // Misc. other options
01172   // -------------------
01173   // Name(const chat* name)          -- Give curve specified name in frame. Useful if curve is to be referenced later
01174   // Invisible(Bool_t flag)          -- Add curve to frame, but do not display. Useful in combination AddTo()
01175   // 
01176 
01177   checkInit() ;
01178 
01179   RooLinkedList argList ;
01180   argList.Add((TObject*)&arg1) ;  argList.Add((TObject*)&arg2) ;  
01181   argList.Add((TObject*)&arg3) ;  argList.Add((TObject*)&arg4) ;
01182   argList.Add((TObject*)&arg5) ;  argList.Add((TObject*)&arg6) ;  
01183   argList.Add((TObject*)&arg7) ;  argList.Add((TObject*)&arg8) ;
01184 
01185   // Process named arguments
01186   RooCmdConfig pc(Form("RooDataSet::plotOnXY(%s)",GetName())) ;
01187   pc.defineString("drawOption","DrawOption",0,"P") ;
01188   pc.defineString("histName","Name",0,"") ;
01189   pc.defineInt("lineColor","LineColor",0,-999) ;
01190   pc.defineInt("lineStyle","LineStyle",0,-999) ;
01191   pc.defineInt("lineWidth","LineWidth",0,-999) ;
01192   pc.defineInt("markerColor","MarkerColor",0,-999) ;
01193   pc.defineInt("markerStyle","MarkerStyle",0,8) ;
01194   pc.defineDouble("markerSize","MarkerSize",0,-999) ;
01195   pc.defineInt("fillColor","FillColor",0,-999) ;
01196   pc.defineInt("fillStyle","FillStyle",0,-999) ;
01197   pc.defineInt("histInvisible","Invisible",0,0) ;
01198   pc.defineDouble("scaleFactor","Rescale",0,1.) ;
01199   pc.defineObject("xvar","XVar",0,0) ;
01200   pc.defineObject("yvar","YVar",0,0) ;
01201 
01202   
01203   // Process & check varargs 
01204   pc.process(argList) ;
01205   if (!pc.ok(kTRUE)) {
01206     return frame ;
01207   }
01208   
01209   // Extract values from named arguments
01210   const char* drawOptions = pc.getString("drawOption") ;
01211   Int_t histInvisible = pc.getInt("histInvisible") ;
01212   const char* histName = pc.getString("histName",0,kTRUE) ;
01213   Double_t scaleFactor = pc.getDouble("scaleFactor") ;
01214 
01215   RooRealVar* xvar = (RooRealVar*) _vars.find(frame->getPlotVar()->GetName()) ;
01216 
01217   // Determine Y variable (default is weight, if present)
01218   RooRealVar* yvar = (RooRealVar*)(pc.getObject("yvar")) ;
01219 
01220   // Sanity check. XY plotting only applies to weighted datasets if no YVar is specified
01221   if (!_wgtVar && !yvar) {
01222     coutE(InputArguments) << "RooDataSet::plotOnXY(" << GetName() << ") ERROR: no YVar() argument specified and dataset is not weighted" << endl ;
01223     return 0 ;
01224   }
01225   
01226   RooRealVar* dataY = yvar ? (RooRealVar*) _vars.find(yvar->GetName()) : 0 ;
01227   if (yvar && !dataY) {
01228     coutE(InputArguments) << "RooDataSet::plotOnXY(" << GetName() << ") ERROR on YVar() argument, dataset does not contain a variable named " << yvar->GetName() << endl ;
01229     return 0 ;
01230   }
01231 
01232 
01233   // Make RooHist representing XY contents of data
01234   RooHist* graph = new RooHist ;
01235   if (histName) {
01236     graph->SetName(histName) ;
01237   } else {
01238     graph->SetName(Form("hxy_%s",GetName())) ;
01239   }
01240   
01241   for (int i=0 ; i<numEntries() ; i++) {
01242     get(i) ;
01243     Double_t x = xvar->getVal() ;
01244     Double_t exlo = xvar->getErrorLo() ;
01245     Double_t exhi = xvar->getErrorHi() ;
01246     Double_t y,eylo,eyhi ;
01247     if (!dataY) {
01248       y = weight() ;
01249       weightError(eylo,eyhi) ;
01250     } else {
01251       y = dataY->getVal() ;
01252       eylo = dataY->getErrorLo() ;
01253       eyhi = dataY->getErrorHi() ;
01254     }
01255     graph->addBinWithXYError(x,y,-1*exlo,exhi,-1*eylo,eyhi,scaleFactor) ;
01256   }
01257 
01258   // Adjust style options according to named arguments
01259   Int_t lineColor   = pc.getInt("lineColor") ;
01260   Int_t lineStyle   = pc.getInt("lineStyle") ;
01261   Int_t lineWidth   = pc.getInt("lineWidth") ;
01262   Int_t markerColor = pc.getInt("markerColor") ;
01263   Int_t markerStyle = pc.getInt("markerStyle") ;
01264   Size_t markerSize  = pc.getDouble("markerSize") ;
01265   Int_t fillColor = pc.getInt("fillColor") ;
01266   Int_t fillStyle = pc.getInt("fillStyle") ;
01267 
01268   if (lineColor!=-999) graph->SetLineColor(lineColor) ;
01269   if (lineStyle!=-999) graph->SetLineStyle(lineStyle) ;
01270   if (lineWidth!=-999) graph->SetLineWidth(lineWidth) ;
01271   if (markerColor!=-999) graph->SetMarkerColor(markerColor) ;
01272   if (markerStyle!=-999) graph->SetMarkerStyle(markerStyle) ;
01273   if (markerSize!=-999) graph->SetMarkerSize(markerSize) ;
01274   if (fillColor!=-999) graph->SetFillColor(fillColor) ;
01275   if (fillStyle!=-999) graph->SetFillStyle(fillStyle) ;
01276 
01277   // Add graph to frame
01278   frame->addPlotable(graph,drawOptions,histInvisible) ;
01279  
01280   return frame ;
01281 }
01282 
01283 
01284 
01285 
01286 //_____________________________________________________________________________
01287 RooDataSet *RooDataSet::read(const char *fileList, const RooArgList &varList,
01288                              const char *verbOpt, const char* commonPath, 
01289                              const char* indexCatName) {
01290   // Read given list of ascii files, and construct a data set, using the given
01291   // ArgList as structure definition.
01292   //
01293   // Multiple file names in fileList should be comma separated. Each
01294   // file is optionally prefixed with 'commonPath' if such a path is
01295   // provided
01296   //
01297   // The arglist specifies the dimensions of the dataset to be built
01298   // and describes the order in which these dimensions appear in the
01299   // ascii files to be read. 
01300   //
01301   // Each line in the ascii file should contain N white space separated
01302   // tokens, with N the number of args in 'variables'. Any text beyond
01303   // N tokens will be ignored with a warning message.
01304   // [ NB: This format is written by RooArgList::writeToStream() ]
01305   // 
01306   // If the value of any of the variables on a given line exceeds the
01307   // fit range associated with that dimension, the entire line will be
01308   // ignored. A warning message is printed in each case, unless the
01309   // 'Q' verbose option is given. (Option 'D' will provide additional
01310   // debugging information) The number of events read and skipped
01311   // is always summarized at the end.
01312   //
01313   // When multiple files are read, a RooCategory arg in 'variables' can 
01314   // optionally be designated to hold information about the source file 
01315   // of each data point. This feature is enabled by giving the name
01316   // of the (already existing) category variable in 'indexCatName'
01317   //
01318   // If no further information is given a label name 'fileNNN' will
01319   // be assigned to each event, where NNN is the sequential number of
01320   // the source file in 'fileList'.
01321   // 
01322   // Alternatively it is possible to override the default label names
01323   // of the index category by specifying them in the fileList string:
01324   // When instead of "file1.txt,file2.txt" the string 
01325   // "file1.txt:FOO,file2.txt:BAR" is specified, a state named "FOO"
01326   // is assigned to the index category for each event originating from
01327   // file1.txt. The labels FOO,BAR may be predefined in the index 
01328   // category via defineType(), but don't have to be
01329   //
01330   // Finally, one can also assign the same label to multiple files,
01331   // either by specifying "file1.txt:FOO,file2,txt:FOO,file3.txt:BAR"
01332   // or "file1.txt,file2.txt:FOO,file3.txt:BAR"
01333   //
01334 
01335   // Make working copy of variables list 
01336   RooArgList variables(varList) ;
01337 
01338   // Append blinding state category to variable list if not already there
01339   Bool_t ownIsBlind(kTRUE) ;
01340   RooAbsArg* blindState = variables.find("blindState") ;
01341   if (!blindState) {
01342     blindState = new RooCategory("blindState","Blinding State") ;
01343     variables.add(*blindState) ;
01344   } else {
01345     ownIsBlind = kFALSE ;    
01346     if (blindState->IsA()!=RooCategory::Class()) {
01347       oocoutE((TObject*)0,DataHandling) << "RooDataSet::read: ERROR: variable list already contains" 
01348                           << "a non-RooCategory blindState member" << endl ;
01349       return 0 ;
01350     }
01351     oocoutW((TObject*)0,DataHandling) << "RooDataSet::read: WARNING: recycling existing "
01352                         << "blindState category in variable list" << endl ;
01353   }
01354   RooCategory* blindCat = (RooCategory*) blindState ;
01355 
01356   // Configure blinding state category
01357   blindCat->setAttribute("Dynamic") ;
01358   blindCat->defineType("Normal",0) ;
01359   blindCat->defineType("Blind",1) ;
01360 
01361   // parse the option string
01362   TString opts= verbOpt;
01363   opts.ToLower();
01364   Bool_t verbose= !opts.Contains("q");
01365   Bool_t debug= opts.Contains("d");
01366 
01367   RooDataSet *data= new RooDataSet("dataset", fileList, variables);
01368   if (ownIsBlind) { variables.remove(*blindState) ; delete blindState ; }
01369   if(!data) {
01370     oocoutE((TObject*)0,DataHandling) << "RooDataSet::read: unable to create a new dataset"
01371                         << endl;
01372     return 0;
01373   }
01374 
01375   // Redirect blindCat to point to the copy stored in the data set
01376   blindCat = (RooCategory*) data->_vars.find("blindState") ;
01377 
01378   // Find index category, if requested
01379   RooCategory *indexCat     = 0;
01380   //RooCategory *indexCatOrig = 0;
01381   if (indexCatName) { 
01382     RooAbsArg* tmp = 0;
01383     tmp = data->_vars.find(indexCatName) ;
01384     if (!tmp) {
01385       oocoutE((TObject*)0,DataHandling) << "RooDataSet::read: no index category named " 
01386                           << indexCatName << " in supplied variable list" << endl ;
01387       return 0 ;
01388     }
01389     if (tmp->IsA()!=RooCategory::Class()) {
01390       oocoutE((TObject*)0,DataHandling) << "RooDataSet::read: variable " << indexCatName 
01391                           << " is not a RooCategory" << endl ;
01392       return 0 ;
01393     }
01394     indexCat = (RooCategory*)tmp ;
01395     
01396     // Prevent RooArgSet from attempting to read in indexCat
01397     indexCat->setAttribute("Dynamic") ;
01398   }
01399 
01400 
01401   Int_t outOfRange(0) ;
01402 
01403   // Make local copy of file list for tokenizing 
01404   char fileList2[10240] ;
01405   strlcpy(fileList2,fileList,10240) ;
01406   
01407   // Loop over all names in comma separated list
01408   char *filename = strtok(fileList2,", ") ;
01409   Int_t fileSeqNum(0) ;
01410   while (filename) {
01411     // Determine index category number, if this option is active
01412     if (indexCat) {
01413 
01414       // Find and detach optional file category name 
01415       char *catname = strchr(filename,':') ;
01416 
01417       if (catname) {
01418         // Use user category name if provided
01419         *catname=0 ;
01420         catname++ ;
01421 
01422         const RooCatType* type = indexCat->lookupType(catname,kFALSE) ;
01423         if (type) {
01424           // Use existing category index
01425           indexCat->setIndex(type->getVal()) ;
01426         } else {
01427           // Register cat name
01428           indexCat->defineType(catname,fileSeqNum) ;
01429           indexCat->setIndex(fileSeqNum) ;
01430         }
01431       } else {
01432         // Assign autogenerated name
01433         char newLabel[128] ;
01434         snprintf(newLabel,128,"file%03d",fileSeqNum) ;
01435         if (indexCat->defineType(newLabel,fileSeqNum)) {
01436           oocoutE((TObject*)0,DataHandling) << "RooDataSet::read: Error, cannot register automatic type name " << newLabel 
01437                               << " in index category " << indexCat->GetName() << endl ;
01438           return 0 ;
01439         }       
01440         // Assign new category number
01441         indexCat->setIndex(fileSeqNum) ;
01442       }
01443     }
01444 
01445     oocoutI((TObject*)0,DataHandling) << "RooDataSet::read: reading file " << filename << endl ;
01446 
01447     // Prefix common path 
01448     TString fullName(commonPath) ;
01449     fullName.Append(filename) ;
01450     ifstream file(fullName) ;
01451 
01452     if(!file.good()) {
01453       oocoutW((TObject*)0,DataHandling) << "RooDataSet::read: unable to open '"
01454            << filename << "', skipping" << endl;
01455     }
01456     
01457 //  Double_t value;
01458     Int_t line(0) ;
01459     Bool_t haveBlindString(false) ;
01460 
01461     while(file.good() && !file.eof()) {
01462       line++;
01463       if(debug) oocxcoutD((TObject*)0,DataHandling) << "reading line " << line << endl;
01464 
01465       // process comment lines
01466       if (file.peek() == '#')
01467         {
01468           if(debug) oocxcoutD((TObject*)0,DataHandling) << "skipping comment on line " << line << endl;     
01469         }
01470       else {    
01471 
01472         // Skip empty lines 
01473         // if(file.peek() == '\n') { file.get(); }
01474 
01475         // Read single line
01476         Bool_t readError = variables.readFromStream(file,kTRUE,verbose) ;
01477         data->_vars = variables ;
01478 //      Bool_t readError = data->_vars.readFromStream(file,kTRUE,verbose) ;
01479 
01480         // Stop at end of file or on read error
01481         if(file.eof()) break ;  
01482         if(!file.good()) {
01483           oocoutE((TObject*)0,DataHandling) << "RooDataSet::read(static): read error at line " << line << endl ;
01484           break;
01485         }       
01486 
01487         if (readError) {
01488           outOfRange++ ;
01489           continue ;
01490         }
01491         blindCat->setIndex(haveBlindString) ;
01492         data->fill(); // store this event
01493       }
01494     }
01495 
01496     file.close();
01497 
01498     // get next file name 
01499     filename = strtok(0," ,") ;
01500     fileSeqNum++ ;
01501   }
01502 
01503   if (indexCat) {
01504     // Copy dynamically defined types from new data set to indexCat in original list
01505     RooCategory* origIndexCat = (RooCategory*) variables.find(indexCatName) ;
01506     TIterator* tIter = indexCat->typeIterator() ;
01507     RooCatType* type = 0;
01508       while ((type=(RooCatType*)tIter->Next())) {
01509         origIndexCat->defineType(type->GetName(),type->getVal()) ;
01510       }
01511   }
01512   oocoutI((TObject*)0,DataHandling) << "RooDataSet::read: read " << data->numEntries()
01513                                     << " events (ignored " << outOfRange << " out of range events)" << endl;
01514   return data;
01515 }
01516 
01517 
01518 
01519 
01520 //_____________________________________________________________________________
01521 Bool_t RooDataSet::write(const char* filename)
01522 {
01523   // Write the contents of this dataset to an ASCII file with the specified name
01524   // Each event will be written as a single line containing the written values
01525   // of each observable in the order they were declared in the dataset and
01526   // separated by whitespaces
01527 
01528   checkInit() ;
01529 
01530   // Open file for writing 
01531   ofstream ofs(filename) ;
01532   if (ofs.fail()) {
01533     coutE(DataHandling) << "RooDataSet::write(" << GetName() << ") cannot create file " << filename << endl ;
01534     return kTRUE ;
01535   }
01536 
01537   // Write all lines as arglist in compact mode
01538   coutI(DataHandling) << "RooDataSet::write(" << GetName() << ") writing ASCII file " << filename << endl ;
01539   Int_t i ;
01540   for (i=0 ; i<numEntries() ; i++) {
01541     RooArgList list(*get(i),"line") ;
01542     list.writeToStream(ofs,kTRUE) ;
01543   }
01544 
01545   if (ofs.fail()) {
01546     coutW(DataHandling) << "RooDataSet::write(" << GetName() << "): WARNING error(s) have occured in writing" << endl ;
01547   }
01548   return ofs.fail() ;
01549 }
01550 
01551 
01552 
01553 //_____________________________________________________________________________
01554 void RooDataSet::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const 
01555 {
01556   // Print info about this dataset to the specified output stream.
01557   //
01558   //   Standard: number of entries
01559   //      Shape: list of variables we define & were generated with
01560 
01561   checkInit() ;
01562   RooAbsData::printMultiline(os,contents,verbose,indent) ;
01563   if (_wgtVar) {
01564     os << indent << "  Dataset variable \"" << _wgtVar->GetName() << "\" is interpreted as the event weight" << endl ;
01565   }
01566 }
01567 
01568 
01569 //_____________________________________________________________________________
01570 void RooDataSet::printValue(ostream& os) const 
01571 {
01572   // Print value of the dataset, i.e. the sum of weights contained in the dataset
01573   os << numEntries() << " entries" ;
01574   if (isWeighted()) {
01575     os << " (" << sumEntries() << " weighted)" ;
01576   }
01577 }
01578 
01579 
01580 
01581 //_____________________________________________________________________________
01582 void RooDataSet::printArgs(ostream& os) const 
01583 {
01584   // Print argument of dataset, i.e. the observable names
01585 
01586   os << "[" ;    
01587   TIterator* iter = _varsNoWgt.createIterator() ;
01588   RooAbsArg* arg ;
01589   Bool_t first(kTRUE) ;
01590   while((arg=(RooAbsArg*)iter->Next())) {
01591     if (first) {
01592       first=kFALSE ;
01593     } else {
01594       os << "," ;
01595     }
01596     os << arg->GetName() ;
01597   }
01598   if (_wgtVar) {
01599     os << ",weight:" << _wgtVar->GetName() ;
01600   }
01601   os << "]" ;
01602   delete iter ;
01603 }
01604 
01605 
01606 
01607 //_____________________________________________________________________________
01608 void RooDataSet::SetName(const char *name) 
01609 {
01610   // Change the name of this dataset into the given name
01611 
01612   if (_dir) _dir->GetList()->Remove(this);
01613   TNamed::SetName(name) ;
01614   if (_dir) _dir->GetList()->Add(this);
01615 }
01616 
01617 
01618 //_____________________________________________________________________________
01619 void RooDataSet::SetNameTitle(const char *name, const char* title) 
01620 {
01621   // Change the title of this dataset into the given name
01622 
01623   if (_dir) _dir->GetList()->Remove(this);
01624   TNamed::SetNameTitle(name,title) ;
01625   if (_dir) _dir->GetList()->Add(this);
01626 }
01627 
01628 
01629 //______________________________________________________________________________
01630 void RooDataSet::Streamer(TBuffer &R__b)
01631 {
01632    // Stream an object of class RooDataSet.
01633    if (R__b.IsReading()) {
01634 
01635      UInt_t R__s, R__c;
01636      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01637 
01638      if (R__v>1) {
01639 
01640        // Use new-style streaming for version >1
01641        R__b.ReadClassBuffer(RooDataSet::Class(),this,R__v,R__s,R__c);
01642 
01643      } else {
01644 
01645        // Legacy dataset conversion happens here. Legacy RooDataSet inherits from RooTreeData
01646        // which in turn inherits from RooAbsData. Manually stream RooTreeData contents on 
01647        // file here and convert it into a RooTreeDataStore which is installed in the 
01648        // new-style RooAbsData base class
01649 
01650        // --- This is the contents of the streamer code of RooTreeData version 1 ---
01651        UInt_t R__s1, R__c1;
01652        Version_t R__v1 = R__b.ReadVersion(&R__s1, &R__c1); if (R__v1) { }
01653        
01654        RooAbsData::Streamer(R__b);
01655        TTree* X_tree(0) ; R__b >> X_tree;
01656        RooArgSet X_truth ; X_truth.Streamer(R__b);
01657        TString X_blindString ; X_blindString.Streamer(R__b);
01658        R__b.CheckByteCount(R__s1, R__c1, RooTreeData::Class());
01659        // --- End of RooTreeData-v1 streamer
01660        
01661        // Construct RooTreeDataStore from X_tree and complete initialization of new-style RooAbsData
01662        _dstore = new RooTreeDataStore(X_tree,_vars) ;
01663        _dstore->SetName(GetName()) ;
01664        _dstore->SetTitle(GetTitle()) ;
01665        _dstore->checkInit() ;       
01666 
01667        // This is the contents of the streamer code of RooDataSet version 1
01668        RooDirItem::Streamer(R__b);
01669        _varsNoWgt.Streamer(R__b);
01670        R__b >> _wgtVar;
01671        R__b.CheckByteCount(R__s, R__c, RooDataSet::IsA());
01672 
01673        
01674      }
01675    } else {
01676       R__b.WriteClassBuffer(RooDataSet::Class(),this);
01677    }
01678 }
01679 

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