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