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