Logo ROOT  
Reference Guide
RooDataHist.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 RooDataHist.cxx
19\class RooDataHist
20\ingroup Roofitcore
21
22The RooDataHist is a container class to hold N-dimensional binned data. Each bin's central
23coordinates in N-dimensional space are represented by a RooArgSet containing RooRealVar, RooCategory
24or RooStringVar objects, thus data can be binned in real and/or discrete dimensions.
25
26There is an unbinned equivalent, RooDataSet.
27
28### Inspecting a datahist
29Inspect a datahist using Print() to get the coordinates and `weight()` to get the bin contents:
30```
31datahist->Print("V");
32datahist->get(0)->Print("V"); std::cout << "w=" << datahist->weight(0) << std::endl;
33datahist->get(1)->Print("V"); std::cout << "w=" << datahist->weight(1) << std::endl;
34...
35```
36
37### Plotting data.
38See RooAbsData::plotOn().
39
40### Creating a datahist using RDataFrame
41\see RooAbsDataHelper, rf408_RDataFrameToRooFit.C
42
43**/
44
45#include "RooDataHist.h"
46
47#include "RooFit.h"
48#include "Riostream.h"
49#include "RooMsgService.h"
51#include "RooAbsLValue.h"
52#include "RooArgList.h"
53#include "RooRealVar.h"
54#include "RooMath.h"
55#include "RooBinning.h"
56#include "RooPlot.h"
57#include "RooHistError.h"
58#include "RooCategory.h"
59#include "RooCmdConfig.h"
60#include "RooLinkedListIter.h"
61#include "RooTreeDataStore.h"
62#include "RooVectorDataStore.h"
63#include "RooTrace.h"
64#include "RooFormulaVar.h"
65#include "RooFormula.h"
66#include "RooUniformBinning.h"
67#include "RooSpan.h"
68
69#include "ROOT/StringUtils.hxx"
70
71#include "TAxis.h"
72#include "TH1.h"
73#include "TTree.h"
74#include "TBuffer.h"
75#include "TMath.h"
76#include "Math/Util.h"
77
78using namespace std;
79
81
82
83////////////////////////////////////////////////////////////////////////////////
84/// Default constructor
85
87{
89}
90
91
92
93////////////////////////////////////////////////////////////////////////////////
94/// Constructor of an empty data hist from a RooArgSet defining the dimensions
95/// of the data space. The range and number of bins in each dimensions are taken
96/// from getMin()getMax(),getBins() of each RooAbsArg representing that
97/// dimension.
98///
99/// For real dimensions, the fit range and number of bins can be set independently
100/// of the plot range and number of bins, but it is advisable to keep the
101/// ratio of the plot bin width and the fit bin width an integer value.
102/// For category dimensions, the fit ranges always comprises all defined states
103/// and each state is always has its individual bin
104///
105/// To effectively bin real dimensions with variable bin sizes,
106/// construct a RooThresholdCategory of the real dimension to be binned variably.
107/// Set the thresholds at the desired bin boundaries, and construct the
108/// data hist as a function of the threshold category instead of the real variable.
109RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgSet& vars, const char* binningName) :
110 RooAbsData(name,title,vars)
111{
112 // Initialize datastore
115
116 initialize(binningName) ;
117
119
120 appendToDir(this,kTRUE) ;
122}
123
124
125
126////////////////////////////////////////////////////////////////////////////////
127/// Constructor of a data hist from an existing data collection (binned or unbinned)
128/// The RooArgSet 'vars' defines the dimensions of the histogram.
129/// The range and number of bins in each dimensions are taken
130/// from getMin(), getMax(), getBins() of each argument passed.
131///
132/// For real dimensions, the fit range and number of bins can be set independently
133/// of the plot range and number of bins, but it is advisable to keep the
134/// ratio of the plot bin width and the fit bin width an integer value.
135/// For category dimensions, the fit ranges always comprises all defined states
136/// and each state is always has its individual bin
137///
138/// To effectively bin real dimensions with variable bin sizes,
139/// construct a RooThresholdCategory of the real dimension to be binned variably.
140/// Set the thresholds at the desired bin boundaries, and construct the
141/// data hist as a function of the threshold category instead of the real variable.
142///
143/// If the constructed data hist has less dimensions that in source data collection,
144/// all missing dimensions will be projected.
145
147 RooAbsData(name,title,vars)
148{
149 // Initialize datastore
152
153 initialize() ;
155
156 add(data,(const RooFormulaVar*)0,wgt) ;
157 appendToDir(this,kTRUE) ;
159}
160
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Constructor of a data hist from a map of TH1,TH2 or TH3 that are collated into a x+1 dimensional
165/// RooDataHist where the added dimension is a category that labels the input source as defined
166/// in the histMap argument. The state names used in histMap must correspond to predefined states
167/// 'indexCat'
168///
169/// The RooArgList 'vars' defines the dimensions of the histogram.
170/// The ranges and number of bins are taken from the input histogram and must be the same in all histograms
171
173 map<string,TH1*> histMap, Double_t wgt) :
174 RooAbsData(name,title,RooArgSet(vars,&indexCat))
175{
176 // Initialize datastore
179
180 importTH1Set(vars, indexCat, histMap, wgt, kFALSE) ;
181
184}
185
186
187
188////////////////////////////////////////////////////////////////////////////////
189/// Constructor of a data hist from a map of RooDataHists that are collated into a x+1 dimensional
190/// RooDataHist where the added dimension is a category that labels the input source as defined
191/// in the histMap argument. The state names used in histMap must correspond to predefined states
192/// 'indexCat'
193///
194/// The RooArgList 'vars' defines the dimensions of the histogram.
195/// The ranges and number of bins are taken from the input histogram and must be the same in all histograms
196
198 map<string,RooDataHist*> dhistMap, Double_t wgt) :
199 RooAbsData(name,title,RooArgSet(vars,&indexCat))
200{
201 // Initialize datastore
204
205 importDHistSet(vars, indexCat, dhistMap, wgt) ;
206
209}
210
211
212
213////////////////////////////////////////////////////////////////////////////////
214/// Constructor of a data hist from an TH1,TH2 or TH3
215/// The RooArgSet 'vars' defines the dimensions of the histogram. The ranges
216/// and number of bins are taken from the input histogram, and the corresponding
217/// values are set accordingly on the arguments in 'vars'
218
220 RooAbsData(name,title,vars)
221{
222 // Initialize datastore
225
226 // Check consistency in number of dimensions
227 if (vars.getSize() != hist->GetDimension()) {
228 coutE(InputArguments) << "RooDataHist::ctor(" << GetName() << ") ERROR: dimension of input histogram must match "
229 << "number of dimension variables" << endl ;
230 assert(0) ;
231 }
232
233 importTH1(vars,*hist,wgt, kFALSE) ;
234
237}
238
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// Constructor of a binned dataset from a RooArgSet defining the dimensions
243/// of the data space. The range and number of bins in each dimensions are taken
244/// from getMin() getMax(),getBins() of each RooAbsArg representing that
245/// dimension.
246///
247/// <table>
248/// <tr><th> Optional Argument <th> Effect
249/// <tr><td> Import(TH1&, Bool_t impDens) <td> Import contents of the given TH1/2/3 into this binned dataset. The
250/// ranges and binning of the binned dataset are automatically adjusted to
251/// match those of the imported histogram.
252///
253/// Please note: for TH1& with unequal binning _only_,
254/// you should decide if you want to import the absolute bin content,
255/// or the bin content expressed as density. The latter is default and will
256/// result in the same histogram as the original TH1. For certain types of
257/// bin contents (containing efficiencies, asymmetries, or ratio is general)
258/// you should import the absolute value and set impDens to kFALSE
259///
260///
261/// <tr><td> Weight(Double_t) <td> Apply given weight factor when importing histograms
262///
263/// <tr><td> Index(RooCategory&) <td> Prepare import of multiple TH1/1/2/3 into a N+1 dimensional RooDataHist
264/// where the extra discrete dimension labels the source of the imported histogram
265/// If the index category defines states for which no histogram is be imported
266/// the corresponding bins will be left empty.
267///
268/// <tr><td> Import(const char*, TH1&) <td> Import a THx to be associated with the given state name of the index category
269/// specified in Index(). If the given state name is not yet defined in the index
270/// category it will be added on the fly. The import command can be specified
271/// multiple times.
272/// <tr><td> Import(map<string,TH1*>&) <td> As above, but allows specification of many imports in a single operation
273/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of global observables to be stored in this RooDataHist.
274/// A snapshot of the passed RooArgSet is stored, meaning the values wont't change unexpectedly.
275/// </table>
276///
277
279 const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) :
280 RooAbsData(name,title,RooArgSet(vars,(RooAbsArg*)RooCmdConfig::decodeObjOnTheFly("RooDataHist::RooDataHist", "IndexCat",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)))
281{
282 // Initialize datastore
285
286 // Define configuration for this method
287 RooCmdConfig pc(Form("RooDataHist::ctor(%s)",GetName())) ;
288 pc.defineObject("impHist","ImportHisto",0) ;
289 pc.defineInt("impDens","ImportHisto",0) ;
290 pc.defineObject("indexCat","IndexCat",0) ;
291 pc.defineObject("impSliceHist","ImportHistoSlice",0,0,kTRUE) ; // array
292 pc.defineString("impSliceState","ImportHistoSlice",0,"",kTRUE) ; // array
293 pc.defineObject("impSliceDHist","ImportDataHistSlice",0,0,kTRUE) ; // array
294 pc.defineString("impSliceDState","ImportDataHistSlice",0,"",kTRUE) ; // array
295 pc.defineDouble("weight","Weight",0,1) ;
296 pc.defineObject("dummy1","ImportDataHistSliceMany",0) ;
297 pc.defineObject("dummy2","ImportHistoSliceMany",0) ;
298 pc.defineSet("glObs","GlobalObservables",0,0) ;
299 pc.defineMutex("ImportHisto","ImportHistoSlice","ImportDataHistSlice") ;
300 pc.defineDependency("ImportHistoSlice","IndexCat") ;
301 pc.defineDependency("ImportDataHistSlice","IndexCat") ;
302
304 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
305 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
306 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
307 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
308
309 // Process & check varargs
310 pc.process(l) ;
311 if (!pc.ok(kTRUE)) {
312 assert(0) ;
313 return ;
314 }
315
316 if(pc.getSet("glObs")) setGlobalObservables(*pc.getSet("glObs"));
317
318 TH1* impHist = static_cast<TH1*>(pc.getObject("impHist")) ;
319 Bool_t impDens = pc.getInt("impDens") ;
320 Double_t initWgt = pc.getDouble("weight") ;
321 const char* impSliceNames = pc.getString("impSliceState","",kTRUE) ;
322 const RooLinkedList& impSliceHistos = pc.getObjectList("impSliceHist") ;
323 RooCategory* indexCat = static_cast<RooCategory*>(pc.getObject("indexCat")) ;
324 const char* impSliceDNames = pc.getString("impSliceDState","",kTRUE) ;
325 const RooLinkedList& impSliceDHistos = pc.getObjectList("impSliceDHist") ;
326
327
328 if (impHist) {
329
330 // Initialize importing contents from TH1
331 importTH1(vars,*impHist,initWgt, impDens) ;
332
333 } else if (indexCat) {
334
335
336 if (impSliceHistos.GetSize()>0) {
337
338 // Initialize importing mapped set of TH1s
339 map<string,TH1*> hmap ;
340 TIter hiter = impSliceHistos.MakeIterator() ;
341 for (const auto& token : ROOT::Split(impSliceNames, ",")) {
342 auto histo = static_cast<TH1*>(hiter.Next());
343 assert(histo);
344 hmap[token] = histo;
345 }
346 importTH1Set(vars,*indexCat,hmap,initWgt,kFALSE) ;
347 } else {
348
349 // Initialize importing mapped set of RooDataHists
350 map<string,RooDataHist*> dmap ;
351 TIter hiter = impSliceDHistos.MakeIterator() ;
352 for (const auto& token : ROOT::Split(impSliceDNames, ",")) {
353 dmap[token] = (RooDataHist*) hiter.Next() ;
354 }
355 importDHistSet(vars,*indexCat,dmap,initWgt) ;
356 }
357
358
359 } else {
360
361 // Initialize empty
362 initialize() ;
363 appendToDir(this,kTRUE) ;
364
365 }
366
369
370}
371
372
373
374
375////////////////////////////////////////////////////////////////////////////////
376/// Import data from given TH1/2/3 into this RooDataHist
377
378void RooDataHist::importTH1(const RooArgList& vars, const TH1& histo, Double_t wgt, Bool_t doDensityCorrection)
379{
380 // Adjust binning of internal observables to match that of input THx
381 Int_t offset[3]{0, 0, 0};
382 adjustBinning(vars, histo, offset) ;
383
384 // Initialize internal data structure
385 initialize() ;
386 appendToDir(this,kTRUE) ;
387
388 // Define x,y,z as 1st, 2nd and 3rd observable
389 RooRealVar* xvar = (RooRealVar*) _vars.find(vars.at(0)->GetName()) ;
390 RooRealVar* yvar = (RooRealVar*) (vars.at(1) ? _vars.find(vars.at(1)->GetName()) : 0 ) ;
391 RooRealVar* zvar = (RooRealVar*) (vars.at(2) ? _vars.find(vars.at(2)->GetName()) : 0 ) ;
392
393 // Transfer contents
394 Int_t xmin(0),ymin(0),zmin(0) ;
395 RooArgSet vset(*xvar) ;
396 Double_t volume = xvar->getMax()-xvar->getMin() ;
397 xmin = offset[0] ;
398 if (yvar) {
399 vset.add(*yvar) ;
400 ymin = offset[1] ;
401 volume *= (yvar->getMax()-yvar->getMin()) ;
402 }
403 if (zvar) {
404 vset.add(*zvar) ;
405 zmin = offset[2] ;
406 volume *= (zvar->getMax()-zvar->getMin()) ;
407 }
408 //Double_t avgBV = volume / numEntries() ;
409// cout << "average bin volume = " << avgBV << endl ;
410
411 Int_t ix(0),iy(0),iz(0) ;
412 for (ix=0 ; ix < xvar->getBins() ; ix++) {
413 xvar->setBin(ix) ;
414 if (yvar) {
415 for (iy=0 ; iy < yvar->getBins() ; iy++) {
416 yvar->setBin(iy) ;
417 if (zvar) {
418 for (iz=0 ; iz < zvar->getBins() ; iz++) {
419 zvar->setBin(iz) ;
420 Double_t bv = doDensityCorrection ? binVolume(vset) : 1;
421 add(vset,bv*histo.GetBinContent(ix+1+xmin,iy+1+ymin,iz+1+zmin)*wgt,bv*TMath::Power(histo.GetBinError(ix+1+xmin,iy+1+ymin,iz+1+zmin)*wgt,2)) ;
422 }
423 } else {
424 Double_t bv = doDensityCorrection ? binVolume(vset) : 1;
425 add(vset,bv*histo.GetBinContent(ix+1+xmin,iy+1+ymin)*wgt,bv*TMath::Power(histo.GetBinError(ix+1+xmin,iy+1+ymin)*wgt,2)) ;
426 }
427 }
428 } else {
429 Double_t bv = doDensityCorrection ? binVolume(vset) : 1 ;
430 add(vset,bv*histo.GetBinContent(ix+1+xmin)*wgt,bv*TMath::Power(histo.GetBinError(ix+1+xmin)*wgt,2)) ;
431 }
432 }
433
434}
435
436namespace {
437bool checkConsistentAxes(const TH1* first, const TH1* second) {
438 return first->GetDimension() == second->GetDimension()
439 && first->GetNbinsX() == second->GetNbinsX()
440 && first->GetNbinsY() == second->GetNbinsY()
441 && first->GetNbinsZ() == second->GetNbinsZ()
442 && first->GetXaxis()->GetXmin() == second->GetXaxis()->GetXmin()
443 && first->GetXaxis()->GetXmax() == second->GetXaxis()->GetXmax()
444 && (first->GetNbinsY() == 1 || (first->GetYaxis()->GetXmin() == second->GetYaxis()->GetXmin()
445 && first->GetYaxis()->GetXmax() == second->GetYaxis()->GetXmax() ) )
446 && (first->GetNbinsZ() == 1 || (first->GetZaxis()->GetXmin() == second->GetZaxis()->GetXmin()
447 && first->GetZaxis()->GetXmax() == second->GetZaxis()->GetXmax() ) );
448}
449}
450
451
452////////////////////////////////////////////////////////////////////////////////
453/// Import data from given set of TH1/2/3 into this RooDataHist. The category indexCat labels the sources
454/// in the constructed RooDataHist. The stl map provides the mapping between the indexCat state labels
455/// and the import source
456
457void RooDataHist::importTH1Set(const RooArgList& vars, RooCategory& indexCat, map<string,TH1*> hmap, Double_t wgt, Bool_t doDensityCorrection)
458{
459 RooCategory* icat = (RooCategory*) _vars.find(indexCat.GetName()) ;
460
461 TH1* histo(0) ;
462 Bool_t init(kFALSE) ;
463 for (const auto& hiter : hmap) {
464 // Store pointer to first histogram from which binning specification will be taken
465 if (!histo) {
466 histo = hiter.second;
467 } else {
468 if (!checkConsistentAxes(histo, hiter.second)) {
469 coutE(InputArguments) << "Axes of histogram " << hiter.second->GetName() << " are not consistent with first processed "
470 << "histogram " << histo->GetName() << std::endl;
471 throw std::invalid_argument("Axes of inputs for RooDataHist are inconsistent");
472 }
473 }
474 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
475 if (!indexCat.hasLabel(hiter.first)) {
476 indexCat.defineType(hiter.first) ;
477 coutI(InputArguments) << "RooDataHist::importTH1Set(" << GetName() << ") defining state \"" << hiter.first << "\" in index category " << indexCat.GetName() << endl ;
478 }
479 if (!icat->hasLabel(hiter.first)) {
480 icat->defineType(hiter.first) ;
481 }
482 }
483
484 // Check consistency in number of dimensions
485 if (histo && (vars.getSize() != histo->GetDimension())) {
486 coutE(InputArguments) << "RooDataHist::importTH1Set(" << GetName() << "): dimension of input histogram must match "
487 << "number of continuous variables" << endl ;
488 throw std::invalid_argument("Inputs histograms for RooDataHist are not compatible with dimensions of variables.");
489 }
490
491 // Copy bins and ranges from THx to dimension observables
492 Int_t offset[3] ;
493 adjustBinning(vars,*histo,offset) ;
494
495 // Initialize internal data structure
496 if (!init) {
497 initialize() ;
498 appendToDir(this,kTRUE) ;
499 init = kTRUE ;
500 }
501
502 // Define x,y,z as 1st, 2nd and 3rd observable
503 RooRealVar* xvar = (RooRealVar*) _vars.find(vars.at(0)->GetName()) ;
504 RooRealVar* yvar = (RooRealVar*) (vars.at(1) ? _vars.find(vars.at(1)->GetName()) : 0 ) ;
505 RooRealVar* zvar = (RooRealVar*) (vars.at(2) ? _vars.find(vars.at(2)->GetName()) : 0 ) ;
506
507 // Transfer contents
508 Int_t xmin(0),ymin(0),zmin(0) ;
509 RooArgSet vset(*xvar) ;
510 Double_t volume = xvar->getMax()-xvar->getMin() ;
511 xmin = offset[0] ;
512 if (yvar) {
513 vset.add(*yvar) ;
514 ymin = offset[1] ;
515 volume *= (yvar->getMax()-yvar->getMin()) ;
516 }
517 if (zvar) {
518 vset.add(*zvar) ;
519 zmin = offset[2] ;
520 volume *= (zvar->getMax()-zvar->getMin()) ;
521 }
522 Double_t avgBV = volume / numEntries() ;
523
524 Int_t ic(0),ix(0),iy(0),iz(0) ;
525 for (ic=0 ; ic < icat->numBins(0) ; ic++) {
526 icat->setBin(ic) ;
527 histo = hmap[icat->getCurrentLabel()] ;
528 for (ix=0 ; ix < xvar->getBins() ; ix++) {
529 xvar->setBin(ix) ;
530 if (yvar) {
531 for (iy=0 ; iy < yvar->getBins() ; iy++) {
532 yvar->setBin(iy) ;
533 if (zvar) {
534 for (iz=0 ; iz < zvar->getBins() ; iz++) {
535 zvar->setBin(iz) ;
536 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
537 add(vset,bv*histo->GetBinContent(ix+1+xmin,iy+1+ymin,iz+1+zmin)*wgt,bv*TMath::Power(histo->GetBinError(ix+1+xmin,iy+1+ymin,iz+1+zmin)*wgt,2)) ;
538 }
539 } else {
540 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
541 add(vset,bv*histo->GetBinContent(ix+1+xmin,iy+1+ymin)*wgt,bv*TMath::Power(histo->GetBinError(ix+1+xmin,iy+1+ymin)*wgt,2)) ;
542 }
543 }
544 } else {
545 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
546 add(vset,bv*histo->GetBinContent(ix+1+xmin)*wgt,bv*TMath::Power(histo->GetBinError(ix+1+xmin)*wgt,2)) ;
547 }
548 }
549 }
550
551}
552
553
554
555////////////////////////////////////////////////////////////////////////////////
556/// Import data from given set of TH1/2/3 into this RooDataHist. The category indexCat labels the sources
557/// in the constructed RooDataHist. The stl map provides the mapping between the indexCat state labels
558/// and the import source
559
560void RooDataHist::importDHistSet(const RooArgList& /*vars*/, RooCategory& indexCat, std::map<std::string,RooDataHist*> dmap, Double_t initWgt)
561{
562 RooCategory* icat = (RooCategory*) _vars.find(indexCat.GetName()) ;
563
564 for (const auto& diter : dmap) {
565
566 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
567 if (!indexCat.hasLabel(diter.first)) {
568 indexCat.defineType(diter.first) ;
569 coutI(InputArguments) << "RooDataHist::importDHistSet(" << GetName() << ") defining state \"" << diter.first << "\" in index category " << indexCat.GetName() << endl ;
570 }
571 if (!icat->hasLabel(diter.first)) {
572 icat->defineType(diter.first) ;
573 }
574 }
575
576 initialize() ;
577 appendToDir(this,kTRUE) ;
578
579
580 for (const auto& diter : dmap) {
581
582 RooDataHist* dhist = diter.second ;
583
584 icat->setLabel(diter.first.c_str()) ;
585
586 // Transfer contents
587 for (Int_t i=0 ; i<dhist->numEntries() ; i++) {
588 _vars = *dhist->get(i) ;
589 add(_vars,dhist->weight()*initWgt, pow(dhist->weightError(SumW2),2) ) ;
590 }
591
592 }
593}
594
595////////////////////////////////////////////////////////////////////////////////
596/// Helper doing the actual work of adjustBinning().
597
598void RooDataHist::_adjustBinning(RooRealVar &theirVar, const TAxis &axis,
599 RooRealVar *ourVar, Int_t *offset)
600{
601 if (!dynamic_cast<RooRealVar*>(static_cast<RooAbsArg*>(ourVar))) {
602 coutE(InputArguments) << "RooDataHist::adjustBinning(" << GetName() << ") ERROR: dimension " << ourVar->GetName() << " must be real" << endl ;
603 assert(0) ;
604 }
605
606 const double xlo = theirVar.getMin();
607 const double xhi = theirVar.getMax();
608
609 if (axis.GetXbins()->GetArray()) {
610 RooBinning xbins(axis.GetNbins(), axis.GetXbins()->GetArray());
611
612 const double tolerance = 1e-6 * xbins.averageBinWidth();
613
614 // Adjust xlo/xhi to nearest boundary
615 const double xloAdj = xbins.binLow(xbins.binNumber(xlo + tolerance));
616 const double xhiAdj = xbins.binHigh(xbins.binNumber(xhi - tolerance));
617 xbins.setRange(xloAdj, xhiAdj);
618
619 theirVar.setBinning(xbins);
620
621 if (true || fabs(xloAdj - xlo) > tolerance || fabs(xhiAdj - xhi) > tolerance) {
622 coutI(DataHandling)<< "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << ourVar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl;
623 }
624
625 ourVar->setBinning(xbins);
626
627 if (offset) {
628 *offset = xbins.rawBinNumber(xloAdj + tolerance);
629 }
630 } else {
631 RooBinning xbins(axis.GetXmin(), axis.GetXmax());
632 xbins.addUniform(axis.GetNbins(), axis.GetXmin(), axis.GetXmax());
633
634 const double tolerance = 1e-6 * xbins.averageBinWidth();
635
636 // Adjust xlo/xhi to nearest boundary
637 const double xloAdj = xbins.binLow(xbins.binNumber(xlo + tolerance));
638 const double xhiAdj = xbins.binHigh(xbins.binNumber(xhi - tolerance));
639 xbins.setRange(xloAdj, xhiAdj);
640 theirVar.setRange(xloAdj, xhiAdj);
641
642 if (fabs(xloAdj - xlo) > tolerance || fabs(xhiAdj - xhi) > tolerance) {
643 coutI(DataHandling)<< "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << ourVar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl;
644 }
645
646 RooUniformBinning xbins2(xloAdj, xhiAdj, xbins.numBins());
647 ourVar->setBinning(xbins2);
648
649 if (offset) {
650 *offset = xbins.rawBinNumber(xloAdj + tolerance);
651 }
652 }
653}
654
655////////////////////////////////////////////////////////////////////////////////
656/// Adjust binning specification on first and optionally second and third
657/// observable to binning in given reference TH1. Used by constructors
658/// that import data from an external TH1.
659/// Both the variables in vars and in this RooDataHist are adjusted.
660/// @param vars List with variables that are supposed to have their binning adjusted.
661/// @param href Reference histogram that dictates the binning
662/// @param offset If not nullptr, a possible bin count offset for the axes x,y,z is saved here as Int_t[3]
663
664void RooDataHist::adjustBinning(const RooArgList& vars, const TH1& href, Int_t* offset)
665{
666 auto xvar = static_cast<RooRealVar*>( _vars.find(*vars.at(0)) );
667 _adjustBinning(*static_cast<RooRealVar*>(vars.at(0)), *href.GetXaxis(), xvar, offset ? &offset[0] : nullptr);
668
669 if (vars.at(1)) {
670 auto yvar = static_cast<RooRealVar*>(_vars.find(*vars.at(1)));
671 if (yvar)
672 _adjustBinning(*static_cast<RooRealVar*>(vars.at(1)), *href.GetYaxis(), yvar, offset ? &offset[1] : nullptr);
673 }
674
675 if (vars.at(2)) {
676 auto zvar = static_cast<RooRealVar*>(_vars.find(*vars.at(2)));
677 if (zvar)
678 _adjustBinning(*static_cast<RooRealVar*>(vars.at(2)), *href.GetZaxis(), zvar, offset ? &offset[2] : nullptr);
679 }
680
681}
682
683
684namespace {
685/// Clone external weight arrays, unless the external array is nullptr.
686void cloneArray(double*& ours, const double* theirs, std::size_t n) {
687 if (ours) delete[] ours;
688 ours = nullptr;
689 if (!theirs) return;
690 ours = new double[n];
691 std::copy(theirs, theirs+n, ours);
692}
693
694/// Allocate and initialise an array with desired size and values.
695void initArray(double*& arr, std::size_t n, double val) {
696 if (arr) delete[] arr;
697 arr = nullptr;
698 if (n == 0) return;
699 arr = new double[n];
700 std::fill(arr, arr+n, val);
701}
702}
703
704
705////////////////////////////////////////////////////////////////////////////////
706/// Initialization procedure: allocate weights array, calculate
707/// multipliers needed for N-space to 1-dim array jump table,
708/// and fill the internal tree with all bin center coordinates
709
710void RooDataHist::initialize(const char* binningName, Bool_t fillTree)
711{
712 _lvvars.clear();
713 _lvbins.clear();
714
715 // Fill array of LValue pointers to variables
716 for (unsigned int i = 0; i < _vars.size(); ++i) {
717 if (binningName) {
718 RooRealVar* rrv = dynamic_cast<RooRealVar*>(_vars[i]);
719 if (rrv) {
720 rrv->setBinning(rrv->getBinning(binningName));
721 }
722 }
723
724 auto lvarg = dynamic_cast<RooAbsLValue*>(_vars[i]);
725 assert(lvarg);
726 _lvvars.push_back(lvarg);
727
728 const RooAbsBinning* binning = lvarg->getBinningPtr(0);
729 _lvbins.emplace_back(binning ? binning->clone() : nullptr);
730 }
731
732
733 // Allocate coefficients array
734 _idxMult.resize(_vars.getSize()) ;
735
736 _arrSize = 1 ;
737 unsigned int n = 0u;
738 for (const auto var : _vars) {
739 auto arg = dynamic_cast<const RooAbsLValue*>(var);
740 assert(arg);
741
742 // Calculate sub-index multipliers for master index
743 for (unsigned int i = 0u; i<n; i++) {
744 _idxMult[i] *= arg->numBins() ;
745 }
746 _idxMult[n++] = 1 ;
747
748 // Calculate dimension of weight array
749 _arrSize *= arg->numBins() ;
750 }
751
752 // Allocate and initialize weight array if necessary
753 if (!_wgt) {
754 initArray(_wgt, _arrSize, 0.);
755 delete[] _errLo; _errLo = nullptr;
756 delete[] _errHi; _errHi = nullptr;
757 delete[] _sumw2; _sumw2 = nullptr;
758 initArray(_binv, _arrSize, 0.);
759
760 // Refill array pointers in data store when reading
761 // from Streamer
762 if (!fillTree) {
764 }
765 }
766
767 if (!fillTree) return ;
768
769 // Fill TTree with bin center coordinates
770 // Calculate plot bins of components from master index
771
772 for (Int_t ibin=0 ; ibin < _arrSize ; ibin++) {
773 Int_t j(0), idx(0), tmp(ibin) ;
774 Double_t theBinVolume(1) ;
775 for (auto arg2 : _lvvars) {
776 idx = tmp / _idxMult[j] ;
777 tmp -= idx*_idxMult[j++] ;
778 arg2->setBin(idx) ;
779 theBinVolume *= arg2->getBinWidth(idx) ;
780 }
781 _binv[ibin] = theBinVolume ;
782
783 fill() ;
784 }
785
786
787}
788
789
790////////////////////////////////////////////////////////////////////////////////
791
793{
794 if (!_binbounds.empty()) return;
795 for (auto& it : _lvbins) {
796 _binbounds.push_back(std::vector<Double_t>());
797 if (it) {
798 std::vector<Double_t>& bounds = _binbounds.back();
799 bounds.reserve(2 * it->numBins());
800 for (Int_t i = 0; i < it->numBins(); ++i) {
801 bounds.push_back(it->binLow(i));
802 bounds.push_back(it->binHigh(i));
803 }
804 }
805 }
806}
807
808
809////////////////////////////////////////////////////////////////////////////////
810/// Copy constructor
811
812RooDataHist::RooDataHist(const RooDataHist& other, const char* newname) :
813 RooAbsData(other,newname), RooDirItem(), _arrSize(other._arrSize), _idxMult(other._idxMult), _pbinvCache(other._pbinvCache)
814{
815 // Allocate and initialize weight array
816 assert(_arrSize == other._arrSize);
817 cloneArray(_wgt, other._wgt, other._arrSize);
818 cloneArray(_errLo, other._errLo, other._arrSize);
819 cloneArray(_errHi, other._errHi, other._arrSize);
820 cloneArray(_binv, other._binv, other._arrSize);
821 cloneArray(_sumw2, other._sumw2, other._arrSize);
822
823 // Fill array of LValue pointers to variables
824 for (const auto rvarg : _vars) {
825 auto lvarg = dynamic_cast<RooAbsLValue*>(rvarg);
826 assert(lvarg);
827 _lvvars.push_back(lvarg);
828 const RooAbsBinning* binning = lvarg->getBinningPtr(0);
829 _lvbins.emplace_back(binning ? binning->clone() : 0) ;
830 }
831
833
834 appendToDir(this,kTRUE) ;
835}
836
837
838
839////////////////////////////////////////////////////////////////////////////////
840/// Constructor of a data hist from (part of) an existing data hist. The dimensions
841/// of the data set are defined by the 'vars' RooArgSet, which can be identical
842/// to 'dset' dimensions, or a subset thereof. Reduced dimensions will be projected
843/// in the output data hist. The optional 'cutVar' formula variable can used to
844/// select the subset of bins to be copied.
845///
846/// For most uses the RooAbsData::reduce() wrapper function, which uses this constructor,
847/// is the most convenient way to create a subset of an existing data
848
850 const RooFormulaVar* cutVar, const char* cutRange, Int_t nStart, Int_t nStop, Bool_t copyCache) :
851 RooAbsData(name,title,varSubset)
852{
853 // Initialize datastore
854 _dstore = new RooTreeDataStore(name,title,*h->_dstore,_vars,cutVar,cutRange,nStart,nStop,copyCache) ;
855
856 initialize(0,kFALSE) ;
857
858 // Copy weight array etc
859 assert(_arrSize == h->_arrSize);
860 cloneArray(_wgt, h->_wgt, _arrSize);
861 cloneArray(_errLo, h->_errLo, _arrSize);
862 cloneArray(_errHi, h->_errHi, _arrSize);
863 cloneArray(_binv, h->_binv, _arrSize);
864 cloneArray(_sumw2, h->_sumw2, _arrSize);
865
867
868 appendToDir(this,kTRUE) ;
870}
871
872
873////////////////////////////////////////////////////////////////////////////////
874/// Construct a clone of this dataset that contains only the cached variables
875
876RooAbsData* RooDataHist::cacheClone(const RooAbsArg* newCacheOwner, const RooArgSet* newCacheVars, const char* newName)
877{
878 checkInit() ;
879
880 RooDataHist* dhist = new RooDataHist(newName?newName:GetName(),GetTitle(),this,*get(),0,0,0,2000000000,kTRUE) ;
881
882 RooArgSet* selCacheVars = (RooArgSet*) newCacheVars->selectCommon(dhist->_cachedVars) ;
883 dhist->attachCache(newCacheOwner, *selCacheVars) ;
884 delete selCacheVars ;
885
886 return dhist ;
887}
888
889
890
891////////////////////////////////////////////////////////////////////////////////
892/// Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods
893
894RooAbsData* RooDataHist::reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange,
895 std::size_t nStart, std::size_t nStop, Bool_t /*copyCache*/)
896{
897 checkInit() ;
898 RooArgSet* myVarSubset = (RooArgSet*) _vars.selectCommon(varSubset) ;
899 RooDataHist *rdh = new RooDataHist(GetName(), GetTitle(), *myVarSubset) ;
900 delete myVarSubset ;
901
902 RooFormulaVar* cloneVar = 0;
903 RooArgSet* tmp(0) ;
904 if (cutVar) {
905 // Deep clone cutVar and attach clone to this dataset
906 tmp = (RooArgSet*) RooArgSet(*cutVar).snapshot() ;
907 if (!tmp) {
908 coutE(DataHandling) << "RooDataHist::reduceEng(" << GetName() << ") Couldn't deep-clone cut variable, abort," << endl ;
909 return 0 ;
910 }
911 cloneVar = (RooFormulaVar*) tmp->find(*cutVar) ;
912 cloneVar->attachDataSet(*this) ;
913 }
914
915 Double_t lo,hi ;
916 const std::size_t nevt = nStop < static_cast<std::size_t>(numEntries()) ? nStop : static_cast<std::size_t>(numEntries());
917 for (auto i=nStart; i<nevt ; i++) {
918 const RooArgSet* row = get(i) ;
919
920 Bool_t doSelect(kTRUE) ;
921 if (cutRange) {
922 for (const auto arg : *row) {
923 if (!arg->inRange(cutRange)) {
924 doSelect = kFALSE ;
925 break ;
926 }
927 }
928 }
929 if (!doSelect) continue ;
930
931 if (!cloneVar || cloneVar->getVal()) {
932 weightError(lo,hi,SumW2) ;
933 rdh->add(*row,weight(),lo*lo) ;
934 }
935 }
936
937 if (cloneVar) {
938 delete tmp ;
939 }
940
941 return rdh ;
942}
943
944
945
946////////////////////////////////////////////////////////////////////////////////
947/// Destructor
948
950{
951 delete[] _wgt;
952 delete[] _errLo;
953 delete[] _errHi;
954 delete[] _sumw2;
955 delete[] _binv;
956
957 removeFromDir(this) ;
959}
960
961
962
963
964////////////////////////////////////////////////////////////////////////////////
965/// Calculate bin number of the given coordinates. If only a subset of the internal
966/// coordinates are passed, the missing coordinates are taken at their current value.
967/// \param[in] coord Variables that are representing the coordinates.
968/// \param[in] fast If the variables in `coord` and the ones of the data hist have the
969/// same size and layout, `fast` can be set to skip checking that all variables are
970/// present in `coord`.
972 checkInit() ;
973 return calcTreeIndex(coord, fast);
974}
975
976
977
978
979////////////////////////////////////////////////////////////////////////////////
980/// Calculate the bin index corresponding to the coordinates passed as argument.
981/// \param[in] coords Coordinates. If `fast == false`, these can be partial.
982/// \param[in] fast Promise that the coordinates in `coords` have the same order
983/// as the internal coordinates. In this case, values are looked up only by index.
984std::size_t RooDataHist::calcTreeIndex(const RooAbsCollection& coords, bool fast) const
985{
986 // With fast, caller promises that layout of "coords" is identical to our internal "vars"
987 assert(!fast || coords.hasSameLayout(_vars));
988
989 if (&_vars == &coords)
990 fast = true;
991
992 std::size_t masterIdx = 0;
993
994 for (unsigned int i=0; i < _vars.size(); ++i) {
995 const RooAbsArg* internalVar = _vars[i];
996 const RooAbsBinning* binning = _lvbins[i].get();
997
998 // Find the variable that we need values from.
999 // That's either the variable directly from the external coordinates
1000 // or we find the external one that has the same name as "internalVar".
1001 const RooAbsArg* theVar = fast ? coords[i] : coords.find(*internalVar);
1002 if (!theVar) {
1003 // Variable is not in external coordinates. Use current internal value.
1004 theVar = internalVar;
1005 }
1006 // If fast is on, users promise that the sets have the same layout
1007 assert(!fast || strcmp(internalVar->GetName(), theVar->GetName()) == 0);
1008
1009 if (binning) {
1010 assert(dynamic_cast<const RooAbsReal*>(theVar));
1011 const double val = static_cast<const RooAbsReal*>(theVar)->getVal();
1012 masterIdx += _idxMult[i] * binning->binNumber(val);
1013 } else {
1014 // We are a category. No binning.
1015 assert(dynamic_cast<const RooAbsCategoryLValue*>(theVar));
1016 auto cat = static_cast<const RooAbsCategoryLValue*>(theVar);
1017 masterIdx += _idxMult[i] * cat->getBin(static_cast<const char*>(nullptr));
1018 }
1019 }
1020
1021 return masterIdx ;
1022}
1023
1024
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// Debug stuff, should go...
1028
1030{
1031 cout << "_arrSize = " << _arrSize << endl ;
1032 for (Int_t i=0 ; i < _arrSize ; i++) {
1033 cout << "wgt[" << i << "] = " << _wgt[i]
1034 << "\tsumw2[" << i << "] = " << (_sumw2 ? _sumw2[i] : -1.)
1035 << "\tvol[" << i << "] = " << _binv[i] << endl ;
1036 }
1037}
1038
1039
1040
1041////////////////////////////////////////////////////////////////////////////////
1042/// Back end function to plotting functionality. Plot RooDataHist on given
1043/// frame in mode specified by plot options 'o'. The main purpose of
1044/// this function is to match the specified binning on 'o' to the
1045/// internal binning of the plot observable in this RooDataHist.
1046/// \see RooAbsData::plotOn() for plotting options.
1048{
1049 checkInit() ;
1050 if (o.bins) return RooAbsData::plotOn(frame,o) ;
1051
1052 if(0 == frame) {
1053 coutE(InputArguments) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << endl;
1054 return 0;
1055 }
1057 if(0 == var) {
1058 coutE(InputArguments) << ClassName() << "::" << GetName()
1059 << ":plotOn: frame does not specify a plot variable" << endl;
1060 return 0;
1061 }
1062
1063 RooRealVar* dataVar = (RooRealVar*) _vars.find(*var) ;
1064 if (!dataVar) {
1065 coutE(InputArguments) << ClassName() << "::" << GetName()
1066 << ":plotOn: dataset doesn't contain plot frame variable" << endl;
1067 return 0;
1068 }
1069
1070 o.bins = &dataVar->getBinning() ;
1072 return RooAbsData::plotOn(frame,o) ;
1073}
1074
1075////////////////////////////////////////////////////////////////////////////////
1076/// A faster version of RooDataHist::weight that assumes the passed arguments
1077/// are aligned with the histogram variables.
1078/// \param[in] bin Coordinates for which the weight should be calculated.
1079/// Has to be aligned with the internal histogram variables.
1080/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1081/// used for the interpolation. If zero, the bare weight for
1082/// the bin enclosing the coordinatesis returned.
1083/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1084/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1085/// underflow bins are assumed to have weight zero and
1086/// overflow bins have weight one. Otherwise, the
1087/// histogram is mirrored at the boundaries for the
1088/// interpolation.
1089
1090double RooDataHist::weightFast(const RooArgSet& bin, Int_t intOrder, Bool_t correctForBinSize, Bool_t cdfBoundaries)
1091{
1092 checkInit() ;
1093
1094 // Handle illegal intOrder values
1095 if (intOrder<0) {
1096 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") ERROR: interpolation order must be positive" << endl ;
1097 return 0 ;
1098 }
1099
1100 // Handle no-interpolation case
1101 if (intOrder==0) {
1102 const auto idx = calcTreeIndex(bin, true);
1103 if (correctForBinSize) {
1104 return get_wgt(idx) / _binv[idx];
1105 } else {
1106 return get_wgt(idx);
1107 }
1108 }
1109
1110 // Handle all interpolation cases
1111 return weightInterpolated(bin, intOrder, correctForBinSize, cdfBoundaries);
1112}
1113
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Return the weight at given coordinates with optional interpolation.
1117/// \param[in] bin Coordinates for which the weight should be calculated.
1118/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1119/// used for the interpolation. If zero, the bare weight for
1120/// the bin enclosing the coordinatesis returned.
1121/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1122/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1123/// underflow bins are assumed to have weight zero and
1124/// overflow bins have weight one. Otherwise, the
1125/// histogram is mirrored at the boundaries for the
1126/// interpolation.
1127/// \param[in] oneSafe Ignored.
1128
1129Double_t RooDataHist::weight(const RooArgSet& bin, Int_t intOrder, Bool_t correctForBinSize, Bool_t cdfBoundaries, Bool_t /*oneSafe*/)
1130{
1131 checkInit() ;
1132
1133 // Handle illegal intOrder values
1134 if (intOrder<0) {
1135 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") ERROR: interpolation order must be positive" << endl ;
1136 return 0 ;
1137 }
1138
1139 // Handle no-interpolation case
1140 if (intOrder==0) {
1141 const auto idx = calcTreeIndex(bin, false);
1142 if (correctForBinSize) {
1143 return get_wgt(idx) / _binv[idx];
1144 } else {
1145 return get_wgt(idx);
1146 }
1147 }
1148
1149 // Handle all interpolation cases
1150 _vars.assignValueOnly(bin) ;
1151
1152 return weightInterpolated(_vars, intOrder, correctForBinSize, cdfBoundaries);
1153}
1154
1155
1156////////////////////////////////////////////////////////////////////////////////
1157/// Return the weight at given coordinates with interpolation.
1158/// \param[in] bin Coordinates for which the weight should be calculated.
1159/// Has to be aligned with the internal histogram variables.
1160/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1161/// used for the interpolation.
1162/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1163/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1164/// underflow bins are assumed to have weight zero and
1165/// overflow bins have weight one. Otherwise, the
1166/// histogram is mirrored at the boundaries for the
1167/// interpolation.
1168
1169double RooDataHist::weightInterpolated(const RooArgSet& bin, int intOrder, bool correctForBinSize, bool cdfBoundaries) {
1170 VarInfo const& varInfo = getVarInfo();
1171
1172 const auto centralIdx = calcTreeIndex(bin, true);
1173
1174 double wInt{0} ;
1175 if (varInfo.nRealVars == 1) {
1176
1177 // 1-dimensional interpolation
1178 auto const& realX = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx1]);
1179 wInt = interpolateDim(varInfo.realVarIdx1, realX.getVal(), centralIdx, intOrder, correctForBinSize, cdfBoundaries) ;
1180
1181 } else if (varInfo.nRealVars == 2) {
1182
1183 // 2-dimensional interpolation
1184 auto const& realX = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx1]);
1185 auto const& realY = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx2]);
1186 double xval = realX.getVal() ;
1187 double yval = realY.getVal() ;
1188
1189 RooAbsBinning const& binningY = realY.getBinning();
1190
1191 int ybinC = binningY.binNumber(yval) ;
1192 int ybinLo = ybinC-intOrder/2 - ((yval<binningY.binCenter(ybinC))?1:0) ;
1193 int ybinM = binningY.numBins() ;
1194
1195 auto idxMultY = _idxMult[varInfo.realVarIdx2];
1196 auto offsetIdx = centralIdx - idxMultY * ybinC;
1197
1198 double yarr[10] = {} ;
1199 double xarr[10] = {} ;
1200 for (int i=ybinLo ; i<=intOrder+ybinLo ; i++) {
1201 int ibin ;
1202 if (i>=0 && i<ybinM) {
1203 // In range
1204 ibin = i ;
1205 xarr[i-ybinLo] = binningY.binCenter(ibin) ;
1206 } else if (i>=ybinM) {
1207 // Overflow: mirror
1208 ibin = 2*ybinM-i-1 ;
1209 xarr[i-ybinLo] = 2*binningY.highBound()-binningY.binCenter(ibin) ;
1210 } else {
1211 // Underflow: mirror
1212 ibin = -i -1;
1213 xarr[i-ybinLo] = 2*binningY.lowBound()-binningY.binCenter(ibin) ;
1214 }
1215 auto centralIdxX = offsetIdx + idxMultY * ibin;
1216 yarr[i-ybinLo] = interpolateDim(varInfo.realVarIdx1,xval,centralIdxX,intOrder,correctForBinSize,kFALSE) ;
1217 }
1218
1219 if (gDebug>7) {
1220 cout << "RooDataHist interpolating data is" << endl ;
1221 cout << "xarr = " ;
1222 for (int q=0; q<=intOrder ; q++) cout << xarr[q] << " " ;
1223 cout << " yarr = " ;
1224 for (int q=0; q<=intOrder ; q++) cout << yarr[q] << " " ;
1225 cout << endl ;
1226 }
1227 wInt = RooMath::interpolate(xarr,yarr,intOrder+1,yval) ;
1228
1229 } else {
1230
1231 // Higher dimensional scenarios not yet implemented
1232 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") interpolation in "
1233 << varInfo.nRealVars << " dimensions not yet implemented" << endl ;
1234 return weightFast(bin,0,correctForBinSize,cdfBoundaries) ;
1235
1236 }
1237
1238 return wInt ;
1239}
1240
1241
1242////////////////////////////////////////////////////////////////////////////////
1243/// Return the asymmetric errors on the current weight.
1244/// \see weightError(ErrorType) const for symmetric error.
1245/// \param[out] lo Low error.
1246/// \param[out] hi High error.
1247/// \param[in] etype Type of error to compute. May throw if not supported.
1248/// Supported errors are
1249/// - `Poisson` Default. Asymmetric Poisson errors (68% CL).
1250/// - `SumW2` The square root of the sum of weights. (Symmetric).
1251/// - `None` Return zero.
1252void RooDataHist::weightError(double& lo, double& hi, ErrorType etype) const
1253{
1254 checkInit() ;
1255
1256 switch (etype) {
1257
1258 case Auto:
1259 throw std::invalid_argument(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
1260 break ;
1261
1262 case Expected:
1263 throw std::invalid_argument(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
1264 break ;
1265
1266 case Poisson:
1267 if (get_curWgtErrLo() >= 0) {
1268 // Weight is preset or precalculated
1269 lo = get_curWgtErrLo();
1270 hi = get_curWgtErrHi();
1271 return ;
1272 }
1273
1274 if (!_errLo || !_errHi) {
1275 // We didn't track asymmetric errors so far, so now we need to allocate
1276 initArray(_errLo, _arrSize, -1.);
1277 initArray(_errHi, _arrSize, -1.);
1279 }
1280
1281 // Calculate poisson errors
1282 Double_t ym,yp ;
1284 _errLo[_curIndex] = weight()-ym;
1285 _errHi[_curIndex] = yp-weight();
1286 lo = _errLo[_curIndex];
1287 hi = _errHi[_curIndex];
1288 return ;
1289
1290 case SumW2:
1291 lo = sqrt(get_curSumW2());
1292 hi = lo;
1293 return ;
1294
1295 case None:
1296 lo = 0 ;
1297 hi = 0 ;
1298 return ;
1299 }
1300}
1301
1302
1303// wve adjust for variable bin sizes
1304
1305////////////////////////////////////////////////////////////////////////////////
1306/// Perform boundary safe 'intOrder'-th interpolation of weights in dimension 'dim'
1307/// at current value 'xval'
1308
1309/// \param[in] iDim Index of the histogram dimension along which to interpolate.
1310/// \param[in] xval Value of histogram variable at dimension `iDim` for which
1311/// we want to interpolate the histogram weight.
1312/// \param[in] centralIdx Index of the bin that the point at which we
1313/// interpolate the histogram weight falls into
1314/// (can be obtained with `RooDataHist::calcTreeIndex`).
1315/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1316/// used for the interpolation.
1317/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1318/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1319/// underflow bins are assumed to have weight zero and
1320/// overflow bins have weight one. Otherwise, the
1321/// histogram is mirrored at the boundaries for the
1322/// interpolation.
1323double RooDataHist::interpolateDim(int iDim, double xval, size_t centralIdx, int intOrder, bool correctForBinSize, bool cdfBoundaries)
1324{
1325 auto const& binning = static_cast<RooRealVar&>(*_vars[iDim]).getBinning();
1326
1327 // Fill workspace arrays spanning interpolation area
1328 int fbinC = binning.binNumber(xval) ;
1329 int fbinLo = fbinC-intOrder/2 - ((xval<binning.binCenter(fbinC))?1:0) ;
1330 int fbinM = binning.numBins() ;
1331
1332 auto idxMult = _idxMult[iDim];
1333 auto offsetIdx = centralIdx - idxMult * fbinC;
1334
1335 double yarr[10] ;
1336 double xarr[10] ;
1337 for (int i=fbinLo ; i<=intOrder+fbinLo ; i++) {
1338 int ibin ;
1339 if (i>=0 && i<fbinM) {
1340 // In range
1341 ibin = i ;
1342 xarr[i-fbinLo] = binning.binCenter(ibin) ;
1343 auto idx = offsetIdx + idxMult * ibin;
1344 yarr[i - fbinLo] = get_wgt(idx);
1345 if (correctForBinSize) yarr[i-fbinLo] /= _binv[idx] ;
1346 } else if (i>=fbinM) {
1347 // Overflow: mirror
1348 ibin = 2*fbinM-i-1 ;
1349 if (cdfBoundaries) {
1350 xarr[i-fbinLo] = binning.highBound()+1e-10*(i-fbinM+1) ;
1351 yarr[i-fbinLo] = 1.0 ;
1352 } else {
1353 auto idx = offsetIdx + idxMult * ibin;
1354 xarr[i-fbinLo] = 2*binning.highBound()-binning.binCenter(ibin) ;
1355 yarr[i - fbinLo] = get_wgt(idx);
1356 if (correctForBinSize)
1357 yarr[i - fbinLo] /= _binv[idx];
1358 }
1359 } else {
1360 // Underflow: mirror
1361 ibin = -i - 1 ;
1362 if (cdfBoundaries) {
1363 xarr[i-fbinLo] = binning.lowBound()-ibin*(1e-10) ; ;
1364 yarr[i-fbinLo] = 0.0 ;
1365 } else {
1366 auto idx = offsetIdx + idxMult * ibin;
1367 xarr[i-fbinLo] = 2*binning.lowBound()-binning.binCenter(ibin) ;
1368 yarr[i - fbinLo] = get_wgt(idx);
1369 if (correctForBinSize)
1370 yarr[i - fbinLo] /= _binv[idx];
1371 }
1372 }
1373 }
1374 return RooMath::interpolate(xarr,yarr,intOrder+1,xval) ;
1375}
1376
1377
1378
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Increment the bin content of the bin enclosing the given coordinates.
1382///
1383/// \param[in] row Coordinates of the bin.
1384/// \param[in] wgt Increment by this weight.
1385/// \param[in] sumw2 Optionally, track the sum of squared weights. If a value > 0 or
1386/// a weight != 1. is passed for the first time, a vector for the squared weights will be allocated.
1387void RooDataHist::add(const RooArgSet& row, Double_t wgt, Double_t sumw2)
1388{
1389 checkInit() ;
1390
1391 if ((sumw2 > 0. || wgt != 1.) && !_sumw2) {
1392 // Receiving a weighted entry. SumW2 != sumw from now on.
1393 _sumw2 = new double[_arrSize];
1394 std::copy(_wgt, _wgt+_arrSize, _sumw2);
1395
1397 }
1398
1399 const auto idx = calcTreeIndex(row, false);
1400
1401 _wgt[idx] += wgt ;
1402 if (_sumw2) _sumw2[idx] += (sumw2 > 0 ? sumw2 : wgt*wgt);
1403
1404 _cache_sum_valid = false;
1405}
1406
1407
1408
1409////////////////////////////////////////////////////////////////////////////////
1410/// Set a bin content.
1411/// \param[in] row Coordinates of the bin to be set.
1412/// \param[in] wgt New bin content.
1413/// \param[in] wgtErrLo Low error of the bin content.
1414/// \param[in] wgtErrHi High error of the bin content.
1415void RooDataHist::set(const RooArgSet& row, Double_t wgt, Double_t wgtErrLo, Double_t wgtErrHi)
1416{
1417 checkInit() ;
1418
1419 if (!_errLo || !_errHi) {
1420 initArray(_errLo, _arrSize, -1.);
1421 initArray(_errHi, _arrSize, -1.);
1423 }
1424
1425 const auto idx = calcTreeIndex(row, false);
1426
1427 _wgt[idx] = wgt ;
1428 _errLo[idx] = wgtErrLo ;
1429 _errHi[idx] = wgtErrHi ;
1430
1431 _cache_sum_valid = false;
1432}
1433
1434
1435
1436////////////////////////////////////////////////////////////////////////////////
1437/// Set bin content of bin that was last loaded with get(std::size_t).
1438/// \param[in] binNumber Optional bin number to set. If empty, currently active bin is set.
1439/// \param[in] wgt New bin content.
1440/// \param[in] wgtErr Error of the new bin content. If the weight need not have an error, use 0. or a negative number.
1441void RooDataHist::set(std::size_t binNumber, double wgt, double wgtErr) {
1442 checkInit() ;
1443
1444 if (wgtErr > 0. && !_sumw2) {
1445 // Receiving a weighted entry. Need to track sumw2 from now on:
1446 cloneArray(_sumw2, _wgt, _arrSize);
1447
1449 }
1450
1451 _wgt[binNumber] = wgt ;
1452 if (_errLo) _errLo[binNumber] = wgtErr;
1453 if (_errHi) _errHi[binNumber] = wgtErr;
1454 if (_sumw2) _sumw2[binNumber] = wgtErr*wgtErr;
1455
1457}
1458
1459
1460////////////////////////////////////////////////////////////////////////////////
1461/// Set bin content of bin that was last loaded with get(std::size_t).
1462/// \deprecated Prefer set(std::size_t, double, double).
1463/// \param[in] wgt New bin content.
1464/// \param[in] wgtErr Optional error of the bin content.
1465void RooDataHist::set(double wgt, double wgtErr) {
1466 if (_curIndex == std::numeric_limits<std::size_t>::max()) {
1467 _curIndex = calcTreeIndex(_vars, true) ;
1468 }
1469
1470 set(_curIndex, wgt, wgtErr);
1471}
1472
1473
1474////////////////////////////////////////////////////////////////////////////////
1475/// Set a bin content.
1476/// \param[in] row Coordinates to compute the bin from.
1477/// \param[in] wgt New bin content.
1478/// \param[in] wgtErr Optional error of the bin content.
1479void RooDataHist::set(const RooArgSet& row, Double_t wgt, Double_t wgtErr) {
1480 set(calcTreeIndex(row, false), wgt, wgtErr);
1481}
1482
1483
1484
1485////////////////////////////////////////////////////////////////////////////////
1486/// Add all data points contained in 'dset' to this data set with given weight.
1487/// Optional cut string expression selects the data points to be added and can
1488/// reference any variable contained in this data set
1489
1490void RooDataHist::add(const RooAbsData& dset, const char* cut, Double_t wgt)
1491{
1492 RooFormulaVar cutVar("select",cut,*dset.get()) ;
1493 add(dset,&cutVar,wgt) ;
1494}
1495
1496
1497
1498////////////////////////////////////////////////////////////////////////////////
1499/// Add all data points contained in 'dset' to this data set with given weight.
1500/// Optional RooFormulaVar pointer selects the data points to be added.
1501
1502void RooDataHist::add(const RooAbsData& dset, const RooFormulaVar* cutVar, Double_t wgt)
1503{
1504 checkInit() ;
1505
1506 RooFormulaVar* cloneVar = 0;
1507 RooArgSet* tmp(0) ;
1508 if (cutVar) {
1509 // Deep clone cutVar and attach clone to this dataset
1510 tmp = (RooArgSet*) RooArgSet(*cutVar).snapshot() ;
1511 if (!tmp) {
1512 coutE(DataHandling) << "RooDataHist::add(" << GetName() << ") Couldn't deep-clone cut variable, abort," << endl ;
1513 return ;
1514 }
1515
1516 cloneVar = (RooFormulaVar*) tmp->find(*cutVar) ;
1517 cloneVar->attachDataSet(dset) ;
1518 }
1519
1520
1521 Int_t i ;
1522 for (i=0 ; i<dset.numEntries() ; i++) {
1523 const RooArgSet* row = dset.get(i) ;
1524 if (!cloneVar || cloneVar->getVal()) {
1525 add(*row,wgt*dset.weight(), wgt*wgt*dset.weightSquared()) ;
1526 }
1527 }
1528
1529 if (cloneVar) {
1530 delete tmp ;
1531 }
1532
1534}
1535
1536
1537
1538////////////////////////////////////////////////////////////////////////////////
1539/// Return the sum of the weights of all bins in the histogram.
1540///
1541/// \param[in] correctForBinSize Multiply the sum of weights in each bin
1542/// with the N-dimensional bin volume, making the return value
1543/// the integral over the function represented by this histogram.
1544/// \param[in] inverseBinCor Divide by the N-dimensional bin volume.
1545Double_t RooDataHist::sum(bool correctForBinSize, bool inverseBinCor) const
1546{
1547 checkInit() ;
1548
1549 // Check if result was cached
1550 const CacheSumState_t cache_code = !correctForBinSize ? kNoBinCorrection : (inverseBinCor ? kInverseBinCorr : kCorrectForBinSize);
1551 if (_cache_sum_valid == static_cast<Int_t>(cache_code)) {
1552 return _cache_sum ;
1553 }
1554
1556 for (Int_t i=0; i < _arrSize; i++) {
1557 const double theBinVolume = correctForBinSize ? (inverseBinCor ? 1/_binv[i] : _binv[i]) : 1.0 ;
1558 kahanSum += get_wgt(i) * theBinVolume;
1559 }
1560
1561 // Store result in cache
1562 _cache_sum_valid = cache_code;
1563 _cache_sum = kahanSum;
1564
1565 return kahanSum;
1566}
1567
1568
1569
1570////////////////////////////////////////////////////////////////////////////////
1571/// Return the sum of the weights of a multi-dimensional slice of the histogram
1572/// by summing only over the dimensions specified in sumSet.
1573///
1574/// The coordinates of all other dimensions are fixed to those given in sliceSet
1575///
1576/// If correctForBinSize is specified, the sum of weights
1577/// is multiplied by the M-dimensional bin volume, (M = N(sumSet)),
1578/// making the return value the integral over the function
1579/// represented by this histogram
1580
1581Double_t RooDataHist::sum(const RooArgSet& sumSet, const RooArgSet& sliceSet, bool correctForBinSize, bool inverseBinCor)
1582{
1583 checkInit() ;
1584
1585 RooArgSet varSave ;
1586 varSave.addClone(_vars) ;
1587
1588 RooArgSet sliceOnlySet(sliceSet);
1589 sliceOnlySet.remove(sumSet,true,true) ;
1590
1591 _vars = sliceOnlySet;
1592 std::vector<double> const * pbinv = nullptr;
1593
1594 if(correctForBinSize && inverseBinCor) {
1595 pbinv = &calculatePartialBinVolume(sliceOnlySet);
1596 } else if(correctForBinSize && !inverseBinCor) {
1597 pbinv = &calculatePartialBinVolume(sumSet);
1598 }
1599
1600 // Calculate mask and refence plot bins for non-iterating variables
1601 std::vector<bool> mask(_vars.getSize());
1602 std::vector<int> refBin(_vars.getSize());
1603
1604 for (unsigned int i = 0; i < _vars.size(); ++i) {
1605 const RooAbsArg* arg = _vars[i];
1606 const RooAbsLValue* argLv = _lvvars[i]; // Same as above, but cross-cast
1607
1608 if (sumSet.find(*arg)) {
1609 mask[i] = false ;
1610 } else {
1611 mask[i] = true ;
1612 refBin[i] = argLv->getBin();
1613 }
1614 }
1615
1616 // Loop over entire data set, skipping masked entries
1618 for (Int_t ibin=0; ibin < _arrSize; ++ibin) {
1619
1620 std::size_t tmpibin = ibin;
1621 Bool_t skip(false) ;
1622
1623 // Check if this bin belongs in selected slice
1624 for (unsigned int ivar = 0; !skip && ivar < _vars.size(); ++ivar) {
1625 const Int_t idx = tmpibin / _idxMult[ivar] ;
1626 tmpibin -= idx*_idxMult[ivar] ;
1627 if (mask[ivar] && idx!=refBin[ivar])
1628 skip = true ;
1629 }
1630
1631 if (!skip) {
1632 const double theBinVolume = correctForBinSize ? (inverseBinCor ? 1/(*pbinv)[ibin] : (*pbinv)[ibin] ) : 1.0 ;
1633 total += get_wgt(ibin) * theBinVolume;
1634 }
1635 }
1636
1637 _vars = varSave ;
1638
1639 return total;
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Return the sum of the weights of a multi-dimensional slice of the histogram
1644/// by summing only over the dimensions specified in sumSet.
1645///
1646/// The coordinates of all other dimensions are fixed to those given in sliceSet
1647///
1648/// If correctForBinSize is specified, the sum of weights
1649/// is multiplied by the M-dimensional bin volume, (M = N(sumSet)),
1650/// or the fraction of it that falls inside the range rangeName,
1651/// making the return value the integral over the function
1652/// represented by this histogram.
1653///
1654/// If correctForBinSize is not specified, the weights are multiplied by the
1655/// fraction of the bin volume that falls inside the range, i.e. a factor of
1656/// binVolumeInRange/totalBinVolume.
1657
1658Double_t RooDataHist::sum(const RooArgSet& sumSet, const RooArgSet& sliceSet,
1659 bool correctForBinSize, bool inverseBinCor,
1660 const std::map<const RooAbsArg*, std::pair<double, double> >& ranges,
1661 std::function<double(int)> getBinScale)
1662{
1663 checkInit();
1665 RooArgSet varSave;
1666 varSave.addClone(_vars);
1667 {
1668 RooArgSet sliceOnlySet(sliceSet);
1669 sliceOnlySet.remove(sumSet, true, true);
1670 _vars = sliceOnlySet;
1671 }
1672
1673 // Calculate mask and reference plot bins for non-iterating variables,
1674 // and get ranges for iterating variables
1675 std::vector<bool> mask(_vars.getSize());
1676 std::vector<int> refBin(_vars.getSize());
1677 std::vector<double> rangeLo(_vars.getSize(), -std::numeric_limits<Double_t>::infinity());
1678 std::vector<double> rangeHi(_vars.getSize(), +std::numeric_limits<Double_t>::infinity());
1679
1680 for (std::size_t i = 0; i < _vars.size(); ++i) {
1681 const RooAbsArg* arg = _vars[i];
1682 const RooAbsLValue* argLV = _lvvars[i]; // Same object as above, but cross cast
1683
1684 RooAbsArg* sumsetv = sumSet.find(*arg);
1685 RooAbsArg* slicesetv = sliceSet.find(*arg);
1686 mask[i] = !sumsetv;
1687 if (mask[i]) {
1688 assert(argLV);
1689 refBin[i] = argLV->getBin();
1690 }
1691
1692 auto it = ranges.find(sumsetv ? sumsetv : slicesetv);
1693 if (ranges.end() != it) {
1694 rangeLo[i] = it->second.first;
1695 rangeHi[i] = it->second.second;
1696 }
1697 }
1698
1699 // Loop over entire data set, skipping masked entries
1701 for (Int_t ibin = 0; ibin < _arrSize; ++ibin) {
1702 // Check if this bin belongs in selected slice
1703 bool skip{false};
1704 for (int ivar = 0, tmp = ibin; !skip && ivar < int(_vars.size()); ++ivar) {
1705 const Int_t idx = tmp / _idxMult[ivar];
1706 tmp -= idx*_idxMult[ivar];
1707 if (mask[ivar] && idx!=refBin[ivar]) skip = true;
1708 }
1709
1710 if (skip) continue;
1711
1712 // Work out bin volume
1713 // It's not necessary to figure out the bin volume for the slice-only set explicitely here.
1714 // We need to loop over the sumSet anyway to get the partial bin containment correction,
1715 // so we can get the slice-only set volume later by dividing _binv[ibin] / binVolumeSumSetFull.
1716 Double_t binVolumeSumSetFull = 1.;
1717 Double_t binVolumeSumSetInRange = 1.;
1718 for (Int_t ivar = 0, tmp = ibin; ivar < (int)_vars.size(); ++ivar) {
1719 const Int_t idx = tmp / _idxMult[ivar];
1720 tmp -= idx*_idxMult[ivar];
1721
1722 // If the current variable is not in the sumSet, it should not be considered for the bin volume
1723 const auto arg = _vars[ivar];
1724 if (!sumSet.find(*arg)) {
1725 continue;
1726 }
1727
1728 if (_binbounds[ivar].empty()) continue;
1729 const Double_t binLo = _binbounds[ivar][2 * idx];
1730 const Double_t binHi = _binbounds[ivar][2 * idx + 1];
1731 if (binHi < rangeLo[ivar] || binLo > rangeHi[ivar]) {
1732 // bin is outside of allowed range - effective bin volume is zero
1733 binVolumeSumSetInRange = 0.;
1734 break;
1735 }
1736
1737 binVolumeSumSetFull *= binHi - binLo;
1738 binVolumeSumSetInRange *= std::min(rangeHi[ivar], binHi) - std::max(rangeLo[ivar], binLo);
1739 }
1740 const Double_t corrPartial = binVolumeSumSetInRange / binVolumeSumSetFull;
1741 if (0. == corrPartial) continue;
1742 const Double_t corr = correctForBinSize ? (inverseBinCor ? binVolumeSumSetFull / _binv[ibin] : binVolumeSumSetFull ) : 1.0;
1743 total += getBinScale(ibin)*(get_wgt(ibin) * corr * corrPartial);
1744 }
1745
1746 _vars = varSave;
1747
1748 return total;
1749}
1750
1751
1752
1753////////////////////////////////////////////////////////////////////////////////
1754/// Fill the transient cache with partial bin volumes with up-to-date
1755/// values for the partial volume specified by observables 'dimSet'
1756
1757const std::vector<double>& RooDataHist::calculatePartialBinVolume(const RooArgSet& dimSet) const
1758{
1759 // The code bitset has all bits set to one whose position corresponds to arguments in dimSet.
1760 // It is used as the key for the bin volume caching hash map.
1761 int code{0};
1762 {
1763 int i{0} ;
1764 for (auto const& v : _vars) {
1765 code += ((dimSet.find(*v) ? 1 : 0) << i) ;
1766 ++i;
1767 }
1768 }
1769
1770 auto& pbinv = _pbinvCache[code];
1771 if(!pbinv.empty()) {
1772 return pbinv;
1773 }
1774 pbinv.resize(_arrSize);
1775
1776 // Calculate plot bins of components from master index
1777 std::vector<bool> selDim(_vars.getSize());
1778 for (std::size_t i = 0; i < selDim.size(); ++i) {
1779 selDim[i] = (code >> i) & 1 ;
1780 }
1781
1782 // Recalculate partial bin volume cache
1783 for (Int_t ibin=0; ibin < _arrSize ;ibin++) {
1784 Int_t idx(0), tmp(ibin) ;
1785 Double_t theBinVolume(1) ;
1786 for (unsigned int j=0; j < _lvvars.size(); ++j) {
1787 const RooAbsLValue* arg = _lvvars[j];
1788 assert(arg);
1789
1790 idx = tmp / _idxMult[j];
1791 tmp -= idx*_idxMult[j];
1792 if (selDim[j]) {
1793 theBinVolume *= arg->getBinWidth(idx) ;
1794 }
1795 }
1796 pbinv[ibin] = theBinVolume ;
1797 }
1798
1799 return pbinv;
1800}
1801
1802
1803
1804////////////////////////////////////////////////////////////////////////////////
1805/// Return the number of bins
1806
1808{
1809 return RooAbsData::numEntries() ;
1810}
1811
1812
1813
1814////////////////////////////////////////////////////////////////////////////////
1815/// Sum the weights of all bins.
1817
1818 if (_maskedWeights.empty()) {
1820 } else {
1822 }
1823}
1824
1825
1826
1827////////////////////////////////////////////////////////////////////////////////
1828/// Return the sum of weights in all entries matching cutSpec (if specified)
1829/// and in named range cutRange (if specified)
1830/// Return the
1831
1832Double_t RooDataHist::sumEntries(const char* cutSpec, const char* cutRange) const
1833{
1834 checkInit() ;
1835
1836 if (cutSpec==0 && cutRange==0) {
1837 return sumEntries();
1838 } else {
1839
1840 // Setup RooFormulaVar for cutSpec if it is present
1841 RooFormula* select = 0 ;
1842 if (cutSpec) {
1843 select = new RooFormula("select",cutSpec,*get()) ;
1844 }
1845
1846 // Otherwise sum the weights in the event
1847 ROOT::Math::KahanSum<> kahanSum;
1848 for (Int_t i=0; i < _arrSize; i++) {
1849 get(i) ;
1850 if ((!_maskedWeights.empty() && _maskedWeights[i] == 0.)
1851 || (select && select->eval() == 0.)
1852 || (cutRange && !_vars.allInRange(cutRange)))
1853 continue;
1854
1855 kahanSum += weight(i);
1856 }
1857
1858 if (select) delete select ;
1859
1860 return kahanSum;
1861 }
1862}
1863
1864
1865
1866////////////////////////////////////////////////////////////////////////////////
1867/// Reset all bin weights to zero
1868
1870{
1871 // WVE DO NOT CALL RooTreeData::reset() for binned
1872 // datasets as this will delete the bin definitions
1873
1874 std::fill(_wgt, _wgt + _arrSize, 0.);
1875 delete[] _errLo; _errLo = nullptr;
1876 delete[] _errHi; _errHi = nullptr;
1877 delete[] _sumw2; _sumw2 = nullptr;
1878
1880
1881 _cache_sum_valid = false;
1882}
1883
1884
1885
1886////////////////////////////////////////////////////////////////////////////////
1887/// Load bin `binNumber`, and return an argset with the coordinates of the bin centre.
1888/// \note The argset is owned by this data hist, and this function has a side effect, because
1889/// it alters the currently active bin.
1890const RooArgSet* RooDataHist::get(Int_t binNumber) const
1891{
1892 checkInit() ;
1893 _curIndex = binNumber;
1894
1895 return RooAbsData::get(_curIndex);
1896}
1897
1898
1899
1900////////////////////////////////////////////////////////////////////////////////
1901/// Return a RooArgSet with whose coordinates denote the bin centre of the bin
1902/// enclosing the point in `coord`.
1903/// \note The argset is owned by this data hist, and this function has a side effect, because
1904/// it alters the currently active bin.
1905const RooArgSet* RooDataHist::get(const RooArgSet& coord) const {
1906 return get(calcTreeIndex(coord, false));
1907}
1908
1909
1910
1911////////////////////////////////////////////////////////////////////////////////
1912/// Return the volume of the bin enclosing coordinates 'coord'.
1914 checkInit() ;
1915 return _binv[calcTreeIndex(coord, false)] ;
1916}
1917
1918
1919////////////////////////////////////////////////////////////////////////////////
1920/// Set all the event weight of all bins to the specified value
1921
1923{
1924 for (Int_t i=0 ; i<_arrSize ; i++) {
1925 _wgt[i] = value ;
1926 }
1927
1929}
1930
1931
1932
1933////////////////////////////////////////////////////////////////////////////////
1934/// Create an iterator over all bins in a slice defined by the subset of observables
1935/// listed in sliceArg. The position of the slice is given by otherArgs
1936
1938{
1939 // Update to current position
1940 _vars = otherArgs ;
1941 _curIndex = calcTreeIndex(_vars, true);
1942
1943 RooAbsArg* intArg = _vars.find(sliceArg) ;
1944 if (!intArg) {
1945 coutE(InputArguments) << "RooDataHist::sliceIterator() variable " << sliceArg.GetName() << " is not part of this RooDataHist" << endl ;
1946 return 0 ;
1947 }
1948 return new RooDataHistSliceIter(*this,*intArg) ;
1949}
1950
1951
1952////////////////////////////////////////////////////////////////////////////////
1953/// Change the name of the RooDataHist
1954
1955void RooDataHist::SetName(const char *name)
1956{
1957 if (_dir) _dir->GetList()->Remove(this);
1959 if (_dir) _dir->GetList()->Add(this);
1960}
1961
1962
1963////////////////////////////////////////////////////////////////////////////////
1964/// Change the title of this RooDataHist
1965
1966void RooDataHist::SetNameTitle(const char *name, const char* title)
1967{
1968 if (_dir) _dir->GetList()->Remove(this);
1969 TNamed::SetNameTitle(name,title) ;
1970 if (_dir) _dir->GetList()->Add(this);
1971}
1972
1973
1974////////////////////////////////////////////////////////////////////////////////
1975/// Print value of the dataset, i.e. the sum of weights contained in the dataset
1976
1977void RooDataHist::printValue(ostream& os) const
1978{
1979 os << numEntries() << " bins (" << sumEntries() << " weights)" ;
1980}
1981
1982
1983
1984
1985////////////////////////////////////////////////////////////////////////////////
1986/// Print argument of dataset, i.e. the observable names
1987
1988void RooDataHist::printArgs(ostream& os) const
1989{
1990 os << "[" ;
1991 Bool_t first(kTRUE) ;
1992 for (const auto arg : _vars) {
1993 if (first) {
1994 first=kFALSE ;
1995 } else {
1996 os << "," ;
1997 }
1998 os << arg->GetName() ;
1999 }
2000 os << "]" ;
2001}
2002
2003
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// Compute which bins of the dataset are part of the currently set fit range.
2008{
2009 checkInit() ;
2010
2011 _maskedWeights.assign(_wgt, _wgt + _arrSize);
2012
2013 for (Int_t i=0; i < _arrSize; ++i) {
2014 get(i) ;
2015
2016 for (const auto arg : _vars) {
2017 if (!arg->inRange(nullptr)) {
2018 _maskedWeights[i] = 0.;
2019 break;
2020 }
2021 }
2022 }
2023
2024}
2025
2026
2027
2028////////////////////////////////////////////////////////////////////////////////
2029/// Returns true if dataset contains entries with a non-integer weight.
2030
2032{
2033 for (Int_t i=0; i < _arrSize; ++i) {
2034 const double wgt = _wgt[i];
2035 double intpart;
2036 if (fabs(std::modf(wgt, &intpart)) > 1.E-10)
2037 return true;
2038 }
2039
2040 return false;
2041}
2042
2043
2044////////////////////////////////////////////////////////////////////////////////
2045/// Print the details on the dataset contents
2046
2048{
2050
2051 os << indent << "Binned Dataset " << GetName() << " (" << GetTitle() << ")" << endl ;
2052 os << indent << " Contains " << numEntries() << " bins with a total weight of " << sumEntries() << endl;
2053
2054 if (!verbose) {
2055 os << indent << " Observables " << _vars << endl ;
2056 } else {
2057 os << indent << " Observables: " ;
2059 }
2060
2061 if(verbose) {
2062 if (_cachedVars.getSize()>0) {
2063 os << indent << " Caches " << _cachedVars << endl ;
2064 }
2065 }
2066}
2067
2068void RooDataHist::printDataHistogram(ostream& os, RooRealVar* obs) const
2069{
2070 for(Int_t i=0; i<obs->getBins(); ++i){
2071 this->get(i);
2072 obs->setBin(i);
2073 os << this->weight() << " +/- " << this->weightSquared() << endl;
2074 }
2075}
2076
2077
2078////////////////////////////////////////////////////////////////////////////////
2079/// Stream an object of class RooDataHist.
2080void RooDataHist::Streamer(TBuffer &R__b) {
2081 if (R__b.IsReading()) {
2082
2083 UInt_t R__s, R__c;
2084 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2085
2086 if (R__v > 2) {
2087 R__b.ReadClassBuffer(RooDataHist::Class(),this,R__v,R__s,R__c);
2088 R__b.CheckByteCount(R__s, R__c, RooDataHist::IsA());
2089 initialize(0, false);
2090 } else {
2091
2092 // Legacy dataset conversion happens here. Legacy RooDataHist inherits from RooTreeData
2093 // which in turn inherits from RooAbsData. Manually stream RooTreeData contents on
2094 // file here and convert it into a RooTreeDataStore which is installed in the
2095 // new-style RooAbsData base class
2096
2097 // --- This is the contents of the streamer code of RooTreeData version 2 ---
2098 UInt_t R__s1, R__c1;
2099 Version_t R__v1 = R__b.ReadVersion(&R__s1, &R__c1); if (R__v1) { }
2100
2101 RooAbsData::Streamer(R__b);
2102 TTree* X_tree(0) ; R__b >> X_tree;
2103 RooArgSet X_truth ; X_truth.Streamer(R__b);
2104 TString X_blindString ; X_blindString.Streamer(R__b);
2105 R__b.CheckByteCount(R__s1, R__c1, TClass::GetClass("RooTreeData"));
2106 // --- End of RooTreeData-v1 streamer
2107
2108 // Construct RooTreeDataStore from X_tree and complete initialization of new-style RooAbsData
2109 _dstore = new RooTreeDataStore(X_tree,_vars) ;
2110 _dstore->SetName(GetName()) ;
2112 _dstore->checkInit() ;
2113
2114 RooDirItem::Streamer(R__b);
2115 R__b >> _arrSize;
2116 delete [] _wgt;
2117 _wgt = new Double_t[_arrSize];
2119 delete [] _errLo;
2120 _errLo = new Double_t[_arrSize];
2122 delete [] _errHi;
2123 _errHi = new Double_t[_arrSize];
2125 delete [] _sumw2;
2126 _sumw2 = new Double_t[_arrSize];
2128 delete [] _binv;
2129 _binv = new Double_t[_arrSize];
2130 RooArgSet tmpSet;
2131 tmpSet.Streamer(R__b);
2132 double tmp;
2133 R__b >> tmp; //_curWeight;
2134 R__b >> tmp; //_curWgtErrLo;
2135 R__b >> tmp; //_curWgtErrHi;
2136 R__b >> tmp; //_curSumW2;
2137 R__b >> tmp; //_curVolume;
2138 R__b >> _curIndex;
2139 R__b.CheckByteCount(R__s, R__c, RooDataHist::IsA());
2140 }
2141
2142 } else {
2143
2145 }
2146}
2147
2148
2149////////////////////////////////////////////////////////////////////////////////
2150/// Return event weights of all events in range [first, first+len).
2151/// If cacheValidEntries() has been called, out-of-range events will have a weight of 0.
2152RooSpan<const double> RooDataHist::getWeightBatch(std::size_t first, std::size_t len) const {
2153 return _maskedWeights.empty() ?
2156}
2157
2158
2159////////////////////////////////////////////////////////////////////////////////
2160/// Write information to retrieve data columns into `evalData.spans`.
2161/// All spans belonging to variables of this dataset are overwritten. Spans to other
2162/// variables remain intact.
2163/// \param[out] evalData Store references to all data batches in this struct's `spans`.
2164/// The key to retrieve an item is the pointer of the variable that owns the data.
2165/// \param first Index of first event that ends up in the batch.
2166/// \param len Number of events in each batch.
2167void RooDataHist::getBatches(RooBatchCompute::RunContext& evalData, std::size_t begin, std::size_t len) const {
2168 for (auto&& batch : store()->getBatches(begin, len).spans) {
2169 evalData.spans[batch.first] = std::move(batch.second);
2170 }
2171}
2172
2173////////////////////////////////////////////////////////////////////////////////
2174/// Hand over pointers to our weight arrays to the data store implementation.
2177}
2178
2179
2180////////////////////////////////////////////////////////////////////////////////
2181/// Return reference to VarInfo struct with cached histogram variable
2182/// information that is frequently used for histogram weights retrieval.
2183///
2184/// If the `_varInfo` struct was not initialized yet, it will be initialized in
2185/// this function.
2187
2188 if(_varInfo.initialized) return _varInfo;
2189
2190 auto& info = _varInfo;
2191
2192 {
2193 // count the number of real vars and get their indices
2194 info.nRealVars = 0;
2195 size_t iVar = 0;
2196 for (const auto real : _vars) {
2197 if (dynamic_cast<RooRealVar*>(real)) {
2198 if(info.nRealVars == 0) info.realVarIdx1 = iVar;
2199 if(info.nRealVars == 1) info.realVarIdx2 = iVar;
2200 ++info.nRealVars;
2201 }
2202 ++iVar;
2203 }
2204 }
2205
2206 {
2207 // assert that the variables are either real values or categories
2208 for (unsigned int i=0; i < _vars.size(); ++i) {
2209 if (_lvbins[i].get()) {
2210 assert(dynamic_cast<const RooAbsReal*>(_vars[i]));
2211 } else {
2212 assert(dynamic_cast<const RooAbsCategoryLValue*>(_vars[i]));
2213 }
2214 }
2215 }
2216
2217 info.initialized = true;
2218
2219 return info;
2220}
void Class()
Definition: Class.C:29
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
#define coutI(a)
Definition: RooMsgService.h:30
#define coutE(a)
Definition: RooMsgService.h:33
#define TRACE_DESTROY
Definition: RooTrace.h:24
#define TRACE_CREATE
Definition: RooTrace.h:23
int Int_t
Definition: RtypesCore.h:45
short Version_t
Definition: RtypesCore.h:65
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
static unsigned int total
char name[80]
Definition: TGX11.cxx:110
float xmin
Definition: THbookFile.cxx:95
float * q
Definition: THbookFile.cxx:89
float ymin
Definition: THbookFile.cxx:95
float type_of_call hi(const int &, const int &)
double pow(double, double)
double sqrt(double)
Int_t gDebug
Definition: TROOT.cxx:592
char * Form(const char *fmt,...)
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition: Util.h:122
static KahanSum< T, N > Accumulate(Iterator begin, Iterator end, T initialValue=T{})
Iterate over a range and return an instance of a KahanSum.
Definition: Util.h:188
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
Definition: RooAbsArg.cxx:1573
RooAbsBinning is the abstract base class for RooRealVar binning definitions.
Definition: RooAbsBinning.h:26
virtual RooAbsBinning * clone(const char *name=0) const =0
Int_t numBins() const
Return number of bins.
Definition: RooAbsBinning.h:38
virtual Double_t highBound() const =0
virtual Double_t binCenter(Int_t bin) const =0
virtual Int_t binNumber(Double_t x) const =0
virtual Double_t lowBound() const =0
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
virtual void setBin(Int_t ibin, const char *rangeName=0)
Set category to i-th fit bin, which is the i-th registered state.
virtual Int_t numBins(const char *rangeName) const
Return the number of fit bins ( = number of types )
bool hasLabel(const std::string &label) const
Check if a state with name label exists.
virtual const char * getCurrentLabel() const
Return label string of current state.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
Int_t getSize() const
virtual RooAbsArg * addClone(const RooAbsArg &var, Bool_t silent=kFALSE)
Add a clone of the specified argument to list.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
bool hasSameLayout(const RooAbsCollection &other) const
Check that all entries where the collections overlap have the same name.
Storage_t::size_type size() const
Bool_t allInRange(const char *rangeSpec) const
Return true if all contained object report to have their value inside the specified range.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our 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 void setExternalWeightArray(const Double_t *, const Double_t *, const Double_t *, const Double_t *)
virtual void checkInit() const
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:79
virtual const RooArgSet * get() const
Definition: RooAbsData.h:125
void setGlobalObservables(RooArgSet const &globalObservables)
Sets the global observables stored in this data.
RooAbsDataStore * store()
Definition: RooAbsData.h:101
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for detailed printing of object.
Definition: RooAbsData.cxx:858
void checkInit() const
virtual Double_t weight() const =0
static StorageType defaultStorageType
Definition: RooAbsData.h:315
virtual Double_t weightSquared() const =0
virtual void fill()
Definition: RooAbsData.cxx:369
RooArgSet _vars
Definition: RooAbsData.h:353
virtual void attachCache(const RooAbsArg *newOwner, const RooArgSet &cachedVars)
Internal method – Attach dataset copied with cache contents to copied instances of functions.
Definition: RooAbsData.cxx:416
RooArgSet _cachedVars
Definition: RooAbsData.h:354
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Definition: RooAbsData.cxx:376
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Definition: RooAbsData.cxx:604
RooAbsDataStore * _dstore
External variables cached with this data set.
Definition: RooAbsData.h:356
Abstract base class for objects that are lvalues, i.e.
Definition: RooAbsLValue.h:26
virtual Double_t getBinWidth(Int_t i, const char *rangeName=0) const =0
virtual Int_t getBin(const char *rangeName=0) const =0
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
virtual void setBin(Int_t ibin, const char *rangeName=0)
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
virtual Int_t numBins(const char *rangeName=0) const
virtual Int_t getBins(const char *name=0) const
Get number of bins of currently defined range.
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
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:35
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:154
Class RooBinning is an implements RooAbsBinning in terms of an array of boundary values,...
Definition: RooBinning.h:28
RooCategory is an object to represent discrete states.
Definition: RooCategory.h:27
bool defineType(const std::string &label)
Define a state with given name.
virtual Bool_t setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:27
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:44
void dump2()
Debug stuff, should go...
Int_t getIndex(const RooAbsCollection &coord, Bool_t fast=false) const
Calculate bin number of the given coordinates.
void initialize(const char *binningName=0, Bool_t fillTree=kTRUE)
Initialization procedure: allocate weights array, calculate multipliers needed for N-space to 1-dim a...
Int_t _cache_sum_valid
Definition: RooDataHist.h:288
double interpolateDim(int iDim, double xval, size_t centralIdx, int intOrder, bool correctForBinSize, bool cdfBoundaries)
Perform boundary safe 'intOrder'-th interpolation of weights in dimension 'dim' at current value 'xva...
friend class RooDataHistSliceIter
Definition: RooDataHist.h:229
void printDataHistogram(std::ostream &os, RooRealVar *obs) const
void getBatches(RooBatchCompute::RunContext &evalData, std::size_t begin, std::size_t len) const override
Write information to retrieve data columns into evalData.spans.
void SetNameTitle(const char *name, const char *title) override
Change the title of this RooDataHist.
std::vector< double > _maskedWeights
Definition: RooDataHist.h:278
VarInfo _varInfo
Definition: RooDataHist.h:297
RooAbsData * reduceEng(const RooArgSet &varSubset, const RooFormulaVar *cutVar, const char *cutRange=0, std::size_t nStart=0, std::size_t nStop=std::numeric_limits< std::size_t >::max(), Bool_t copyCache=kTRUE) override
Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods.
const std::vector< double > & calculatePartialBinVolume(const RooArgSet &dimSet) const
Fill the transient cache with partial bin volumes with up-to-date values for the partial volume speci...
Double_t weight() const override
Return weight of last bin that was requested with get().
Definition: RooDataHist.h:188
double weightInterpolated(const RooArgSet &bin, int intOrder, bool correctForBinSize, bool cdfBoundaries)
Cache for sum of entries ;.
RooAbsData * cacheClone(const RooAbsArg *newCacheOwner, const RooArgSet *newCacheVars, const char *newName=0) override
Construct a clone of this dataset that contains only the cached variables.
std::unordered_map< int, std::vector< double > > _pbinvCache
Definition: RooDataHist.h:282
void checkBinBounds() const
double weight(std::size_t i) const
Return weight of i-th bin.
Definition: RooDataHist.h:111
void set(std::size_t binNumber, double weight, double wgtErr)
Set bin content of bin that was last loaded with get(std::size_t).
Double_t sumEntries() const override
Sum the weights of all bins.
RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len) const override
Return event weights of all events in range [first, first+len).
Double_t weightSquared() const override
Return squared weight of last bin that was requested with get().
Definition: RooDataHist.h:193
virtual void add(const RooArgSet &row, Double_t wgt=1.0)
Add wgt to the bin content enclosed by the coordinates passed in row.
Definition: RooDataHist.h:73
void weightError(double &lo, double &hi, ErrorType etype=Poisson) const override
Return the asymmetric errors on the current weight.
double * _errHi
Definition: RooDataHist.h:274
double * _binv
Definition: RooDataHist.h:276
RooDataHist()
Default constructor.
Definition: RooDataHist.cxx:86
Double_t get_curWgtErrLo() const
Definition: RooDataHist.h:263
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const override
Print the details on the dataset contents.
void importTH1Set(const RooArgList &vars, RooCategory &indexCat, std::map< std::string, TH1 * > hmap, Double_t initWgt, Bool_t doDensityCorrection)
Import data from given set of TH1/2/3 into this RooDataHist.
double weightFast(const RooArgSet &bin, int intOrder, bool correctForBinSize, bool cdfBoundaries)
A faster version of RooDataHist::weight that assumes the passed arguments are aligned with the histog...
RooPlot * plotOn(RooPlot *frame, PlotOpt o) const override
Back end function to plotting functionality.
Double_t get_curSumW2() const
Definition: RooDataHist.h:265
Bool_t isNonPoissonWeighted() const override
Returns true if dataset contains entries with a non-integer weight.
virtual void printArgs(std::ostream &os) const override
Print argument of dataset, i.e. the observable names.
void _adjustBinning(RooRealVar &theirVar, const TAxis &axis, RooRealVar *ourVar, Int_t *offset)
Helper doing the actual work of adjustBinning().
std::vector< std::vector< Double_t > > _binbounds
List of used binnings associated with lvalues.
Definition: RooDataHist.h:285
double * _sumw2
Definition: RooDataHist.h:275
TIterator * sliceIterator(RooAbsArg &sliceArg, const RooArgSet &otherArgs)
Create an iterator over all bins in a slice defined by the subset of observables listed in sliceArg.
void importTH1(const RooArgList &vars, const TH1 &histo, Double_t initWgt, Bool_t doDensityCorrection)
Import data from given TH1/2/3 into this RooDataHist.
std::size_t _curIndex
Copy of _wgtVec, but masked events have a weight of zero.
Definition: RooDataHist.h:280
Int_t calcTreeIndex() const
Legacy overload to calculate the tree index from the current value of _vars.
Definition: RooDataHist.h:236
Double_t get_curWgtErrHi() const
Definition: RooDataHist.h:264
~RooDataHist() override
Destructor.
void setAllWeights(Double_t value)
Set all the event weight of all bins to the specified value.
Double_t get_wgt(std::size_t idx) const
Definition: RooDataHist.h:256
void importDHistSet(const RooArgList &vars, RooCategory &indexCat, std::map< std::string, RooDataHist * > dmap, Double_t initWgt)
Import data from given set of TH1/2/3 into this RooDataHist.
Int_t _arrSize
Definition: RooDataHist.h:269
std::vector< RooAbsLValue * > _lvvars
Cache for arrays of partial bin volumes.
Definition: RooDataHist.h:283
Int_t numEntries() const override
Return the number of bins.
void cacheValidEntries()
Compute which bins of the dataset are part of the currently set fit range.
void SetName(const char *name) override
Change the name of the RooDataHist.
std::vector< std::unique_ptr< const RooAbsBinning > > _lvbins
List of observables casted as RooAbsLValue.
Definition: RooDataHist.h:284
std::vector< Int_t > _idxMult
Definition: RooDataHist.h:270
void registerWeightArraysToDataStore() const
Hand over pointers to our weight arrays to the data store implementation.
void reset() override
Reset all bin weights to zero.
double * _errLo
Definition: RooDataHist.h:273
void adjustBinning(const RooArgList &vars, const TH1 &href, Int_t *offset=0)
Adjust binning specification on first and optionally second and third observable to binning in given ...
double * _wgt
Definition: RooDataHist.h:272
CacheSumState_t
list of bin bounds per dimension
Definition: RooDataHist.h:287
@ kCorrectForBinSize
Definition: RooDataHist.h:287
virtual void printValue(std::ostream &os) const override
Print value of the dataset, i.e. the sum of weights contained in the dataset.
Double_t _cache_sum
Is cache sum valid? Needs to be Int_t instead of CacheSumState_t for subclasses.
Definition: RooDataHist.h:289
VarInfo const & getVarInfo()
Return reference to VarInfo struct with cached histogram variable information that is frequently used...
Double_t binVolume() const
Return volume of current bin.
Definition: RooDataHist.h:197
const RooArgSet * get() const override
Get bin centre of current bin.
Definition: RooDataHist.h:83
Double_t sum(bool correctForBinSize, bool inverseCorr=false) const
Return the sum of the weights of all bins in the histogram.
RooDirItem is a utility base class for RooFit objects that are to be attached to ROOT directories.
Definition: RooDirItem.h:22
void appendToDir(TObject *obj, Bool_t forceMemoryResident=kFALSE)
Append object to directory.
Definition: RooDirItem.cxx:55
void removeFromDir(TObject *obj)
Remove object from directory it was added to.
Definition: RooDirItem.cxx:43
TDirectory * _dir
Definition: RooDirItem.h:33
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition: RooFormula.h:34
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
Definition: RooFormula.cxx:342
Bool_t getPoissonInterval(Int_t n, Double_t &mu1, Double_t &mu2, Double_t nSigma=1) const
Return a confidence interval for the expected number of events given n observed (unweighted) events.
static const RooHistError & instance()
Return a reference to a singleton object that is created the first time this method is called.
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:38
Int_t GetSize() const
Definition: RooLinkedList.h:63
TIterator * MakeIterator(Bool_t forward=kTRUE) const
Create a TIterator for this list.
static Double_t interpolate(Double_t yArr[], Int_t nOrder, Double_t x)
Definition: RooMath.cxx:605
A RooPlot is a plot frame and a container for graphics objects within that frame.
Definition: RooPlot.h:44
RooAbsRealLValue * getPlotVar() const
Definition: RooPlot.h:139
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:39
void setRange(const char *name, Double_t min, Double_t max)
Set a fit or plotting range.
Definition: RooRealVar.cxx:526
const RooAbsBinning & getBinning(const char *name=0, Bool_t verbose=kTRUE, Bool_t createOnTheFly=kFALSE) const
Return binning definition with name.
Definition: RooRealVar.cxx:318
void setBinning(const RooAbsBinning &binning, const char *name=0)
Add given binning under name 'name' with this variable.
Definition: RooRealVar.cxx:415
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
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.
const Double_t * GetArray() const
Definition: TArrayD.h:43
Class to manage histogram axis.
Definition: TAxis.h:30
const TArrayD * GetXbins() const
Definition: TAxis.h:130
Double_t GetXmax() const
Definition: TAxis.h:134
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
Bool_t IsReading() const
Definition: TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2955
virtual TList * GetList() const
Definition: TDirectory.h:213
TH1 is the base class of all histogram classes in ROOT.
Definition: TH1.h:58
TAxis * GetZaxis()
Definition: TH1.h:322
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8906
virtual Int_t GetDimension() const
Definition: TH1.h:282
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:320
TAxis * GetYaxis()
Definition: TH1.h:321
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4994
TObject * Next()
Definition: TCollection.h:251
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:822
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: TNamed.cxx:154
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
Basic string class.
Definition: TString.h:136
A TTree represents a columnar dataset.
Definition: TTree.h:79
const Int_t n
Definition: legend1.C:16
basic_string_view< char > string_view
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:152
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
Definition: StringUtils.cxx:23
@ DataHandling
Definition: RooGlobalFunc.h:62
@ InputArguments
Definition: RooGlobalFunc.h:61
static constexpr double pc
static constexpr double second
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:735
Definition: first.py:1
fill
Definition: fit1_py.py:6
const double xbins[xbins_n]
RooAbsBinning * bins
Definition: RooAbsData.h:210
Bool_t correctForBinWidth
Definition: RooAbsData.h:220
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
std::unordered_map< const RooAbsReal *, RooSpan< const double > > spans
Once an object has computed its value(s), the span pointing to the results is registered here.
Definition: RunContext.h:52
Structure to cache information on the histogram variable that is frequently used for histogram weight...
Definition: RooDataHist.h:218
auto * l
Definition: textangle.C:4