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