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