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