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