Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsData.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 RooAbsData.cxx
19\class RooAbsData
20\ingroup Roofitcore
21
22Abstract base class for binned and unbinned
23datasets. The abstract interface defines plotting and tabulating entry
24points for its contents and provides an iterator over its elements
25(bins for binned data sets, data points for unbinned datasets).
26
27### Storing global observables in RooFit datasets
28
29RooFit groups model variables into *observables* and *parameters*, depending on
30if their values are stored in the dataset. For fits with parameter
31constraints, there is a third kind of variables, called *global observables*.
32These represent the results of auxiliary measurements that constrain the
33nuisance parameters. In the RooFit implementation, a likelihood is generally
34the sum of two terms:
35- the likelihood of the data given the parameters, where the normalization set
36 is the set of observables (implemented by RooNLLVar)
37- the constraint term, where the normalization set is the set of *global
38observables* (implemented by RooConstraintSum)
39
40Before this release, the global observable values were always taken from the
41model/pdf. With this release, a mechanism is added to store a snapshot of
42global observables in any RooDataSet or RooDataHist. For toy studies where the
43global observables assume a different values for each toy, the bookkeeping of
44the set of global observables and in particular their values is much easier
45with this change.
46
47Usage example for a model with global observables `g1` and `g2`:
48```
49using namespace RooFit;
50
51std::unique_ptr<RooAbsData> data{model.generate(x, 1000)}; // data has only the single observables x
52data->setGlobalObservables(g1, g2); // now, data also stores a snapshot of g1 and g2
53
54// If you fit the model to the data, the global observables and their values
55// are taken from the dataset:
56model.fitTo(*data);
57
58// You can still define the set of global observables yourself, but the values
59// will be takes from the dataset if available:
60model.fitTo(*data, GlobalObservables(g1, g2));
61
62// To force `fitTo` to take the global observable values from the model even
63// though they are in the dataset, you can use the new `GlobalObservablesSource`
64// command argument:
65model.fitTo(*data, GlobalObservables(g1, g2), GlobalObservablesSource("model"));
66// The only other allowed value for `GlobalObservablesSource` is "data", which
67// corresponds to the new default behavior explained above.
68```
69
70In case you create a RooFit dataset directly by calling its constructor, you
71can also pass the global observables in a command argument instead of calling
72RooAbsData::setGlobalObservables() later:
73```
74RooDataSet data{"dataset", "dataset", x, RooFit::GlobalObservables(g1, g2)};
75```
76
77To access the set of global observables stored in a RooAbsData, call
78RooAbsData::getGlobalObservables(). It returns a `nullptr` if no global
79observable snapshots are stored in the dataset.
80**/
81
82#include "RooAbsData.h"
83
84#include "TBuffer.h"
85#include "TMath.h"
86#include "TTree.h"
87
88#include "RooFormula.h"
89#include "RooFormulaVar.h"
90#include "RooCmdConfig.h"
91#include "RooAbsRealLValue.h"
92#include "RooMsgService.h"
93#include "RooMultiCategory.h"
94#include "Roo1DTable.h"
95#include "RooAbsDataStore.h"
96#include "RooVectorDataStore.h"
97#include "RooTreeDataStore.h"
98#include "RooDataHist.h"
99#include "RooDataSet.h"
101#include "RooCategory.h"
102#include "RooUniformBinning.h"
103#include "RooSimultaneous.h"
104
105#include "RooRealVar.h"
106#include "RooGlobalFunc.h"
107#include "RooPlot.h"
108#include "RooCurve.h"
109#include "RooHist.h"
110#include "RooHelpers.h"
111
112#include "ROOT/StringUtils.hxx"
113#include "TPaveText.h"
114#include "TH1.h"
115#include "TH2.h"
116#include "TH3.h"
117#include "Math/Util.h"
118
119#include <iostream>
120#include <memory>
121#include <sstream>
122#include <stdexcept>
123#include <unordered_map>
124
125
126
128
129////////////////////////////////////////////////////////////////////////////////
130
132{
133 if (RooAbsData::Composite == s) {
134 std::cout << "Composite storage is not a valid *default* storage type." << std::endl;
135 } else {
137 }
138}
139
140////////////////////////////////////////////////////////////////////////////////
141
146
147////////////////////////////////////////////////////////////////////////////////
148/// Default constructor
149
150RooAbsData::RooAbsData() : storageType(defaultStorageType)
151{
152}
153
155{
156 if(!_vars.empty()) {
157 throw std::runtime_error("RooAbsData::initializeVars(): the variables are already initialized!");
158 }
159
160 // clone the fundamentals of the given data set into internal buffer
161 for (const auto var : vars) {
162 if (!var->isFundamental()) {
163 coutE(InputArguments) << "RooAbsDataStore::initialize(" << GetName()
164 << "): Data set cannot contain non-fundamental types, ignoring " << var->GetName()
165 << std::endl;
166 throw std::invalid_argument(std::string("Only fundamental variables can be placed into datasets. This is violated for ") + var->GetName());
167 } else {
168 _vars.addClone(*var);
169 }
170 }
171
172 // reconnect any parameterized ranges to internal dataset observables
173 for (auto var : _vars) {
174 var->attachArgs(_vars);
175 }
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Constructor from a set of variables. Only fundamental elements of vars
180/// (RooRealVar,RooCategory etc) are stored as part of the dataset
181
183 TNamed(name,title),
184 _vars("Dataset Variables"),
185 _cachedVars("Cached Variables"),
186 _dstore(dstore)
187{
188 if (dynamic_cast<RooTreeDataStore *>(dstore)) {
190 } else if (dynamic_cast<RooVectorDataStore *>(dstore)) {
192 } else {
194 }
195
196 initializeVars(vars);
197
198 _namePtr = RooNameReg::instance().constPtr(GetName()) ;
199}
200
202{
203 _namePtr = newName ? RooNameReg::instance().constPtr(newName) : other._namePtr;
204
205 _vars.addClone(other._vars);
206
207 // reconnect any parameterized ranges to internal dataset observables
208 for (auto var : _vars) {
209 var->attachArgs(_vars);
210 }
211
212 if (!other._ownedComponents.empty()) {
213
214 // copy owned components here
215
216 std::map<std::string, RooAbsDataStore *> smap;
217 for (auto &itero : other._ownedComponents) {
218 RooAbsData *dclone = static_cast<RooAbsData *>(itero.second->Clone());
220 smap[itero.first] = dclone->store();
221 }
222
223 auto compStore = static_cast<RooCompositeDataStore const *>(other.store());
224 auto idx = static_cast<RooCategory *>(_vars.find(*(const_cast<RooCompositeDataStore *>(compStore)->index())));
225 _dstore = std::make_unique<RooCompositeDataStore>(newName ? newName : other.GetName(), other.GetTitle(), _vars,
226 *idx, smap);
228
229 } else {
230
231 // Convert to vector store if default is vector
232 _dstore.reset(other._dstore->clone(_vars, newName ? newName : other.GetName()));
233 storageType = other.storageType;
234 }
235
237}
238
239////////////////////////////////////////////////////////////////////////////////
240/// Copy constructor
241
243 : TNamed{newName ? newName : other.GetName(), other.GetTitle()},
245 _cachedVars{"Cached Variables"}
246{
248}
249
251{
253 RooPrintable::operator=(other);
254
255 copyImpl(other, nullptr);
256
257 return *this;
258}
259
260
262 if (other._globalObservables) {
263 if(_globalObservables == nullptr) _globalObservables = std::make_unique<RooArgSet>();
264 else _globalObservables->clear();
265 other._globalObservables->snapshot(*_globalObservables);
266 } else {
267 _globalObservables.reset();
268 }
269}
270
271
272////////////////////////////////////////////////////////////////////////////////
273/// Destructor
274
276{
277 // Delete owned dataset components
278 for (auto& item : _ownedComponents) {
279 delete item.second;
280 }
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Convert tree-based storage to vector-based storage
285
287{
288 if (auto treeStore = dynamic_cast<RooTreeDataStore*>(_dstore.get())) {
289 _dstore = std::make_unique<RooVectorDataStore>(*treeStore, _vars, GetName());
291 }
292}
293
294////////////////////////////////////////////////////////////////////////////////
295
296bool RooAbsData::changeObservableName(const char* from, const char* to)
297{
298 bool ret = _dstore->changeObservableName(from,to) ;
299
300 RooAbsArg* tmp = _vars.find(from) ;
301 if (tmp) {
302 tmp->SetName(to) ;
303 }
304 return ret ;
305}
306
307////////////////////////////////////////////////////////////////////////////////
308
310{
311 _dstore->fill() ;
312}
313
314////////////////////////////////////////////////////////////////////////////////
315
317{
318 return nullptr != _dstore ? _dstore->numEntries() : 0;
319}
320
321////////////////////////////////////////////////////////////////////////////////
322
324{
325 _dstore->reset() ;
326}
327
328////////////////////////////////////////////////////////////////////////////////
329
331{
332 checkInit() ;
333 return _dstore->get(index) ;
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Internal method -- Cache given set of functions with data
338
339void RooAbsData::cacheArgs(const RooAbsArg* cacheOwner, RooArgSet& varSet, const RooArgSet* nset, bool skipZeroWeights)
340{
341 _dstore->cacheArgs(cacheOwner,varSet,nset,skipZeroWeights) ;
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Internal method -- Remove cached function values
346
348{
349 _dstore->resetCache() ;
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// Internal method -- Attach dataset copied with cache contents to copied instances of functions
355
357{
358 _dstore->attachCache(newOwner, cachedVars) ;
359}
360
361////////////////////////////////////////////////////////////////////////////////
362
363void RooAbsData::setArgStatus(const RooArgSet& set, bool active)
364{
365 _dstore->setArgStatus(set,active) ;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Control propagation of dirty flags from observables in dataset
370
372{
373 _dstore->setDirtyProp(flag) ;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Create a reduced copy of this dataset. The caller takes ownership of the returned dataset
378///
379/// The following optional named arguments are accepted
380/// <table>
381/// <tr><td> `SelectVars(const RooArgSet& vars)` <td> Only retain the listed observables in the output dataset
382/// <tr><td> `Cut(const char* expression)` <td> Only retain event surviving the given cut expression.
383/// <tr><td> `Cut(const RooFormulaVar& expr)` <td> Only retain event surviving the given cut formula.
384/// <tr><td> `CutRange(const char* name)` <td> Only retain events inside range with given name. Multiple CutRange
385/// arguments may be given to select multiple ranges.
386/// Note that this will also consider the variables that are not selected by SelectVars().
387/// <tr><td> `EventRange(int lo, int hi)` <td> Only retain events with given sequential event numbers
388/// <tr><td> `Name(const char* name)` <td> Give specified name to output dataset
389/// <tr><td> `Title(const char* name)` <td> Give specified title to output dataset
390/// </table>
391
393 const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) const
394{
395 // Define configuration for this method
396 RooCmdConfig pc("RooAbsData::reduce(" + std::string(GetName()) + ")");
397 pc.defineString("name","Name",0,"") ;
398 pc.defineString("title","Title",0,"") ;
399 pc.defineString("cutRange","CutRange",0,"") ;
400 pc.defineString("cutSpec","CutSpec",0,"") ;
401 pc.defineObject("cutVar","CutVar",0,nullptr) ;
402 pc.defineInt("evtStart","EventRange",0,0) ;
403 pc.defineInt("evtStop","EventRange",1,std::numeric_limits<int>::max()) ;
404 pc.defineSet("varSel","SelectVars",0,nullptr) ;
405 pc.defineMutex("CutVar","CutSpec") ;
406
407 // Process & check varargs
409 if (!pc.ok(true)) {
410 return nullptr;
411 }
412
413 // Extract values from named arguments
414 const char* cutRange = pc.getString("cutRange",nullptr,true) ;
415 const char* cutSpec = pc.getString("cutSpec",nullptr,true) ;
416 RooFormulaVar* cutVar = static_cast<RooFormulaVar*>(pc.getObject("cutVar",nullptr)) ;
417 int nStart = pc.getInt("evtStart",0) ;
418 int nStop = pc.getInt("evtStop",std::numeric_limits<int>::max()) ;
419 RooArgSet* varSet = pc.getSet("varSel");
420 const char* name = pc.getString("name",nullptr,true) ;
421 const char* title = pc.getString("title",nullptr,true) ;
422
423 // Make sure varSubset doesn't contain any variable not in this dataset
425 if (varSet) {
426 varSubset.add(*varSet) ;
427 for (const auto arg : varSubset) {
428 if (!_vars.find(arg->GetName())) {
429 coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
430 << arg->GetName() << " not in dataset, ignored" << std::endl ;
431 varSubset.remove(*arg) ;
432 }
433 }
434 } else {
435 varSubset.add(*get()) ;
436 }
437
438 std::unique_ptr<RooAbsData> ret;
439 if (cutSpec) {
440
443
444 } else {
445
447
448 }
449
450 if (!ret) return nullptr;
451
452 if (name) ret->SetName(name) ;
453 if (title) ret->SetTitle(title) ;
454
455 ret->copyGlobalObservables(*this);
456 return RooFit::makeOwningPtr(std::move(ret));
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Create a subset of the data set by applying the given cut on the data points.
461/// The cut expression can refer to any variable in the data set. For cuts involving
462/// other variables, such as intermediate formula objects, use the equivalent
463/// reduce method specifying the as a RooFormulVar reference.
464
466{
467 return reduce(RooFormulaVar{cut,cut,*get()});
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// Create a subset of the data set by applying the given cut on the data points.
472/// The 'cutVar' formula variable is used to select the subset of data points to be
473/// retained in the reduced data collection.
474
476{
477 auto ret = reduceEng(*get(),&cutVar,nullptr,0,std::numeric_limits<std::size_t>::max()) ;
478 ret->copyGlobalObservables(*this);
479 return RooFit::makeOwningPtr(std::move(ret));
480}
481
482////////////////////////////////////////////////////////////////////////////////
483/// Create a subset of the data set by applying the given cut on the data points
484/// and reducing the dimensions to the specified set.
485///
486/// The cut expression can refer to any variable in the data set. For cuts involving
487/// other variables, such as intermediate formula objects, use the equivalent
488/// reduce method specifying the as a RooFormulVar reference.
489
491{
492 // Make sure varSubset doesn't contain any variable not in this dataset
494 for (const auto arg : varSubset) {
495 if (!_vars.find(arg->GetName())) {
496 coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
497 << arg->GetName() << " not in dataset, ignored" << std::endl ;
498 varSubset2.remove(*arg) ;
499 }
500 }
501
502 std::unique_ptr<RooAbsData> ret;
503 if (cut && strlen(cut)>0) {
504 RooFormulaVar cutVar(cut, cut, *get(), false);
505 ret = reduceEng(varSubset2,&cutVar,nullptr,0,std::numeric_limits<std::size_t>::max());
506 } else {
507 ret = reduceEng(varSubset2,nullptr,nullptr,0,std::numeric_limits<std::size_t>::max());
508 }
509 ret->copyGlobalObservables(*this);
510 return RooFit::makeOwningPtr(std::move(ret));
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Create a subset of the data set by applying the given cut on the data points
515/// and reducing the dimensions to the specified set.
516///
517/// The 'cutVar' formula variable is used to select the subset of data points to be
518/// retained in the reduced data collection.
519
521{
522 // Make sure varSubset doesn't contain any variable not in this dataset
524 for(RooAbsArg * arg : varSubset) {
525 if (!_vars.find(arg->GetName())) {
526 coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
527 << arg->GetName() << " not in dataset, ignored" << std::endl ;
528 varSubset2.remove(*arg) ;
529 }
530 }
531
532 auto ret = reduceEng(varSubset2,&cutVar,nullptr,0,std::numeric_limits<std::size_t>::max()) ;
533 ret->copyGlobalObservables(*this);
534 return RooFit::makeOwningPtr(std::move(ret));
535}
536
537
539 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
540 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
541{
543 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
544 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
545 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
546 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
547 return plotOn(frame,l) ;
548}
549
550
552 const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
553 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
554{
556 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
557 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
558 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
559 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
560
561 return createHistogram(name,xvar,l) ;
562}
563
564////////////////////////////////////////////////////////////////////////////////
565/// Create and fill a ROOT histogram TH1,TH2 or TH3 with the values of this
566/// dataset for the variables with given names.
567///
568/// \param[in] varNameList Comma-separated variable names.
569/// \param[in] binArgX Control the binning for the `x` variable.
570/// \param[in] binArgY Control the binning for the `y` variable.
571/// \param[in] binArgZ Control the binning for the `z` variable.
572/// \return Histogram now owned by user.
573///
574/// The possible binning command arguments for each axis are:
575///
576/// <table>
577/// <tr><td> `AutoBinning(Int_t nbins, Double_y margin)` <td> Automatically calculate range with given added fractional margin, set binning to nbins
578/// <tr><td> `AutoSymBinning(Int_t nbins, Double_y margin)` <td> Automatically calculate range with given added fractional margin,
579/// with additional constraint that mean of data is in center of range, set binning to nbins
580/// <tr><td> `Binning(const char* name)` <td> Apply binning with given name to x axis of histogram
581/// <tr><td> `Binning(RooAbsBinning& binning)` <td> Apply specified binning to x axis of histogram
582/// <tr><td> `Binning(int nbins, double lo, double hi)` <td> Apply specified binning to x axis of histogram
583///
584/// <tr><td> `YVar(const RooAbsRealLValue& var,...)` <td> Observable to be mapped on y axis of ROOT histogram
585/// <tr><td> `ZVar(const RooAbsRealLValue& var,...)` <td> Observable to be mapped on z axis of ROOT histogram
586/// </table>
587
589 const RooCmdArg& binArgX,
590 const RooCmdArg& binArgY,
591 const RooCmdArg& binArgZ) const
592{
593 // Parse list of variable names
594 const auto varNames = ROOT::Split(varNameList, ",:");
595 RooRealVar* vars[3] = {nullptr, nullptr, nullptr};
596
597 for (unsigned int i = 0; i < varNames.size(); ++i) {
598 if (i >= 3) {
599 coutW(InputArguments) << "RooAbsData::createHistogram(" << GetName() << "): Can only create 3-dimensional histograms. Variable "
600 << i << " " << varNames[i] << " unused." << std::endl;
601 continue;
602 }
603
604 vars[i] = static_cast<RooRealVar*>(get()->find(varNames[i].data()) );
605 if (!vars[i]) {
606 coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varNames[i] << std::endl;
607 return nullptr;
608 }
609 }
610
611 if (!vars[0]) {
612 coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << "): No variable to be histogrammed in list '" << varNameList << "'" << std::endl;
613 return nullptr;
614 }
615
616 // Fill command argument list
617 RooLinkedList argList;
618 argList.Add(binArgX.Clone());
619 if (vars[1]) {
620 argList.Add(RooFit::YVar(*vars[1],binArgY).Clone());
621 }
622 if (vars[2]) {
623 argList.Add(RooFit::ZVar(*vars[2],binArgZ).Clone());
624 }
625
626 // Call implementation function
627 TH1* result = createHistogram(GetName(), *vars[0], argList);
628
629 // Delete temporary list of RooCmdArgs
630 argList.Delete() ;
631
632 return result ;
633}
634
635////////////////////////////////////////////////////////////////////////////////
636///
637/// This function accepts the following arguments
638///
639/// \param[in] name Name of the ROOT histogram
640/// \param[in] xvar Observable to be mapped on x axis of ROOT histogram
641/// \param[in] argListIn list of input arguments
642/// \return Histogram now owned by user.
643///
644/// <table>
645/// <tr><td> `AutoBinning(Int_t nbins, Double_y margin)` <td> Automatically calculate range with given added fractional margin, set binning to nbins
646/// <tr><td> `AutoSymBinning(Int_t nbins, Double_y margin)` <td> Automatically calculate range with given added fractional margin,
647/// with additional constraint that mean of data is in center of range, set binning to nbins
648/// <tr><td> `Binning(const char* name)` <td> Apply binning with given name to x axis of histogram
649/// <tr><td> `Binning(RooAbsBinning& binning)` <td> Apply specified binning to x axis of histogram
650/// <tr><td> `Binning(int nbins, double lo, double hi)` <td> Apply specified binning to x axis of histogram
651///
652/// <tr><td> `YVar(const RooAbsRealLValue& var,...)` <td> Observable to be mapped on y axis of ROOT histogram
653/// <tr><td> `ZVar(const RooAbsRealLValue& var,...)` <td> Observable to be mapped on z axis of ROOT histogram
654/// </table>
655///
656/// The YVar() and ZVar() arguments can be supplied with optional Binning() Auto(Sym)Range() arguments to control the binning of the Y and Z axes, e.g.
657/// ```
658/// createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
659/// ```
660///
661/// The caller takes ownership of the returned histogram
662
664{
665 RooLinkedList argList(argListIn) ;
666
667 // Define configuration for this method
668 RooCmdConfig pc("RooAbsData::createHistogram(" + std::string(GetName()) + ")");
669 pc.defineString("cutRange","CutRange",0,"",true) ;
670 pc.defineString("cutString","CutSpec",0,"") ;
671 pc.defineObject("yvar","YVar",0,nullptr) ;
672 pc.defineObject("zvar","ZVar",0,nullptr) ;
673 pc.allowUndefined() ;
674
675 // Process & check varargs
676 pc.process(argList) ;
677 if (!pc.ok(true)) {
678 return nullptr;
679 }
680
681 const char* cutSpec = pc.getString("cutString",nullptr,true) ;
682 const char* cutRange = pc.getString("cutRange",nullptr,true) ;
683
684 RooArgList vars(xvar) ;
685 RooAbsArg* yvar = static_cast<RooAbsArg*>(pc.getObject("yvar")) ;
686 if (yvar) {
687 vars.add(*yvar) ;
688 }
689 RooAbsArg* zvar = static_cast<RooAbsArg*>(pc.getObject("zvar")) ;
690 if (zvar) {
691 vars.add(*zvar) ;
692 }
693
694 RooCmdConfig::stripCmdList(argList,"CutRange,CutSpec") ;
695
696 // Swap Auto(Sym)RangeData with a Binning command
698 RooCmdArg* autoRD = static_cast<RooCmdArg*>(argList.find("AutoRangeData")) ;
699 if (autoRD) {
700 double xmin;
701 double xmax;
702 if (!getRange(static_cast<RooRealVar const&>(xvar),xmin,xmax,autoRD->getDouble(0),autoRD->getInt(0))) {
703 RooCmdArg* bincmd = static_cast<RooCmdArg*>(RooFit::Binning(autoRD->getInt(1),xmin,xmax).Clone()) ;
704 ownedCmds.Add(bincmd) ;
705 argList.Replace(autoRD,bincmd) ;
706 }
707 }
708
709 if (yvar) {
710 std::unique_ptr<RooCmdArg> autoRDY{static_cast<RooCmdArg*>((static_cast<RooCmdArg*>(argList.find("YVar")))->subArgs().find("AutoRangeData"))};
711 if (autoRDY) {
712 double ymin;
713 double ymax;
714 if (!getRange(static_cast<RooRealVar &>(*yvar), ymin, ymax, autoRDY->getDouble(0), autoRDY->getInt(0))) {
715 RooCmdArg *bincmd = static_cast<RooCmdArg *>(RooFit::Binning(autoRDY->getInt(1), ymin, ymax).Clone());
716 // ownedCmds.Add(bincmd) ;
717 (static_cast<RooCmdArg *>(argList.find("YVar")))->subArgs().Replace(autoRDY.get(), bincmd);
718 }
719 }
720 }
721
722 if (zvar) {
723 std::unique_ptr<RooCmdArg> autoRDZ{static_cast<RooCmdArg*>((static_cast<RooCmdArg*>(argList.find("ZVar")))->subArgs().find("AutoRangeData"))};
724 if (autoRDZ) {
725 double zmin;
726 double zmax;
727 if (!getRange(static_cast<RooRealVar&>(*zvar),zmin,zmax,autoRDZ->getDouble(0),autoRDZ->getInt(0))) {
728 RooCmdArg* bincmd = static_cast<RooCmdArg*>(RooFit::Binning(autoRDZ->getInt(1),zmin,zmax).Clone()) ;
729 //ownedCmds.Add(bincmd) ;
730 (static_cast<RooCmdArg*>(argList.find("ZVar")))->subArgs().Replace(autoRDZ.get(),bincmd) ;
731 }
732 }
733 }
734
735
736 TH1* histo = xvar.createHistogram(name,argList) ;
737 fillHistogram(histo,vars,cutSpec,cutRange) ;
738
739 ownedCmds.Delete() ;
740
741 return histo ;
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Construct table for product of categories in catSet
746
747Roo1DTable* RooAbsData::table(const RooArgSet& catSet, const char* cuts, const char* opts) const
748{
750
751 std::string prodName("(") ;
752 for(auto * arg : catSet) {
753 if (dynamic_cast<RooAbsCategory*>(arg)) {
754 if (auto varsArg = dynamic_cast<RooAbsCategory*>(_vars.find(arg->GetName()))) catSet2.add(*varsArg) ;
755 else catSet2.add(*arg) ;
756 if (prodName.length()>1) {
757 prodName += " x " ;
758 }
759 prodName += arg->GetName() ;
760 } else {
761 coutW(InputArguments) << "RooAbsData::table(" << GetName() << ") non-RooAbsCategory input argument " << arg->GetName() << " ignored" << std::endl ;
762 }
763 }
764 prodName += ")" ;
765
766 RooMultiCategory tmp(prodName.c_str(),prodName.c_str(),catSet2) ;
767 return table(tmp,cuts,opts) ;
768}
769
770////////////////////////////////////////////////////////////////////////////////
771/// Print name of dataset
772
773void RooAbsData::printName(std::ostream& os) const
774{
775 os << GetName() ;
776}
777
778////////////////////////////////////////////////////////////////////////////////
779/// Print title of dataset
780
781void RooAbsData::printTitle(std::ostream& os) const
782{
783 os << GetTitle() ;
784}
785
786////////////////////////////////////////////////////////////////////////////////
787/// Print class name of dataset
788
789void RooAbsData::printClassName(std::ostream& os) const
790{
791 os << ClassName() ;
792}
793
794////////////////////////////////////////////////////////////////////////////////
795
796void RooAbsData::printMultiline(std::ostream& os, Int_t contents, bool verbose, TString indent) const
797{
798 _dstore->printMultiline(os,contents,verbose,indent) ;
799}
800
801////////////////////////////////////////////////////////////////////////////////
802/// Define default print options, for a given print style
803
808
809////////////////////////////////////////////////////////////////////////////////
810/// Calculate standardized moment.
811///
812/// \param[in] var Variable to be used for calculating the moment.
813/// \param[in] order Order of the moment.
814/// \param[in] cutSpec If specified, the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
815/// \param[in] cutRange If specified, calculate inside the range named 'cutRange' (also applies cut spec)
816/// \return \f$ \frac{\left< \left( X - \left< X \right> \right)^n \right>}{\sigma^n} \f$, where n = order.
817
818double RooAbsData::standMoment(const RooRealVar &var, double order, const char* cutSpec, const char* cutRange) const
819{
820 // Hardwire invariant answer for first and second moment
821 if (order==1) return 0 ;
822 if (order==2) return 1 ;
823
824 return moment(var,order,cutSpec,cutRange) / std::pow(sigma(var,cutSpec,cutRange),order) ;
825}
826
827////////////////////////////////////////////////////////////////////////////////
828/// Calculate moment of requested order.
829///
830/// \param[in] var Variable to be used for calculating the moment.
831/// \param[in] order Order of the moment.
832/// \param[in] cutSpec If specified, the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
833/// \param[in] cutRange If specified, calculate inside the range named 'cutRange' (also applies cut spec)
834/// \return \f$ \left< \left( X - \left< X \right> \right)^n \right> \f$ of order \f$n\f$.
835///
836
837double RooAbsData::moment(const RooRealVar& var, double order, const char* cutSpec, const char* cutRange) const
838{
839 double offset = order>1 ? moment(var,1,cutSpec,cutRange) : 0 ;
840 return moment(var,order,offset,cutSpec,cutRange) ;
841
842}
843
844////////////////////////////////////////////////////////////////////////////////
845/// Return the 'order'-ed moment of observable 'var' in this dataset. If offset is non-zero it is subtracted
846/// from the values of 'var' prior to the moment calculation. If cutSpec and/or cutRange are specified
847/// the moment is calculated on the subset of the data which pass the C++ cut specification expression 'cutSpec'
848/// and/or are inside the range named 'cutRange'
849
850double RooAbsData::moment(const RooRealVar& var, double order, double offset, const char* cutSpec, const char* cutRange) const
851{
852 // Lookup variable in dataset
853 auto arg = _vars.find(var.GetName());
854 if (!arg) {
855 coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << std::endl;
856 return 0;
857 }
858
859 auto varPtr = dynamic_cast<const RooRealVar*>(arg);
860 // Check if found variable is of type RooRealVar
861 if (!varPtr) {
862 coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << std::endl ;
863 return 0;
864 }
865
866 // Check if dataset is not empty
867 if(sumEntries(cutSpec, cutRange) == 0.) {
868 coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") WARNING: empty dataset" << std::endl ;
869 return 0;
870 }
871
872 // Setup RooFormulaVar for cutSpec if it is present
873 std::unique_ptr<RooFormula> select;
874 if (cutSpec) {
875 select = std::make_unique<RooFormula>("select",cutSpec,*get());
876 }
877
878
879 // Calculate requested moment
881 for(int index= 0; index < numEntries(); index++) {
882 const RooArgSet* vars = get(index) ;
883 if (select && select->eval()==0) continue ;
884 if (cutRange && vars->allInRange(cutRange)) continue ;
885
886 sum += weight() * std::pow(varPtr->getVal() - offset,order);
887 }
888
889 return sum.Sum()/sumEntries(cutSpec, cutRange);
890}
891
892////////////////////////////////////////////////////////////////////////////////
893/// Internal method to check if given RooRealVar maps to a RooRealVar in this dataset
894
896{
897 // Lookup variable in dataset
898 RooRealVar *xdata = static_cast<RooRealVar*>(_vars.find(extVar.GetName()));
899 if(!xdata) {
900 coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not in data" << std::endl ;
901 return nullptr;
902 }
903 // Check if found variable is of type RooRealVar
904 if (!dynamic_cast<RooRealVar*>(xdata)) {
905 coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not of type RooRealVar in data" << std::endl ;
906 return nullptr;
907 }
908 return xdata;
909}
910
911////////////////////////////////////////////////////////////////////////////////
912/// Internal method to calculate single correlation and covariance elements
913
914double RooAbsData::corrcov(const RooRealVar &x, const RooRealVar &y, const char* cutSpec, const char* cutRange, bool corr) const
915{
916 // Lookup variable in dataset
917 RooRealVar *xdata = dataRealVar(corr?"correlation":"covariance",x) ;
918 RooRealVar *ydata = dataRealVar(corr?"correlation":"covariance",y) ;
919 if (!xdata||!ydata) return 0 ;
920
921 // Check if dataset is not empty
922 if(sumEntries(cutSpec, cutRange) == 0.) {
923 coutW(InputArguments) << "RooDataSet::" << (corr?"correlation":"covariance") << "(" << GetName() << ") WARNING: empty dataset, returning zero" << std::endl ;
924 return 0;
925 }
926
927 // Setup RooFormulaVar for cutSpec if it is present
928 std::unique_ptr<RooFormula> select;
929 if (cutSpec) select = std::make_unique<RooFormula>("select",cutSpec,*get());
930
931 // Calculate requested moment
932 double xysum(0);
933 double xsum(0);
934 double ysum(0);
935 double x2sum(0);
936 double y2sum(0);
937 const RooArgSet* vars ;
938 for(int index= 0; index < numEntries(); index++) {
939 vars = get(index) ;
940 if (select && select->eval()==0) continue ;
941 if (cutRange && vars->allInRange(cutRange)) continue ;
942
943 xysum += weight()*xdata->getVal()*ydata->getVal() ;
944 xsum += weight()*xdata->getVal() ;
945 ysum += weight()*ydata->getVal() ;
946 if (corr) {
947 x2sum += weight()*xdata->getVal()*xdata->getVal() ;
948 y2sum += weight()*ydata->getVal()*ydata->getVal() ;
949 }
950 }
951
952 // Normalize entries
953 xysum/=sumEntries(cutSpec, cutRange) ;
954 xsum/=sumEntries(cutSpec, cutRange) ;
955 ysum/=sumEntries(cutSpec, cutRange) ;
956 if (corr) {
957 x2sum/=sumEntries(cutSpec, cutRange) ;
958 y2sum/=sumEntries(cutSpec, cutRange) ;
959 }
960
961 // Return covariance or correlation as requested
962 if (corr) {
963 return (xysum-xsum*ysum)/(sqrt(x2sum-(xsum*xsum))*sqrt(y2sum-(ysum*ysum))) ;
964 } else {
965 return (xysum-xsum*ysum);
966 }
967}
968
969////////////////////////////////////////////////////////////////////////////////
970/// Return covariance matrix from data for given list of observables
971
972RooFit::OwningPtr<TMatrixDSym> RooAbsData::corrcovMatrix(const RooArgList& vars, const char* cutSpec, const char* cutRange, bool corr) const
973{
975 for(auto * var : static_range_cast<RooRealVar*>(vars)) {
976 RooRealVar* datavar = dataRealVar("covarianceMatrix",*var) ;
977 if (!datavar) {
978 return nullptr;
979 }
980 varList.add(*datavar) ;
981 }
982
983
984 // Check if dataset is not empty
985 if(sumEntries(cutSpec, cutRange) == 0.) {
986 coutW(InputArguments) << "RooDataSet::covariance(" << GetName() << ") WARNING: empty dataset, returning zero" << std::endl ;
987 return nullptr;
988 }
989
990 // Setup RooFormulaVar for cutSpec if it is present
991 std::unique_ptr<RooFormula> select = cutSpec ? std::make_unique<RooFormula>("select",cutSpec,*get()) : nullptr;
992
993 TMatrixDSym xysum(varList.size()) ;
994 std::vector<double> xsum(varList.size()) ;
995 std::vector<double> x2sum(varList.size()) ;
996
997 // Calculate <x_i> and <x_i y_j>
998 for(int index= 0; index < numEntries(); index++) {
999 const RooArgSet* dvars = get(index) ;
1000 if (select && select->eval()==0) continue ;
1001 if (cutRange && dvars->allInRange(cutRange)) continue ;
1002
1003 for(std::size_t iX = 0; iX < varList.size(); ++iX) {
1004 auto varx = static_cast<RooRealVar const&>(varList[iX]);
1005 xsum[iX] += weight() * varx.getVal() ;
1006 if (corr) {
1007 x2sum[iX] += weight() * varx.getVal() * varx.getVal();
1008 }
1009
1010 for(std::size_t iY = iX; iY < varList.size(); ++iY) {
1011 auto vary = static_cast<RooRealVar const&>(varList[iY]);
1012 xysum(iX,iY) += weight() * varx.getVal() * vary.getVal();
1013 xysum(iY,iX) = xysum(iX,iY) ;
1014 }
1015 }
1016
1017 }
1018
1019 // Normalize sums
1020 for (std::size_t iX=0 ; iX<varList.size() ; iX++) {
1021 xsum[iX] /= sumEntries(cutSpec, cutRange) ;
1022 if (corr) {
1023 x2sum[iX] /= sumEntries(cutSpec, cutRange) ;
1024 }
1025 for (std::size_t iY=0 ; iY<varList.size() ; iY++) {
1026 xysum(iX,iY) /= sumEntries(cutSpec, cutRange) ;
1027 }
1028 }
1029
1030 // Calculate covariance matrix
1031 auto C = std::make_unique<TMatrixDSym>(varList.size()) ;
1032 for (std::size_t iX=0 ; iX<varList.size() ; iX++) {
1033 for (std::size_t iY=0 ; iY<varList.size() ; iY++) {
1034 (*C)(iX,iY) = xysum(iX,iY)-xsum[iX]*xsum[iY] ;
1035 if (corr) {
1036 (*C)(iX,iY) /= std::sqrt((x2sum[iX]-(xsum[iX]*xsum[iX]))*(x2sum[iY]-(xsum[iY]*xsum[iY]))) ;
1037 }
1038 }
1039 }
1040
1041 return RooFit::makeOwningPtr(std::move(C));
1042}
1043
1044////////////////////////////////////////////////////////////////////////////////
1045/// Create a RooRealVar containing the mean of observable 'var' in
1046/// this dataset. If cutSpec and/or cutRange are specified the
1047/// moment is calculated on the subset of the data which pass the C++
1048/// cut specification expression 'cutSpec' and/or are inside the
1049/// range named 'cutRange'
1050
1051RooRealVar* RooAbsData::meanVar(const RooRealVar &var, const char* cutSpec, const char* cutRange) const
1052{
1053 // Create a new variable with appropriate strings. The error is calculated as
1054 // RMS/Sqrt(N) which is generally valid.
1055
1056 // Create holder variable for mean
1057 std::string name = std::string{var.GetName()} + "Mean";
1058 std::string title = std::string{"Mean of "} + var.GetTitle();
1059 auto *meanv= new RooRealVar(name.c_str(), title.c_str(), 0) ;
1060 meanv->setConstant(false) ;
1061
1062 // Adjust plot label
1063 std::string label = "<" + std::string{var.getPlotLabel()} + ">";
1064 meanv->setPlotLabel(label.c_str());
1065
1066 // fill in this variable's value and error
1067 double meanVal=moment(var,1,0,cutSpec,cutRange) ;
1068 double N(sumEntries(cutSpec,cutRange)) ;
1069
1070 double rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
1071 meanv->setVal(meanVal) ;
1072 meanv->setError(N > 0 ? rmsVal/sqrt(N) : 0);
1073
1074 return meanv;
1075}
1076
1077////////////////////////////////////////////////////////////////////////////////
1078/// Create a RooRealVar containing the RMS of observable 'var' in
1079/// this dataset. If cutSpec and/or cutRange are specified the
1080/// moment is calculated on the subset of the data which pass the C++
1081/// cut specification expression 'cutSpec' and/or are inside the
1082/// range named 'cutRange'
1083
1084RooRealVar* RooAbsData::rmsVar(const RooRealVar &var, const char* cutSpec, const char* cutRange) const
1085{
1086 // Create a new variable with appropriate strings. The error is calculated as
1087 // RMS/(2*Sqrt(N)) which is only valid if the variable has a Gaussian distribution.
1088
1089 // Create RMS value holder
1090 std::string name(var.GetName());
1091 std::string title("RMS of ");
1092 name += "RMS";
1093 title += var.GetTitle();
1094 auto *rms= new RooRealVar(name.c_str(), title.c_str(), 0) ;
1095 rms->setConstant(false) ;
1096
1097 // Adjust plot label
1098 std::string label(var.getPlotLabel());
1099 label += "_{RMS}";
1100 rms->setPlotLabel(label.c_str());
1101
1102 // Fill in this variable's value and error
1103 double meanVal(moment(var,1,0,cutSpec,cutRange)) ;
1104 double N(sumEntries(cutSpec, cutRange));
1105 double rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
1106 rms->setVal(rmsVal) ;
1107 rms->setError(rmsVal/sqrt(2*N));
1108
1109 return rms;
1110}
1111
1112////////////////////////////////////////////////////////////////////////////////
1113/// Add a box with statistics information to the specified frame. By default a box with the
1114/// event count, mean and rms of the plotted variable is added.
1115///
1116/// The following optional named arguments are accepted
1117/// <table>
1118/// <tr><td> `What(const char* whatstr)` <td> Controls what is printed: "N" = count, "M" is mean, "R" is RMS.
1119/// <tr><td> `Format(const char* optStr)` <td> \deprecated Classing parameter formatting options, provided for backward compatibility
1120///
1121/// <tr><td> `Format(const char* what,...)` <td> Parameter formatting options.
1122/// <table>
1123/// <tr><td> const char* what <td> Controls what is shown:
1124/// - "N" adds name
1125/// - "E" adds error
1126/// - "A" shows asymmetric error
1127/// - "U" shows unit
1128/// - "H" hides the value
1129/// <tr><td> `FixedPrecision(int n)` <td> Controls precision, set fixed number of digits
1130/// <tr><td> `AutoPrecision(int n)` <td> Controls precision. Number of shown digits is calculated from error + n specified additional digits (1 is sensible default)
1131/// <tr><td> `VerbatimName(bool flag)` <td> Put variable name in a \\verb+ + clause.
1132/// </table>
1133/// <tr><td> `Label(const chat* label)` <td> Add header label to parameter box
1134/// <tr><td> `Layout(double xmin, double xmax, double ymax)` <td> Specify relative position of left,right side of box and top of box. Position of
1135/// bottom of box is calculated automatically from number lines in box
1136/// <tr><td> `Cut(const char* expression)` <td> Apply given cut expression to data when calculating statistics
1137/// <tr><td> `CutRange(const char* rangeName)` <td> Only consider events within given range when calculating statistics. Multiple
1138/// CutRange() argument may be specified to combine ranges.
1139///
1140/// </table>
1141
1143 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
1144 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1145{
1146 // Stuff all arguments in a list
1148 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
1149 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
1150 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
1151 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
1152
1153 // Select the pdf-specific commands
1154 RooCmdConfig pc("RooTreeData::statOn(" + std::string(GetName()) + ")");
1155 pc.defineString("what","What",0,"MNR") ;
1156 pc.defineString("label","Label",0,"") ;
1157 pc.defineDouble("xmin","Layout",0,0.65) ;
1158 pc.defineDouble("xmax","Layout",1,0.99) ;
1159 pc.defineInt("ymaxi","Layout",0,int(0.95*10000)) ;
1160 pc.defineString("formatStr","Format",0,"NELU") ;
1161 pc.defineInt("sigDigit","Format",0,2) ;
1162 pc.defineInt("dummy","FormatArgs",0,0) ;
1163 pc.defineString("cutRange","CutRange",0,"",true) ;
1164 pc.defineString("cutString","CutSpec",0,"") ;
1165 pc.defineMutex("Format","FormatArgs") ;
1166
1167 // Process and check varargs
1168 pc.process(cmdList) ;
1169 if (!pc.ok(true)) {
1170 return frame ;
1171 }
1172
1173 const char* label = pc.getString("label") ;
1174 double xmin = pc.getDouble("xmin") ;
1175 double xmax = pc.getDouble("xmax") ;
1176 double ymax = pc.getInt("ymaxi") / 10000. ;
1177 const char* formatStr = pc.getString("formatStr") ;
1178 int sigDigit = pc.getInt("sigDigit") ;
1179 const char* what = pc.getString("what") ;
1180
1181 const char* cutSpec = pc.getString("cutString",nullptr,true) ;
1182 const char* cutRange = pc.getString("cutRange",nullptr,true) ;
1183
1184 if (pc.hasProcessed("FormatArgs")) {
1185 RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
1186 return statOn(frame,what,label,0,nullptr,xmin,xmax,ymax,cutSpec,cutRange,formatCmd) ;
1187 } else {
1188 return statOn(frame,what,label,sigDigit,formatStr,xmin,xmax,ymax,cutSpec,cutRange) ;
1189 }
1190}
1191
1192////////////////////////////////////////////////////////////////////////////////
1193/// Implementation back-end of statOn() method with named arguments
1194
1195RooPlot* RooAbsData::statOn(RooPlot* frame, const char* what, const char *label, Int_t sigDigits,
1196 Option_t *options, double xmin, double xmax, double ymax,
1197 const char* cutSpec, const char* cutRange, const RooCmdArg* formatCmd)
1198{
1199 bool showLabel= (label != nullptr && strlen(label) > 0);
1200
1201 std::string whatStr{what};
1202 std::transform(whatStr.begin(), whatStr.end(), whatStr.begin(), [](unsigned char c){ return std::toupper(c); });
1203 bool showN = whatStr.find('N') != std::string::npos;
1204 bool showR = whatStr.find('R') != std::string::npos;
1205 bool showM = whatStr.find('M') != std::string::npos;
1206 int nPar= 0;
1207 if (showN) nPar++ ;
1208 if (showR) nPar++ ;
1209 if (showM) nPar++ ;
1210
1211 // calculate the box's size
1212 double dy(0.06);
1213 double ymin(ymax - nPar * dy);
1214 if(showLabel) ymin-= dy;
1215
1216 // create the box and set its options
1217 TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
1218 if(!box) return nullptr;
1219 box->SetName((std::string{GetName()} + "_statBox").c_str());
1220 box->SetFillColor(0);
1221 box->SetBorderSize(1);
1222 box->SetTextAlign(12);
1223 box->SetTextSize(0.04F);
1224 box->SetFillStyle(1001);
1225
1226 // add formatted text for each statistic
1227 RooRealVar N("N","Number of Events",sumEntries(cutSpec,cutRange));
1228 N.setPlotLabel("Entries") ;
1229 std::unique_ptr<RooRealVar> meanv{meanVar(*static_cast<RooRealVar*>(frame->getPlotVar()),cutSpec,cutRange)};
1230 meanv->setPlotLabel("Mean") ;
1231 std::unique_ptr<RooRealVar> rms{rmsVar(*static_cast<RooRealVar*>(frame->getPlotVar()),cutSpec,cutRange)};
1232 rms->setPlotLabel("RMS") ;
1233 std::string rmsText = options ? rms->format(sigDigits,options) : rms->format(*formatCmd);
1234 std::string meanText = options ? meanv->format(sigDigits,options) : meanv->format(*formatCmd);
1235 std::string NText = options ? N.format(sigDigits,options) : N.format(*formatCmd);
1236 if (showR) box->AddText(rmsText.c_str());
1237 if (showM) box->AddText(meanText.c_str());
1238 if (showN) box->AddText(NText.c_str());
1239
1240 // add the optional label if specified
1241 if(showLabel) box->AddText(label);
1242
1243 frame->addObject(box) ;
1244 return frame ;
1245}
1246
1247////////////////////////////////////////////////////////////////////////////////
1248/// Loop over columns of our tree data and fill the input histogram. Returns a pointer to the
1249/// input histogram, or zero in case of an error. The input histogram can be any TH1 subclass, and
1250/// therefore of arbitrary dimension. Variables are matched with the (x,y,...) dimensions of the input
1251/// histogram according to the order in which they appear in the input plotVars list.
1252
1253TH1 *RooAbsData::fillHistogram(TH1 *hist, const RooArgList &plotVars, const char *cuts, const char* cutRange) const
1254{
1255 // Do we have a valid histogram to use?
1256 if(nullptr == hist) {
1257 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: no valid histogram to fill" << std::endl;
1258 return nullptr;
1259 }
1260
1261 // Check that the number of plotVars matches the input histogram's dimension
1262 std::size_t hdim= hist->GetDimension();
1263 if(hdim != plotVars.size()) {
1264 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: plotVars has the wrong dimension" << std::endl;
1265 return nullptr;
1266 }
1267
1268 // Check that the plot variables are all actually RooAbsReal's and print a warning if we do not
1269 // explicitly depend on one of them. Clone any variables that we do not contain directly and
1270 // redirect them to use our event data.
1273 for(std::size_t index= 0; index < plotVars.size(); index++) {
1274 const RooAbsArg *var= plotVars.at(index);
1275 const RooAbsReal *realVar= dynamic_cast<const RooAbsReal*>(var);
1276 if(realVar == nullptr) {
1277 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot plot variable \"" << var->GetName()
1278 << "\" of type " << var->ClassName() << std::endl;
1279 return nullptr;
1280 }
1281 RooAbsArg *found= _vars.find(realVar->GetName());
1282 if(!found) {
1283 RooAbsArg *clone= plotClones.addClone(*realVar,true); // do not complain about duplicates
1284 assert(nullptr != clone);
1285 if(!clone->dependsOn(_vars)) {
1286 coutE(InputArguments) << ClassName() << "::" << GetName()
1287 << ":fillHistogram: Data does not contain the variable '" << realVar->GetName() << "'." << std::endl;
1288 return nullptr;
1289 }
1290 else {
1292 }
1293 localVars.add(*clone);
1294 }
1295 else {
1296 localVars.add(*found);
1297 }
1298 }
1299
1300 // Create selection formula if selection cuts are specified
1301 std::unique_ptr<RooFormula> select;
1302 if (cuts != nullptr && strlen(cuts) > 0) {
1303 select = std::make_unique<RooFormula>(cuts, cuts, _vars, false);
1304 if (!select || !select->ok()) {
1305 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: invalid cuts \"" << cuts << "\"" << std::endl;
1306 return nullptr;
1307 }
1308 }
1309
1310 // Lookup each of the variables we are binning in our tree variables
1311 const RooAbsReal *xvar = nullptr;
1312 const RooAbsReal *yvar = nullptr;
1313 const RooAbsReal *zvar = nullptr;
1314 switch(hdim) {
1315 case 3:
1316 zvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(2)->GetName()));
1317 assert(nullptr != zvar);
1318 // fall through to next case...
1319 case 2:
1320 yvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(1)->GetName()));
1321 assert(nullptr != yvar);
1322 // fall through to next case...
1323 case 1:
1324 xvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(0)->GetName()));
1325 assert(nullptr != xvar);
1326 break;
1327 default:
1328 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot fill histogram with "
1329 << hdim << " dimensions" << std::endl;
1330 break;
1331 }
1332
1333 // Parse cutRange specification
1334 const auto cutVec = ROOT::Split(cutRange ? cutRange : "", ",");
1335
1336 // Loop over events and fill the histogram
1337 if (hist->GetSumw2()->fN==0) {
1338 hist->Sumw2() ;
1339 }
1340 int nevent= numEntries() ; //(int)_tree->GetEntries();
1341 for(int i=0; i < nevent; ++i) {
1342
1343 //int entryNumber= _tree->GetEntryNumber(i);
1344 //if (entryNumber<0) break;
1345 get(i);
1346
1347 // Apply expression based selection criteria
1348 if (select && select->eval()==0) {
1349 continue ;
1350 }
1351
1352
1353 // Apply range based selection criteria
1354 bool selectByRange = true ;
1355 if (cutRange) {
1356 for (const auto arg : _vars) {
1357 bool selectThisArg = false ;
1358 for (auto const& cut : cutVec) {
1359 if (!cut.empty() && arg->inRange(cut.c_str())) {
1361 break ;
1362 }
1363 }
1364 if (!selectThisArg) {
1366 break ;
1367 }
1368 }
1369 }
1370
1371 if (!selectByRange) {
1372 // Go to next event in loop over events
1373 continue ;
1374 }
1375
1376 int bin(0);
1377 switch(hdim) {
1378 case 1:
1379 bin= hist->FindBin(xvar->getVal());
1380 hist->Fill(xvar->getVal(),weight()) ;
1381 break;
1382 case 2:
1383 bin= hist->FindBin(xvar->getVal(),yvar->getVal());
1384 static_cast<TH2*>(hist)->Fill(xvar->getVal(),yvar->getVal(),weight()) ;
1385 break;
1386 case 3:
1387 bin= hist->FindBin(xvar->getVal(),yvar->getVal(),zvar->getVal());
1388 static_cast<TH3*>(hist)->Fill(xvar->getVal(),yvar->getVal(),zvar->getVal(),weight()) ;
1389 break;
1390 default:
1391 assert(hdim < 3);
1392 break;
1393 }
1394
1395
1396 double error2 = std::pow(hist->GetBinError(bin),2)-std::pow(weight(),2) ;
1397 double we = weightError(RooAbsData::SumW2) ;
1398 if (we==0) we = weight() ;
1399 error2 += std::pow(we,2) ;
1400
1401
1402// double we = weightError(RooAbsData::SumW2) ;
1403// double error2(0) ;
1404// if (we==0) {
1405// we = weight() ; //sqrt(weight()) ;
1406// error2 = std::pow(hist->GetBinError(bin),2)-std::pow(weight(),2) + std::pow(we,2) ;
1407// } else {
1408// error2 = std::pow(hist->GetBinError(bin),2)-std::pow(weight(),2) + std::pow(we,2) ;
1409// }
1410 //hist->AddBinContent(bin,weight());
1411 hist->SetBinError(bin,sqrt(error2)) ;
1412
1413 //cout << "RooTreeData::fillHistogram() bin = " << bin << " weight() = " << weight() << " we = " << we << std::endl ;
1414
1415 }
1416
1417 return hist;
1418}
1419
1420
1421namespace {
1422
1423struct SplittingSetup {
1424 RooArgSet ownedSet;
1425 RooAbsCategory *cloneCat = nullptr;
1426 RooArgSet subsetVars;
1427 bool addWeightVar = false;
1428};
1429
1430SplittingSetup initSplit(RooAbsData const &data, RooAbsCategory const &splitCat)
1431{
1432 SplittingSetup setup;
1433
1434 // Sanity check
1435 if (!splitCat.dependsOn(*data.get())) {
1436 oocoutE(&data, InputArguments) << "RooTreeData::split(" << data.GetName() << ") ERROR category "
1437 << splitCat.GetName() << " doesn't depend on any variable in this dataset"
1438 << std::endl;
1439 return setup;
1440 }
1441
1442 // Clone splitting category and attach to self
1443 if (splitCat.isDerived()) {
1444 RooArgSet(splitCat).snapshot(setup.ownedSet, true);
1445 setup.cloneCat = static_cast<RooAbsCategory *>(setup.ownedSet.find(splitCat.GetName()));
1446 setup.cloneCat->attachDataSet(data);
1447 } else {
1448 setup.cloneCat = dynamic_cast<RooAbsCategory *>(data.get()->find(splitCat.GetName()));
1449 if (!setup.cloneCat) {
1450 oocoutE(&data, InputArguments) << "RooTreeData::split(" << data.GetName() << ") ERROR category "
1451 << splitCat.GetName() << " is fundamental and does not appear in this dataset"
1452 << std::endl;
1453 return setup;
1454 }
1455 }
1456
1457 // Construct set of variables to be included in split sets = full set - split category
1458 setup.subsetVars.add(*data.get());
1459 if (splitCat.isDerived()) {
1460 std::unique_ptr<RooArgSet> vars{splitCat.getVariables()};
1461 setup.subsetVars.remove(*vars, true, true);
1462 } else {
1463 setup.subsetVars.remove(splitCat, true, true);
1464 }
1465
1466 // Add weight variable explicitly if dataset has weights, but no top-level weight
1467 // variable exists (can happen with composite datastores)
1468 setup.addWeightVar = data.isWeighted();
1469
1470 return setup;
1471}
1472
1473std::vector<std::unique_ptr<RooAbsData>>
1474splitImpl(RooAbsData const &data, const RooAbsCategory &cloneCat, bool createEmptyDataSets,
1475 std::function<std::unique_ptr<RooAbsData>(const char *label)> createEmptyData)
1476{
1477 std::vector<std::unique_ptr<RooAbsData>> dsetList;
1478
1479 // If createEmptyDataSets is true, prepopulate with empty sets corresponding to all states
1480 if (createEmptyDataSets) {
1481 for (const auto &nameIdx : cloneCat) {
1482 dsetList.emplace_back(createEmptyData(nameIdx.first.c_str()).release());
1483 }
1484 }
1485
1486 bool isDataHist = dynamic_cast<RooDataHist const *>(&data);
1487
1488 // Loop over dataset and copy event to matching subset
1489 for (int i = 0; i < data.numEntries(); ++i) {
1490 const RooArgSet *row = data.get(i);
1491 auto found = std::find_if(dsetList.begin(), dsetList.end(), [&](auto const &item) {
1492 return strcmp(item->GetName(), cloneCat.getCurrentLabel()) == 0;
1493 });
1494 RooAbsData *subset = found != dsetList.end() ? found->get() : nullptr;
1495 if (!subset) {
1496 dsetList.emplace_back(createEmptyData(cloneCat.getCurrentLabel()));
1497 subset = dsetList.back().get();
1498 }
1499
1500 // For datasets with weight errors or sumW2, the interface to fill
1501 // RooDataHist and RooDataSet is not the same.
1502 if (isDataHist) {
1503 static_cast<RooDataHist *>(subset)->add(*row, data.weight(), data.weightSquared());
1504 } else {
1505 static_cast<RooDataSet *>(subset)->add(*row, data.weight(), data.weightError());
1506 }
1507 }
1508
1509 return dsetList;
1510}
1511
1512} // namespace
1513
1514
1515/**
1516 * \brief Split the dataset into subsets based on states of a categorical variable in this dataset.
1517 *
1518 * Returns a list of sub-datasets, which each dataset named after a given state
1519 * name in the `splitCat`. The observables `splitCat` itself is no longer present
1520 * in the sub-datasets.
1521 *
1522 * \note If you mean to split a dataset into sub-datasets that correspond to
1523 * the individual channels of a RooSimultaneous, it is better to use
1524 * RooAbsData::split(const RooSimultaneous &, bool), because then the
1525 * sub-datasets only contain variables that the pdf for the corresponding
1526 * channel depends on. This is much faster in case of many channels, and the
1527 * resulting sub-datasets don't waste memory for unused columns.
1528 *
1529 * \throws `std::runtime_error` if an error occurs.
1530 *
1531 * \param splitCat The categorical variable used for splitting the dataset.
1532 * \param createEmptyDataSets Flag indicating whether to create empty datasets
1533 * for missing categories (`false` by default).
1534 *
1535 * \return Subsets of the dataset.
1536 *
1537 * \note **Backwards compatibility:**
1538 * In releases before ROOT 6.38.00, this function returned a `TList*`. If you
1539 * still need a `TList*`, you can convert the return value with a small helper:
1540 *
1541 * ```cpp
1542 * TList *splitsToTList(std::vector<std::unique_ptr<RooAbsData>> &&vec) {
1543 * auto *tlist = new TList;
1544 * for (auto &d : vec)
1545 * tlist->Add(d.release());
1546 * return tlist;
1547 * }
1548 *
1549 * // Example usage:
1550 * TList *splits = splitsToTList(data->split(*category));
1551 * // ... do something with splits ...
1552 * splits->Delete();
1553 * delete splits;
1554 * ```
1555 *
1556 * This way, you can continue to work with `TList` while adopting the new
1557 * `std::vector<std::unique_ptr<RooAbsData>>` API over time, which ensures
1558 * automatic cleanup of resources.
1559 */
1560
1561std::vector<std::unique_ptr<RooAbsData>>
1563{
1564 SplittingSetup setup = initSplit(*this, splitCat);
1565
1566 // Something went wrong
1567 if (!setup.cloneCat)
1568 throw std::runtime_error("runtime error in RooAbsData::split");
1569
1570 auto createEmptyData = [&](const char *label) -> std::unique_ptr<RooAbsData> {
1571 return std::unique_ptr<RooAbsData>{
1572 emptyClone(label, label, &setup.subsetVars, setup.addWeightVar ? "weight" : nullptr)};
1573 };
1574
1575 return splitImpl(*this, *setup.cloneCat, createEmptyDataSets, createEmptyData);
1576}
1577
1578/**
1579 * \brief Split the dataset into subsets based on the channels of a RooSimultaneous.
1580 *
1581 * Returns a list of sub-datasets, which each dataset named after the
1582 * applicable state name of the RooSimultaneous index category. The index
1583 * category itself is no longer present in the sub-datasets. The sub-datasets
1584 * only contain variables that the pdf for the corresponding channel depends
1585 * on.
1586 *
1587 * \throws `std::runtime_error` if an error occurs.
1588 *
1589 * \param simPdf The simultaneous pdf used for splitting the dataset.
1590 * \param createEmptyDataSets Flag indicating whether to create empty datasets
1591 * for missing categories (`false` by default).
1592 *
1593 * \return Subsets of the dataset.
1594 */
1595std::vector<std::unique_ptr<RooAbsData>>
1597{
1598 auto &splitCat = const_cast<RooAbsCategoryLValue &>(simPdf.indexCat());
1599
1600 SplittingSetup setup = initSplit(*this, splitCat);
1601
1602 // Something went wrong
1603 if (!setup.cloneCat)
1604 throw std::runtime_error("runtime error in RooAbsData::split");
1605
1606 // Get the observables for a given pdf in the RooSimultaneous, or an empty
1607 // RooArgSet if no pdf is set
1608 auto getPdfObservables = [this, &simPdf](const char *label) {
1610 if (RooAbsPdf *catPdf = simPdf.getPdf(label)) {
1611 catPdf->getObservables(this->get(), obsSet);
1612 }
1613 return obsSet;
1614 };
1615
1616 // By default, remove all category observables from the subdatasets
1618 for (const auto &catPair : splitCat) {
1619 allObservables.add(getPdfObservables(catPair.first.c_str()));
1620 }
1621 setup.subsetVars.remove(allObservables, true, true);
1622
1623 auto createEmptyData = [&](const char *label) -> std::unique_ptr<RooAbsData> {
1624 // Add in the subset only the observables corresponding to this category
1625 RooArgSet subsetVarsCat(setup.subsetVars);
1626 subsetVarsCat.add(getPdfObservables(label));
1627 return std::unique_ptr<RooAbsData>{
1628 this->emptyClone(label, label, &subsetVarsCat, setup.addWeightVar ? "weight" : nullptr)};
1629 };
1630
1631 return splitImpl(*this, *setup.cloneCat, createEmptyDataSets, createEmptyData);
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Plot dataset on specified frame.
1636///
1637/// By default:
1638/// - An unbinned dataset will use the default binning of the target frame.
1639/// - A binned dataset will retain its intrinsic binning.
1640///
1641/// The following optional named arguments can be used to modify the behaviour:
1642/// \note Please follow the function links in the left column to learn about PyROOT specifics for a given option.
1643///
1644/// <table>
1645///
1646/// <tr><th> <th> Data representation options
1647/// <tr><td> RooFit::Asymmetry(const RooCategory& c)
1648/// <td> Show the asymmetry of the data in given two-state category [F(+)-F(-)] / [F(+)+F(-)].
1649/// Category must have two states with indices -1 and +1 or three states with indices -1,0 and +1.
1650/// <tr><td> RooFit::Efficiency(const RooCategory& c)
1651/// <td> Show the efficiency F(acc)/[F(acc)+F(rej)]. Category must have two states with indices 0 and 1
1652/// <tr><td> RooFit::DataError(Int_t)
1653/// <td> Select the type of error drawn:
1654/// - `Auto(default)` results in Poisson for unweighted data and SumW2 for weighted data
1655/// - `Poisson` draws asymmetric Poisson confidence intervals.
1656/// - `SumW2` draws symmetric sum-of-weights error ( \f$ \left( \sum w \right)^2 / \sum\left(w^2\right) \f$ )
1657/// - `None` draws no error bars
1658/// <tr><td> RooFit::Binning(int nbins, double xlo, double xhi)
1659/// <td> Use specified binning to draw dataset
1660/// <tr><td> RooFit::Binning(const RooAbsBinning&)
1661/// <td> Use specified binning to draw dataset
1662/// <tr><td> RooFit::Binning(const char* name)
1663/// <td> Use binning with specified name to draw dataset
1664/// <tr><td> RooFit::RefreshNorm()
1665/// <td> Force refreshing for PDF normalization information in frame.
1666/// If set, any subsequent PDF will normalize to this dataset, even if it is
1667/// not the first one added to the frame. By default only the 1st dataset
1668/// added to a frame will update the normalization information
1669/// <tr><td> RooFit::Rescale(double f)
1670/// <td> Rescale drawn histogram by given factor.
1671/// <tr><td> RooFit::Cut(const char*)
1672/// <td> Only plot entries that pass the given cut.
1673/// Apart from cutting in continuous variables `Cut("x>5")`, this can also be used to plot a specific
1674/// category state. Use something like `Cut("myCategory == myCategory::stateA")`, where
1675/// `myCategory` resolves to the state number for a given entry and
1676/// `myCategory::stateA` resolves to the state number of the state named "stateA".
1677///
1678/// <tr><td> RooFit::CutRange(const char*)
1679/// <td> Only plot data from given range. Separate multiple ranges with ",".
1680/// \note This often requires passing the normalisation when plotting the PDF because RooFit does not save
1681/// how many events were being plotted (it will only work for cutting slices out of uniformly distributed
1682/// variables).
1683/// ```
1684/// data->plotOn(frame01, CutRange("SB1"));
1685/// const double nData = data->sumEntries("", "SB1");
1686/// // Make clear that the target normalisation is nData. The enumerator NumEvent
1687/// // is needed to switch between relative and absolute scaling.
1688/// model.plotOn(frame01, Normalization(nData, RooAbsReal::NumEvent),
1689/// ProjectionRange("SB1"));
1690/// ```
1691///
1692/// <tr><th> <th> Histogram drawing options
1693/// <tr><td> RooFit::DrawOption(const char* opt)
1694/// <td> Select ROOT draw option for resulting TGraph object
1695/// <tr><td> RooFit::LineStyle(Style_t style)
1696/// <td> Select line style by ROOT line style code, default is solid
1697/// <tr><td> RooFit::LineColor(Color_t color)
1698/// <td> Select line color by ROOT color code, default is black
1699/// <tr><td> RooFit::LineWidth(Width_t width)
1700/// <td> Select line with in pixels, default is 3
1701/// <tr><td> RooFit::MarkerStyle(Style_t style)
1702/// <td> Select the ROOT marker style, default is 21
1703/// <tr><td> RooFit::MarkerColor(Color_t color)
1704/// <td> Select the ROOT marker color, default is black
1705/// <tr><td> RooFit::MarkerSize(Size_t size)
1706/// <td> Select the ROOT marker size
1707/// <tr><td> RooFit::FillStyle(Style_t style)
1708/// <td> Select fill style, default is filled.
1709/// <tr><td> RooFit::FillColor(Color_t color)
1710/// <td> Select fill color by ROOT color code
1711/// <tr><td> RooFit::XErrorSize(double frac)
1712/// <td> Select size of X error bar as fraction of the bin width, default is 1
1713///
1714/// <tr><th> <th> Misc. other options
1715/// <tr><td> RooFit::Name(const char* name)
1716/// <td> Give curve specified name in frame. Useful if curve is to be referenced later
1717/// <tr><td> RooFit::Invisible()
1718/// <td> Add curve to frame, but do not display. Useful in combination AddTo()
1719/// <tr><td> RooFit::AddTo(const char* name, double wgtSel, double wgtOther)
1720/// <td> Add constructed histogram to already existing histogram with given name and relative weight factors
1721///
1722/// </table>
1723
1724RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooLinkedList& argList) const
1725{
1726 // New experimental plotOn() with varargs...
1727
1728 // Define configuration for this method
1729 RooCmdConfig pc("RooAbsData::plotOn(" + std::string(GetName()) + ")");
1730 pc.defineString("drawOption","DrawOption",0,"P") ;
1731 pc.defineString("cutRange","CutRange",0,"",true) ;
1732 pc.defineString("cutString","CutSpec",0,"") ;
1733 pc.defineString("histName","Name",0,"") ;
1734 pc.defineObject("cutVar","CutVar",0) ;
1735 pc.defineObject("binning","Binning",0) ;
1736 pc.defineString("binningName","BinningName",0,"") ;
1737 pc.defineInt("nbins","BinningSpec",0,100) ;
1738 pc.defineDouble("xlo","BinningSpec",0,0) ;
1739 pc.defineDouble("xhi","BinningSpec",1,1) ;
1740 pc.defineObject("asymCat","Asymmetry",0) ;
1741 pc.defineObject("effCat","Efficiency",0) ;
1742 pc.defineInt("lineColor","LineColor",0,-999) ;
1743 pc.defineInt("lineStyle","LineStyle",0,-999) ;
1744 pc.defineInt("lineWidth","LineWidth",0,-999) ;
1745 pc.defineInt("markerColor","MarkerColor",0,-999) ;
1746 pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
1747 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
1748 pc.defineInt("fillColor","FillColor",0,-999) ;
1749 pc.defineInt("fillStyle","FillStyle",0,-999) ;
1750 pc.defineInt("errorType","DataError",0,(int)RooAbsData::Auto) ;
1751 pc.defineInt("histInvisible","Invisible",0,0) ;
1752 pc.defineInt("refreshFrameNorm","RefreshNorm",0,1) ;
1753 pc.defineString("addToHistName","AddTo",0,"") ;
1754 pc.defineDouble("addToWgtSelf","AddTo",0,1.) ;
1755 pc.defineDouble("addToWgtOther","AddTo",1,1.) ;
1756 pc.defineDouble("xErrorSize","XErrorSize",0,1.) ;
1757 pc.defineDouble("scaleFactor","Rescale",0,1.) ;
1758 pc.defineMutex("DataError","Asymmetry","Efficiency") ;
1759 pc.defineMutex("Binning","BinningName","BinningSpec") ;
1760
1761 // Process & check varargs
1762 pc.process(argList) ;
1763 if (!pc.ok(true)) {
1764 return frame ;
1765 }
1766
1767 PlotOpt o ;
1768
1769 // Extract values from named arguments
1770 o.drawOptions = pc.getString("drawOption") ;
1771 o.cuts = pc.getString("cutString") ;
1772 if (pc.hasProcessed("Binning")) {
1773 o.bins = static_cast<RooAbsBinning*>(pc.getObject("binning")) ;
1774 } else if (pc.hasProcessed("BinningName")) {
1775 o.bins = &frame->getPlotVar()->getBinning(pc.getString("binningName")) ;
1776 } else if (pc.hasProcessed("BinningSpec")) {
1777 double xlo = pc.getDouble("xlo") ;
1778 double xhi = pc.getDouble("xhi") ;
1779 o.bins = new RooUniformBinning((xlo==xhi)?frame->getPlotVar()->getMin():xlo,
1780 (xlo==xhi)?frame->getPlotVar()->getMax():xhi,pc.getInt("nbins")) ;
1781 }
1782 const RooAbsCategoryLValue* asymCat = static_cast<const RooAbsCategoryLValue*>(pc.getObject("asymCat")) ;
1783 const RooAbsCategoryLValue* effCat = static_cast<const RooAbsCategoryLValue*>(pc.getObject("effCat")) ;
1784 o.etype = (RooAbsData::ErrorType) pc.getInt("errorType") ;
1785 o.histInvisible = pc.getInt("histInvisible") ;
1786 o.xErrorSize = pc.getDouble("xErrorSize") ;
1787 o.cutRange = pc.getString("cutRange",nullptr,true) ;
1788 o.histName = pc.getString("histName",nullptr,true) ;
1789 o.addToHistName = pc.getString("addToHistName",nullptr,true) ;
1790 o.addToWgtSelf = pc.getDouble("addToWgtSelf") ;
1791 o.addToWgtOther = pc.getDouble("addToWgtOther") ;
1792 o.refreshFrameNorm = pc.getInt("refreshFrameNorm") ;
1793 o.scaleFactor = pc.getDouble("scaleFactor") ;
1794
1795 // Map auto error type to actual type
1796 if (o.etype == Auto) {
1798 if (o.etype == SumW2) {
1799 coutI(InputArguments) << "RooAbsData::plotOn(" << GetName()
1800 << ") INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors" << std::endl ;
1801 }
1802 }
1803
1804 if (o.addToHistName && !frame->findObject(o.addToHistName,RooHist::Class())) {
1805 coutE(InputArguments) << "RooAbsData::plotOn(" << GetName() << ") cannot find existing histogram " << o.addToHistName
1806 << " to add to in RooPlot" << std::endl ;
1807 return frame ;
1808 }
1809
1810 RooPlot* ret ;
1811 if (!asymCat && !effCat) {
1812 ret = plotOnImpl(frame,o) ;
1813 } else if (asymCat) {
1814 ret = plotAsymOn(frame,*asymCat,o) ;
1815 } else {
1816 ret = plotEffOn(frame,*effCat,o) ;
1817 }
1818
1819 int lineColor = pc.getInt("lineColor") ;
1820 int lineStyle = pc.getInt("lineStyle") ;
1821 int lineWidth = pc.getInt("lineWidth") ;
1822 int markerColor = pc.getInt("markerColor") ;
1823 int markerStyle = pc.getInt("markerStyle") ;
1824 Size_t markerSize = pc.getDouble("markerSize") ;
1825 int fillColor = pc.getInt("fillColor") ;
1826 int fillStyle = pc.getInt("fillStyle") ;
1827 if (lineColor!=-999) ret->getAttLine()->SetLineColor(lineColor) ;
1828 if (lineStyle!=-999) ret->getAttLine()->SetLineStyle(lineStyle) ;
1829 if (lineWidth!=-999) ret->getAttLine()->SetLineWidth(lineWidth) ;
1830 if (markerColor!=-999) ret->getAttMarker()->SetMarkerColor(markerColor) ;
1831 if (markerStyle!=-999) ret->getAttMarker()->SetMarkerStyle(markerStyle) ;
1832 if (markerSize!=-999) ret->getAttMarker()->SetMarkerSize(markerSize) ;
1833 if (fillColor!=-999) ret->getAttFill()->SetFillColor(fillColor) ;
1834 if (fillStyle!=-999) ret->getAttFill()->SetFillStyle(fillStyle) ;
1835
1836 if (pc.hasProcessed("BinningSpec")) {
1837 delete o.bins ;
1838 }
1839
1840 return ret ;
1841}
1842
1843////////////////////////////////////////////////////////////////////////////////
1844/// Create and fill a histogram of the frame's variable and append it to the frame.
1845/// The frame variable must be one of the data sets dimensions.
1846///
1847/// The plot range and the number of plot bins is determined by the parameters
1848/// of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins()).
1849///
1850/// The optional cut string expression can be used to select the events to be plotted.
1851/// The cut specification may refer to any variable contained in the data set.
1852///
1853/// The drawOptions are passed to the TH1::Draw() method.
1854/// \see RooAbsData::plotOn(RooPlot*,const RooLinkedList&) const
1856{
1857 if(nullptr == frame) {
1858 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << std::endl;
1859 return nullptr;
1860 }
1862 if(nullptr == var) {
1863 coutE(Plotting) << ClassName() << "::" << GetName()
1864 << ":plotOn: frame does not specify a plot variable" << std::endl;
1865 return nullptr;
1866 }
1867
1868 // create and fill a temporary histogram of this variable
1869 const std::string histName = std::string{GetName()} + "_plot";
1870 std::unique_ptr<TH1> hist;
1871 if (o.bins) {
1872 hist.reset( var->createHistogram(histName.c_str(), RooFit::AxisLabel("Events"), RooFit::Binning(*o.bins)) );
1873 } else if (!frame->getPlotVar()->getBinning().isUniform()) {
1874 hist.reset( var->createHistogram(histName.c_str(), RooFit::AxisLabel("Events"),
1875 RooFit::Binning(frame->getPlotVar()->getBinning())) );
1876 } else {
1877 hist.reset( var->createHistogram(histName.c_str(), "Events",
1878 frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(), frame->GetNbinsX()) );
1879 }
1880
1881 // Keep track of sum-of-weights error
1882 hist->Sumw2() ;
1883
1884 if(nullptr == fillHistogram(hist.get(), RooArgList(*var),o.cuts,o.cutRange)) {
1885 coutE(Plotting) << ClassName() << "::" << GetName()
1886 << ":plotOn: fillHistogram() failed" << std::endl;
1887 return nullptr;
1888 }
1889
1890 // If frame has no predefined bin width (event density) it will be adjusted to
1891 // our histograms bin width so we should force that bin width here
1892 double nomBinWidth ;
1893 if (frame->getFitRangeNEvt()==0 && o.bins) {
1895 } else {
1896 nomBinWidth = o.bins ? frame->getFitRangeBinW() : 0 ;
1897 }
1898
1899 // convert this histogram to a RooHist object on the heap
1901 if(nullptr == graph) {
1902 coutE(Plotting) << ClassName() << "::" << GetName()
1903 << ":plotOn: unable to create a RooHist object" << std::endl;
1904 return nullptr;
1905 }
1906
1907 // If the dataset variable has a wide range than the plot variable,
1908 // calculate the number of entries in the dataset in the plot variable fit range
1909 RooAbsRealLValue* dataVar = static_cast<RooAbsRealLValue*>(_vars.find(var->GetName())) ;
1910 double nEnt(sumEntries()) ;
1911 if (dataVar->getMin()<var->getMin() || dataVar->getMax()>var->getMax()) {
1912 std::unique_ptr<RooAbsData> tmp{const_cast<RooAbsData*>(this)->reduce(RooFit::SelectVars(*var))};
1913 nEnt = tmp->sumEntries() ;
1914 }
1915
1916 // Store the number of entries before the cut, if any was made
1917 if ((o.cuts && strlen(o.cuts)) || o.cutRange) {
1918 coutI(Plotting) << "RooTreeData::plotOn: plotting " << hist->GetSumOfWeights() << " events out of " << nEnt << " total events" << std::endl ;
1919 graph->setRawEntries(nEnt) ;
1920 }
1921
1922 // Add self to other hist if requested
1923 if (o.addToHistName) {
1924 RooHist* otherGraph = static_cast<RooHist*>(frame->findObject(o.addToHistName,RooHist::Class())) ;
1925
1926 if (!graph->hasIdenticalBinning(*otherGraph)) {
1927 coutE(Plotting) << "RooTreeData::plotOn: ERROR Histogram to be added to, '" << o.addToHistName << "',has different binning" << std::endl ;
1928 delete graph ;
1929 return frame ;
1930 }
1931
1933 delete graph ;
1934 graph = sumGraph ;
1935 }
1936
1937 // Rename graph if requested
1938 if (o.histName) {
1939 graph->SetName(o.histName) ;
1940 } else {
1941 std::string hname = std::string{"h_"} + GetName();
1942 if (o.cutRange && strlen(o.cutRange)>0) {
1943 hname += std::string{"_CutRange["} + o.cutRange + "]";
1944 }
1945 if (o.cuts && strlen(o.cuts)>0) {
1946 hname += std::string{"_Cut["} + o.cuts + "]";
1947 }
1948 graph->SetName(hname.c_str()) ;
1949 }
1950
1951 // initialize the frame's normalization setup, if necessary
1952 frame->updateNormVars(_vars);
1953
1954
1955 // add the RooHist to the specified plot
1957
1958 return frame;
1959}
1960
1962 std::string cuts1, std::string cuts2, RooAbsData::PlotOpt opt, bool efficiency,
1963 double scaleFactor)
1964{
1965 // create and fill temporary histograms of this variable for each state
1966 std::string hist1Name = std::string{absData.GetName()} + "_plot_1";
1967 std::string hist2Name = std::string{absData.GetName()} + "_plot_2";
1968 std::unique_ptr<TH1> hist1;
1969 std::unique_ptr<TH1> hist2;
1970
1971 if (opt.bins) {
1972 hist1.reset(var.createHistogram(hist1Name.c_str(), "Events", *opt.bins));
1973 hist2.reset(var.createHistogram(hist2Name.c_str(), "Events", *opt.bins));
1974 } else {
1975 auto &axis = *frame.GetXaxis();
1976 hist1.reset(var.createHistogram(hist1Name.c_str(), "Events", axis.GetXmin(), axis.GetXmax(), frame.GetNbinsX()));
1977 hist2.reset(var.createHistogram(hist2Name.c_str(), "Events", axis.GetXmin(), axis.GetXmax(), frame.GetNbinsX()));
1978 }
1979
1980 if (opt.cuts && strlen(opt.cuts)) {
1981 std::string cuts = opt.cuts;
1982 cuts1 += "&&(" + cuts + ")";
1983 cuts2 += "&&(" + cuts + ")";
1984 }
1985
1986 if (!absData.fillHistogram(hist1.get(), RooArgList(var), cuts1.c_str(), opt.cutRange) ||
1987 !absData.fillHistogram(hist2.get(), RooArgList(var), cuts2.c_str(), opt.cutRange)) {
1988 return nullptr;
1989 }
1990
1991 // convert this histogram to a RooHist object on the heap
1992 return new RooHist(*hist1, *hist2, 0, 1, opt.etype, opt.xErrorSize, efficiency, scaleFactor);
1993}
1994
1995////////////////////////////////////////////////////////////////////////////////
1996/// Create and fill a histogram with the asymmetry N[+] - N[-] / ( N[+] + N[-] ),
1997/// where N(+/-) is the number of data points with asymCat=+1 and asymCat=-1
1998/// as function of the frames variable. The asymmetry category 'asymCat' must
1999/// have exactly 2 (or 3) states defined with index values +1,-1 (and 0)
2000///
2001/// The plot range and the number of plot bins is determined by the parameters
2002/// of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins())
2003///
2004/// The optional cut string expression can be used to select the events to be plotted.
2005/// The cut specification may refer to any variable contained in the data set
2006///
2007/// The drawOptions are passed to the TH1::Draw() method
2008
2010{
2011 if(nullptr == frame) {
2012 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotAsymOn: frame is null" << std::endl;
2013 return nullptr;
2014 }
2016 if(nullptr == var) {
2017 coutE(Plotting) << ClassName() << "::" << GetName()
2018 << ":plotAsymOn: frame does not specify a plot variable" << std::endl;
2019 return nullptr;
2020 }
2021
2022 std::string catName = asymCat.GetName();
2023 RooHist *graph =
2024 createAndFillRooHist(*this, *frame, *var, "(" + catName + ">0)", "(" + catName + "<0)", o, false, o.scaleFactor);
2025 if (graph == nullptr) {
2026 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotAsymOn: createHistogram() failed" << std::endl;
2027 return nullptr;
2028 }
2029 graph->setYAxisLabel((std::string{"Asymmetry in "} + asymCat.GetName()).c_str());
2030
2031 // initialize the frame's normalization setup, if necessary
2032 frame->updateNormVars(_vars);
2033
2034 // Rename graph if requested
2035 if (o.histName) {
2036 graph->SetName(o.histName) ;
2037 } else {
2038 std::stringstream hname;
2039 hname << "h_" << GetName() << "_Asym[" << asymCat.GetName() << "]";
2040 if (o.cutRange && strlen(o.cutRange) > 0) {
2041 hname << "_CutRange[" << o.cutRange << "]";
2042 }
2043 if (o.cuts && strlen(o.cuts)>0) {
2044 hname << "_Cut[" << o.cuts << "]";
2045 }
2046 graph->SetName(hname.str().c_str());
2047 }
2048
2049 // add the RooHist to the specified plot
2051
2052 return frame;
2053}
2054
2055////////////////////////////////////////////////////////////////////////////////
2056/// Create and fill a histogram with the efficiency N[1] / ( N[1] + N[0] ),
2057/// where N(1/0) is the number of data points with effCat=1 and effCat=0
2058/// as function of the frames variable. The efficiency category 'effCat' must
2059/// have exactly 2 +1 and 0.
2060///
2061/// The plot range and the number of plot bins is determined by the parameters
2062/// of the plot variable of the frame (RooAbsReal::setPlotRange(), RooAbsReal::setPlotBins())
2063///
2064/// The optional cut string expression can be used to select the events to be plotted.
2065/// The cut specification may refer to any variable contained in the data set
2066///
2067/// The drawOptions are passed to the TH1::Draw() method
2068
2070{
2071 if(nullptr == frame) {
2072 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotEffOn: frame is null" << std::endl;
2073 return nullptr;
2074 }
2076 if(nullptr == var) {
2077 coutE(Plotting) << ClassName() << "::" << GetName()
2078 << ":plotEffOn: frame does not specify a plot variable" << std::endl;
2079 return nullptr;
2080 }
2081
2082 std::string catName = effCat.GetName();
2083 RooHist *graph =
2084 createAndFillRooHist(*this, *frame, *var, "(" + catName + "==1)", "(" + catName + "==0)", o, true, 1.0);
2085
2086 if (graph == nullptr) {
2087 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotEffOn: createHistogram() failed" << std::endl;
2088 return nullptr;
2089 }
2090
2091 graph->setYAxisLabel(("Efficiency of " + catName + "=" + effCat.lookupName(1)).c_str());
2092
2093 // initialize the frame's normalization setup, if necessary
2094 frame->updateNormVars(_vars);
2095
2096 // Rename graph if requested
2097 if (o.histName) {
2098 graph->SetName(o.histName) ;
2099 } else {
2100 std::string hname = "h_" + std::string{GetName()} + "_Eff[" + catName + "]";
2101 if (o.cutRange && strlen(o.cutRange) > 0) {
2102 hname += "_CutRange[" + std::string{o.cutRange} + " ]";
2103 }
2104 if (o.cuts && strlen(o.cuts)>0) {
2105 hname += "_Cut[" + std::string{o.cuts} + " ]";
2106 }
2107 graph->SetName(hname.c_str()) ;
2108 }
2109
2110 // add the RooHist to the specified plot
2112
2113 return frame;
2114}
2115
2116////////////////////////////////////////////////////////////////////////////////
2117/// Create and fill a 1-dimensional table for given category column
2118/// This functions is the equivalent of plotOn() for category dimensions.
2119///
2120/// The optional cut string expression can be used to select the events to be tabulated
2121/// The cut specification may refer to any variable contained in the data set
2122///
2123/// The option string is currently not used
2124
2125Roo1DTable* RooAbsData::table(const RooAbsCategory& cat, const char* cuts, const char* /*opts*/) const
2126{
2127 // First see if var is in data set
2128 RooAbsCategory* tableVar = static_cast<RooAbsCategory*>(_vars.find(cat.GetName())) ;
2129 std::unique_ptr<RooArgSet> tableSet;
2130 if (!tableVar) {
2131 if (!cat.dependsOn(_vars)) {
2132 coutE(Plotting) << "RooTreeData::Table(" << GetName() << "): Argument " << cat.GetName()
2133 << " is not in dataset and is also not dependent on data set" << std::endl ;
2134 return nullptr;
2135 }
2136
2137 // Clone derived variable
2138 tableSet = std::make_unique<RooArgSet>();
2139 if (RooArgSet(cat).snapshot(*tableSet, true)) {
2140 coutE(Plotting) << "RooTreeData::table(" << GetName() << ") Couldn't deep-clone table category, abort." << std::endl;
2141 return nullptr;
2142 }
2143 tableVar = static_cast<RooAbsCategory*>(tableSet->find(cat.GetName())) ;
2144
2145 //Redirect servers of derived clone to internal ArgSet representing the data in this set
2146 tableVar->recursiveRedirectServers(_vars) ;
2147 }
2148
2149 std::unique_ptr<RooFormulaVar> cutVar;
2150 std::string tableName{GetName()};
2151 if (cuts && strlen(cuts)) {
2152 tableName += "(";
2153 tableName += cuts;
2154 tableName += ")";
2155 // Make cut selector if cut is specified
2156 cutVar = std::make_unique<RooFormulaVar>("cutVar",cuts,_vars) ;
2157 }
2158 Roo1DTable* table2 = tableVar->createTable(tableName.c_str());
2159
2160 // Dump contents
2161 int nevent= numEntries() ;
2162 for(int i=0; i < nevent; ++i) {
2163 get(i);
2164
2165 if (cutVar && cutVar->getVal()==0) continue ;
2166
2167 table2->fill(*tableVar,weight()) ;
2168 }
2169
2170 return table2 ;
2171}
2172
2173////////////////////////////////////////////////////////////////////////////////
2174/// Fill Doubles 'lowest' and 'highest' with the lowest and highest value of
2175/// observable 'var' in this dataset. If the return value is true and error
2176/// occurred
2177
2178bool RooAbsData::getRange(const RooAbsRealLValue& var, double& lowest, double& highest, double marginFrac, bool symMode) const
2179{
2180 // Lookup variable in dataset
2181 const auto arg = _vars.find(var.GetName());
2182 if (!arg) {
2183 coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << std::endl ;
2184 return true;
2185 }
2186
2187 auto varPtr = dynamic_cast<const RooRealVar*>(arg);
2188 // Check if found variable is of type RooRealVar
2189 if (!varPtr) {
2190 coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << std::endl ;
2191 return true;
2192 }
2193
2194 // Check if dataset is not empty
2195 if(sumEntries() == 0.) {
2196 coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") WARNING: empty dataset" << std::endl ;
2197 return true;
2198 }
2199
2200 // Look for highest and lowest value
2203 for (int i=0 ; i<numEntries() ; i++) {
2204 get(i) ;
2205 if (varPtr->getVal()<lowest) {
2206 lowest = varPtr->getVal() ;
2207 }
2208 if (varPtr->getVal()>highest) {
2209 highest = varPtr->getVal() ;
2210 }
2211 }
2212
2213 if (marginFrac>0) {
2214 if (symMode==false) {
2215
2216 double margin = marginFrac*(highest-lowest) ;
2217 lowest -= margin ;
2218 highest += margin ;
2219 if (lowest<var.getMin()) lowest = var.getMin() ;
2220 if (highest>var.getMax()) highest = var.getMax() ;
2221
2222 } else {
2223
2224 double mom1 = moment(*varPtr,1) ;
2225 double delta = ((highest-mom1)>(mom1-lowest)?(highest-mom1):(mom1-lowest))*(1+marginFrac) ;
2226 lowest = mom1-delta ;
2227 highest = mom1+delta ;
2228 if (lowest<var.getMin()) lowest = var.getMin() ;
2229 if (highest>var.getMax()) highest = var.getMax() ;
2230
2231 }
2232 }
2233
2234 return false ;
2235}
2236
2237////////////////////////////////////////////////////////////////////////////////
2238/// Prepare dataset for use with cached constant terms listed in
2239/// 'cacheList' of expression 'arg'. Deactivate tree branches
2240/// for any dataset observable that is either not used at all,
2241/// or is used exclusively by cached branch nodes.
2242
2244{
2246
2247 // Add unused observables in this dataset to pruneSet
2248 pruneSet.add(*get()) ;
2249 std::unique_ptr<RooArgSet> usedObs{arg.getObservables(*this)};
2250 pruneSet.remove(*usedObs,true,true) ;
2251
2252 // Add observables exclusively used to calculate cached observables to pruneSet
2253 for(auto * var : *get()) {
2254 if (allClientsCached(var,cacheList)) {
2255 pruneSet.add(*var) ;
2256 }
2257 }
2258
2259
2260 if (!pruneSet.empty()) {
2261
2262 // Go over all used observables and check if any of them have parameterized
2263 // ranges in terms of pruned observables. If so, remove those observable
2264 // from the pruning list
2265 for(auto const* rrv : dynamic_range_cast<RooRealVar*>(*usedObs)) {
2266 if (rrv && !rrv->getBinning().isShareable()) {
2268 RooAbsReal* loFunc = rrv->getBinning().lowBoundFunc() ;
2269 RooAbsReal* hiFunc = rrv->getBinning().highBoundFunc() ;
2270 if (loFunc) {
2271 loFunc->leafNodeServerList(&depObs,nullptr,true) ;
2272 }
2273 if (hiFunc) {
2274 hiFunc->leafNodeServerList(&depObs,nullptr,true) ;
2275 }
2276 if (!depObs.empty()) {
2277 pruneSet.remove(depObs,true,true) ;
2278 }
2279 }
2280 }
2281 }
2282
2283
2284 // Remove all observables in keep list from prune list
2285 pruneSet.remove(keepObsList,true,true) ;
2286
2287 if (!pruneSet.empty()) {
2288
2289 // Deactivate tree branches here
2290 cxcoutI(Optimization) << "RooTreeData::optimizeReadingForTestStatistic(" << GetName() << "): Observables " << pruneSet
2291 << " in dataset are either not used at all, orserving exclusively p.d.f nodes that are now cached, disabling reading of these observables for TTree" << std::endl ;
2292 setArgStatus(pruneSet,false) ;
2293 }
2294}
2295
2296////////////////////////////////////////////////////////////////////////////////
2297/// Utility function that determines if all clients of object 'var'
2298/// appear in given list of cached nodes.
2299
2301{
2302 bool ret(true);
2303 bool anyClient(false);
2304
2305 for (const auto client : var->valueClients()) {
2306 anyClient = true ;
2307 if (!cacheList.find(client->GetName())) {
2308 // If client is not cached recurse
2310 }
2311 }
2312
2313 return anyClient?ret:false ;
2314}
2315
2316////////////////////////////////////////////////////////////////////////////////
2317
2319{
2320 _dstore->attachBuffers(extObs) ;
2321}
2322
2323////////////////////////////////////////////////////////////////////////////////
2324
2326{
2327 _dstore->resetBuffers() ;
2328}
2329
2330////////////////////////////////////////////////////////////////////////////////
2331
2333{
2334 return !_ownedComponents.empty();
2335}
2336
2337////////////////////////////////////////////////////////////////////////////////
2338
2340{
2341 auto i = _ownedComponents.find(name);
2342 return i==_ownedComponents.end() ? nullptr : i->second;
2343}
2344
2345////////////////////////////////////////////////////////////////////////////////
2346
2351
2352////////////////////////////////////////////////////////////////////////////////
2353/// Stream an object of class RooAbsData.
2354
2356{
2357 if (R__b.IsReading()) {
2358 R__b.ReadClassBuffer(RooAbsData::Class(),this);
2359 _namePtr = RooNameReg::instance().constPtr(GetName()) ;
2360
2361 // Convert on the fly to vector storage if that the current working default
2364 }
2365
2366 } else {
2367 R__b.WriteClassBuffer(RooAbsData::Class(),this);
2368 }
2369}
2370
2371////////////////////////////////////////////////////////////////////////////////
2372
2374{
2375 _dstore->checkInit() ;
2376}
2377
2378////////////////////////////////////////////////////////////////////////////////
2379/// Forward draw command to data store
2380
2382{
2383 if (_dstore) _dstore->Draw(option) ;
2384}
2385
2386////////////////////////////////////////////////////////////////////////////////
2387
2389{
2390 return _dstore->hasFilledCache() ;
2391}
2392
2393////////////////////////////////////////////////////////////////////////////////
2394/// Return a pointer to the TTree which stores the data. Returns a nullpointer
2395/// if vector-based storage is used. The RooAbsData remains owner of the tree.
2396/// GetClonedTree() can be used to get a tree even if the internal storage does not use one.
2397
2399{
2401 return static_cast<RooTreeDataStore&>(*_dstore).tree();
2402 } else {
2403 coutW(InputArguments) << "RooAbsData::tree(" << GetName() << ") WARNING: is not of StorageType::Tree. "
2404 << "Use GetClonedTree() instead or convert to tree storage." << std::endl;
2405 return nullptr;
2406 }
2407}
2408
2409////////////////////////////////////////////////////////////////////////////////
2410/// Return a clone of the TTree which stores the data or create such a tree
2411/// if vector storage is used. The user is responsible for deleting the tree
2412
2414{
2416 return static_cast<RooTreeDataStore&>(*_dstore).tree()->CloneTree();
2417 } else {
2418 RooTreeDataStore buffer(GetName(), GetTitle(), *get(), *_dstore);
2419 return buffer.tree()->CloneTree();
2420 }
2421}
2422
2423////////////////////////////////////////////////////////////////////////////////
2424/// Convert vector-based storage to tree-based storage
2425
2427{
2429 _dstore = std::make_unique<RooTreeDataStore>(GetName(), GetTitle(), _vars, *_dstore);
2431 }
2432}
2433
2434////////////////////////////////////////////////////////////////////////////////
2435/// If one of the TObject we have a referenced to is deleted, remove the
2436/// reference.
2437
2439{
2440 for(auto &iter : _ownedComponents) {
2441 if (iter.second == obj) {
2442 iter.second = nullptr;
2443 }
2444 }
2445}
2446
2447
2448////////////////////////////////////////////////////////////////////////////////
2449/// Sets the global observables stored in this data. A snapshot of the
2450/// observables will be saved.
2451/// \param[in] globalObservables The set of global observables to take a snapshot of.
2452
2453void RooAbsData::setGlobalObservables(RooArgSet const& globalObservables) {
2454 if(_globalObservables == nullptr) _globalObservables = std::make_unique<RooArgSet>();
2455 else _globalObservables->clear();
2456 globalObservables.snapshot(*_globalObservables);
2457 for(auto * arg : *_globalObservables) {
2458 arg->setAttribute("global",true);
2459 // Global observables are also always constant in fits
2460 if(auto lval = dynamic_cast<RooAbsRealLValue*>(arg)) lval->setConstant(true);
2461 if(auto lval = dynamic_cast<RooAbsCategoryLValue*>(arg)) lval->setConstant(true);
2462 }
2463}
2464
2465
2466////////////////////////////////////////////////////////////////////////////////
2467
2468void RooAbsData::SetName(const char* name)
2469{
2471 auto newPtr = RooNameReg::instance().constPtr(GetName()) ;
2472 if (newPtr != _namePtr) {
2473 //cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << std::endl;
2474 _namePtr = newPtr;
2477 }
2478}
2479
2480
2481
2482
2483////////////////////////////////////////////////////////////////////////////////
2484
2485void RooAbsData::SetNameTitle(const char *name, const char *title)
2486{
2487 TNamed::SetTitle(title) ;
2488 SetName(name);
2489}
2490
2491
2492
2493////////////////////////////////////////////////////////////////////////////////
2494/// Return sum of squared weights of this data.
2495
2497 const std::span<const double> eventWeights = getWeightBatch(0, numEntries(), /*sumW2=*/true);
2498 if (eventWeights.empty()) {
2499 return numEntries() * weightSquared();
2500 }
2501
2503 for (std::size_t i = 0; i < eventWeights.size(); ++i) {
2504 kahanWeight.AddIndexed(eventWeights[i], i);
2505 }
2506 return kahanWeight.Sum();
2507}
2508
2509
2510////////////////////////////////////////////////////////////////////////////////
2511/// Write information to retrieve data columns into `evalData.spans`.
2512/// All spans belonging to variables of this dataset are overwritten. Spans to other
2513/// variables remain intact.
2514/// \param begin Index of first event that ends up in the batch.
2515/// \param len Number of events in each batch.
2516RooAbsData::RealSpans RooAbsData::getBatches(std::size_t begin, std::size_t len) const {
2517 return store()->getBatches(begin, len);
2518}
2519
2520
2521RooAbsData::CategorySpans RooAbsData::getCategoryBatches(std::size_t first, std::size_t len) const {
2522 return store()->getCategoryBatches(first, len);
2523}
2524
2525////////////////////////////////////////////////////////////////////////////////
2526/// Create a TH2F histogram of the distribution of the specified variable
2527/// using this dataset. Apply any cuts to select which events are used.
2528/// The variable being plotted can either be contained directly in this
2529/// dataset, or else be a function of the variables in this dataset.
2530/// The histogram will be created using RooAbsReal::createHistogram() with
2531/// the name provided (with our dataset name prepended).
2532
2534 const char *name) const
2535{
2536 checkInit();
2537 const int nBins1 = var1.getBins()!=0 ? var1.getBins() : RooAbsRealLValue::DefaultNBins;
2538 const int nBins2 = var2.getBins()!=0 ? var2.getBins() : RooAbsRealLValue::DefaultNBins;
2539 return createHistogram(var1, var2, nBins1, nBins2, cuts, name);
2540}
2541
2542////////////////////////////////////////////////////////////////////////////////
2543/// Create a TH2F histogram of the distribution of the specified variable
2544/// using this dataset. Apply any cuts to select which events are used.
2545/// The variable being plotted can either be contained directly in this
2546/// dataset, or else be a function of the variables in this dataset.
2547/// The histogram will be created using RooAbsReal::createHistogram() with
2548/// the name provided (with our dataset name prepended).
2549
2551 const char *cuts, const char *name) const
2552{
2553 checkInit();
2554 static int counter(0);
2555
2556 std::unique_ptr<RooAbsReal> ownedPlotVarX;
2557 // Is this variable in our dataset?
2558 auto *plotVarX = static_cast<RooAbsReal *>(_vars.find(var1.GetName()));
2559 if (plotVarX == nullptr) {
2560 // Is this variable a client of our dataset?
2561 if (!var1.dependsOn(_vars)) {
2562 coutE(InputArguments) << GetName() << "::createHistogram: Argument " << var1.GetName()
2563 << " is not in dataset and is also not dependent on data set" << std::endl;
2564 return nullptr;
2565 }
2566
2567 // Clone derived variable
2568 ownedPlotVarX.reset(static_cast<RooAbsReal *>(var1.Clone()));
2569 plotVarX = ownedPlotVarX.get();
2570
2571 // Redirect servers of derived clone to internal ArgSet representing the data in this set
2572 plotVarX->redirectServers(const_cast<RooArgSet &>(_vars));
2573 }
2574
2575 std::unique_ptr<RooAbsReal> ownedPlotVarY;
2576 // Is this variable in our dataset?
2577 RooAbsReal *plotVarY = static_cast<RooAbsReal *>(_vars.find(var2.GetName()));
2578 if (plotVarY == nullptr) {
2579 // Is this variable a client of our dataset?
2580 if (!var2.dependsOn(_vars)) {
2581 coutE(InputArguments) << GetName() << "::createHistogram: Argument " << var2.GetName()
2582 << " is not in dataset and is also not dependent on data set" << std::endl;
2583 return nullptr;
2584 }
2585
2586 // Clone derived variable
2587 ownedPlotVarY.reset(static_cast<RooAbsReal *>(var2.Clone()));
2588 plotVarY = ownedPlotVarY.get();
2589
2590 // Redirect servers of derived clone to internal ArgSet representing the data in this set
2591 plotVarY->redirectServers(const_cast<RooArgSet &>(_vars));
2592 }
2593
2594 // Create selection formula if selection cuts are specified
2595 std::unique_ptr<RooFormula> select;
2596 if (nullptr != cuts && strlen(cuts)) {
2597 select = std::make_unique<RooFormula>(cuts, cuts, _vars);
2598 if (!select->ok()) {
2599 return nullptr;
2600 }
2601 }
2602
2603 std::stringstream histName;
2604 histName << GetName() << "_" << name << "_" << std::setw(8) << std::setfill('0') << std::hex << counter++;
2605
2606 // create the histogram
2607 auto *histogram =
2608 new TH2F(histName.str().c_str(), "Events", nx, var1.getMin(), var1.getMax(), ny, var2.getMin(), var2.getMax());
2609 if (!histogram) {
2610 coutE(DataHandling) << GetName() << "::createHistogram: unable to create a new histogram" << std::endl;
2611 return nullptr;
2612 }
2613
2614 // Dump contents
2615 int nevent = numEntries();
2616 for (int i = 0; i < nevent; ++i) {
2617 get(i);
2618
2619 if (select && select->eval() == 0)
2620 continue;
2621 histogram->Fill(plotVarX->getVal(), plotVarY->getVal(), weight());
2622 }
2623
2624 return histogram;
2625}
2626
2627////////////////////////////////////////////////////////////////////////////////
2628/// Convert a string to the value of the RooAbsData::ErrorType enum with the
2629/// same name.
2631{
2632 using Map = std::unordered_map<std::string, RooAbsData::ErrorType>;
2633 static Map enumMap{{"Poisson", RooAbsData::Poisson},
2634 {"SumW2", RooAbsData::SumW2},
2635 {"None", RooAbsData::None},
2636 {"Auto", RooAbsData::Auto},
2637 {"Expected", RooAbsData::Expected}};
2638 auto found = enumMap.find(name);
2639 if (found == enumMap.end()) {
2640 std::stringstream msg;
2641 msg << "Unsupported error type type passed to DataError(). "
2642 "Supported decay types are : \"Poisson\", \"SumW2\", \"Auto\", \"Expected\", and None.";
2643 throw std::invalid_argument(msg.str());
2644 }
2645 return found->second;
2646}
#define c(i)
Definition RSha256.hxx:101
#define coutI(a)
#define cxcoutI(a)
#define coutW(a)
#define oocoutE(o, a)
#define coutE(a)
float Size_t
Attribute size (float)
Definition RtypesCore.h:104
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define N
Option_t Option_t option
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 Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
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 result
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
char name[80]
Definition TGX11.cxx:148
float xmin
float ymin
float xmax
float ymax
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:141
const_iterator begin() const
const_iterator end() const
One-dimensional table.
Definition Roo1DTable.h:23
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
bool recursiveRedirectServers(const RooAbsCollection &newSet, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
const RefCountList_t & valueClients() const
List of all value clients of this object. Value clients receive value updates.
Definition RooAbsArg.h:139
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
Abstract base class for RooRealVar binning definitions.
virtual double averageBinWidth() const =0
Abstract base class for objects that represent a discrete value that can be set from the outside,...
A space to attach TBranches.
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.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for a data collection.
virtual RooAbsData::CategorySpans getCategoryBatches(std::size_t, std::size_t) const
virtual RooAbsData::RealSpans getBatches(std::size_t first, std::size_t len) const =0
Retrieve batches for all observables in this data store.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:56
virtual double weight() const =0
virtual double sumEntries() const =0
Return effective number of entries in dataset, i.e., sum all weights.
virtual const RooArgSet * get() const
Definition RooAbsData.h:100
RooRealVar * meanVar(const RooRealVar &var, const char *cutSpec=nullptr, const char *cutRange=nullptr) const
Create a RooRealVar containing the mean of observable 'var' in this dataset.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for detailed printing of object.
const TNamed * _namePtr
! De-duplicated name pointer. This will be equal for all objects with the same name.
Definition RooAbsData.h:364
static RooHist * createAndFillRooHist(RooAbsData const &absData, RooPlot const &frame, RooAbsRealLValue const &var, std::string cuts1, std::string cuts2, RooAbsData::PlotOpt opt, bool efficiency, double scaleFactor)
RooAbsData()
Default constructor.
static void setDefaultStorageType(StorageType s)
void SetName(const char *name) override
Set the name of the TNamed.
CategorySpans getCategoryBatches(std::size_t first=0, std::size_t len=std::numeric_limits< std::size_t >::max()) const
RooFit::OwningPtr< TMatrixDSym > corrcovMatrix(const RooArgList &vars, const char *cutSpec, const char *cutRange, bool corr) const
Return covariance matrix from data for given list of observables.
RooRealVar * dataRealVar(const char *methodname, const RooRealVar &extVar) const
Internal method to check if given RooRealVar maps to a RooRealVar in this dataset.
virtual Roo1DTable * table(const RooArgSet &catSet, const char *cuts="", const char *opts="") const
Construct table for product of categories in catSet.
std::map< RooFit::Detail::DataKey, std::span< const double > > RealSpans
Definition RooAbsData.h:132
void setGlobalObservables(RooArgSet const &globalObservables)
Sets the global observables stored in this data.
RooAbsDataStore * store()
Definition RooAbsData.h:76
void printClassName(std::ostream &os) const override
Print class name of dataset.
virtual void reset()
RooRealVar * rmsVar(const RooRealVar &var, const char *cutSpec=nullptr, const char *cutRange=nullptr) const
Create a RooRealVar containing the RMS of observable 'var' in this dataset.
double standMoment(const RooRealVar &var, double order, const char *cutSpec=nullptr, const char *cutRange=nullptr) const
Calculate standardized moment.
virtual RooPlot * statOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Add a box with statistics information to the specified frame.
void Draw(Option_t *option="") override
Forward draw command to data store.
virtual bool changeObservableName(const char *from, const char *to)
void printTitle(std::ostream &os) const override
Print title of dataset.
void RecursiveRemove(TObject *obj) override
If one of the TObject we have a referenced to is deleted, remove the reference.
virtual double weightError(ErrorType=Poisson) const
Return the symmetric error on the current weight.
Definition RooAbsData.h:113
void setDirtyProp(bool flag)
Control propagation of dirty flags from observables in dataset.
std::map< RooFit::Detail::DataKey, std::span< const RooAbsCategory::value_type > > CategorySpans
Definition RooAbsData.h:133
virtual TH1 * fillHistogram(TH1 *hist, const RooArgList &plotVars, const char *cuts="", const char *cutRange=nullptr) const
Loop over columns of our tree data and fill the input histogram.
void checkInit() const
virtual void setArgStatus(const RooArgSet &set, bool active)
virtual void cacheArgs(const RooAbsArg *owner, RooArgSet &varSet, const RooArgSet *nset=nullptr, bool skipZeroWeights=false)
Internal method – Cache given set of functions with data.
virtual RooPlot * plotEffOn(RooPlot *frame, const RooAbsCategoryLValue &effCat, PlotOpt o) const
Create and fill a histogram with the efficiency N[1] / ( N[1] + N[0] ), where N(1/0) is the number of...
RealSpans getBatches(std::size_t first=0, std::size_t len=std::numeric_limits< std::size_t >::max()) const
Write information to retrieve data columns into evalData.spans.
virtual void optimizeReadingWithCaching(RooAbsArg &arg, const RooArgSet &cacheList, const RooArgSet &keepObsList)
Prepare dataset for use with cached constant terms listed in 'cacheList' of expression 'arg'.
static StorageType defaultStorageType
Definition RooAbsData.h:298
virtual std::span< const double > getWeightBatch(std::size_t first, std::size_t len, bool sumW2=false) const =0
Return event weights of all events in range [first, first+len).
virtual std::unique_ptr< RooAbsData > reduceEng(const RooArgSet &varSubset, const RooFormulaVar *cutVar, const char *cutRange=nullptr, std::size_t nStart=0, std::size_t=std::numeric_limits< std::size_t >::max()) const =0
RooFit::OwningPtr< RooAbsData > reduce(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a reduced copy of this dataset.
double corrcov(const RooRealVar &x, const RooRealVar &y, const char *cutSpec, const char *cutRange, bool corr) const
Internal method to calculate single correlation and covariance elements.
bool allClientsCached(RooAbsArg *, const RooArgSet &)
Utility function that determines if all clients of object 'var' appear in given list of cached nodes.
std::unique_ptr< RooAbsDataStore > _dstore
Data storage implementation.
Definition RooAbsData.h:358
std::vector< std::unique_ptr< RooAbsData > > split(const RooAbsCategory &splitCat, bool createEmptyDataSets=false) const
Split the dataset into subsets based on states of a categorical variable in this dataset.
static TClass * Class()
void addOwnedComponent(const char *idxlabel, RooAbsData &data)
virtual void fill()
RooArgSet _vars
Dimensions of this data set.
Definition RooAbsData.h:355
bool canSplitFast() const
virtual RooPlot * plotAsymOn(RooPlot *frame, const RooAbsCategoryLValue &asymCat, PlotOpt o) const
Create and fill a histogram with the asymmetry N[+] - N[-] / ( N[+] + N[-] ), where N(+/-) is the num...
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
RooAbsData * getSimData(const char *idxstate)
void copyGlobalObservables(const RooAbsData &other)
virtual bool isNonPoissonWeighted() const
Definition RooAbsData.h:157
bool hasFilledCache() const
double sumEntriesW2() const
Return sum of squared weights of this data.
virtual void attachCache(const RooAbsArg *newOwner, const RooArgSet &cachedVars)
Internal method – Attach dataset copied with cache contents to copied instances of functions.
void convertToVectorStore()
Convert tree-based storage to vector-based storage.
bool getRange(const RooAbsRealLValue &var, double &lowest, double &highest, double marginFrac=0.0, bool symMode=false) const
Fill Doubles 'lowest' and 'highest' with the lowest and highest value of observable 'var' in this dat...
RooArgSet _cachedVars
! External variables cached with this data set
Definition RooAbsData.h:356
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
virtual void convertToTreeStore()
Convert vector-based storage to tree-based storage.
double moment(const RooRealVar &var, double order, const char *cutSpec=nullptr, const char *cutRange=nullptr) const
Calculate moment of requested order.
StorageType storageType
Definition RooAbsData.h:300
RooAbsData & operator=(const RooAbsData &other)
virtual RooFit::OwningPtr< RooAbsData > emptyClone(const char *newName=nullptr, const char *newTitle=nullptr, const RooArgSet *vars=nullptr, const char *wgtVarName=nullptr) const =0
void SetNameTitle(const char *name, const char *title) override
Set all the TNamed parameters (name and title).
void copyImpl(const RooAbsData &other, const char *newname)
virtual void resetCache()
Internal method – Remove cached function values.
Int_t defaultPrintContents(Option_t *opt) const override
Define default print options, for a given print style.
std::unique_ptr< RooArgSet > _globalObservables
Snapshot of global observables.
Definition RooAbsData.h:362
virtual double weightSquared() const =0
TTree * GetClonedTree() const
Return a clone of the TTree which stores the data or create such a tree if vector storage is used.
void attachBuffers(const RooArgSet &extObs)
std::map< std::string, RooAbsData * > _ownedComponents
Owned external components.
Definition RooAbsData.h:360
static StorageType getDefaultStorageType()
void Streamer(TBuffer &) override
Stream an object of class RooAbsData.
void resetBuffers()
virtual RooPlot * plotOnImpl(RooPlot *frame, PlotOpt o) const
Create and fill a histogram of the frame's variable and append it to the frame.
void printName(std::ostream &os) const override
Print name of dataset.
static ErrorType errorTypeFromString(std::string const &name)
Convert a string to the value of the RooAbsData::ErrorType enum with the same name.
const TTree * tree() const
Return a pointer to the TTree which stores the data.
TH1 * createHistogram(const char *name, const RooAbsRealLValue &xvar, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Calls createHistogram(const char *name, const RooAbsRealLValue& xvar, const RooLinkedList& argList) c...
void initializeVars(RooArgSet const &vars)
~RooAbsData() override
Destructor.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
TH1 * createHistogram(const char *name, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
static constexpr int DefaultNBins
Historical default number of bins, injected by routines that need a concrete bin count when a variabl...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
virtual const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const =0
Retrieve binning configuration with given name or default binning.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
const char * getPlotLabel() const
Get the label associated with the variable.
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:24
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:159
Object to represent discrete states.
Definition RooCategory.h:28
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
RooLinkedList const & subArgs() const
Return list of sub-arguments in this RooCmdArg.
Definition RooCmdArg.h:53
TObject * Clone(const char *newName=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooCmdArg.h:58
Configurable parser for RooCmdArg named arguments.
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
static void stripCmdList(RooLinkedList &cmdList, const char *cmdsToPurge)
Utility function that strips command names listed (comma separated) in cmdsToPurge from cmdList.
RooArgSet * getSet(const char *name, RooArgSet *set=nullptr) const
Return RooArgSet property registered with name 'name'.
bool defineSet(const char *name, const char *argName, int setNum, const RooArgSet *set=nullptr)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
void allowUndefined(bool flag=true)
If flag is true the processing of unrecognized RooCmdArgs is not considered an error.
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
TObject * getObject(const char *name, TObject *obj=nullptr) const
Return TObject property registered with name 'name'.
Combines several disjunct datasets into one.
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
Container class to hold unbinned data.
Definition RooDataSet.h:32
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Graphical representation of binned data based on the TGraphAsymmErrors class.
Definition RooHist.h:29
static TClass * Class()
void setRawEntries(double n)
Definition RooHist.h:74
bool hasIdenticalBinning(const RooHist &other) const
Return true if binning of this RooHist is identical to that of 'other'.
Definition RooHist.cxx:609
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
bool Replace(const TObject *oldArg, const TObject *newArg)
Replace object 'oldArg' in collection with new object 'newArg'.
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
TObject * find(const char *name) const
Return pointer to object with given name in collection.
virtual void Add(TObject *arg)
Connects several RooAbsCategory objects into a single category.
static RooNameReg & instance()
Return reference to singleton instance.
static void incrementRenameCounter()
The renaming counter has to be incremented every time a RooAbsArg is renamed.
@ kRenamedArg
TNamed flag to indicate that some RooAbsArg has been renamed (flag set in new name)
Definition RooNameReg.h:46
static constexpr double infinity()
Return internal infinity representation.
Definition RooNumber.h:25
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:43
void addObject(TObject *obj, Option_t *drawOptions="", bool invisible=false)
Add a generic object to this plot.
Definition RooPlot.cxx:326
TObject * findObject(const char *name, const TClass *tClass=nullptr) const
Find the named object in our list of items and return a pointer to it.
Definition RooPlot.cxx:902
double getFitRangeNEvt() const
Return the number of events in the fit range.
Definition RooPlot.h:139
RooAbsRealLValue * getPlotVar() const
Definition RooPlot.h:137
TAxis * GetXaxis() const
Definition RooPlot.cxx:1228
void updateNormVars(const RooArgSet &vars)
Install the given set of observables are reference normalization variables for this frame.
Definition RooPlot.cxx:311
Int_t GetNbinsX() const
Definition RooPlot.cxx:1232
void addPlotable(RooPlotable *plotable, Option_t *drawOptions="", bool invisible=false, bool refreshNorm=false)
Add the specified plotable object to our plot.
Definition RooPlot.cxx:476
double getFitRangeBinW() const
Return the bin width that is being used to normalise the PDF.
Definition RooPlot.h:142
void setYAxisLabel(const char *label)
Definition RooPlotable.h:29
A 'mix-in' base class that define the standard RooFit plotting and printing methods.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
Facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
TTree-backed data storage.
Implementation of RooAbsBinning that provides a uniform binning in 'n' bins between the range end poi...
Uses std::vector to store data columns.
Double_t GetXmax() const
Definition TAxis.h:142
Double_t GetXmin() const
Definition TAxis.h:141
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2428
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9293
virtual Int_t GetDimension() const
Definition TH1.h:527
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9436
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3489
virtual TArrayD * GetSumw2()
Definition TH1.h:560
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3823
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9253
2-D histogram with a float per channel (see TH1 documentation)
Definition TH2.h:345
Service class for 2-D histogram classes.
Definition TH2.h:30
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:45
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:73
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:50
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
A Pave (see TPave) with text, lines or/and boxes inside.
Definition TPaveText.h:21
Basic string class.
Definition TString.h:138
A TTree represents a columnar dataset.
Definition TTree.h:89
virtual TTree * CloneTree(Long64_t nentries=-1, Option_t *option="")
Create a clone of this tree and copy nentries.
Definition TTree.cxx:3173
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
RooCmdArg ZVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg SelectVars(const RooArgSet &vars)
RooCmdArg YVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg AxisLabel(const char *name)
RooCmdArg Binning(const RooAbsBinning &binning)
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
OwningPtr< T > makeOwningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
Definition Config.h:40
static const char * what
Definition stlLoader.cc:5
const char * cuts
Definition RooAbsData.h:311
const char * cutRange
Definition RooAbsData.h:315
const char * histName
Definition RooAbsData.h:316
const char * addToHistName
Definition RooAbsData.h:318
RooAbsData::ErrorType etype
Definition RooAbsData.h:314
RooAbsBinning * bins
Definition RooAbsData.h:313
Option_t * drawOptions
Definition RooAbsData.h:312
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2335