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