Logo ROOT  
Reference Guide
RooDataSet.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooDataSet.cxx
19\class RooDataSet
20\ingroup Roofitcore
21
22RooDataSet is a container class to hold unbinned data. The binned equivalent is
23RooDataHist. In RooDataSet, each data point in N-dimensional space is represented
24by a RooArgSet of RooRealVar, RooCategory or RooStringVar objects, which can be
25retrieved using get().
26
27Since RooDataSet saves every event, it allows for fits with highest precision. With a large
28amount of data, however, it could be beneficial to represent them in binned form,
29i.e., RooDataHist. Binning the data will incur a loss of information, though.
30RooDataHist on the other hand may suffer from the curse of dimensionality if a high-dimensional
31problem with a lot of bins on each axis is tackled.
32
33### Inspecting a dataset
34Inspect a dataset using Print() with the "verbose" option:
35```
36dataset->Print("V");
37dataset->get(0)->Print("V");
38dataset->get(1)->Print("V");
39...
40```
41
42### Plotting data.
43See RooAbsData::plotOn().
44
45
46### Storage strategy
47There are two storage backends:
48- RooVectorDataStore (default): std::vectors in memory. They are fast, but they
49cannot be serialised if the dataset exceeds a size of 1 Gb
50- RooTreeDataStore: Uses a TTree, which can be file backed if a file is opened
51before creating the dataset. This significantly reduces the memory pressure, as the
52baskets of the tree can be written to a file, and only the basket that's currently
53being read stays in RAM.
54 - Enable tree-backed storage similar to this:
55 ```
56 TFile outputFile("filename.root", "RECREATE");
57 RooAbsData::setDefaultStorageType(RooAbsData::Tree);
58 RooDataSet mydata(...);
59 ```
60 - Or convert an existing memory-backed data storage:
61 ```
62 RooDataSet mydata(...);
63
64 TFile outputFile("filename.root", "RECREATE");
65 mydata.convertToTreeStore();
66 ```
67
68For the inverse conversion, see `RooAbsData::convertToVectorStore()`.
69
70
71### Creating a dataset using RDataFrame
72\see RooAbsDataHelper, rf408_RDataFrameToRooFit.C
73
74### Uniquely identifying RooDataSet objects
75
76\warning Before v6.28, it was ensured that no RooDataSet objects on the heap
77were located at an address that had already been used for a RooDataSet before.
78With v6.28, this is not guaranteed anymore. Hence, if your code uses pointer
79comparisons to uniquely identify RooDataSet instances, please consider using
80the new `RooAbsData::uniqueId()`.
81
82
83**/
84
85#include "RooDataSet.h"
86
87#include "RooPlot.h"
88#include "RooAbsReal.h"
89#include "Roo1DTable.h"
90#include "RooCategory.h"
91#include "RooFormulaVar.h"
92#include "RooArgList.h"
93#include "RooAbsRealLValue.h"
94#include "RooRealVar.h"
95#include "RooDataHist.h"
96#include "RooMsgService.h"
97#include "RooCmdConfig.h"
98#include "RooHist.h"
99#include "RooTreeDataStore.h"
100#include "RooVectorDataStore.h"
102#include "RooSentinel.h"
103#include "RooTrace.h"
104
105#include "ROOT/StringUtils.hxx"
106
107#include "Math/Util.h"
108#include "TTree.h"
109#include "TH2.h"
110#include "TFile.h"
111#include "TBuffer.h"
112#include "strlcpy.h"
113#include "snprintf.h"
114
115#include <iostream>
116#include <memory>
117#include <fstream>
118
119
120using namespace std;
121
123
124#ifndef USEMEMPOOLFORDATASET
126#else
127
128#include "MemPoolForRooSets.h"
129
130RooDataSet::MemPool* RooDataSet::memPool() {
132 static auto * memPool = new RooDataSet::MemPool();
133 return memPool;
134}
135
136void RooDataSet::cleanup() {
137 auto pool = memPool();
138 pool->teardown();
139
140 //The pool will have to leak if it's not empty at this point.
141 if (pool->empty())
142 delete pool;
143}
144
145
146////////////////////////////////////////////////////////////////////////////////
147/// Overloaded new operator guarantees that all RooDataSets allocated with new
148/// have a unique address, a property that is exploited in several places
149/// in roofit to quickly index contents on normalization set pointers.
150/// The memory pool only allocates space for the class itself. The elements
151/// stored in the set are stored outside the pool.
152
153void* RooDataSet::operator new (size_t bytes)
154{
155 //This will fail if a derived class uses this operator
156 assert(sizeof(RooDataSet) == bytes);
157
158 return memPool()->allocate(bytes);
159}
160
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Memory is owned by pool, we need to do nothing to release it
165
166void RooDataSet::operator delete (void* ptr)
167{
168 // Decrease use count in pool that ptr is on
169 if (memPool()->deallocate(ptr))
170 return;
171
172 std::cerr << __func__ << " " << ptr << " is not in any of the pools." << std::endl;
173
174 // Not part of any pool; use global op delete:
175 ::operator delete(ptr);
176}
177
178#endif
179
180
181////////////////////////////////////////////////////////////////////////////////
182/// Default constructor for persistence
183
185{
187}
188
189
190
191
192
193////////////////////////////////////////////////////////////////////////////////
194/// Construct an unbinned dataset from a RooArgSet defining the dimensions of the data space. Optionally, data
195/// can be imported at the time of construction.
196///
197/// <table>
198/// <tr><th> %RooCmdArg <th> Effect
199/// <tr><td> Import(TTree*) <td> Import contents of given TTree. Only braches of the TTree that have names
200/// corresponding to those of the RooAbsArgs that define the RooDataSet are
201/// imported.
202/// <tr><td> ImportFromFile(const char* fileName, const char* treeName) <td> Import tree with given name from file with given name.
203/// <tr><td> Import(RooDataSet&)
204/// <td> Import contents of given RooDataSet. Only observables that are common with the definition of this dataset will be imported
205/// <tr><td> Index(RooCategory&) <td> Prepare import of datasets into a N+1 dimensional RooDataSet
206/// where the extra discrete dimension labels the source of the imported histogram.
207/// <tr><td> Import(const char*, RooDataSet&)
208/// <td> Import a dataset to be associated with the given state name of the index category
209/// specified in Index(). If the given state name is not yet defined in the index
210/// category it will be added on the fly. The import command can be specified multiple times.
211/// <tr><td> Link(const char*, RooDataSet&) <td> Link contents of supplied RooDataSet to this dataset for given index category state name.
212/// In this mode, no data is copied and the linked dataset must be remain live for the duration
213/// of this dataset. Note that link is active for both reading and writing, so modifications
214/// to the aggregate dataset will also modify its components. Link() and Import() are mutually exclusive.
215/// <tr><td> OwnLinked() <td> Take ownership of all linked datasets
216/// <tr><td> Import(map<string,RooDataSet*>&) <td> As above, but allows specification of many imports in a single operation
217/// <tr><td> Link(map<string,RooDataSet*>&) <td> As above, but allows specification of many links in a single operation
218/// <tr><td> Cut(const char*) <br>
219/// Cut(RooFormulaVar&)
220/// <td> Apply the given cut specification when importing data
221/// <tr><td> CutRange(const char*) <td> Only accept events in the observable range with the given name
222/// <tr><td> WeightVar(const char*) <br>
223/// WeightVar(const RooAbsArg&)
224/// <td> Interpret the given variable as event weight rather than as observable
225/// <tr><td> StoreError(const RooArgSet&) <td> Store symmetric error along with value for given subset of observables
226/// <tr><td> StoreAsymError(const RooArgSet&) <td> Store asymmetric error along with value for given subset of observables
227/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of global observables to be stored in this RooDataSet.
228/// A snapshot of the passed RooArgSet is stored, meaning the values wont't change unexpectedly.
229/// </table>
230///
231
232RooDataSet::RooDataSet(RooStringView name, RooStringView title, const RooArgSet& vars, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
233 const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) :
234 RooAbsData(name,title,RooArgSet(vars,(RooAbsArg*)RooCmdConfig::decodeObjOnTheFly("RooDataSet::RooDataSet", "IndexCat",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)))
235{
236 // Define configuration for this method
237 RooCmdConfig pc(Form("RooDataSet::ctor(%s)",GetName())) ;
238 pc.defineInt("ownLinked","OwnLinked",0) ;
239 pc.defineObject("impTree","ImportTree",0) ;
240 pc.defineObject("impData","ImportData",0) ;
241 pc.defineObject("indexCat","IndexCat",0) ;
242 pc.defineObject("impSliceData","ImportDataSlice",0,0,true) ; // array
243 pc.defineString("impSliceState","ImportDataSlice",0,"",true) ; // array
244 pc.defineObject("lnkSliceData","LinkDataSlice",0,0,true) ; // array
245 pc.defineString("lnkSliceState","LinkDataSlice",0,"",true) ; // array
246 pc.defineString("cutSpec","CutSpec",0,"") ;
247 pc.defineObject("cutVar","CutVar",0) ;
248 pc.defineString("cutRange","CutRange",0,"") ;
249 pc.defineString("wgtVarName","WeightVarName",0,"") ;
250 pc.defineInt("newWeight1","WeightVarName",0,0) ;
251 pc.defineString("fname","ImportFromFile",0,"") ;
252 pc.defineString("tname","ImportFromFile",1,"") ;
253 pc.defineObject("wgtVar","WeightVar",0) ;
254 pc.defineInt("newWeight2","WeightVar",0,0) ;
255 pc.defineObject("dummy1","ImportDataSliceMany",0) ;
256 pc.defineObject("dummy2","LinkDataSliceMany",0) ;
257 pc.defineSet("errorSet","StoreError",0) ;
258 pc.defineSet("asymErrSet","StoreAsymError",0) ;
259 pc.defineSet("glObs","GlobalObservables",0,0) ;
260 pc.defineMutex("ImportTree","ImportData","ImportDataSlice","LinkDataSlice","ImportFromFile") ;
261 pc.defineMutex("CutSpec","CutVar") ;
262 pc.defineMutex("WeightVarName","WeightVar") ;
263 pc.defineDependency("ImportDataSlice","IndexCat") ;
264 pc.defineDependency("LinkDataSlice","IndexCat") ;
265 pc.defineDependency("OwnLinked","LinkDataSlice") ;
266
267
269 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
270 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
271 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
272 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
273
274 // Process & check varargs
275 pc.process(l) ;
276 if (!pc.ok(true)) {
277 assert(0) ;
278 return ;
279 }
280
281 if(pc.getSet("glObs")) setGlobalObservables(*pc.getSet("glObs"));
282
283 // Extract relevant objects
284 TTree* impTree = static_cast<TTree*>(pc.getObject("impTree")) ;
285 RooDataSet* impData = static_cast<RooDataSet*>(pc.getObject("impData")) ;
286 RooFormulaVar* cutVar = static_cast<RooFormulaVar*>(pc.getObject("cutVar")) ;
287 const char* cutSpec = pc.getString("cutSpec","",true) ;
288 const char* cutRange = pc.getString("cutRange","",true) ;
289 const char* wgtVarName = pc.getString("wgtVarName","",true) ;
290 RooRealVar* wgtVar = static_cast<RooRealVar*>(pc.getObject("wgtVar")) ;
291 const char* impSliceNames = pc.getString("impSliceState","",true) ;
292 const RooLinkedList& impSliceData = pc.getObjectList("impSliceData") ;
293 const char* lnkSliceNames = pc.getString("lnkSliceState","",true) ;
294 const RooLinkedList& lnkSliceData = pc.getObjectList("lnkSliceData") ;
295 RooCategory* indexCat = static_cast<RooCategory*>(pc.getObject("indexCat")) ;
296 RooArgSet* errorSet = pc.getSet("errorSet") ;
297 RooArgSet* asymErrorSet = pc.getSet("asymErrSet") ;
298 const char* fname = pc.getString("fname") ;
299 const char* tname = pc.getString("tname") ;
300 Int_t ownLinked = pc.getInt("ownLinked") ;
301 Int_t newWeight = pc.getInt("newWeight1") + pc.getInt("newWeight2") ;
302
303 // Case 1 --- Link multiple dataset as slices
304 if (lnkSliceNames) {
305
306 // Make import mapping if index category is specified
307 map<string,RooAbsData*> hmap ;
308 if (indexCat) {
309 char tmp[64000];
310 strlcpy(tmp, lnkSliceNames, 64000);
311 char *token = strtok(tmp, ",");
312 TIterator *hiter = lnkSliceData.MakeIterator();
313 while (token) {
314 hmap[token] = (RooAbsData *)hiter->Next();
315 token = strtok(0, ",");
316 }
317 delete hiter ;
318 }
319
320 // Lookup name of weight variable if it was specified by object reference
321 if (wgtVar) {
322 // coverity[UNUSED_VALUE]
323 wgtVarName = wgtVar->GetName() ;
324 }
325
326 appendToDir(this,true) ;
327
328 // Initialize RooDataSet with optional weight variable
329 initialize(0) ;
330
331 map<string,RooAbsDataStore*> storeMap ;
332 RooCategory* icat = (RooCategory*) (indexCat ? _vars.find(indexCat->GetName()) : 0 ) ;
333 if (!icat) {
334 throw std::string("RooDataSet::RooDataSet() ERROR in constructor, cannot find index category") ;
335 }
336 for (map<string,RooAbsData*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
337 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
338 if (indexCat && !indexCat->hasLabel(hiter->first)) {
339 indexCat->defineType(hiter->first) ;
340 coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
341 }
342 if (icat && !icat->hasLabel(hiter->first)) {
343 icat->defineType(hiter->first) ;
344 }
345 icat->setLabel(hiter->first.c_str()) ;
346 storeMap[icat->getCurrentLabel()]=hiter->second->store() ;
347
348 // Take ownership of slice if requested
349 if (ownLinked) {
350 addOwnedComponent(hiter->first.c_str(),*hiter->second) ;
351 }
352 }
353
354 // Create composite datastore
355 _dstore = new RooCompositeDataStore(name,title,_vars,*icat,storeMap) ;
356
357 } else {
358
359 if (wgtVar) {
360 wgtVarName = wgtVar->GetName() ;
361 }
362
363 // Clone weight variable of imported dataset if we are not weighted
364 if (!wgtVar && !wgtVarName && impData && impData->_wgtVar) {
367 wgtVarName = _wgtVar->GetName() ;
368 }
369
370 // Create empty datastore
371 RooTreeDataStore* tstore(0) ;
372 RooVectorDataStore* vstore(0) ;
373
375 tstore = new RooTreeDataStore(name,title,_vars,wgtVarName) ;
376 _dstore = tstore ;
377 } else if (defaultStorageType==Vector) {
378 if (wgtVarName && newWeight) {
379 RooAbsArg* wgttmp = _vars.find(wgtVarName) ;
380 if (wgttmp) {
381 wgttmp->setAttribute("NewWeight") ;
382 }
383 }
384 vstore = new RooVectorDataStore(name,title,_vars,wgtVarName) ;
385 _dstore = vstore ;
386 } else {
387 _dstore = 0 ;
388 }
389
390
391 // Make import mapping if index category is specified
392 map<string,RooDataSet*> hmap ;
393 if (indexCat) {
394 TIterator* hiter = impSliceData.MakeIterator() ;
395 for (const auto& token : ROOT::Split(impSliceNames, ",")) {
396 hmap[token] = (RooDataSet*) hiter->Next() ;
397 }
398 delete hiter ;
399 }
400
401 // process StoreError requests
402 if (errorSet) {
403 std::unique_ptr<RooArgSet> intErrorSet{static_cast<RooArgSet*>(_vars.selectCommon(*errorSet))};
404 intErrorSet->setAttribAll("StoreError") ;
405 for(RooAbsArg* arg : *intErrorSet) {
406 arg->attachToStore(*_dstore) ;
407 }
408 }
409 if (asymErrorSet) {
410 std::unique_ptr<RooArgSet> intAsymErrorSet{static_cast<RooArgSet*>(_vars.selectCommon(*asymErrorSet))};
411 intAsymErrorSet->setAttribAll("StoreAsymError") ;
412 for(RooAbsArg* arg : *intAsymErrorSet) {
413 arg->attachToStore(*_dstore) ;
414 }
415 }
416
417 // Lookup name of weight variable if it was specified by object reference
418 if (wgtVar) {
419 wgtVarName = wgtVar->GetName() ;
420 }
421
422
423 appendToDir(this,true) ;
424
425 // Initialize RooDataSet with optional weight variable
426 if (wgtVarName && *wgtVarName) {
427 // Use the supplied weight column
428 initialize(wgtVarName) ;
429
430 } else {
431 if (impData && impData->_wgtVar && vars.find(impData->_wgtVar->GetName())) {
432
433 // Use the weight column of the source data set
434 initialize(impData->_wgtVar->GetName()) ;
435
436 } else if (indexCat) {
437
438 RooDataSet* firstDS = hmap.begin()->second ;
439 if (firstDS->_wgtVar && vars.find(firstDS->_wgtVar->GetName())) {
440 initialize(firstDS->_wgtVar->GetName()) ;
441 } else {
442 initialize(0) ;
443 }
444 } else {
445 initialize(0) ;
446 }
447 }
448
449 // Import one or more datasets with a cut specification
450 if (cutSpec && *cutSpec) {
451
452 // Create a RooFormulaVar cut from given cut expression
453 if (indexCat) {
454
455 // Case 2a --- Import multiple RooDataSets as slices with cutspec
456 RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
457 for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
458 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
459 if (!indexCat->hasLabel(hiter->first)) {
460 indexCat->defineType(hiter->first) ;
461 coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
462 }
463 if (!icat->hasLabel(hiter->first)) {
464 icat->defineType(hiter->first) ;
465 }
466 icat->setLabel(hiter->first.c_str()) ;
467
468 RooFormulaVar cutVarTmp(cutSpec,cutSpec,hiter->second->_vars) ;
469 _dstore->loadValues(hiter->second->store(),&cutVarTmp,cutRange) ;
470 }
471
472 } else if (impData) {
473
474 // Case 3a --- Import RooDataSet with cutspec
475 RooFormulaVar cutVarTmp(cutSpec,cutSpec,impData->_vars) ;
476 _dstore->loadValues(impData->store(),&cutVarTmp,cutRange);
477 } else if (impTree) {
478
479 // Case 4a --- Import TTree from memory with cutspec
480 RooFormulaVar cutVarTmp(cutSpec,cutSpec,_vars) ;
481 if (tstore) {
482 tstore->loadValues(impTree,&cutVarTmp,cutRange);
483 } else {
484 RooTreeDataStore tmpstore(name,title,_vars,wgtVarName) ;
485 tmpstore.loadValues(impTree,&cutVarTmp,cutRange) ;
486 _dstore->append(tmpstore) ;
487 }
488 } else if (fname && strlen(fname)) {
489
490 // Case 5a --- Import TTree from file with cutspec
491 TFile *f = TFile::Open(fname) ;
492 if (!f) {
493 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;
494 throw string(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
495 }
496 TTree* t = dynamic_cast<TTree*>(f->Get(tname)) ;
497 if (!t) {
498 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
499 throw string(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
500 }
501 RooFormulaVar cutVarTmp(cutSpec,cutSpec,_vars) ;
502 if (tstore) {
503 tstore->loadValues(t,&cutVarTmp,cutRange);
504 } else {
505 RooTreeDataStore tmpstore(name,title,_vars,wgtVarName) ;
506 tmpstore.loadValues(t,&cutVarTmp,cutRange) ;
507 _dstore->append(tmpstore) ;
508 }
509 f->Close() ;
510
511 }
512
513 // Import one or more datasets with a cut formula
514 } else if (cutVar) {
515
516 if (indexCat) {
517
518 // Case 2b --- Import multiple RooDataSets as slices with cutvar
519
520 RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
521 for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
522 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
523 if (!indexCat->hasLabel(hiter->first)) {
524 indexCat->defineType(hiter->first) ;
525 coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
526 }
527 if (!icat->hasLabel(hiter->first)) {
528 icat->defineType(hiter->first) ;
529 }
530 icat->setLabel(hiter->first.c_str()) ;
531 _dstore->loadValues(hiter->second->store(),cutVar,cutRange) ;
532 }
533
534
535 } else if (impData) {
536 // Case 3b --- Import RooDataSet with cutvar
537 _dstore->loadValues(impData->store(),cutVar,cutRange);
538 } else if (impTree) {
539 // Case 4b --- Import TTree from memory with cutvar
540 if (tstore) {
541 tstore->loadValues(impTree,cutVar,cutRange);
542 } else {
543 RooTreeDataStore tmpstore(name,title,_vars,wgtVarName) ;
544 tmpstore.loadValues(impTree,cutVar,cutRange) ;
545 _dstore->append(tmpstore) ;
546 }
547 } else if (fname && strlen(fname)) {
548 // Case 5b --- Import TTree from file with cutvar
549 TFile *f = TFile::Open(fname) ;
550 if (!f) {
551 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;
552 throw string(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
553 }
554 TTree* t = dynamic_cast<TTree*>(f->Get(tname)) ;
555 if (!t) {
556 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
557 throw string(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
558 }
559 if (tstore) {
560 tstore->loadValues(t,cutVar,cutRange);
561 } else {
562 RooTreeDataStore tmpstore(name,title,_vars,wgtVarName) ;
563 tmpstore.loadValues(t,cutVar,cutRange) ;
564 _dstore->append(tmpstore) ;
565 }
566
567 f->Close() ;
568 }
569
570 // Import one or more datasets without cuts
571 } else {
572
573 if (indexCat) {
574
575 RooCategory* icat = (RooCategory*) _vars.find(indexCat->GetName()) ;
576 for (map<string,RooDataSet*>::iterator hiter = hmap.begin() ; hiter!=hmap.end() ; ++hiter) {
577 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
578 if (!indexCat->hasLabel(hiter->first)) {
579 indexCat->defineType(hiter->first) ;
580 coutI(InputArguments) << "RooDataSet::ctor(" << GetName() << ") defining state \"" << hiter->first << "\" in index category " << indexCat->GetName() << endl ;
581 }
582 if (!icat->hasLabel(hiter->first)) {
583 icat->defineType(hiter->first) ;
584 }
585 icat->setLabel(hiter->first.c_str()) ;
586 // Case 2c --- Import multiple RooDataSets as slices
587 _dstore->loadValues(hiter->second->store(),0,cutRange) ;
588 }
589
590 } else if (impData) {
591 // Case 3c --- Import RooDataSet
592 _dstore->loadValues(impData->store(),0,cutRange);
593
594 } else if (impTree || (fname && strlen(fname))) {
595 // Case 4c --- Import TTree from memory / file
596 std::unique_ptr<TFile> file;
597
598 if (impTree == nullptr) {
599 file.reset(TFile::Open(fname));
600 if (!file) {
601 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' cannot be opened or does not exist" << endl ;
602 throw std::invalid_argument(Form("RooDataSet::ctor(%s) ERROR file %s cannot be opened or does not exist",GetName(),fname)) ;
603 }
604
605 file->GetObject(tname, impTree);
606 if (!impTree) {
607 coutE(InputArguments) << "RooDataSet::ctor(" << GetName() << ") ERROR file '" << fname << "' does not contain a TTree named '" << tname << "'" << endl ;
608 throw std::invalid_argument(Form("RooDataSet::ctor(%s) ERROR file %s does not contain a TTree named %s",GetName(),fname,tname)) ;
609 }
610 }
611
612 if (tstore) {
613 tstore->loadValues(impTree,0,cutRange);
614 } else {
615 RooTreeDataStore tmpstore(name,title,_vars,wgtVarName) ;
616 tmpstore.loadValues(impTree,0,cutRange) ;
617 _dstore->append(tmpstore) ;
618 }
619 }
620 }
621
622 }
624}
625
626
627
628////////////////////////////////////////////////////////////////////////////////
629/// Constructor of an empty data set from a RooArgSet defining the dimensions
630/// of the data space.
631
632RooDataSet::RooDataSet(RooStringView name, RooStringView title, const RooArgSet& vars, const char* wgtVarName) :
633 RooAbsData(name,title,vars)
634{
635// cout << "RooDataSet::ctor(" << this << ") storageType = " << ((defaultStorageType==Tree)?"Tree":"Vector") << endl ;
636 _dstore = (defaultStorageType==Tree) ? ((RooAbsDataStore*) new RooTreeDataStore(name,title,_vars,wgtVarName)) :
637 ((RooAbsDataStore*) new RooVectorDataStore(name,title,_vars,wgtVarName)) ;
638
639 appendToDir(this,true) ;
640 initialize(wgtVarName) ;
642}
643
644
645////////////////////////////////////////////////////////////////////////////////
646/// Constructor of a data set from (part of) an existing data
647/// set. The dimensions of the data set are defined by the 'vars'
648/// RooArgSet, which can be identical to 'dset' dimensions, or a
649/// subset thereof. The 'cuts' string is an optional RooFormula
650/// expression and can be used to select the subset of the data
651/// points in 'dset' to be copied. The cut expression can refer to
652/// any variable in the source dataset. For cuts involving variables
653/// other than those contained in the source data set, such as
654/// intermediate formula objects, use the equivalent constructor
655/// accepting RooFormulaVar reference as cut specification.
656///
657/// This constructor will internally store the data in a TTree.
658///
659/// For most uses the RooAbsData::reduce() wrapper function, which
660/// uses this constructor, is the most convenient way to create a
661/// subset of an existing data
662///
663
665 const RooArgSet& vars, const char *cuts, const char* wgtVarName) :
666 RooAbsData(name,title,vars)
667{
668 // Initialize datastore
669 _dstore = new RooTreeDataStore(name,title,_vars,*dset->_dstore,cuts,wgtVarName) ;
670
671 appendToDir(this,true) ;
672
673 if (wgtVarName) {
674 // Use the supplied weight column
675 initialize(wgtVarName) ;
676 } else {
677 if (dset->_wgtVar && vars.find(dset->_wgtVar->GetName())) {
678 // Use the weight column of the source data set
679 initialize(dset->_wgtVar->GetName()) ;
680 } else {
681 initialize(0) ;
682 }
683 }
685}
686
687
688////////////////////////////////////////////////////////////////////////////////
689/// Constructor of a data set from (part of) an existing data
690/// set. The dimensions of the data set are defined by the 'vars'
691/// RooArgSet, which can be identical to 'dset' dimensions, or a
692/// subset thereof. The 'cutVar' formula variable is used to select
693/// the subset of data points to be copied. For subsets without
694/// selection on the data points, or involving cuts operating
695/// exclusively and directly on the data set dimensions, the
696/// equivalent constructor with a string based cut expression is
697/// recommended.
698///
699/// This constructor will internally store the data in a TTree.
700///
701/// For most uses the RooAbsData::reduce() wrapper function, which
702/// uses this constructor, is the most convenient way to create a
703/// subset of an existing data
704
706 const RooArgSet& vars, const RooFormulaVar& cutVar, const char* wgtVarName)
707 : RooDataSet{name, title, dset, vars, cutVar.expression(), wgtVarName} {}
708
709
710
711////////////////////////////////////////////////////////////////////////////////
712/// Constructor of a data set from (part of) an ROOT TTRee. The dimensions
713/// of the data set are defined by the 'vars' RooArgSet. For each dimension
714/// specified, the TTree must have a branch with the same name. For category
715/// branches, this branch should contain the numeric index value. Real dimensions
716/// can be constructed from either 'double' or 'Float_t' tree branches. In the
717/// latter case, an automatic conversion is applied.
718///
719/// The 'cutVar' formula variable
720/// is used to select the subset of data points to be copied.
721/// For subsets without selection on the data points, or involving cuts
722/// operating exclusively and directly on the data set dimensions, the equivalent
723/// constructor with a string based cut expression is recommended.
724
726 const RooArgSet& vars, const RooFormulaVar& cutVar, const char* wgtVarName)
727 : RooDataSet{name, title, theTree, vars, cutVar.expression(), wgtVarName} {}
728
729
730
731////////////////////////////////////////////////////////////////////////////////
732/// Constructor of a data set from (part of) a ROOT TTree.
733///
734/// \param[in] name Name of this dataset.
735/// \param[in] title Title for e.g. plotting.
736/// \param[in] theTree Tree to be imported.
737/// \param[in] vars Defines the columns of the data set. For each dimension
738/// specified, the TTree must have a branch with the same name. For category
739/// branches, this branch should contain the numeric index value. Real dimensions
740/// can be constructed from either 'double' or 'Float_t' tree branches. In the
741/// latter case, an automatic conversion is applied.
742/// \param[in] cuts Optional RooFormula expression to select the subset of the data points
743/// to be imported. The cut expression can refer to any variable in `vars`.
744/// \warning The expression only evaluates variables that are also in `vars`.
745/// Passing e.g.
746/// ```
747/// RooDataSet("data", "data", tree, RooArgSet(x), "x>y")
748/// ```
749/// Will load `x` from the tree, but leave `y` at an undefined value.
750/// If other expressions are needed, such as intermediate formula objects, use
751/// RooDataSet::RooDataSet(const char*,const char*,TTree*,const RooArgSet&,const RooFormulaVar&,const char*)
752/// \param[in] wgtVarName Name of the variable in `vars` that represents an event weight.
754 const RooArgSet& vars, const char* cuts, const char* wgtVarName) :
755 RooAbsData(name,title,vars)
756{
757 // Create tree version of datastore
758 RooTreeDataStore* tstore = new RooTreeDataStore(name,title,_vars,*theTree,cuts,wgtVarName);
759
760 // Convert to vector datastore if needed
762 _dstore = tstore ;
763 } else if (defaultStorageType==Vector) {
764 RooVectorDataStore* vstore = new RooVectorDataStore(name,title,_vars,wgtVarName) ;
765 _dstore = vstore ;
766 _dstore->append(*tstore) ;
767 delete tstore ;
768 } else {
769 _dstore = 0 ;
770 }
771
772 appendToDir(this,true) ;
773
774 initialize(wgtVarName) ;
776}
777
778
779
780////////////////////////////////////////////////////////////////////////////////
781/// Copy constructor
782
783RooDataSet::RooDataSet(RooDataSet const & other, const char* newname) :
784 RooAbsData(other,newname), RooDirItem()
785{
786 appendToDir(this,true) ;
787 initialize(other._wgtVar?other._wgtVar->GetName():0) ;
789}
790
791////////////////////////////////////////////////////////////////////////////////
792/// Protected constructor for internal use only
793
795 const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
796 std::size_t nStart, std::size_t nStop) :
797 RooAbsData(name,title,vars)
798{
799 _dstore = dset->_dstore->reduce(name, title, _vars, cutVar, cutRange, nStart, nStop);
800
802
803 appendToDir(this, true);
804 initialize(dset->_wgtVar ? dset->_wgtVar->GetName() : 0);
806}
807
808
809////////////////////////////////////////////////////////////////////////////////
810/// Helper function for constructor that adds optional weight variable to construct
811/// total set of observables
812
813RooArgSet RooDataSet::addWgtVar(const RooArgSet& origVars, const RooAbsArg* wgtVar)
814{
815 RooArgSet tmp(origVars) ;
816 if (wgtVar) tmp.add(*wgtVar) ;
817 return tmp ;
818}
819
820
821////////////////////////////////////////////////////////////////////////////////
822/// Return an empty clone of this dataset. If vars is not null, only the variables in vars
823/// are added to the definition of the empty clone
824
825RooAbsData* RooDataSet::emptyClone(const char* newName, const char* newTitle, const RooArgSet* vars, const char* wgtVarName) const
826{
827 // If variables are given, be sure to include weight variable if it exists and is not included
828 RooArgSet vars2 ;
829 RooRealVar* tmpWgtVar = _wgtVar ;
830 if (wgtVarName && vars && !_wgtVar) {
831 tmpWgtVar = (RooRealVar*) vars->find(wgtVarName) ;
832 }
833
834 if (vars) {
835 vars2.add(*vars) ;
836 if (_wgtVar && !vars2.find(_wgtVar->GetName())) {
837 vars2.add(*_wgtVar) ;
838 }
839 } else {
840 vars2.add(_vars) ;
841 }
842
843 RooDataSet* dset = new RooDataSet(newName?newName:GetName(),newTitle?newTitle:GetTitle(),vars2,tmpWgtVar?tmpWgtVar->GetName():0) ;
844 //if (_wgtVar) dset->setWeightVar(_wgtVar->GetName()) ;
845 return dset ;
846}
847
848
849
850////////////////////////////////////////////////////////////////////////////////
851/// Initialize the dataset. If wgtVarName is not null, interpret the observable
852/// with that name as event weight
853
854void RooDataSet::initialize(const char* wgtVarName)
855{
858 _wgtVar = 0 ;
859 if (wgtVarName) {
860 RooAbsArg* wgt = _varsNoWgt.find(wgtVarName) ;
861 if (!wgt) {
862 coutE(DataHandling) << "RooDataSet::RooDataSet(" << GetName() << "): designated weight variable "
863 << wgtVarName << " not found in set of variables, no weighting will be assigned" << endl ;
864 throw std::invalid_argument("RooDataSet::initialize() weight variable could not be initialised.");
865 } else if (!dynamic_cast<RooRealVar*>(wgt)) {
866 coutE(DataHandling) << "RooDataSet::RooDataSet(" << GetName() << "): designated weight variable "
867 << wgtVarName << " is not of type RooRealVar, no weighting will be assigned" << endl ;
868 throw std::invalid_argument("RooDataSet::initialize() weight variable could not be initialised.");
869 } else {
870 _varsNoWgt.remove(*wgt) ;
871 _wgtVar = (RooRealVar*) wgt ;
872 }
873 }
874}
875
876
877
878////////////////////////////////////////////////////////////////////////////////
879/// Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods
880
881RooAbsData* RooDataSet::reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange,
882 std::size_t nStart, std::size_t nStop)
883{
884 checkInit() ;
885 RooArgSet tmp(varSubset) ;
886 if (_wgtVar) {
887 tmp.add(*_wgtVar) ;
888 }
889 return new RooDataSet(GetName(), GetTitle(), this, tmp, cutVar, cutRange, nStart, nStop) ;
890}
891
892
893
894////////////////////////////////////////////////////////////////////////////////
895/// Destructor
896
898{
899 removeFromDir(this) ;
901}
902
903
904
905////////////////////////////////////////////////////////////////////////////////
906/// Return binned clone of this dataset
907
908RooDataHist* RooDataSet::binnedClone(const char* newName, const char* newTitle) const
909{
910 std::string title;
911 std::string name;
912 if (newName) {
913 name = newName ;
914 } else {
915 name = std::string(GetName()) + "_binned" ;
916 }
917 if (newTitle) {
918 title = newTitle ;
919 } else {
920 name = std::string(GetTitle()) + "_binned" ;
921 }
922
923 return new RooDataHist(name,title,*get(),*this) ;
924}
925
926
927
928////////////////////////////////////////////////////////////////////////////////
929/// Return event weight of current event
930
931double RooDataSet::weight() const
932{
933 return store()->weight() ;
934}
935
936
937
938////////////////////////////////////////////////////////////////////////////////
939/// Return squared event weight of current event
940
942{
943 return store()->weight()*store()->weight() ;
944}
945
946
947////////////////////////////////////////////////////////////////////////////////
948/// \see RooAbsData::getWeightBatch().
949RooSpan<const double> RooDataSet::getWeightBatch(std::size_t first, std::size_t len, bool sumW2 /*=false*/) const {
950
951 std::size_t nEntries = this->numEntries(); // for the casting to std::size_t
952
953 if(first >= nEntries || (first + len) > nEntries) {
954 throw std::runtime_error("RooDataSet::getWeightBatch(): requested range not valid for dataset.");
955 }
956
958 if(allWeights.empty()) return {};
959
960 if(!sumW2) return {std::cbegin(allWeights) + first, std::cbegin(allWeights) + first + len};
961
962 // Treat the sumW2 case with a result buffer, first reset buffer if the
963 // number of entries doesn't match with the dataset anymore
964 if(_sumW2Buffer && _sumW2Buffer->size() != nEntries) _sumW2Buffer.reset(nullptr);
965
966 if (!_sumW2Buffer) {
967 _sumW2Buffer = std::make_unique<std::vector<double>>();
968 _sumW2Buffer->reserve(nEntries);
969
970 for (std::size_t i = 0; i < nEntries; ++i) {
971 // Unlike in the RooDataHist case, the sum of weights squared for each
972 // entry is simply the square of the weight.
973 _sumW2Buffer->push_back(allWeights[i] * allWeights[i]);
974 }
975 }
976
977 return RooSpan<const double>(_sumW2Buffer->begin() + first, _sumW2Buffer->begin() + first + len);
978}
979
980
981////////////////////////////////////////////////////////////////////////////////
982/// \copydoc RooAbsData::weightError(double&,double&,RooAbsData::ErrorType) const
983/// \param etype error type
984void RooDataSet::weightError(double& lo, double& hi, ErrorType etype) const
985{
986 store()->weightError(lo,hi,etype) ;
987}
988
989
990////////////////////////////////////////////////////////////////////////////////
991/// \copydoc RooAbsData::weightError(ErrorType)
992/// \param etype error type
994{
995 return store()->weightError(etype) ;
996}
997
998
999////////////////////////////////////////////////////////////////////////////////
1000/// Return RooArgSet with coordinates of event 'index'
1001
1003{
1004 const RooArgSet* ret = RooAbsData::get(index) ;
1005 return ret ? &_varsNoWgt : 0 ;
1006}
1007
1008
1009////////////////////////////////////////////////////////////////////////////////
1010
1012{
1013 return store()->sumEntries() ;
1014}
1015
1016
1017////////////////////////////////////////////////////////////////////////////////
1018/// Return the sum of weights in all entries matching cutSpec (if specified)
1019/// and in named range cutRange (if specified)
1020
1021double RooDataSet::sumEntries(const char* cutSpec, const char* cutRange) const
1022{
1023 // Setup RooFormulaVar for cutSpec if it is present
1024 std::unique_ptr<RooFormula> select = nullptr ;
1025 if (cutSpec && strlen(cutSpec) > 0) {
1026 select = std::make_unique<RooFormula>("select",cutSpec,*get()) ;
1027 }
1028
1029 // Shortcut for unweighted unselected datasets
1030 if (!select && !cutRange && !isWeighted()) {
1031 return numEntries() ;
1032 }
1033
1034 // Otherwise sum the weights in the event
1036 for (int i = 0 ; i<numEntries() ; i++) {
1037 get(i) ;
1038 if (select && select->eval()==0.) continue ;
1039 if (cutRange && !_vars.allInRange(cutRange)) continue ;
1040 sumw += weight();
1041 }
1042
1043 return sumw.Sum() ;
1044}
1045
1046
1047
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Return true if dataset contains weighted events
1051
1053{
1054 return store() ? store()->isWeighted() : false;
1055}
1056
1057
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Returns true if histogram contains bins with entries with a non-integer weight
1061
1063{
1064 // Return false if we have no weights
1065 if (!_wgtVar) return false ;
1066
1067 // Now examine individual weights
1068 for (int i=0 ; i<numEntries() ; i++) {
1069 get(i) ;
1070 if (fabs(weight()-Int_t(weight()))>1e-10) return true ;
1071 }
1072 // If sum of weights is less than number of events there are negative (integer) weights
1073 if (sumEntries()<numEntries()) return true ;
1074
1075 return false ;
1076}
1077
1078
1079
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// Return a RooArgSet with the coordinates of the current event
1083
1085{
1086 return &_varsNoWgt ;
1087}
1088
1089
1090
1091////////////////////////////////////////////////////////////////////////////////
1092/// Add a data point, with its coordinates specified in the 'data' argset, to the data set.
1093/// Any variables present in 'data' but not in the dataset will be silently ignored.
1094/// \param[in] data Data point.
1095/// \param[in] wgt Event weight. Defaults to 1. The current value of the weight variable is
1096/// ignored.
1097/// \note To obtain weighted events, a variable must be designated `WeightVar` in the constructor.
1098/// \param[in] wgtError Optional weight error.
1099/// \note This requires including the weight variable in the set of `StoreError` variables when constructing
1100/// the dataset.
1101
1102void RooDataSet::add(const RooArgSet& data, double wgt, double wgtError)
1103{
1104 checkInit() ;
1105
1106 const double oldW = _wgtVar ? _wgtVar->getVal() : 0.;
1107
1109
1110 if (_wgtVar) {
1111 _wgtVar->setVal(wgt) ;
1112 if (wgtError!=0.) {
1113 _wgtVar->setError(wgtError) ;
1114 }
1115 } else if ((wgt != 1. || wgtError != 0.) && _errorMsgCount < 5) {
1116 ccoutE(DataHandling) << "An event weight/error was passed but no weight variable was defined"
1117 << " in the dataset '" << GetName() << "'. The weight will be ignored." << std::endl;
1119 }
1120
1122 && wgtError != 0.
1123 && fabs(wgt*wgt - wgtError)/wgtError > 1.E-15 //Exception for standard wgt^2 errors, which need not be stored.
1124 && _errorMsgCount < 5 && !_wgtVar->getAttribute("StoreError")) {
1125 coutE(DataHandling) << "An event weight error was passed to the RooDataSet '" << GetName()
1126 << "', but the weight variable '" << _wgtVar->GetName()
1127 << "' does not store errors. Check `StoreError` in the RooDataSet constructor." << std::endl;
1129 }
1130
1131 fill();
1132
1133 // Restore weight state
1134 if (_wgtVar) {
1135 _wgtVar->setVal(oldW);
1137 }
1138}
1139
1140
1141
1142
1143////////////////////////////////////////////////////////////////////////////////
1144/// Add a data point, with its coordinates specified in the 'data' argset, to the data set.
1145/// Any variables present in 'data' but not in the dataset will be silently ignored.
1146/// \param[in] indata Data point.
1147/// \param[in] inweight Event weight. The current value of the weight variable is ignored.
1148/// \note To obtain weighted events, a variable must be designated `WeightVar` in the constructor.
1149/// \param[in] weightErrorLo Asymmetric weight error.
1150/// \param[in] weightErrorHi Asymmetric weight error.
1151/// \note This requires including the weight variable in the set of `StoreAsymError` variables when constructing
1152/// the dataset.
1153
1154void RooDataSet::add(const RooArgSet& indata, double inweight, double weightErrorLo, double weightErrorHi)
1155{
1156 checkInit() ;
1157
1158 const double oldW = _wgtVar ? _wgtVar->getVal() : 0.;
1159
1160 _varsNoWgt.assign(indata);
1161 if (_wgtVar) {
1162 _wgtVar->setVal(inweight) ;
1163 _wgtVar->setAsymError(weightErrorLo,weightErrorHi) ;
1164 } else if (inweight != 1. && _errorMsgCount < 5) {
1165 ccoutE(DataHandling) << "An event weight was given but no weight variable was defined"
1166 << " in the dataset '" << GetName() << "'. The weight will be ignored." << std::endl;
1168 }
1169
1171 && _errorMsgCount < 5 && !_wgtVar->getAttribute("StoreAsymError")) {
1172 coutE(DataHandling) << "An event weight error was passed to the RooDataSet '" << GetName()
1173 << "', but the weight variable '" << _wgtVar->GetName()
1174 << "' does not store errors. Check `StoreAsymError` in the RooDataSet constructor." << std::endl;
1176 }
1177
1178 fill();
1179
1180 // Restore weight state
1181 if (_wgtVar) {
1182 _wgtVar->setVal(oldW);
1184 }
1185}
1186
1187
1188
1189
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// Add a data point, with its coordinates specified in the 'data' argset, to the data set.
1193/// \attention The order and type of the input variables are **assumed** to be the same as
1194/// for the RooArgSet returned by RooDataSet::get(). Input values will just be written
1195/// into the internal data columns by ordinal position.
1196/// \param[in] data Data point.
1197/// \param[in] wgt Event weight. Defaults to 1. The current value of the weight variable is
1198/// ignored.
1199/// \note To obtain weighted events, a variable must be designated `WeightVar` in the constructor.
1200/// \param[in] wgtError Optional weight error.
1201/// \note This requires including the weight variable in the set of `StoreError` variables when constructing
1202/// the dataset.
1203
1204void RooDataSet::addFast(const RooArgSet& data, double wgt, double wgtError)
1205{
1206 checkInit() ;
1207
1208 const double oldW = _wgtVar ? _wgtVar->getVal() : 0.;
1209
1211 if (_wgtVar) {
1212 _wgtVar->setVal(wgt) ;
1213 if (wgtError!=0.) {
1214 _wgtVar->setError(wgtError) ;
1215 }
1216 } else if (wgt != 1. && _errorMsgCount < 5) {
1217 ccoutE(DataHandling) << "An event weight was given but no weight variable was defined"
1218 << " in the dataset '" << GetName() << "'. The weight will be ignored." << std::endl;
1220 }
1221
1222 fill();
1223
1225 && wgtError != 0. && wgtError != wgt*wgt //Exception for standard weight error, which need not be stored
1226 && _errorMsgCount < 5 && !_wgtVar->getAttribute("StoreError")) {
1227 coutE(DataHandling) << "An event weight error was passed to the RooDataSet '" << GetName()
1228 << "', but the weight variable '" << _wgtVar->GetName()
1229 << "' does not store errors. Check `StoreError` in the RooDataSet constructor." << std::endl;
1231 }
1233 _doWeightErrorCheck = false;
1234 }
1235
1236 if (_wgtVar) {
1237 _wgtVar->setVal(oldW);
1239 }
1240}
1241
1242
1243
1244////////////////////////////////////////////////////////////////////////////////
1245
1247 RooDataSet* data4, RooDataSet* data5, RooDataSet* data6)
1248{
1249 checkInit() ;
1250 list<RooDataSet*> dsetList ;
1251 if (data1) dsetList.push_back(data1) ;
1252 if (data2) dsetList.push_back(data2) ;
1253 if (data3) dsetList.push_back(data3) ;
1254 if (data4) dsetList.push_back(data4) ;
1255 if (data5) dsetList.push_back(data5) ;
1256 if (data6) dsetList.push_back(data6) ;
1257 return merge(dsetList) ;
1258}
1259
1260
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// Merge columns of supplied data set(s) with this data set. All
1264/// data sets must have equal number of entries. In case of
1265/// duplicate columns the column of the last dataset in the list
1266/// prevails
1267
1268bool RooDataSet::merge(list<RooDataSet*>dsetList)
1269{
1270
1271 checkInit() ;
1272 // Sanity checks: data sets must have the same size
1273 for (list<RooDataSet*>::iterator iter = dsetList.begin() ; iter != dsetList.end() ; ++iter) {
1274 if (numEntries()!=(*iter)->numEntries()) {
1275 coutE(InputArguments) << "RooDataSet::merge(" << GetName() << ") ERROR: datasets have different size" << endl ;
1276 return true ;
1277 }
1278 }
1279
1280 // Extend vars with elements of other dataset
1281 list<RooAbsDataStore*> dstoreList ;
1282 for (list<RooDataSet*>::iterator iter = dsetList.begin() ; iter != dsetList.end() ; ++iter) {
1283 _vars.addClone((*iter)->_vars,true) ;
1284 dstoreList.push_back((*iter)->store()) ;
1285 }
1286
1287 // Merge data stores
1288 RooAbsDataStore* mergedStore = _dstore->merge(_vars,dstoreList) ;
1289 mergedStore->SetName(_dstore->GetName()) ;
1290 mergedStore->SetTitle(_dstore->GetTitle()) ;
1291
1292 // Replace current data store with merged store
1293 delete _dstore ;
1294 _dstore = mergedStore ;
1295
1297 return false ;
1298}
1299
1300
1301////////////////////////////////////////////////////////////////////////////////
1302/// Add all data points of given data set to this data set.
1303/// Observable in 'data' that are not in this dataset
1304/// with not be transferred
1305
1307{
1308 checkInit() ;
1309 _dstore->append(*data._dstore) ;
1310}
1311
1312
1313
1314////////////////////////////////////////////////////////////////////////////////
1315/// Add a column with the values of the given (function) argument
1316/// to this dataset. The function value is calculated for each
1317/// event using the observable values of each event in case the
1318/// function depends on variables with names that are identical
1319/// to the observable names in the dataset
1320
1322{
1323 checkInit() ;
1324 RooAbsArg* ret = _dstore->addColumn(var,adjustRange) ;
1325 _vars.addOwned(*ret) ;
1327 return ret ;
1328}
1329
1330
1331////////////////////////////////////////////////////////////////////////////////
1332/// Add a column with the values of the given list of (function)
1333/// argument to this dataset. Each function value is calculated for
1334/// each event using the observable values of the event in case the
1335/// function depends on variables with names that are identical to
1336/// the observable names in the dataset
1337
1339{
1340 auto * holderSet = new RooArgSet{};
1341 for(RooAbsArg * var : varList) {
1342 holderSet->add(*addColumn(*var));
1343 }
1344 return holderSet;
1345}
1346
1347
1348
1349
1350
1351////////////////////////////////////////////////////////////////////////////////
1352/// Special plot method for 'X-Y' datasets used in \f$ \chi^2 \f$ fitting.
1353/// For general plotting, see RooAbsData::plotOn().
1354///
1355/// These datasets
1356/// have one observable (X) and have weights (Y) and associated errors.
1357/// <table>
1358/// <tr><th> Contents options <th> Effect
1359/// <tr><td> YVar(RooRealVar& var) <td> Designate specified observable as 'y' variable
1360/// If not specified, the event weight will be the y variable
1361/// <tr><th> Histogram drawing options <th> Effect
1362/// <tr><td> DrawOption(const char* opt) <td> Select ROOT draw option for resulting TGraph object
1363/// <tr><td> LineStyle(Int_t style) <td> Select line style by ROOT line style code, default is solid
1364/// <tr><td> LineColor(Int_t color) <td> Select line color by ROOT color code, default is black
1365/// <tr><td> LineWidth(Int_t width) <td> Select line with in pixels, default is 3
1366/// <tr><td> MarkerStyle(Int_t style) <td> Select the ROOT marker style, default is 21
1367/// <tr><td> MarkerColor(Int_t color) <td> Select the ROOT marker color, default is black
1368/// <tr><td> MarkerSize(double size) <td> Select the ROOT marker size
1369/// <tr><td> Rescale(double factor) <td> Apply global rescaling factor to histogram
1370/// <tr><th> Misc. other options <th> Effect
1371/// <tr><td> Name(const chat* name) <td> Give curve specified name in frame. Useful if curve is to be referenced later
1372/// <tr><td> Invisible(bool flag) <td> Add curve to frame, but do not display. Useful in combination AddTo()
1373/// </table>
1374
1375RooPlot* RooDataSet::plotOnXY(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
1376 const RooCmdArg& arg3, const RooCmdArg& arg4,
1377 const RooCmdArg& arg5, const RooCmdArg& arg6,
1378 const RooCmdArg& arg7, const RooCmdArg& arg8) const
1379{
1380 checkInit() ;
1381
1382 RooLinkedList argList ;
1383 argList.Add((TObject*)&arg1) ; argList.Add((TObject*)&arg2) ;
1384 argList.Add((TObject*)&arg3) ; argList.Add((TObject*)&arg4) ;
1385 argList.Add((TObject*)&arg5) ; argList.Add((TObject*)&arg6) ;
1386 argList.Add((TObject*)&arg7) ; argList.Add((TObject*)&arg8) ;
1387
1388 // Process named arguments
1389 RooCmdConfig pc(Form("RooDataSet::plotOnXY(%s)",GetName())) ;
1390 pc.defineString("drawOption","DrawOption",0,"P") ;
1391 pc.defineString("histName","Name",0,"") ;
1392 pc.defineInt("lineColor","LineColor",0,-999) ;
1393 pc.defineInt("lineStyle","LineStyle",0,-999) ;
1394 pc.defineInt("lineWidth","LineWidth",0,-999) ;
1395 pc.defineInt("markerColor","MarkerColor",0,-999) ;
1396 pc.defineInt("markerStyle","MarkerStyle",0,8) ;
1397 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
1398 pc.defineInt("fillColor","FillColor",0,-999) ;
1399 pc.defineInt("fillStyle","FillStyle",0,-999) ;
1400 pc.defineInt("histInvisible","Invisible",0,0) ;
1401 pc.defineDouble("scaleFactor","Rescale",0,1.) ;
1402 pc.defineObject("xvar","XVar",0,0) ;
1403 pc.defineObject("yvar","YVar",0,0) ;
1404
1405
1406 // Process & check varargs
1407 pc.process(argList) ;
1408 if (!pc.ok(true)) {
1409 return frame ;
1410 }
1411
1412 // Extract values from named arguments
1413 const char* drawOptions = pc.getString("drawOption") ;
1414 Int_t histInvisible = pc.getInt("histInvisible") ;
1415 const char* histName = pc.getString("histName",0,true) ;
1416 double scaleFactor = pc.getDouble("scaleFactor") ;
1417
1418 RooRealVar* xvar = (RooRealVar*) _vars.find(frame->getPlotVar()->GetName()) ;
1419
1420 // Determine Y variable (default is weight, if present)
1421 RooRealVar* yvar = (RooRealVar*)(pc.getObject("yvar")) ;
1422
1423 // Sanity check. XY plotting only applies to weighted datasets if no YVar is specified
1424 if (!_wgtVar && !yvar) {
1425 coutE(InputArguments) << "RooDataSet::plotOnXY(" << GetName() << ") ERROR: no YVar() argument specified and dataset is not weighted" << endl ;
1426 return 0 ;
1427 }
1428
1429 RooRealVar* dataY = yvar ? (RooRealVar*) _vars.find(yvar->GetName()) : 0 ;
1430 if (yvar && !dataY) {
1431 coutE(InputArguments) << "RooDataSet::plotOnXY(" << GetName() << ") ERROR on YVar() argument, dataset does not contain a variable named " << yvar->GetName() << endl ;
1432 return 0 ;
1433 }
1434
1435
1436 // Make RooHist representing XY contents of data
1437 RooHist* graph = new RooHist ;
1438 if (histName) {
1439 graph->SetName(histName) ;
1440 } else {
1441 graph->SetName(Form("hxy_%s",GetName())) ;
1442 }
1443
1444 for (int i=0 ; i<numEntries() ; i++) {
1445 get(i) ;
1446 double x = xvar->getVal() ;
1447 double exlo = xvar->getErrorLo() ;
1448 double exhi = xvar->getErrorHi() ;
1449 double y,eylo,eyhi ;
1450 if (!dataY) {
1451 y = weight() ;
1452 weightError(eylo,eyhi) ;
1453 } else {
1454 y = dataY->getVal() ;
1455 eylo = dataY->getErrorLo() ;
1456 eyhi = dataY->getErrorHi() ;
1457 }
1458 graph->addBinWithXYError(x,y,-1*exlo,exhi,-1*eylo,eyhi,scaleFactor) ;
1459 }
1460
1461 // Adjust style options according to named arguments
1462 Int_t lineColor = pc.getInt("lineColor") ;
1463 Int_t lineStyle = pc.getInt("lineStyle") ;
1464 Int_t lineWidth = pc.getInt("lineWidth") ;
1465 Int_t markerColor = pc.getInt("markerColor") ;
1466 Int_t markerStyle = pc.getInt("markerStyle") ;
1467 Size_t markerSize = pc.getDouble("markerSize") ;
1468 Int_t fillColor = pc.getInt("fillColor") ;
1469 Int_t fillStyle = pc.getInt("fillStyle") ;
1470
1471 if (lineColor!=-999) graph->SetLineColor(lineColor) ;
1472 if (lineStyle!=-999) graph->SetLineStyle(lineStyle) ;
1473 if (lineWidth!=-999) graph->SetLineWidth(lineWidth) ;
1474 if (markerColor!=-999) graph->SetMarkerColor(markerColor) ;
1475 if (markerStyle!=-999) graph->SetMarkerStyle(markerStyle) ;
1476 if (markerSize!=-999) graph->SetMarkerSize(markerSize) ;
1477 if (fillColor!=-999) graph->SetFillColor(fillColor) ;
1478 if (fillStyle!=-999) graph->SetFillStyle(fillStyle) ;
1479
1480 // Add graph to frame
1481 frame->addPlotable(graph,drawOptions,histInvisible) ;
1482
1483 return frame ;
1484}
1485
1486
1487
1488
1489////////////////////////////////////////////////////////////////////////////////
1490/// Read given list of ascii files, and construct a data set, using the given
1491/// ArgList as structure definition.
1492/// \param fileList Multiple file names, comma separated. Each
1493/// file is optionally prefixed with 'commonPath' if such a path is
1494/// provided
1495///
1496/// \param varList Specify the dimensions of the dataset to be built.
1497/// This list describes the order in which these dimensions appear in the
1498/// ascii files to be read.
1499/// Each line in the ascii file should contain N white-space separated
1500/// tokens, with N the number of args in `varList`. Any text beyond
1501/// N tokens will be ignored with a warning message.
1502/// (NB: This is the default output of RooArgList::writeToStream())
1503///
1504/// \param verbOpt `Q` be quiet, `D` debug mode (verbose)
1505///
1506/// \param commonPath All filenames in `fileList` will be prefixed with this optional path.
1507///
1508/// \param indexCatName Interpret the data as belonging to category `indexCatName`.
1509/// When multiple files are read, a RooCategory arg in `varList` can
1510/// optionally be designated to hold information about the source file
1511/// of each data point. This feature is enabled by giving the name
1512/// of the (already existing) category variable in `indexCatName`.
1513///
1514/// \attention If the value of any of the variables on a given line exceeds the
1515/// fit range associated with that dimension, the entire line will be
1516/// ignored. A warning message is printed in each case, unless the
1517/// `Q` verbose option is given. The number of events read and skipped
1518/// is always summarized at the end.
1519///
1520/// If no further information is given a label name 'fileNNN' will
1521/// be assigned to each event, where NNN is the sequential number of
1522/// the source file in `fileList`.
1523///
1524/// Alternatively, it is possible to override the default label names
1525/// of the index category by specifying them in the fileList string:
1526/// When instead of `file1.txt,file2.txt` the string
1527/// `file1.txt:FOO,file2.txt:BAR` is specified, a state named "FOO"
1528/// is assigned to the index category for each event originating from
1529/// file1.txt. The labels FOO,BAR may be predefined in the index
1530/// category via defineType(), but don't have to be.
1531///
1532/// Finally, one can also assign the same label to multiple files,
1533/// either by specifying `file1.txt:FOO,file2,txt:FOO,file3.txt:BAR`
1534/// or `file1.txt,file2.txt:FOO,file3.txt:BAR`.
1535///
1536
1537RooDataSet *RooDataSet::read(const char *fileList, const RooArgList &varList,
1538 const char *verbOpt, const char* commonPath,
1539 const char* indexCatName) {
1540 // Make working copy of variables list
1541 RooArgList variables(varList) ;
1542
1543 // Append blinding state category to variable list if not already there
1544 bool ownIsBlind(true) ;
1545 RooAbsArg* blindState = variables.find("blindState") ;
1546 if (!blindState) {
1547 blindState = new RooCategory("blindState","Blinding State") ;
1548 variables.add(*blindState) ;
1549 } else {
1550 ownIsBlind = false ;
1551 if (blindState->IsA()!=RooCategory::Class()) {
1552 oocoutE(nullptr,DataHandling) << "RooDataSet::read: ERROR: variable list already contains"
1553 << "a non-RooCategory blindState member" << endl ;
1554 return 0 ;
1555 }
1556 oocoutW(nullptr,DataHandling) << "RooDataSet::read: WARNING: recycling existing "
1557 << "blindState category in variable list" << endl ;
1558 }
1559 RooCategory* blindCat = (RooCategory*) blindState ;
1560
1561 // Configure blinding state category
1562 blindCat->setAttribute("Dynamic") ;
1563 blindCat->defineType("Normal",0) ;
1564 blindCat->defineType("Blind",1) ;
1565
1566 // parse the option string
1567 TString opts= verbOpt;
1568 opts.ToLower();
1569 bool verbose= !opts.Contains("q");
1570 bool debug= opts.Contains("d");
1571
1572 auto data = std::make_unique<RooDataSet>("dataset", fileList, variables);
1573 if (ownIsBlind) { variables.remove(*blindState) ; delete blindState ; }
1574 if(!data) {
1575 oocoutE(nullptr,DataHandling) << "RooDataSet::read: unable to create a new dataset"
1576 << endl;
1577 return nullptr;
1578 }
1579
1580 // Redirect blindCat to point to the copy stored in the data set
1581 blindCat = (RooCategory*) data->_vars.find("blindState") ;
1582
1583 // Find index category, if requested
1584 RooCategory *indexCat = 0;
1585 //RooCategory *indexCatOrig = 0;
1586 if (indexCatName) {
1587 RooAbsArg* tmp = 0;
1588 tmp = data->_vars.find(indexCatName) ;
1589 if (!tmp) {
1590 oocoutE(data.get(),DataHandling) << "RooDataSet::read: no index category named "
1591 << indexCatName << " in supplied variable list" << endl ;
1592 return nullptr;
1593 }
1594 if (tmp->IsA()!=RooCategory::Class()) {
1595 oocoutE(data.get(),DataHandling) << "RooDataSet::read: variable " << indexCatName
1596 << " is not a RooCategory" << endl ;
1597 return nullptr;
1598 }
1599 indexCat = static_cast<RooCategory*>(tmp);
1600
1601 // Prevent RooArgSet from attempting to read in indexCat
1602 indexCat->setAttribute("Dynamic") ;
1603 }
1604
1605
1606 Int_t outOfRange(0) ;
1607
1608 // Loop over all names in comma separated list
1609 Int_t fileSeqNum(0);
1610 for (const auto& filename : ROOT::Split(std::string(fileList), ", ")) {
1611 // Determine index category number, if this option is active
1612 if (indexCat) {
1613
1614 // Find and detach optional file category name
1615 const char *catname = strchr(filename.c_str(),':');
1616
1617 if (catname) {
1618 // Use user category name if provided
1619 catname++ ;
1620
1621 if (indexCat->hasLabel(catname)) {
1622 // Use existing category index
1623 indexCat->setLabel(catname);
1624 } else {
1625 // Register cat name
1626 indexCat->defineType(catname,fileSeqNum) ;
1627 indexCat->setIndex(fileSeqNum) ;
1628 }
1629 } else {
1630 // Assign autogenerated name
1631 char newLabel[128] ;
1632 snprintf(newLabel,128,"file%03d",fileSeqNum) ;
1633 if (indexCat->defineType(newLabel,fileSeqNum)) {
1634 oocoutE(data.get(), DataHandling) << "RooDataSet::read: Error, cannot register automatic type name " << newLabel
1635 << " in index category " << indexCat->GetName() << endl ;
1636 return 0 ;
1637 }
1638 // Assign new category number
1639 indexCat->setIndex(fileSeqNum) ;
1640 }
1641 }
1642
1643 oocoutI(data.get(), DataHandling) << "RooDataSet::read: reading file " << filename << endl ;
1644
1645 // Prefix common path
1646 TString fullName(commonPath) ;
1647 fullName.Append(filename) ;
1648 ifstream file(fullName) ;
1649
1650 if (!file.good()) {
1651 oocoutE(data.get(), DataHandling) << "RooDataSet::read: unable to open '"
1652 << filename << "'. Returning nullptr now." << endl;
1653 return nullptr;
1654 }
1655
1656 // double value;
1657 Int_t line(0) ;
1658 bool haveBlindString(false) ;
1659
1660 while(file.good() && !file.eof()) {
1661 line++;
1662 if(debug) oocxcoutD(data.get(),DataHandling) << "reading line " << line << endl;
1663
1664 // process comment lines
1665 if (file.peek() == '#') {
1666 if(debug) oocxcoutD(data.get(),DataHandling) << "skipping comment on line " << line << endl;
1667 } else {
1668 // Read single line
1669 bool readError = variables.readFromStream(file,true,verbose) ;
1670 data->_vars.assign(variables) ;
1671
1672 // Stop on read error
1673 if(!file.good()) {
1674 oocoutE(data.get(), DataHandling) << "RooDataSet::read(static): read error at line " << line << endl ;
1675 break;
1676 }
1677
1678 if (readError) {
1679 outOfRange++ ;
1680 } else {
1681 blindCat->setIndex(haveBlindString) ;
1682 data->fill(); // store this event
1683 }
1684 }
1685
1686 // Skip all white space (including empty lines).
1687 while (isspace(file.peek())) {
1688 char dummy;
1689 file >> std::noskipws >> dummy >> std::skipws;
1690 }
1691 }
1692
1693 file.close();
1694
1695 // get next file name
1696 fileSeqNum++ ;
1697 }
1698
1699 if (indexCat) {
1700 // Copy dynamically defined types from new data set to indexCat in original list
1701 assert(dynamic_cast<RooCategory*>(variables.find(indexCatName)));
1702 const auto origIndexCat = static_cast<RooCategory*>(variables.find(indexCatName));
1703 for (const auto& nameIdx : *indexCat) {
1704 origIndexCat->defineType(nameIdx.first, nameIdx.second);
1705 }
1706 }
1707 oocoutI(data.get(),DataHandling) << "RooDataSet::read: read " << data->numEntries()
1708 << " events (ignored " << outOfRange << " out of range events)" << endl;
1709
1710 return data.release();
1711}
1712
1713
1714
1715
1716////////////////////////////////////////////////////////////////////////////////
1717/// Write the contents of this dataset to an ASCII file with the specified name.
1718/// Each event will be written as a single line containing the written values
1719/// of each observable in the order they were declared in the dataset and
1720/// separated by whitespaces
1721
1722bool RooDataSet::write(const char* filename) const
1723{
1724 // Open file for writing
1725 ofstream ofs(filename) ;
1726 if (ofs.fail()) {
1727 coutE(DataHandling) << "RooDataSet::write(" << GetName() << ") cannot create file " << filename << endl ;
1728 return true ;
1729 }
1730
1731 // Write all lines as arglist in compact mode
1732 coutI(DataHandling) << "RooDataSet::write(" << GetName() << ") writing ASCII file " << filename << endl ;
1733 return write(ofs);
1734}
1735
1736////////////////////////////////////////////////////////////////////////////////
1737/// Write the contents of this dataset to the stream.
1738/// Each event will be written as a single line containing the written values
1739/// of each observable in the order they were declared in the dataset and
1740/// separated by whitespaces
1741
1742bool RooDataSet::write(ostream & ofs) const {
1743 checkInit();
1744
1745 for (Int_t i=0; i<numEntries(); ++i) {
1746 get(i)->writeToStream(ofs,true);
1747 }
1748
1749 if (ofs.fail()) {
1750 coutW(DataHandling) << "RooDataSet::write(" << GetName() << "): WARNING error(s) have occured in writing" << endl ;
1751 }
1752
1753 return ofs.fail() ;
1754}
1755
1756
1757////////////////////////////////////////////////////////////////////////////////
1758/// Print info about this dataset to the specified output stream.
1759///
1760/// Standard: number of entries
1761/// Shape: list of variables we define & were generated with
1762
1763void RooDataSet::printMultiline(ostream& os, Int_t contents, bool verbose, TString indent) const
1764{
1765 checkInit() ;
1767 if (_wgtVar) {
1768 os << indent << " Dataset variable \"" << _wgtVar->GetName() << "\" is interpreted as the event weight" << endl ;
1769 }
1770}
1771
1772
1773////////////////////////////////////////////////////////////////////////////////
1774/// Print value of the dataset, i.e. the sum of weights contained in the dataset
1775
1776void RooDataSet::printValue(ostream& os) const
1777{
1778 os << numEntries() << " entries" ;
1779 if (isWeighted()) {
1780 os << " (" << sumEntries() << " weighted)" ;
1781 }
1782}
1783
1784
1785
1786////////////////////////////////////////////////////////////////////////////////
1787/// Print argument of dataset, i.e. the observable names
1788
1789void RooDataSet::printArgs(ostream& os) const
1790{
1791 os << "[" ;
1792 bool first(true) ;
1793 for(RooAbsArg* arg : _varsNoWgt) {
1794 if (first) {
1795 first=false ;
1796 } else {
1797 os << "," ;
1798 }
1799 os << arg->GetName() ;
1800 }
1801 if (_wgtVar) {
1802 os << ",weight:" << _wgtVar->GetName() ;
1803 }
1804 os << "]" ;
1805}
1806
1807
1808
1809////////////////////////////////////////////////////////////////////////////////
1810/// Change the name of this dataset into the given name
1811
1812void RooDataSet::SetName(const char *name)
1813{
1814 if (_dir) _dir->GetList()->Remove(this);
1816 if (_dir) _dir->GetList()->Add(this);
1817}
1818
1819
1820////////////////////////////////////////////////////////////////////////////////
1821/// Change the title of this dataset into the given name
1822
1823void RooDataSet::SetNameTitle(const char *name, const char* title)
1824{
1825 if (_dir) _dir->GetList()->Remove(this);
1826 TNamed::SetNameTitle(name,title) ;
1827 if (_dir) _dir->GetList()->Add(this);
1828}
1829
1830
1831////////////////////////////////////////////////////////////////////////////////
1832/// Stream an object of class RooDataSet.
1833
1835{
1836 if (R__b.IsReading()) {
1837
1838 UInt_t R__s, R__c;
1839 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1840
1841 if (R__v>1) {
1842
1843 // Use new-style streaming for version >1
1844 R__b.ReadClassBuffer(RooDataSet::Class(),this,R__v,R__s,R__c);
1845
1846 } else {
1847
1848 // Legacy dataset conversion happens here. Legacy RooDataSet inherits from RooTreeData
1849 // which in turn inherits from RooAbsData. Manually stream RooTreeData contents on
1850 // file here and convert it into a RooTreeDataStore which is installed in the
1851 // new-style RooAbsData base class
1852
1853 // --- This is the contents of the streamer code of RooTreeData version 1 ---
1854 UInt_t R__s1, R__c1;
1855 Version_t R__v1 = R__b.ReadVersion(&R__s1, &R__c1); if (R__v1) { }
1856
1858 TTree* X_tree(0) ; R__b >> X_tree;
1859 RooArgSet X_truth ; X_truth.Streamer(R__b);
1860 TString X_blindString ; X_blindString.Streamer(R__b);
1861 R__b.CheckByteCount(R__s1, R__c1, TClass::GetClass("RooTreeData"));
1862 // --- End of RooTreeData-v1 streamer
1863
1864 // Construct RooTreeDataStore from X_tree and complete initialization of new-style RooAbsData
1865 _dstore = new RooTreeDataStore(X_tree,_vars) ;
1866 _dstore->SetName(GetName()) ;
1868 _dstore->checkInit() ;
1869
1870 // This is the contents of the streamer code of RooDataSet version 1
1872 _varsNoWgt.Streamer(R__b);
1873 R__b >> _wgtVar;
1874 R__b.CheckByteCount(R__s, R__c, RooDataSet::IsA());
1875
1876
1877 }
1878 } else {
1880 }
1881}
1882
1883
1884
1885////////////////////////////////////////////////////////////////////////////////
1886/// Convert vector-based storage to tree-based storage. This implementation overrides the base class
1887/// implementation because the latter doesn't transfer weights.
1889{
1891 RooTreeDataStore *newStore = new RooTreeDataStore(GetName(), GetTitle(), _vars, *_dstore, nullptr, _wgtVar ? _wgtVar->GetName() : nullptr);
1892 delete _dstore;
1893 _dstore = newStore;
1895 }
1896}
1897
1898
1899// Compile-time test if we can still use TStrings for the constructors of
1900// RooDataClasses, either for both name and title or for only one of them.
1901namespace {
1902 TString tstr = "tstr";
1903 const char * cstr = "cstr";
1904 RooRealVar x{"x", "x", 1.0};
1905 RooArgSet vars{x};
1906 RooDataSet d1(tstr, tstr, vars, nullptr);
1907 RooDataSet d2(tstr, cstr, vars, nullptr);
1908 RooDataSet d3(cstr, tstr, vars, nullptr);
1909}
#define f(i)
Definition: RSha256.hxx:104
#define e(i)
Definition: RSha256.hxx:103
#define coutI(a)
Definition: RooMsgService.h:34
#define ccoutE(a)
Definition: RooMsgService.h:45
#define oocoutW(o, a)
Definition: RooMsgService.h:51
#define oocxcoutD(o, a)
Definition: RooMsgService.h:87
#define coutW(a)
Definition: RooMsgService.h:36
#define oocoutE(o, a)
Definition: RooMsgService.h:52
#define oocoutI(o, a)
Definition: RooMsgService.h:49
#define coutE(a)
Definition: RooMsgService.h:37
#define TRACE_DESTROY
Definition: RooTrace.h:24
#define TRACE_CREATE
Definition: RooTrace.h:23
int Int_t
Definition: RtypesCore.h:45
float Size_t
Definition: RtypesCore.h:96
short Version_t
Definition: RtypesCore.h:65
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
char name[80]
Definition: TGX11.cxx:110
#define hi
Definition: THbookFile.cxx:128
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition: TString.cxx:2447
#define snprintf
Definition: civetweb.c:1540
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:278
bool hasLabel(const std::string &label) const
Check if a state with name label exists.
virtual const char * getCurrentLabel() const
Return label string of current state.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
bool allInRange(const char *rangeSpec) const
Return true if all contained object report to have their value inside the specified range.
void assignFast(const RooAbsCollection &other, bool setValDirty=true) const
Functional equivalent of assign() but assumes this and other collection have same layout.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void setAttribAll(const Text_t *name, bool value=true)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsDataStore is the abstract base class for data collection that use a TTree as internal storage m...
virtual RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len) const =0
const RooArgSet & cachedVars() const
virtual void append(RooAbsDataStore &other)=0
virtual bool isWeighted() const =0
virtual void checkInit() const
virtual void loadValues(const RooAbsDataStore *tds, const RooFormulaVar *select=0, const char *rangeName=0, std::size_t nStart=0, std::size_t nStop=std::numeric_limits< std::size_t >::max())=0
virtual double sumEntries() const
virtual RooAbsDataStore * reduce(RooStringView name, RooStringView title, const RooArgSet &vars, const RooFormulaVar *cutVar, const char *cutRange, std::size_t nStart, std::size_t nStop)=0
virtual RooAbsDataStore * merge(const RooArgSet &allvars, std::list< RooAbsDataStore * > dstoreList)=0
bool dirtyProp() const
virtual double weightError(RooAbsData::ErrorType etype=RooAbsData::Poisson) const =0
virtual RooAbsArg * addColumn(RooAbsArg &var, bool adjustRange=true)=0
virtual double weight() const =0
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:62
virtual const RooArgSet * get() const
Definition: RooAbsData.h:106
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for detailed printing of object.
Definition: RooAbsData.cxx:939
void setGlobalObservables(RooArgSet const &globalObservables)
Sets the global observables stored in this data.
RooAbsDataStore * store()
Definition: RooAbsData.h:82
void checkInit() const
static StorageType defaultStorageType
Definition: RooAbsData.h:328
void addOwnedComponent(const char *idxlabel, RooAbsData &data)
virtual void fill()
Definition: RooAbsData.cxx:372
RooArgSet _vars
Dimensions of this data set.
Definition: RooAbsData.h:365
RooArgSet _cachedVars
! External variables cached with this data set
Definition: RooAbsData.h:366
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Definition: RooAbsData.cxx:379
StorageType storageType
Definition: RooAbsData.h:330
void Streamer(TBuffer &) override
Stream an object of class RooAbsData.
RooAbsDataStore * _dstore
Data storage implementation.
Definition: RooAbsData.h:368
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:94
RooAbsArg * createFundamental(const char *newname=0) const override
Create a RooRealVar fundamental object with our properties.
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
virtual void writeToStream(std::ostream &os, bool compact, const char *section=0) const
Write the contents of the argset in ASCII form to given stream.
Definition: RooArgSet.cxx:351
void Streamer(TBuffer &) override
Stream an object of class TObject.
RooCategory is an object to represent discrete states.
Definition: RooCategory.h:28
bool setIndex(Int_t index, bool printError=true) override
Set value by specifying the index code of the desired state.
bool defineType(const std::string &label)
Define a state with given name.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
static TClass * Class()
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:26
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:31
RooCompositeDataStore combines several disjunct datasets into one.
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:45
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:55
RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len, bool sumW2) const override
Definition: RooDataSet.cxx:949
RooRealVar * _wgtVar
Pointer to weight variable (if set)
Definition: RooDataSet.h:173
bool _doWeightErrorCheck
! When adding events with weights, check that weights can actually be stored.
Definition: RooDataSet.h:181
static void cleanup()
Definition: RooDataSet.cxx:125
RooArgSet _varsNoWgt
Vars without weight variable.
Definition: RooDataSet.h:172
RooAbsData * emptyClone(const char *newName=0, const char *newTitle=0, const RooArgSet *vars=0, const char *wgtVarName=0) const override
Return an empty clone of this dataset.
Definition: RooDataSet.cxx:825
void weightError(double &lo, double &hi, ErrorType etype=SumW2) const override
Return the asymmetric errors on the current weight.
Definition: RooDataSet.cxx:984
const RooArgSet * get() const override
Return a RooArgSet with the coordinates of the current event.
RooAbsData * reduceEng(const RooArgSet &varSubset, const RooFormulaVar *cutVar, const char *cutRange=0, std::size_t nStart=0, std::size_t nStop=std::numeric_limits< std::size_t >::max()) override
Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods.
Definition: RooDataSet.cxx:881
RooArgSet addWgtVar(const RooArgSet &origVars, const RooAbsArg *wgtVar)
Helper function for constructor that adds optional weight variable to construct total set of observab...
Definition: RooDataSet.cxx:813
void initialize(const char *wgtVarName)
Initialize the dataset.
Definition: RooDataSet.cxx:854
void printArgs(std::ostream &os) const override
Print argument of dataset, i.e. the observable names.
void SetName(const char *name) override
Change the name of this dataset into the given name.
TClass * IsA() const override
Definition: RooDataSet.h:185
virtual RooAbsArg * addColumn(RooAbsArg &var, bool adjustRange=true)
Add a column with the values of the given (function) argument to this dataset.
bool write(const char *filename) const
Write the contents of this dataset to an ASCII file with the specified name.
double sumEntries() const override
Return effective number of entries in dataset, i.e., sum all weights.
static RooDataSet * read(const char *filename, const RooArgList &variables, const char *opts="", const char *commonPath="", const char *indexCatName=0)
Read data from a text file and create a dataset from it.
virtual RooArgSet * addColumns(const RooArgList &varList)
Add a column with the values of the given list of (function) argument to this dataset.
~RooDataSet() override
Destructor.
Definition: RooDataSet.cxx:897
bool isNonPoissonWeighted() const override
Returns true if histogram contains bins with entries with a non-integer weight.
void SetNameTitle(const char *name, const char *title) override
Change the title of this dataset into the given name.
void printValue(std::ostream &os) const override
Print value of the dataset, i.e. the sum of weights contained in the dataset.
virtual RooPlot * plotOnXY(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Special plot method for 'X-Y' datasets used in fitting.
void append(RooDataSet &data)
Add all data points of given data set to this data set.
bool merge(RooDataSet *data1, RooDataSet *data2=0, RooDataSet *data3=0, RooDataSet *data4=0, RooDataSet *data5=0, RooDataSet *data6=0)
RooDataSet()
Default constructor for persistence.
Definition: RooDataSet.cxx:184
void add(const RooArgSet &row, double weight=1.0, double weightError=0) override
Add one ore more rows of data.
virtual void addFast(const RooArgSet &row, double weight=1.0, double weightError=0)
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
std::unique_ptr< std::vector< double > > _sumW2Buffer
! Buffer for sumW2 in case a batch of values is requested.
Definition: RooDataSet.h:183
void Streamer(TBuffer &) override
Stream an object of class RooDataSet.
unsigned short _errorMsgCount
! Counter to silence error messages when filling dataset.
Definition: RooDataSet.h:180
RooDataHist * binnedClone(const char *newName=0, const char *newTitle=0) const
Return binned clone of this dataset.
Definition: RooDataSet.cxx:908
static TClass * Class()
void convertToTreeStore() override
Convert vector-based storage to tree-based storage.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print info about this dataset to the specified output stream.
double weightSquared() const override
Return squared event weight of current event.
Definition: RooDataSet.cxx:941
double weight() const override
Return event weight of current event.
Definition: RooDataSet.cxx:931
bool isWeighted() const override
Return true if dataset contains weighted events.
RooDirItem is a utility base class for RooFit objects that are to be attached to ROOT directories.
Definition: RooDirItem.h:22
virtual void Streamer(TBuffer &)
void removeFromDir(TObject *obj)
Remove object from directory it was added to.
Definition: RooDirItem.cxx:41
TDirectory * _dir
! Associated directory
Definition: RooDirItem.h:33
void appendToDir(TObject *obj, bool forceMemoryResident=false)
Append object to directory.
Definition: RooDirItem.cxx:53
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
A RooHist is a graphical representation of binned data based on the TGraphAsymmErrors class.
Definition: RooHist.h:27
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:38
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:67
TIterator * MakeIterator(bool forward=true) const
Create a TIterator for this list.
A RooPlot is a plot frame and a container for graphics objects within that frame.
Definition: RooPlot.h:43
RooAbsRealLValue * getPlotVar() const
Definition: RooPlot.h:140
void addPlotable(RooPlotable *plotable, Option_t *drawOptions="", bool invisible=false, bool refreshNorm=false)
Add the specified plotable object to our plot.
Definition: RooPlot.cxx:561
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:40
void setVal(double value) override
Set value of variable to 'value'.
Definition: RooRealVar.cxx:281
void setError(double value)
Definition: RooRealVar.h:65
double getErrorLo() const
Definition: RooRealVar.h:72
void removeAsymError()
Definition: RooRealVar.h:70
void setAsymError(double lo, double hi)
Definition: RooRealVar.h:71
double getErrorHi() const
Definition: RooRealVar.h:73
void removeError()
Definition: RooRealVar.h:66
static void activate()
Install atexit handler that calls CleanupRooFitAtExit() on program termination.
Definition: RooSentinel.cxx:54
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
constexpr bool empty() const noexcept
Definition: RooSpan.h:125
The RooStringView is a wrapper around a C-syle string that can also be constructed from a std::string...
Definition: RooStringView.h:27
RooTreeDataStore is a TTree-backed data storage.
void loadValues(const TTree *t, const RooFormulaVar *select=0, const char *rangeName=0, Int_t nStart=0, Int_t nStop=2000000000)
Load values from tree 't' into this data collection, optionally selecting events using the RooFormula...
RooVectorDataStore uses std::vectors to store data columns.
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Bool_t IsReading() const
Definition: TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2968
virtual TList * GetList() const
Definition: TDirectory.h:213
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:4019
Iterator abstract base class.
Definition: TIterator.h:30
virtual TObject * Next()=0
void Add(TObject *obj) override
Definition: TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition: TList.cxx:822
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition: TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
TClass * IsA() const override
Definition: TNamed.h:58
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: TNamed.cxx:154
Mother of all ROOT objects.
Definition: TObject.h:37
Basic string class.
Definition: TString.h:136
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1150
virtual void Streamer(TBuffer &)
Stream a string object.
Definition: TString.cxx:1370
TString & Append(const char *cs)
Definition: TString.h:564
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
A TTree represents a columnar dataset.
Definition: TTree.h:79
TLine * line
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
Definition: StringUtils.cxx:23
@ DataHandling
Definition: RooGlobalFunc.h:65
@ InputArguments
Definition: RooGlobalFunc.h:64
static constexpr double pc
void variables(TString dataset, TString fin="TMVA.root", TString dirName="InputVariables_Id", TString title="TMVA Input Variables", Bool_t isRegression=kFALSE, Bool_t useTMVAStyle=kTRUE)
Definition: file.py:1
Definition: first.py:1
Definition: graph.py:1
auto * l
Definition: textangle.C:4