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