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