Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
146RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgSet& vars, const RooAbsData& data, Double_t wgt) :
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
172RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgList& vars, RooCategory& indexCat,
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
197RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgList& vars, RooCategory& indexCat,
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
219RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgList& vars, const TH1* hist, Double_t wgt) :
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
278RooDataHist::RooDataHist(std::string_view name, std::string_view title, const RooArgList& vars, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
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 xmin = offset[0] ;
397 if (yvar) {
398 vset.add(*yvar) ;
399 ymin = offset[1] ;
400 }
401 if (zvar) {
402 vset.add(*zvar) ;
403 zmin = offset[2] ;
404 }
405
406 Int_t ix(0),iy(0),iz(0) ;
407 for (ix=0 ; ix < xvar->getBins() ; ix++) {
408 xvar->setBin(ix) ;
409 if (yvar) {
410 for (iy=0 ; iy < yvar->getBins() ; iy++) {
411 yvar->setBin(iy) ;
412 if (zvar) {
413 for (iz=0 ; iz < zvar->getBins() ; iz++) {
414 zvar->setBin(iz) ;
415 Double_t bv = doDensityCorrection ? binVolume(vset) : 1;
416 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)) ;
417 }
418 } else {
419 Double_t bv = doDensityCorrection ? binVolume(vset) : 1;
420 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)) ;
421 }
422 }
423 } else {
424 Double_t bv = doDensityCorrection ? binVolume(vset) : 1 ;
425 add(vset,bv*histo.GetBinContent(ix+1+xmin)*wgt,bv*TMath::Power(histo.GetBinError(ix+1+xmin)*wgt,2)) ;
426 }
427 }
428
429}
430
431namespace {
432bool checkConsistentAxes(const TH1* first, const TH1* second) {
433 return first->GetDimension() == second->GetDimension()
434 && first->GetNbinsX() == second->GetNbinsX()
435 && first->GetNbinsY() == second->GetNbinsY()
436 && first->GetNbinsZ() == second->GetNbinsZ()
437 && first->GetXaxis()->GetXmin() == second->GetXaxis()->GetXmin()
438 && first->GetXaxis()->GetXmax() == second->GetXaxis()->GetXmax()
439 && (first->GetNbinsY() == 1 || (first->GetYaxis()->GetXmin() == second->GetYaxis()->GetXmin()
440 && first->GetYaxis()->GetXmax() == second->GetYaxis()->GetXmax() ) )
441 && (first->GetNbinsZ() == 1 || (first->GetZaxis()->GetXmin() == second->GetZaxis()->GetXmin()
442 && first->GetZaxis()->GetXmax() == second->GetZaxis()->GetXmax() ) );
443}
444}
445
446
447////////////////////////////////////////////////////////////////////////////////
448/// Import data from given set of TH1/2/3 into this RooDataHist. The category indexCat labels the sources
449/// in the constructed RooDataHist. The stl map provides the mapping between the indexCat state labels
450/// and the import source
451
452void RooDataHist::importTH1Set(const RooArgList& vars, RooCategory& indexCat, map<string,TH1*> hmap, Double_t wgt, Bool_t doDensityCorrection)
453{
454 RooCategory* icat = (RooCategory*) _vars.find(indexCat.GetName()) ;
455
456 TH1* histo(0) ;
457 Bool_t init(kFALSE) ;
458 for (const auto& hiter : hmap) {
459 // Store pointer to first histogram from which binning specification will be taken
460 if (!histo) {
461 histo = hiter.second;
462 } else {
463 if (!checkConsistentAxes(histo, hiter.second)) {
464 coutE(InputArguments) << "Axes of histogram " << hiter.second->GetName() << " are not consistent with first processed "
465 << "histogram " << histo->GetName() << std::endl;
466 throw std::invalid_argument("Axes of inputs for RooDataHist are inconsistent");
467 }
468 }
469 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
470 if (!indexCat.hasLabel(hiter.first)) {
471 indexCat.defineType(hiter.first) ;
472 coutI(InputArguments) << "RooDataHist::importTH1Set(" << GetName() << ") defining state \"" << hiter.first << "\" in index category " << indexCat.GetName() << endl ;
473 }
474 if (!icat->hasLabel(hiter.first)) {
475 icat->defineType(hiter.first) ;
476 }
477 }
478
479 // Check consistency in number of dimensions
480 if (histo && (vars.getSize() != histo->GetDimension())) {
481 coutE(InputArguments) << "RooDataHist::importTH1Set(" << GetName() << "): dimension of input histogram must match "
482 << "number of continuous variables" << endl ;
483 throw std::invalid_argument("Inputs histograms for RooDataHist are not compatible with dimensions of variables.");
484 }
485
486 // Copy bins and ranges from THx to dimension observables
487 Int_t offset[3] ;
488 adjustBinning(vars,*histo,offset) ;
489
490 // Initialize internal data structure
491 if (!init) {
492 initialize() ;
493 appendToDir(this,kTRUE) ;
494 init = kTRUE ;
495 }
496
497 // Define x,y,z as 1st, 2nd and 3rd observable
498 RooRealVar* xvar = (RooRealVar*) _vars.find(vars.at(0)->GetName()) ;
499 RooRealVar* yvar = (RooRealVar*) (vars.at(1) ? _vars.find(vars.at(1)->GetName()) : 0 ) ;
500 RooRealVar* zvar = (RooRealVar*) (vars.at(2) ? _vars.find(vars.at(2)->GetName()) : 0 ) ;
501
502 // Transfer contents
503 Int_t xmin(0),ymin(0),zmin(0) ;
504 RooArgSet vset(*xvar) ;
505 Double_t volume = xvar->getMax()-xvar->getMin() ;
506 xmin = offset[0] ;
507 if (yvar) {
508 vset.add(*yvar) ;
509 ymin = offset[1] ;
510 volume *= (yvar->getMax()-yvar->getMin()) ;
511 }
512 if (zvar) {
513 vset.add(*zvar) ;
514 zmin = offset[2] ;
515 volume *= (zvar->getMax()-zvar->getMin()) ;
516 }
517 Double_t avgBV = volume / numEntries() ;
518
519 Int_t ic(0),ix(0),iy(0),iz(0) ;
520 for (ic=0 ; ic < icat->numBins(0) ; ic++) {
521 icat->setBin(ic) ;
522 histo = hmap[icat->getCurrentLabel()] ;
523 for (ix=0 ; ix < xvar->getBins() ; ix++) {
524 xvar->setBin(ix) ;
525 if (yvar) {
526 for (iy=0 ; iy < yvar->getBins() ; iy++) {
527 yvar->setBin(iy) ;
528 if (zvar) {
529 for (iz=0 ; iz < zvar->getBins() ; iz++) {
530 zvar->setBin(iz) ;
531 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
532 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)) ;
533 }
534 } else {
535 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
536 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)) ;
537 }
538 }
539 } else {
540 Double_t bv = doDensityCorrection ? binVolume(vset)/avgBV : 1;
541 add(vset,bv*histo->GetBinContent(ix+1+xmin)*wgt,bv*TMath::Power(histo->GetBinError(ix+1+xmin)*wgt,2)) ;
542 }
543 }
544 }
545
546}
547
548
549
550////////////////////////////////////////////////////////////////////////////////
551/// Import data from given set of TH1/2/3 into this RooDataHist. The category indexCat labels the sources
552/// in the constructed RooDataHist. The stl map provides the mapping between the indexCat state labels
553/// and the import source
554
555void RooDataHist::importDHistSet(const RooArgList& /*vars*/, RooCategory& indexCat, std::map<std::string,RooDataHist*> dmap, Double_t initWgt)
556{
557 RooCategory* icat = (RooCategory*) _vars.find(indexCat.GetName()) ;
558
559 for (const auto& diter : dmap) {
560
561 // Define state labels in index category (both in provided indexCat and in internal copy in dataset)
562 if (!indexCat.hasLabel(diter.first)) {
563 indexCat.defineType(diter.first) ;
564 coutI(InputArguments) << "RooDataHist::importDHistSet(" << GetName() << ") defining state \"" << diter.first << "\" in index category " << indexCat.GetName() << endl ;
565 }
566 if (!icat->hasLabel(diter.first)) {
567 icat->defineType(diter.first) ;
568 }
569 }
570
571 initialize() ;
572 appendToDir(this,kTRUE) ;
573
574
575 for (const auto& diter : dmap) {
576
577 RooDataHist* dhist = diter.second ;
578
579 icat->setLabel(diter.first.c_str()) ;
580
581 // Transfer contents
582 for (Int_t i=0 ; i<dhist->numEntries() ; i++) {
583 _vars.assign(*dhist->get(i)) ;
584 add(_vars,dhist->weight()*initWgt, pow(dhist->weightError(SumW2),2) ) ;
585 }
586
587 }
588}
589
590////////////////////////////////////////////////////////////////////////////////
591/// Helper doing the actual work of adjustBinning().
592
593void RooDataHist::_adjustBinning(RooRealVar &theirVar, const TAxis &axis,
594 RooRealVar *ourVar, Int_t *offset)
595{
596 if (!dynamic_cast<RooRealVar*>(static_cast<RooAbsArg*>(ourVar))) {
597 coutE(InputArguments) << "RooDataHist::adjustBinning(" << GetName() << ") ERROR: dimension " << ourVar->GetName() << " must be real" << endl ;
598 assert(0) ;
599 }
600
601 const double xlo = theirVar.getMin();
602 const double xhi = theirVar.getMax();
603
604 if (axis.GetXbins()->GetArray()) {
605 RooBinning xbins(axis.GetNbins(), axis.GetXbins()->GetArray());
606
607 const double tolerance = 1e-6 * xbins.averageBinWidth();
608
609 // Adjust xlo/xhi to nearest boundary
610 const double xloAdj = xbins.binLow(xbins.binNumber(xlo + tolerance));
611 const double xhiAdj = xbins.binHigh(xbins.binNumber(xhi - tolerance));
612 xbins.setRange(xloAdj, xhiAdj);
613
614 theirVar.setBinning(xbins);
615
616 if (true || fabs(xloAdj - xlo) > tolerance || fabs(xhiAdj - xhi) > tolerance) {
617 coutI(DataHandling)<< "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << ourVar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl;
618 }
619
620 ourVar->setBinning(xbins);
621
622 if (offset) {
623 *offset = xbins.rawBinNumber(xloAdj + tolerance);
624 }
625 } else {
626 RooBinning xbins(axis.GetXmin(), axis.GetXmax());
627 xbins.addUniform(axis.GetNbins(), axis.GetXmin(), axis.GetXmax());
628
629 const double tolerance = 1e-6 * xbins.averageBinWidth();
630
631 // Adjust xlo/xhi to nearest boundary
632 const double xloAdj = xbins.binLow(xbins.binNumber(xlo + tolerance));
633 const double xhiAdj = xbins.binHigh(xbins.binNumber(xhi - tolerance));
634 xbins.setRange(xloAdj, xhiAdj);
635 theirVar.setRange(xloAdj, xhiAdj);
636
637 if (fabs(xloAdj - xlo) > tolerance || fabs(xhiAdj - xhi) > tolerance) {
638 coutI(DataHandling)<< "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << ourVar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl;
639 }
640
641 RooUniformBinning xbins2(xloAdj, xhiAdj, xbins.numBins());
642 ourVar->setBinning(xbins2);
643
644 if (offset) {
645 *offset = xbins.rawBinNumber(xloAdj + tolerance);
646 }
647 }
648}
649
650////////////////////////////////////////////////////////////////////////////////
651/// Adjust binning specification on first and optionally second and third
652/// observable to binning in given reference TH1. Used by constructors
653/// that import data from an external TH1.
654/// Both the variables in vars and in this RooDataHist are adjusted.
655/// @param vars List with variables that are supposed to have their binning adjusted.
656/// @param href Reference histogram that dictates the binning
657/// @param offset If not nullptr, a possible bin count offset for the axes x,y,z is saved here as Int_t[3]
658
659void RooDataHist::adjustBinning(const RooArgList& vars, const TH1& href, Int_t* offset)
660{
661 auto xvar = static_cast<RooRealVar*>( _vars.find(*vars.at(0)) );
662 _adjustBinning(*static_cast<RooRealVar*>(vars.at(0)), *href.GetXaxis(), xvar, offset ? &offset[0] : nullptr);
663
664 if (vars.at(1)) {
665 auto yvar = static_cast<RooRealVar*>(_vars.find(*vars.at(1)));
666 if (yvar)
667 _adjustBinning(*static_cast<RooRealVar*>(vars.at(1)), *href.GetYaxis(), yvar, offset ? &offset[1] : nullptr);
668 }
669
670 if (vars.at(2)) {
671 auto zvar = static_cast<RooRealVar*>(_vars.find(*vars.at(2)));
672 if (zvar)
673 _adjustBinning(*static_cast<RooRealVar*>(vars.at(2)), *href.GetZaxis(), zvar, offset ? &offset[2] : nullptr);
674 }
675
676}
677
678
679namespace {
680/// Clone external weight arrays, unless the external array is nullptr.
681void cloneArray(double*& ours, const double* theirs, std::size_t n) {
682 if (ours) delete[] ours;
683 ours = nullptr;
684 if (!theirs) return;
685 ours = new double[n];
686 std::copy(theirs, theirs+n, ours);
687}
688
689/// Allocate and initialise an array with desired size and values.
690void initArray(double*& arr, std::size_t n, double val) {
691 if (arr) delete[] arr;
692 arr = nullptr;
693 if (n == 0) return;
694 arr = new double[n];
695 std::fill(arr, arr+n, val);
696}
697}
698
699
700////////////////////////////////////////////////////////////////////////////////
701/// Initialization procedure: allocate weights array, calculate
702/// multipliers needed for N-space to 1-dim array jump table,
703/// and fill the internal tree with all bin center coordinates
704
705void RooDataHist::initialize(const char* binningName, Bool_t fillTree)
706{
707 _lvvars.clear();
708 _lvbins.clear();
709
710 // Fill array of LValue pointers to variables
711 for (unsigned int i = 0; i < _vars.size(); ++i) {
712 if (binningName) {
713 RooRealVar* rrv = dynamic_cast<RooRealVar*>(_vars[i]);
714 if (rrv) {
715 rrv->setBinning(rrv->getBinning(binningName));
716 }
717 }
718
719 auto lvarg = dynamic_cast<RooAbsLValue*>(_vars[i]);
720 assert(lvarg);
721 _lvvars.push_back(lvarg);
722
723 const RooAbsBinning* binning = lvarg->getBinningPtr(0);
724 _lvbins.emplace_back(binning ? binning->clone() : nullptr);
725 }
726
727
728 // Allocate coefficients array
729 _idxMult.resize(_vars.getSize()) ;
730
731 _arrSize = 1 ;
732 unsigned int n = 0u;
733 for (const auto var : _vars) {
734 auto arg = dynamic_cast<const RooAbsLValue*>(var);
735 assert(arg);
736
737 // Calculate sub-index multipliers for master index
738 for (unsigned int i = 0u; i<n; i++) {
739 _idxMult[i] *= arg->numBins() ;
740 }
741 _idxMult[n++] = 1 ;
742
743 // Calculate dimension of weight array
744 _arrSize *= arg->numBins() ;
745 }
746
747 // Allocate and initialize weight array if necessary
748 if (!_wgt) {
749 initArray(_wgt, _arrSize, 0.);
750 delete[] _errLo; _errLo = nullptr;
751 delete[] _errHi; _errHi = nullptr;
752 delete[] _sumw2; _sumw2 = nullptr;
753 initArray(_binv, _arrSize, 0.);
754
755 // Refill array pointers in data store when reading
756 // from Streamer
757 if (!fillTree) {
759 }
760 }
761
762 if (!fillTree) return ;
763
764 // Fill TTree with bin center coordinates
765 // Calculate plot bins of components from master index
766
767 for (Int_t ibin=0 ; ibin < _arrSize ; ibin++) {
768 Int_t j(0), idx(0), tmp(ibin) ;
769 Double_t theBinVolume(1) ;
770 for (auto arg2 : _lvvars) {
771 idx = tmp / _idxMult[j] ;
772 tmp -= idx*_idxMult[j++] ;
773 arg2->setBin(idx) ;
774 theBinVolume *= arg2->getBinWidth(idx) ;
775 }
776 _binv[ibin] = theBinVolume ;
777
778 fill() ;
779 }
780
781
782}
783
784
785////////////////////////////////////////////////////////////////////////////////
786
788{
789 if (!_binbounds.empty()) return;
790 for (auto& it : _lvbins) {
791 _binbounds.push_back(std::vector<Double_t>());
792 if (it) {
793 std::vector<Double_t>& bounds = _binbounds.back();
794 bounds.reserve(2 * it->numBins());
795 for (Int_t i = 0; i < it->numBins(); ++i) {
796 bounds.push_back(it->binLow(i));
797 bounds.push_back(it->binHigh(i));
798 }
799 }
800 }
801}
802
803
804////////////////////////////////////////////////////////////////////////////////
805/// Copy constructor
806
807RooDataHist::RooDataHist(const RooDataHist& other, const char* newname) :
808 RooAbsData(other,newname), RooDirItem(), _arrSize(other._arrSize), _idxMult(other._idxMult), _pbinvCache(other._pbinvCache)
809{
810 // Allocate and initialize weight array
811 assert(_arrSize == other._arrSize);
812 cloneArray(_wgt, other._wgt, other._arrSize);
813 cloneArray(_errLo, other._errLo, other._arrSize);
814 cloneArray(_errHi, other._errHi, other._arrSize);
815 cloneArray(_binv, other._binv, other._arrSize);
816 cloneArray(_sumw2, other._sumw2, other._arrSize);
817
818 // Fill array of LValue pointers to variables
819 for (const auto rvarg : _vars) {
820 auto lvarg = dynamic_cast<RooAbsLValue*>(rvarg);
821 assert(lvarg);
822 _lvvars.push_back(lvarg);
823 const RooAbsBinning* binning = lvarg->getBinningPtr(0);
824 _lvbins.emplace_back(binning ? binning->clone() : 0) ;
825 }
826
828
829 appendToDir(this,kTRUE) ;
830}
831
832
833
834////////////////////////////////////////////////////////////////////////////////
835/// Constructor of a data hist from (part of) an existing data hist. The dimensions
836/// of the data set are defined by the 'vars' RooArgSet, which can be identical
837/// to 'dset' dimensions, or a subset thereof. Reduced dimensions will be projected
838/// in the output data hist. The optional 'cutVar' formula variable can used to
839/// select the subset of bins to be copied.
840///
841/// For most uses the RooAbsData::reduce() wrapper function, which uses this constructor,
842/// is the most convenient way to create a subset of an existing data
843
844RooDataHist::RooDataHist(std::string_view name, std::string_view title, RooDataHist* h, const RooArgSet& varSubset,
845 const RooFormulaVar* cutVar, const char* cutRange, Int_t nStart, Int_t nStop, Bool_t copyCache) :
846 RooAbsData(name,title,varSubset)
847{
848 // Initialize datastore
849 _dstore = new RooTreeDataStore(name,title,*h->_dstore,_vars,cutVar,cutRange,nStart,nStop,copyCache) ;
850
851 initialize(0,kFALSE) ;
852
853 // Copy weight array etc
854 assert(_arrSize == h->_arrSize);
855 cloneArray(_wgt, h->_wgt, _arrSize);
856 cloneArray(_errLo, h->_errLo, _arrSize);
857 cloneArray(_errHi, h->_errHi, _arrSize);
858 cloneArray(_binv, h->_binv, _arrSize);
859 cloneArray(_sumw2, h->_sumw2, _arrSize);
860
862
863 appendToDir(this,kTRUE) ;
865}
866
867
868////////////////////////////////////////////////////////////////////////////////
869/// Construct a clone of this dataset that contains only the cached variables
870
871RooAbsData* RooDataHist::cacheClone(const RooAbsArg* newCacheOwner, const RooArgSet* newCacheVars, const char* newName)
872{
873 checkInit() ;
874
875 RooDataHist* dhist = new RooDataHist(newName?newName:GetName(),GetTitle(),this,*get(),0,0,0,2000000000,kTRUE) ;
876
877 RooArgSet* selCacheVars = (RooArgSet*) newCacheVars->selectCommon(dhist->_cachedVars) ;
878 dhist->attachCache(newCacheOwner, *selCacheVars) ;
879 delete selCacheVars ;
880
881 return dhist ;
882}
883
884
885
886////////////////////////////////////////////////////////////////////////////////
887/// Implementation of RooAbsData virtual method that drives the RooAbsData::reduce() methods
888
889RooAbsData* RooDataHist::reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange,
890 std::size_t nStart, std::size_t nStop, Bool_t /*copyCache*/)
891{
892 checkInit() ;
893 RooArgSet* myVarSubset = (RooArgSet*) _vars.selectCommon(varSubset) ;
894 RooDataHist *rdh = new RooDataHist(GetName(), GetTitle(), *myVarSubset) ;
895 delete myVarSubset ;
896
897 RooFormulaVar* cloneVar = 0;
898 RooArgSet* tmp(0) ;
899 if (cutVar) {
900 // Deep clone cutVar and attach clone to this dataset
901 tmp = (RooArgSet*) RooArgSet(*cutVar).snapshot() ;
902 if (!tmp) {
903 coutE(DataHandling) << "RooDataHist::reduceEng(" << GetName() << ") Couldn't deep-clone cut variable, abort," << endl ;
904 return 0 ;
905 }
906 cloneVar = (RooFormulaVar*) tmp->find(*cutVar) ;
907 cloneVar->attachDataSet(*this) ;
908 }
909
910 Double_t lo,hi ;
911 const std::size_t nevt = nStop < static_cast<std::size_t>(numEntries()) ? nStop : static_cast<std::size_t>(numEntries());
912 for (auto i=nStart; i<nevt ; i++) {
913 const RooArgSet* row = get(i) ;
914
915 Bool_t doSelect(kTRUE) ;
916 if (cutRange) {
917 for (const auto arg : *row) {
918 if (!arg->inRange(cutRange)) {
919 doSelect = kFALSE ;
920 break ;
921 }
922 }
923 }
924 if (!doSelect) continue ;
925
926 if (!cloneVar || cloneVar->getVal()) {
927 weightError(lo,hi,SumW2) ;
928 rdh->add(*row,weight(),lo*lo) ;
929 }
930 }
931
932 if (cloneVar) {
933 delete tmp ;
934 }
935
936 return rdh ;
937}
938
939
940
941////////////////////////////////////////////////////////////////////////////////
942/// Destructor
943
945{
946 delete[] _wgt;
947 delete[] _errLo;
948 delete[] _errHi;
949 delete[] _sumw2;
950 delete[] _binv;
951
952 removeFromDir(this) ;
954}
955
956
957
958
959////////////////////////////////////////////////////////////////////////////////
960/// Calculate bin number of the given coordinates. If only a subset of the internal
961/// coordinates are passed, the missing coordinates are taken at their current value.
962/// \param[in] coord Variables that are representing the coordinates.
963/// \param[in] fast If the variables in `coord` and the ones of the data hist have the
964/// same size and layout, `fast` can be set to skip checking that all variables are
965/// present in `coord`.
967 checkInit() ;
968 return calcTreeIndex(coord, fast);
969}
970
971
972
973
974////////////////////////////////////////////////////////////////////////////////
975/// Calculate the bin index corresponding to the coordinates passed as argument.
976/// \param[in] coords Coordinates. If `fast == false`, these can be partial.
977/// \param[in] fast Promise that the coordinates in `coords` have the same order
978/// as the internal coordinates. In this case, values are looked up only by index.
979std::size_t RooDataHist::calcTreeIndex(const RooAbsCollection& coords, bool fast) const
980{
981 // With fast, caller promises that layout of `coords` is identical to our internal `vars`.
982 // Previously, this was verified with an assert in debug mode like this:
983 //
984 // assert(!fast || coords.hasSameLayout(_vars));
985 //
986 // However, there are usecases where the externally provided `coords` have
987 // different names than the internal variables, even though they correspond
988 // to each other. For example, if the observables in the computation graph
989 // are renamed with `redirectServers`. Hence, we can't do a meaningful assert
990 // here.
991
992 if (&_vars == &coords)
993 fast = true;
994
995 std::size_t masterIdx = 0;
996
997 for (unsigned int i=0; i < _vars.size(); ++i) {
998 const RooAbsArg* internalVar = _vars[i];
999 const RooAbsBinning* binning = _lvbins[i].get();
1000
1001 // Find the variable that we need values from.
1002 // That's either the variable directly from the external coordinates
1003 // or we find the external one that has the same name as "internalVar".
1004 const RooAbsArg* theVar = fast ? coords[i] : coords.find(*internalVar);
1005 if (!theVar) {
1006 // Variable is not in external coordinates. Use current internal value.
1007 theVar = internalVar;
1008 }
1009 // If fast is on, users promise that the sets have the same layout:
1010 //
1011 // assert(!fast || strcmp(internalVar->GetName(), theVar->GetName()) == 0);
1012 //
1013 // This assert is commented out for the same reasons that applied to the
1014 // other assert explained above.
1015
1016 if (binning) {
1017 assert(dynamic_cast<const RooAbsReal*>(theVar));
1018 const double val = static_cast<const RooAbsReal*>(theVar)->getVal();
1019 masterIdx += _idxMult[i] * binning->binNumber(val);
1020 } else {
1021 // We are a category. No binning.
1022 assert(dynamic_cast<const RooAbsCategoryLValue*>(theVar));
1023 auto cat = static_cast<const RooAbsCategoryLValue*>(theVar);
1024 masterIdx += _idxMult[i] * cat->getBin(static_cast<const char*>(nullptr));
1025 }
1026 }
1027
1028 return masterIdx ;
1029}
1030
1031
1032
1033////////////////////////////////////////////////////////////////////////////////
1034/// Debug stuff, should go...
1035
1037{
1038 cout << "_arrSize = " << _arrSize << endl ;
1039 for (Int_t i=0 ; i < _arrSize ; i++) {
1040 cout << "wgt[" << i << "] = " << _wgt[i]
1041 << "\tsumw2[" << i << "] = " << (_sumw2 ? _sumw2[i] : -1.)
1042 << "\tvol[" << i << "] = " << _binv[i] << endl ;
1043 }
1044}
1045
1046
1047
1048////////////////////////////////////////////////////////////////////////////////
1049/// Back end function to plotting functionality. Plot RooDataHist on given
1050/// frame in mode specified by plot options 'o'. The main purpose of
1051/// this function is to match the specified binning on 'o' to the
1052/// internal binning of the plot observable in this RooDataHist.
1053/// \see RooAbsData::plotOn() for plotting options.
1055{
1056 checkInit() ;
1057 if (o.bins) return RooAbsData::plotOn(frame,o) ;
1058
1059 if(0 == frame) {
1060 coutE(InputArguments) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << endl;
1061 return 0;
1062 }
1064 if(0 == var) {
1065 coutE(InputArguments) << ClassName() << "::" << GetName()
1066 << ":plotOn: frame does not specify a plot variable" << endl;
1067 return 0;
1068 }
1069
1070 RooRealVar* dataVar = (RooRealVar*) _vars.find(*var) ;
1071 if (!dataVar) {
1072 coutE(InputArguments) << ClassName() << "::" << GetName()
1073 << ":plotOn: dataset doesn't contain plot frame variable" << endl;
1074 return 0;
1075 }
1076
1077 o.bins = &dataVar->getBinning() ;
1078 return RooAbsData::plotOn(frame,o) ;
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// A faster version of RooDataHist::weight that assumes the passed arguments
1083/// are aligned with the histogram variables.
1084/// \param[in] bin Coordinates for which the weight should be calculated.
1085/// Has to be aligned with the internal histogram variables.
1086/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1087/// used for the interpolation. If zero, the bare weight for
1088/// the bin enclosing the coordinatesis returned.
1089/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1090/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1091/// underflow bins are assumed to have weight zero and
1092/// overflow bins have weight one. Otherwise, the
1093/// histogram is mirrored at the boundaries for the
1094/// interpolation.
1095
1096double RooDataHist::weightFast(const RooArgSet& bin, Int_t intOrder, Bool_t correctForBinSize, Bool_t cdfBoundaries)
1097{
1098 checkInit() ;
1099
1100 // Handle illegal intOrder values
1101 if (intOrder<0) {
1102 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") ERROR: interpolation order must be positive" << endl ;
1103 return 0 ;
1104 }
1105
1106 // Handle no-interpolation case
1107 if (intOrder==0) {
1108 const auto idx = calcTreeIndex(bin, true);
1109 if (correctForBinSize) {
1110 return get_wgt(idx) / _binv[idx];
1111 } else {
1112 return get_wgt(idx);
1113 }
1114 }
1115
1116 // Handle all interpolation cases
1117 return weightInterpolated(bin, intOrder, correctForBinSize, cdfBoundaries);
1118}
1119
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Return the weight at given coordinates with optional interpolation.
1123/// \param[in] bin Coordinates for which the weight should be calculated.
1124/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1125/// used for the interpolation. If zero, the bare weight for
1126/// the bin enclosing the coordinatesis returned.
1127/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1128/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1129/// underflow bins are assumed to have weight zero and
1130/// overflow bins have weight one. Otherwise, the
1131/// histogram is mirrored at the boundaries for the
1132/// interpolation.
1133/// \param[in] oneSafe Ignored.
1134
1135Double_t RooDataHist::weight(const RooArgSet& bin, Int_t intOrder, Bool_t correctForBinSize, Bool_t cdfBoundaries, Bool_t /*oneSafe*/)
1136{
1137 checkInit() ;
1138
1139 // Handle illegal intOrder values
1140 if (intOrder<0) {
1141 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") ERROR: interpolation order must be positive" << endl ;
1142 return 0 ;
1143 }
1144
1145 // Handle no-interpolation case
1146 if (intOrder==0) {
1147 const auto idx = calcTreeIndex(bin, false);
1148 if (correctForBinSize) {
1149 return get_wgt(idx) / _binv[idx];
1150 } else {
1151 return get_wgt(idx);
1152 }
1153 }
1154
1155 // Handle all interpolation cases
1156 _vars.assignValueOnly(bin) ;
1157
1158 return weightInterpolated(_vars, intOrder, correctForBinSize, cdfBoundaries);
1159}
1160
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Return the weight at given coordinates with interpolation.
1164/// \param[in] bin Coordinates for which the weight should be calculated.
1165/// Has to be aligned with the internal histogram variables.
1166/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1167/// used for the interpolation.
1168/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1169/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1170/// underflow bins are assumed to have weight zero and
1171/// overflow bins have weight one. Otherwise, the
1172/// histogram is mirrored at the boundaries for the
1173/// interpolation.
1174
1175double RooDataHist::weightInterpolated(const RooArgSet& bin, int intOrder, bool correctForBinSize, bool cdfBoundaries) {
1176 VarInfo const& varInfo = getVarInfo();
1177
1178 const auto centralIdx = calcTreeIndex(bin, true);
1179
1180 double wInt{0} ;
1181 if (varInfo.nRealVars == 1) {
1182
1183 // 1-dimensional interpolation
1184 auto const& realX = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx1]);
1185 wInt = interpolateDim(varInfo.realVarIdx1, realX.getVal(), centralIdx, intOrder, correctForBinSize, cdfBoundaries) ;
1186
1187 } else if (varInfo.nRealVars == 2) {
1188
1189 // 2-dimensional interpolation
1190 auto const& realX = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx1]);
1191 auto const& realY = static_cast<RooRealVar const&>(*bin[varInfo.realVarIdx2]);
1192 double xval = realX.getVal() ;
1193 double yval = realY.getVal() ;
1194
1195 RooAbsBinning const& binningY = realY.getBinning();
1196
1197 int ybinC = binningY.binNumber(yval) ;
1198 int ybinLo = ybinC-intOrder/2 - ((yval<binningY.binCenter(ybinC))?1:0) ;
1199 int ybinM = binningY.numBins() ;
1200
1201 auto idxMultY = _idxMult[varInfo.realVarIdx2];
1202 auto offsetIdx = centralIdx - idxMultY * ybinC;
1203
1204 std::vector<double> yarr(intOrder+1);
1205 std::vector<double> xarr(intOrder+1);
1206 for (int i=ybinLo ; i<=intOrder+ybinLo ; i++) {
1207 int ibin ;
1208 if (i>=0 && i<ybinM) {
1209 // In range
1210 ibin = i ;
1211 xarr[i-ybinLo] = binningY.binCenter(ibin) ;
1212 } else if (i>=ybinM) {
1213 // Overflow: mirror
1214 ibin = 2*ybinM-i-1 ;
1215 xarr[i-ybinLo] = 2*binningY.highBound()-binningY.binCenter(ibin) ;
1216 } else {
1217 // Underflow: mirror
1218 ibin = -i -1;
1219 xarr[i-ybinLo] = 2*binningY.lowBound()-binningY.binCenter(ibin) ;
1220 }
1221 auto centralIdxX = offsetIdx + idxMultY * ibin;
1222 yarr[i-ybinLo] = interpolateDim(varInfo.realVarIdx1,xval,centralIdxX,intOrder,correctForBinSize,kFALSE) ;
1223 }
1224
1225 if (gDebug>7) {
1226 cout << "RooDataHist interpolating data is" << endl ;
1227 cout << "xarr = " ;
1228 for (int q=0; q<=intOrder ; q++) cout << xarr[q] << " " ;
1229 cout << " yarr = " ;
1230 for (int q=0; q<=intOrder ; q++) cout << yarr[q] << " " ;
1231 cout << endl ;
1232 }
1233 wInt = RooMath::interpolate(xarr.data(),yarr.data(),intOrder+1,yval) ;
1234
1235 } else {
1236
1237 // Higher dimensional scenarios not yet implemented
1238 coutE(InputArguments) << "RooDataHist::weight(" << GetName() << ") interpolation in "
1239 << varInfo.nRealVars << " dimensions not yet implemented" << endl ;
1240 return weightFast(bin,0,correctForBinSize,cdfBoundaries) ;
1241
1242 }
1243
1244 return wInt ;
1245}
1246
1247
1248////////////////////////////////////////////////////////////////////////////////
1249/// Return the asymmetric errors on the current weight.
1250/// \see weightError(ErrorType) const for symmetric error.
1251/// \param[out] lo Low error.
1252/// \param[out] hi High error.
1253/// \param[in] etype Type of error to compute. May throw if not supported.
1254/// Supported errors are
1255/// - `Poisson` Default. Asymmetric Poisson errors (68% CL).
1256/// - `SumW2` The square root of the sum of weights. (Symmetric).
1257/// - `None` Return zero.
1258void RooDataHist::weightError(double& lo, double& hi, ErrorType etype) const
1259{
1260 checkInit() ;
1261
1262 switch (etype) {
1263
1264 case Auto:
1265 throw std::invalid_argument(Form("RooDataHist::weightError(%s) error type Auto not allowed here",GetName())) ;
1266 break ;
1267
1268 case Expected:
1269 throw std::invalid_argument(Form("RooDataHist::weightError(%s) error type Expected not allowed here",GetName())) ;
1270 break ;
1271
1272 case Poisson:
1273 if (get_curWgtErrLo() >= 0) {
1274 // Weight is preset or precalculated
1275 lo = get_curWgtErrLo();
1276 hi = get_curWgtErrHi();
1277 return ;
1278 }
1279
1280 if (!_errLo || !_errHi) {
1281 // We didn't track asymmetric errors so far, so now we need to allocate
1282 initArray(_errLo, _arrSize, -1.);
1283 initArray(_errHi, _arrSize, -1.);
1285 }
1286
1287 // Calculate poisson errors
1288 Double_t ym,yp ;
1290 _errLo[_curIndex] = weight()-ym;
1291 _errHi[_curIndex] = yp-weight();
1292 lo = _errLo[_curIndex];
1293 hi = _errHi[_curIndex];
1294 return ;
1295
1296 case SumW2:
1297 lo = sqrt(get_curSumW2());
1298 hi = lo;
1299 return ;
1300
1301 case None:
1302 lo = 0 ;
1303 hi = 0 ;
1304 return ;
1305 }
1306}
1307
1308
1309// wve adjust for variable bin sizes
1310
1311////////////////////////////////////////////////////////////////////////////////
1312/// Perform boundary safe 'intOrder'-th interpolation of weights in dimension 'dim'
1313/// at current value 'xval'
1314
1315/// \param[in] iDim Index of the histogram dimension along which to interpolate.
1316/// \param[in] xval Value of histogram variable at dimension `iDim` for which
1317/// we want to interpolate the histogram weight.
1318/// \param[in] centralIdx Index of the bin that the point at which we
1319/// interpolate the histogram weight falls into
1320/// (can be obtained with `RooDataHist::calcTreeIndex`).
1321/// \param[in] intOrder Interpolation order, i.e. how many neighbouring bins are
1322/// used for the interpolation.
1323/// \param[in] correctForBinSize Enable the inverse bin volume correction factor.
1324/// \param[in] cdfBoundaries Enable the special boundary coundition for a cdf:
1325/// underflow bins are assumed to have weight zero and
1326/// overflow bins have weight one. Otherwise, the
1327/// histogram is mirrored at the boundaries for the
1328/// interpolation.
1329double RooDataHist::interpolateDim(int iDim, double xval, size_t centralIdx, int intOrder, bool correctForBinSize, bool cdfBoundaries)
1330{
1331 auto const& binning = static_cast<RooRealVar&>(*_vars[iDim]).getBinning();
1332
1333 // Fill workspace arrays spanning interpolation area
1334 int fbinC = binning.binNumber(xval) ;
1335 int fbinLo = fbinC-intOrder/2 - ((xval<binning.binCenter(fbinC))?1:0) ;
1336 int fbinM = binning.numBins() ;
1337
1338 auto idxMult = _idxMult[iDim];
1339 auto offsetIdx = centralIdx - idxMult * fbinC;
1340
1341 std::vector<double> yarr(intOrder+1) ;
1342 std::vector<double> xarr(intOrder+1);
1343 for (int i=fbinLo ; i<=intOrder+fbinLo ; i++) {
1344 int ibin ;
1345 if (i>=0 && i<fbinM) {
1346 // In range
1347 ibin = i ;
1348 xarr[i-fbinLo] = binning.binCenter(ibin) ;
1349 auto idx = offsetIdx + idxMult * ibin;
1350 yarr[i - fbinLo] = get_wgt(idx);
1351 if (correctForBinSize) yarr[i-fbinLo] /= _binv[idx] ;
1352 } else if (i>=fbinM) {
1353 // Overflow: mirror
1354 ibin = 2*fbinM-i-1 ;
1355 if (cdfBoundaries) {
1356 xarr[i-fbinLo] = binning.highBound()+1e-10*(i-fbinM+1) ;
1357 yarr[i-fbinLo] = 1.0 ;
1358 } else {
1359 auto idx = offsetIdx + idxMult * ibin;
1360 xarr[i-fbinLo] = 2*binning.highBound()-binning.binCenter(ibin) ;
1361 yarr[i - fbinLo] = get_wgt(idx);
1362 if (correctForBinSize)
1363 yarr[i - fbinLo] /= _binv[idx];
1364 }
1365 } else {
1366 // Underflow: mirror
1367 ibin = -i - 1 ;
1368 if (cdfBoundaries) {
1369 xarr[i-fbinLo] = binning.lowBound()-ibin*(1e-10) ; ;
1370 yarr[i-fbinLo] = 0.0 ;
1371 } else {
1372 auto idx = offsetIdx + idxMult * ibin;
1373 xarr[i-fbinLo] = 2*binning.lowBound()-binning.binCenter(ibin) ;
1374 yarr[i - fbinLo] = get_wgt(idx);
1375 if (correctForBinSize)
1376 yarr[i - fbinLo] /= _binv[idx];
1377 }
1378 }
1379 }
1380 return RooMath::interpolate(xarr.data(),yarr.data(),intOrder+1,xval) ;
1381}
1382
1383
1384
1385
1386////////////////////////////////////////////////////////////////////////////////
1387/// Increment the bin content of the bin enclosing the given coordinates.
1388///
1389/// \param[in] row Coordinates of the bin.
1390/// \param[in] wgt Increment by this weight.
1391/// \param[in] sumw2 Optionally, track the sum of squared weights. If a value > 0 or
1392/// a weight != 1. is passed for the first time, a vector for the squared weights will be allocated.
1393void RooDataHist::add(const RooArgSet& row, Double_t wgt, Double_t sumw2)
1394{
1395 checkInit() ;
1396
1397 if ((sumw2 > 0. || wgt != 1.) && !_sumw2) {
1398 // Receiving a weighted entry. SumW2 != sumw from now on.
1399 _sumw2 = new double[_arrSize];
1400 std::copy(_wgt, _wgt+_arrSize, _sumw2);
1401
1403 }
1404
1405 const auto idx = calcTreeIndex(row, false);
1406
1407 _wgt[idx] += wgt ;
1408 if (_sumw2) _sumw2[idx] += (sumw2 > 0 ? sumw2 : wgt*wgt);
1409
1410 _cache_sum_valid = false;
1411}
1412
1413
1414
1415////////////////////////////////////////////////////////////////////////////////
1416/// Set a bin content.
1417/// \param[in] row Coordinates of the bin to be set.
1418/// \param[in] wgt New bin content.
1419/// \param[in] wgtErrLo Low error of the bin content.
1420/// \param[in] wgtErrHi High error of the bin content.
1421void RooDataHist::set(const RooArgSet& row, Double_t wgt, Double_t wgtErrLo, Double_t wgtErrHi)
1422{
1423 checkInit() ;
1424
1425 if (!_errLo || !_errHi) {
1426 initArray(_errLo, _arrSize, -1.);
1427 initArray(_errHi, _arrSize, -1.);
1429 }
1430
1431 const auto idx = calcTreeIndex(row, false);
1432
1433 _wgt[idx] = wgt ;
1434 _errLo[idx] = wgtErrLo ;
1435 _errHi[idx] = wgtErrHi ;
1436
1437 _cache_sum_valid = false;
1438}
1439
1440
1441
1442////////////////////////////////////////////////////////////////////////////////
1443/// Set bin content of bin that was last loaded with get(std::size_t).
1444/// \param[in] binNumber Optional bin number to set. If empty, currently active bin is set.
1445/// \param[in] wgt New bin content.
1446/// \param[in] wgtErr Error of the new bin content. If the weight need not have an error, use 0. or a negative number.
1447void RooDataHist::set(std::size_t binNumber, double wgt, double wgtErr) {
1448 checkInit() ;
1449
1450 if (wgtErr > 0. && !_sumw2) {
1451 // Receiving a weighted entry. Need to track sumw2 from now on:
1452 cloneArray(_sumw2, _wgt, _arrSize);
1453
1455 }
1456
1457 _wgt[binNumber] = wgt ;
1458 if (_errLo) _errLo[binNumber] = wgtErr;
1459 if (_errHi) _errHi[binNumber] = wgtErr;
1460 if (_sumw2) _sumw2[binNumber] = wgtErr*wgtErr;
1461
1463}
1464
1465
1466////////////////////////////////////////////////////////////////////////////////
1467/// Set bin content of bin that was last loaded with get(std::size_t).
1468/// \deprecated Prefer set(std::size_t, double, double).
1469/// \param[in] wgt New bin content.
1470/// \param[in] wgtErr Optional error of the bin content.
1471void RooDataHist::set(double wgt, double wgtErr) {
1472 if (_curIndex == std::numeric_limits<std::size_t>::max()) {
1473 _curIndex = calcTreeIndex(_vars, true) ;
1474 }
1475
1476 set(_curIndex, wgt, wgtErr);
1477}
1478
1479
1480////////////////////////////////////////////////////////////////////////////////
1481/// Set a bin content.
1482/// \param[in] row Coordinates to compute the bin from.
1483/// \param[in] wgt New bin content.
1484/// \param[in] wgtErr Optional error of the bin content.
1485void RooDataHist::set(const RooArgSet& row, Double_t wgt, Double_t wgtErr) {
1486 set(calcTreeIndex(row, false), wgt, wgtErr);
1487}
1488
1489
1490
1491////////////////////////////////////////////////////////////////////////////////
1492/// Add all data points contained in 'dset' to this data set with given weight.
1493/// Optional cut string expression selects the data points to be added and can
1494/// reference any variable contained in this data set
1495
1496void RooDataHist::add(const RooAbsData& dset, const char* cut, Double_t wgt)
1497{
1498 RooFormulaVar cutVar("select",cut,*dset.get()) ;
1499 add(dset,&cutVar,wgt) ;
1500}
1501
1502
1503
1504////////////////////////////////////////////////////////////////////////////////
1505/// Add all data points contained in 'dset' to this data set with given weight.
1506/// Optional RooFormulaVar pointer selects the data points to be added.
1507
1508void RooDataHist::add(const RooAbsData& dset, const RooFormulaVar* cutVar, Double_t wgt)
1509{
1510 checkInit() ;
1511
1512 RooFormulaVar* cloneVar = 0;
1513 RooArgSet* tmp(0) ;
1514 if (cutVar) {
1515 // Deep clone cutVar and attach clone to this dataset
1516 tmp = (RooArgSet*) RooArgSet(*cutVar).snapshot() ;
1517 if (!tmp) {
1518 coutE(DataHandling) << "RooDataHist::add(" << GetName() << ") Couldn't deep-clone cut variable, abort," << endl ;
1519 return ;
1520 }
1521
1522 cloneVar = (RooFormulaVar*) tmp->find(*cutVar) ;
1523 cloneVar->attachDataSet(dset) ;
1524 }
1525
1526
1527 Int_t i ;
1528 for (i=0 ; i<dset.numEntries() ; i++) {
1529 const RooArgSet* row = dset.get(i) ;
1530 if (!cloneVar || cloneVar->getVal()) {
1531 add(*row,wgt*dset.weight(), wgt*wgt*dset.weightSquared()) ;
1532 }
1533 }
1534
1535 if (cloneVar) {
1536 delete tmp ;
1537 }
1538
1540}
1541
1542
1543
1544////////////////////////////////////////////////////////////////////////////////
1545/// Return the sum of the weights of all bins in the histogram.
1546///
1547/// \param[in] correctForBinSize Multiply the sum of weights in each bin
1548/// with the N-dimensional bin volume, making the return value
1549/// the integral over the function represented by this histogram.
1550/// \param[in] inverseBinCor Divide by the N-dimensional bin volume.
1551Double_t RooDataHist::sum(bool correctForBinSize, bool inverseBinCor) const
1552{
1553 checkInit() ;
1554
1555 // Check if result was cached
1556 const CacheSumState_t cache_code = !correctForBinSize ? kNoBinCorrection : (inverseBinCor ? kInverseBinCorr : kCorrectForBinSize);
1557 if (_cache_sum_valid == static_cast<Int_t>(cache_code)) {
1558 return _cache_sum ;
1559 }
1560
1562 for (Int_t i=0; i < _arrSize; i++) {
1563 const double theBinVolume = correctForBinSize ? (inverseBinCor ? 1/_binv[i] : _binv[i]) : 1.0 ;
1564 kahanSum += get_wgt(i) * theBinVolume;
1565 }
1566
1567 // Store result in cache
1568 _cache_sum_valid = cache_code;
1569 _cache_sum = kahanSum;
1570
1571 return kahanSum;
1572}
1573
1574
1575
1576////////////////////////////////////////////////////////////////////////////////
1577/// Return the sum of the weights of a multi-dimensional slice of the histogram
1578/// by summing only over the dimensions specified in sumSet.
1579///
1580/// The coordinates of all other dimensions are fixed to those given in sliceSet
1581///
1582/// If correctForBinSize is specified, the sum of weights
1583/// is multiplied by the M-dimensional bin volume, (M = N(sumSet)),
1584/// making the return value the integral over the function
1585/// represented by this histogram
1586
1587Double_t RooDataHist::sum(const RooArgSet& sumSet, const RooArgSet& sliceSet, bool correctForBinSize, bool inverseBinCor)
1588{
1589 checkInit() ;
1590
1591 RooArgSet varSave ;
1592 varSave.addClone(_vars) ;
1593
1594 RooArgSet sliceOnlySet(sliceSet);
1595 sliceOnlySet.remove(sumSet,true,true) ;
1596
1597 _vars.assign(sliceOnlySet);
1598 std::vector<double> const * pbinv = nullptr;
1599
1600 if(correctForBinSize && inverseBinCor) {
1601 pbinv = &calculatePartialBinVolume(sliceOnlySet);
1602 } else if(correctForBinSize && !inverseBinCor) {
1603 pbinv = &calculatePartialBinVolume(sumSet);
1604 }
1605
1606 // Calculate mask and refence plot bins for non-iterating variables
1607 std::vector<bool> mask(_vars.getSize());
1608 std::vector<int> refBin(_vars.getSize());
1609
1610 for (unsigned int i = 0; i < _vars.size(); ++i) {
1611 const RooAbsArg* arg = _vars[i];
1612 const RooAbsLValue* argLv = _lvvars[i]; // Same as above, but cross-cast
1613
1614 if (sumSet.find(*arg)) {
1615 mask[i] = false ;
1616 } else {
1617 mask[i] = true ;
1618 refBin[i] = argLv->getBin();
1619 }
1620 }
1621
1622 // Loop over entire data set, skipping masked entries
1624 for (Int_t ibin=0; ibin < _arrSize; ++ibin) {
1625
1626 std::size_t tmpibin = ibin;
1627 Bool_t skip(false) ;
1628
1629 // Check if this bin belongs in selected slice
1630 for (unsigned int ivar = 0; !skip && ivar < _vars.size(); ++ivar) {
1631 const Int_t idx = tmpibin / _idxMult[ivar] ;
1632 tmpibin -= idx*_idxMult[ivar] ;
1633 if (mask[ivar] && idx!=refBin[ivar])
1634 skip = true ;
1635 }
1636
1637 if (!skip) {
1638 const double theBinVolume = correctForBinSize ? (inverseBinCor ? 1/(*pbinv)[ibin] : (*pbinv)[ibin] ) : 1.0 ;
1639 total += get_wgt(ibin) * theBinVolume;
1640 }
1641 }
1642
1643 _vars.assign(varSave) ;
1644
1645 return total;
1646}
1647
1648////////////////////////////////////////////////////////////////////////////////
1649/// Return the sum of the weights of a multi-dimensional slice of the histogram
1650/// by summing only over the dimensions specified in sumSet.
1651///
1652/// The coordinates of all other dimensions are fixed to those given in sliceSet
1653///
1654/// If correctForBinSize is specified, the sum of weights
1655/// is multiplied by the M-dimensional bin volume, (M = N(sumSet)),
1656/// or the fraction of it that falls inside the range rangeName,
1657/// making the return value the integral over the function
1658/// represented by this histogram.
1659///
1660/// If correctForBinSize is not specified, the weights are multiplied by the
1661/// fraction of the bin volume that falls inside the range, i.e. a factor of
1662/// binVolumeInRange/totalBinVolume.
1663
1664Double_t RooDataHist::sum(const RooArgSet& sumSet, const RooArgSet& sliceSet,
1665 bool correctForBinSize, bool inverseBinCor,
1666 const std::map<const RooAbsArg*, std::pair<double, double> >& ranges,
1667 std::function<double(int)> getBinScale)
1668{
1669 checkInit();
1671 RooArgSet varSave;
1672 varSave.addClone(_vars);
1673 {
1674 RooArgSet sliceOnlySet(sliceSet);
1675 sliceOnlySet.remove(sumSet, true, true);
1676 _vars.assign(sliceOnlySet);
1677 }
1678
1679 // Calculate mask and reference plot bins for non-iterating variables,
1680 // and get ranges for iterating variables
1681 std::vector<bool> mask(_vars.getSize());
1682 std::vector<int> refBin(_vars.getSize());
1683 std::vector<double> rangeLo(_vars.getSize(), -std::numeric_limits<Double_t>::infinity());
1684 std::vector<double> rangeHi(_vars.getSize(), +std::numeric_limits<Double_t>::infinity());
1685
1686 for (std::size_t i = 0; i < _vars.size(); ++i) {
1687 const RooAbsArg* arg = _vars[i];
1688 const RooAbsLValue* argLV = _lvvars[i]; // Same object as above, but cross cast
1689
1690 RooAbsArg* sumsetv = sumSet.find(*arg);
1691 RooAbsArg* slicesetv = sliceSet.find(*arg);
1692 mask[i] = !sumsetv;
1693 if (mask[i]) {
1694 assert(argLV);
1695 refBin[i] = argLV->getBin();
1696 }
1697
1698 auto it = ranges.find(sumsetv ? sumsetv : slicesetv);
1699 if (ranges.end() != it) {
1700 rangeLo[i] = it->second.first;
1701 rangeHi[i] = it->second.second;
1702 }
1703 }
1704
1705 // Loop over entire data set, skipping masked entries
1707 for (Int_t ibin = 0; ibin < _arrSize; ++ibin) {
1708 // Check if this bin belongs in selected slice
1709 bool skip{false};
1710 for (int ivar = 0, tmp = ibin; !skip && ivar < int(_vars.size()); ++ivar) {
1711 const Int_t idx = tmp / _idxMult[ivar];
1712 tmp -= idx*_idxMult[ivar];
1713 if (mask[ivar] && idx!=refBin[ivar]) skip = true;
1714 }
1715
1716 if (skip) continue;
1717
1718 // Work out bin volume
1719 // It's not necessary to figure out the bin volume for the slice-only set explicitely here.
1720 // We need to loop over the sumSet anyway to get the partial bin containment correction,
1721 // so we can get the slice-only set volume later by dividing _binv[ibin] / binVolumeSumSetFull.
1722 Double_t binVolumeSumSetFull = 1.;
1723 Double_t binVolumeSumSetInRange = 1.;
1724 for (Int_t ivar = 0, tmp = ibin; ivar < (int)_vars.size(); ++ivar) {
1725 const Int_t idx = tmp / _idxMult[ivar];
1726 tmp -= idx*_idxMult[ivar];
1727
1728 // If the current variable is not in the sumSet, it should not be considered for the bin volume
1729 const auto arg = _vars[ivar];
1730 if (!sumSet.find(*arg)) {
1731 continue;
1732 }
1733
1734 if (_binbounds[ivar].empty()) continue;
1735 const Double_t binLo = _binbounds[ivar][2 * idx];
1736 const Double_t binHi = _binbounds[ivar][2 * idx + 1];
1737 if (binHi < rangeLo[ivar] || binLo > rangeHi[ivar]) {
1738 // bin is outside of allowed range - effective bin volume is zero
1739 binVolumeSumSetInRange = 0.;
1740 break;
1741 }
1742
1743 binVolumeSumSetFull *= binHi - binLo;
1744 binVolumeSumSetInRange *= std::min(rangeHi[ivar], binHi) - std::max(rangeLo[ivar], binLo);
1745 }
1746 const Double_t corrPartial = binVolumeSumSetInRange / binVolumeSumSetFull;
1747 if (0. == corrPartial) continue;
1748 const Double_t corr = correctForBinSize ? (inverseBinCor ? binVolumeSumSetFull / _binv[ibin] : binVolumeSumSetFull ) : 1.0;
1749 total += getBinScale(ibin)*(get_wgt(ibin) * corr * corrPartial);
1750 }
1751
1752 _vars.assign(varSave);
1753
1754 return total;
1755}
1756
1757
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Fill the transient cache with partial bin volumes with up-to-date
1761/// values for the partial volume specified by observables 'dimSet'
1762
1763const std::vector<double>& RooDataHist::calculatePartialBinVolume(const RooArgSet& dimSet) const
1764{
1765 // The code bitset has all bits set to one whose position corresponds to arguments in dimSet.
1766 // It is used as the key for the bin volume caching hash map.
1767 int code{0};
1768 {
1769 int i{0} ;
1770 for (auto const& v : _vars) {
1771 code += ((dimSet.find(*v) ? 1 : 0) << i) ;
1772 ++i;
1773 }
1774 }
1775
1776 auto& pbinv = _pbinvCache[code];
1777 if(!pbinv.empty()) {
1778 return pbinv;
1779 }
1780 pbinv.resize(_arrSize);
1781
1782 // Calculate plot bins of components from master index
1783 std::vector<bool> selDim(_vars.getSize());
1784 for (std::size_t i = 0; i < selDim.size(); ++i) {
1785 selDim[i] = (code >> i) & 1 ;
1786 }
1787
1788 // Recalculate partial bin volume cache
1789 for (Int_t ibin=0; ibin < _arrSize ;ibin++) {
1790 Int_t idx(0), tmp(ibin) ;
1791 Double_t theBinVolume(1) ;
1792 for (unsigned int j=0; j < _lvvars.size(); ++j) {
1793 const RooAbsLValue* arg = _lvvars[j];
1794 assert(arg);
1795
1796 idx = tmp / _idxMult[j];
1797 tmp -= idx*_idxMult[j];
1798 if (selDim[j]) {
1799 theBinVolume *= arg->getBinWidth(idx) ;
1800 }
1801 }
1802 pbinv[ibin] = theBinVolume ;
1803 }
1804
1805 return pbinv;
1806}
1807
1808
1809
1810////////////////////////////////////////////////////////////////////////////////
1811/// Return the number of bins
1812
1814{
1815 return RooAbsData::numEntries() ;
1816}
1817
1818
1819
1820////////////////////////////////////////////////////////////////////////////////
1821/// Sum the weights of all bins.
1823
1824 if (_maskedWeights.empty()) {
1826 } else {
1828 }
1829}
1830
1831
1832
1833////////////////////////////////////////////////////////////////////////////////
1834/// Return the sum of weights in all entries matching cutSpec (if specified)
1835/// and in named range cutRange (if specified)
1836/// Return the
1837
1838Double_t RooDataHist::sumEntries(const char* cutSpec, const char* cutRange) const
1839{
1840 checkInit() ;
1841
1842 if (cutSpec==0 && cutRange==0) {
1843 return sumEntries();
1844 } else {
1845
1846 // Setup RooFormulaVar for cutSpec if it is present
1847 RooFormula* select = 0 ;
1848 if (cutSpec) {
1849 select = new RooFormula("select",cutSpec,*get()) ;
1850 }
1851
1852 // Otherwise sum the weights in the event
1853 ROOT::Math::KahanSum<> kahanSum;
1854 for (Int_t i=0; i < _arrSize; i++) {
1855 get(i) ;
1856 if ((!_maskedWeights.empty() && _maskedWeights[i] == 0.)
1857 || (select && select->eval() == 0.)
1858 || (cutRange && !_vars.allInRange(cutRange)))
1859 continue;
1860
1861 kahanSum += weight(i);
1862 }
1863
1864 if (select) delete select ;
1865
1866 return kahanSum;
1867 }
1868}
1869
1870
1871
1872////////////////////////////////////////////////////////////////////////////////
1873/// Reset all bin weights to zero
1874
1876{
1877 // WVE DO NOT CALL RooTreeData::reset() for binned
1878 // datasets as this will delete the bin definitions
1879
1880 std::fill(_wgt, _wgt + _arrSize, 0.);
1881 delete[] _errLo; _errLo = nullptr;
1882 delete[] _errHi; _errHi = nullptr;
1883 delete[] _sumw2; _sumw2 = nullptr;
1884
1886
1887 _cache_sum_valid = false;
1888}
1889
1890
1891
1892////////////////////////////////////////////////////////////////////////////////
1893/// Load bin `binNumber`, and return an argset with the coordinates of the bin centre.
1894/// \note The argset is owned by this data hist, and this function has a side effect, because
1895/// it alters the currently active bin.
1896const RooArgSet* RooDataHist::get(Int_t binNumber) const
1897{
1898 checkInit() ;
1899 _curIndex = binNumber;
1900
1901 return RooAbsData::get(_curIndex);
1902}
1903
1904
1905
1906////////////////////////////////////////////////////////////////////////////////
1907/// Return a RooArgSet with whose coordinates denote the bin centre of the bin
1908/// enclosing the point in `coord`.
1909/// \note The argset is owned by this data hist, and this function has a side effect, because
1910/// it alters the currently active bin.
1911const RooArgSet* RooDataHist::get(const RooArgSet& coord) const {
1912 return get(calcTreeIndex(coord, false));
1913}
1914
1915
1916
1917////////////////////////////////////////////////////////////////////////////////
1918/// Return the volume of the bin enclosing coordinates 'coord'.
1920 checkInit() ;
1921 return _binv[calcTreeIndex(coord, false)] ;
1922}
1923
1924
1925////////////////////////////////////////////////////////////////////////////////
1926/// Set all the event weight of all bins to the specified value
1927
1929{
1930 for (Int_t i=0 ; i<_arrSize ; i++) {
1931 _wgt[i] = value ;
1932 }
1933
1935}
1936
1937
1938
1939////////////////////////////////////////////////////////////////////////////////
1940/// Create an iterator over all bins in a slice defined by the subset of observables
1941/// listed in sliceArg. The position of the slice is given by otherArgs
1942
1944{
1945 // Update to current position
1946 _vars.assign(otherArgs) ;
1947 _curIndex = calcTreeIndex(_vars, true);
1948
1949 RooAbsArg* intArg = _vars.find(sliceArg) ;
1950 if (!intArg) {
1951 coutE(InputArguments) << "RooDataHist::sliceIterator() variable " << sliceArg.GetName() << " is not part of this RooDataHist" << endl ;
1952 return 0 ;
1953 }
1954 return new RooDataHistSliceIter(*this,*intArg) ;
1955}
1956
1957
1958////////////////////////////////////////////////////////////////////////////////
1959/// Change the name of the RooDataHist
1960
1961void RooDataHist::SetName(const char *name)
1962{
1963 if (_dir) _dir->GetList()->Remove(this);
1964 // We need to use the function from RooAbsData, because it already overrides TNamed::SetName
1966 if (_dir) _dir->GetList()->Add(this);
1967}
1968
1969
1970////////////////////////////////////////////////////////////////////////////////
1971/// Change the title of this RooDataHist
1972
1973void RooDataHist::SetNameTitle(const char *name, const char* title)
1974{
1975 SetName(name);
1976 SetTitle(title);
1977}
1978
1979
1980////////////////////////////////////////////////////////////////////////////////
1981/// Print value of the dataset, i.e. the sum of weights contained in the dataset
1982
1983void RooDataHist::printValue(ostream& os) const
1984{
1985 os << numEntries() << " bins (" << sumEntries() << " weights)" ;
1986}
1987
1988
1989
1990
1991////////////////////////////////////////////////////////////////////////////////
1992/// Print argument of dataset, i.e. the observable names
1993
1994void RooDataHist::printArgs(ostream& os) const
1995{
1996 os << "[" ;
1997 Bool_t first(kTRUE) ;
1998 for (const auto arg : _vars) {
1999 if (first) {
2000 first=kFALSE ;
2001 } else {
2002 os << "," ;
2003 }
2004 os << arg->GetName() ;
2005 }
2006 os << "]" ;
2007}
2008
2009
2010
2011////////////////////////////////////////////////////////////////////////////////
2012/// Compute which bins of the dataset are part of the currently set fit range.
2014{
2015 checkInit() ;
2016
2017 _maskedWeights.assign(_wgt, _wgt + _arrSize);
2018 if(_sumw2) _maskedSumw2.assign(_sumw2, _sumw2 + _arrSize);
2019
2020 for (Int_t i=0; i < _arrSize; ++i) {
2021 get(i) ;
2022
2023 for (const auto arg : _vars) {
2024 if (!arg->inRange(nullptr)) {
2025 _maskedWeights[i] = 0.;
2026 if(_sumw2) _maskedSumw2[i] = 0.;
2027 break;
2028 }
2029 }
2030 }
2031
2032}
2033
2034
2035
2036////////////////////////////////////////////////////////////////////////////////
2037/// Returns true if dataset contains entries with a non-integer weight.
2038
2040{
2041 for (Int_t i=0; i < _arrSize; ++i) {
2042 const double wgt = _wgt[i];
2043 double intpart;
2044 if (fabs(std::modf(wgt, &intpart)) > 1.E-10)
2045 return true;
2046 }
2047
2048 return false;
2049}
2050
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Print the details on the dataset contents
2054
2055void RooDataHist::printMultiline(ostream& os, Int_t content, Bool_t verbose, TString indent) const
2056{
2057 RooAbsData::printMultiline(os,content,verbose,indent) ;
2058
2059 os << indent << "Binned Dataset " << GetName() << " (" << GetTitle() << ")" << endl ;
2060 os << indent << " Contains " << numEntries() << " bins with a total weight of " << sumEntries() << endl;
2061
2062 if (!verbose) {
2063 os << indent << " Observables " << _vars << endl ;
2064 } else {
2065 os << indent << " Observables: " ;
2067 }
2068
2069 if(verbose) {
2070 if (_cachedVars.getSize()>0) {
2071 os << indent << " Caches " << _cachedVars << endl ;
2072 }
2073 }
2074}
2075
2076void RooDataHist::printDataHistogram(ostream& os, RooRealVar* obs) const
2077{
2078 for(Int_t i=0; i<obs->getBins(); ++i){
2079 this->get(i);
2080 obs->setBin(i);
2081 os << this->weight() << " +/- " << this->weightSquared() << endl;
2082 }
2083}
2084
2085
2086////////////////////////////////////////////////////////////////////////////////
2087/// Stream an object of class RooDataHist.
2088void RooDataHist::Streamer(TBuffer &R__b) {
2089 if (R__b.IsReading()) {
2090
2091 UInt_t R__s, R__c;
2092 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2093
2094 if (R__v > 2) {
2095 R__b.ReadClassBuffer(RooDataHist::Class(),this,R__v,R__s,R__c);
2096 R__b.CheckByteCount(R__s, R__c, RooDataHist::IsA());
2097 initialize(0, false);
2098 } else {
2099
2100 // Legacy dataset conversion happens here. Legacy RooDataHist inherits from RooTreeData
2101 // which in turn inherits from RooAbsData. Manually stream RooTreeData contents on
2102 // file here and convert it into a RooTreeDataStore which is installed in the
2103 // new-style RooAbsData base class
2104
2105 // --- This is the contents of the streamer code of RooTreeData version 2 ---
2106 UInt_t R__s1, R__c1;
2107 Version_t R__v1 = R__b.ReadVersion(&R__s1, &R__c1); if (R__v1) { }
2108
2109 RooAbsData::Streamer(R__b);
2110 TTree* X_tree(0) ; R__b >> X_tree;
2111 RooArgSet X_truth ; X_truth.Streamer(R__b);
2112 TString X_blindString ; X_blindString.Streamer(R__b);
2113 R__b.CheckByteCount(R__s1, R__c1, TClass::GetClass("RooTreeData"));
2114 // --- End of RooTreeData-v1 streamer
2115
2116 // Construct RooTreeDataStore from X_tree and complete initialization of new-style RooAbsData
2117 _dstore = new RooTreeDataStore(X_tree,_vars) ;
2118 _dstore->SetName(GetName()) ;
2120 _dstore->checkInit() ;
2121
2122 RooDirItem::Streamer(R__b);
2123 R__b >> _arrSize;
2124 delete [] _wgt;
2125 _wgt = new Double_t[_arrSize];
2127 delete [] _errLo;
2128 _errLo = new Double_t[_arrSize];
2130 delete [] _errHi;
2131 _errHi = new Double_t[_arrSize];
2133 delete [] _sumw2;
2134 _sumw2 = new Double_t[_arrSize];
2136 delete [] _binv;
2137 _binv = new Double_t[_arrSize];
2138 RooArgSet tmpSet;
2139 tmpSet.Streamer(R__b);
2140 double tmp;
2141 R__b >> tmp; //_curWeight;
2142 R__b >> tmp; //_curWgtErrLo;
2143 R__b >> tmp; //_curWgtErrHi;
2144 R__b >> tmp; //_curSumW2;
2145 R__b >> tmp; //_curVolume;
2146 R__b >> _curIndex;
2147 R__b.CheckByteCount(R__s, R__c, RooDataHist::IsA());
2148 }
2149
2150 } else {
2151
2152 R__b.WriteClassBuffer(RooDataHist::Class(),this);
2153 }
2154}
2155
2156
2157////////////////////////////////////////////////////////////////////////////////
2158/// Return event weights of all events in range [first, first+len).
2159/// If cacheValidEntries() has been called, out-of-range events will have a weight of 0.
2160RooSpan<const double> RooDataHist::getWeightBatch(std::size_t first, std::size_t len, bool sumW2 /*=false*/) const {
2161 if(sumW2 && _sumw2) {
2162 return _maskedSumw2.empty() ?
2165 } else {
2166 return _maskedWeights.empty() ?
2169 }
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}
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
#define coutI(a)
#define coutE(a)
#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
const Bool_t kFALSE
Definition RtypesCore.h:101
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
#define hi
float * q
float ymin
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:211
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:69
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
RooAbsBinning is the abstract base class for RooRealVar binning definitions.
virtual RooAbsBinning * clone(const char *name=0) const =0
Int_t numBins() const
Return number of bins.
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 getBin(const char *=nullptr) const
Get the index of the plot bin for the current value of this category.
virtual Int_t numBins(const char *rangeName=nullptr) 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.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
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:82
virtual const RooArgSet * get() const
Definition RooAbsData.h:128
void SetName(const char *name)
Set the name of the TNamed.
void setGlobalObservables(RooArgSet const &globalObservables)
Sets the global observables stored in this data.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for detailed printing of object.
void checkInit() const
virtual Double_t weight() const =0
static StorageType defaultStorageType
Definition RooAbsData.h:334
virtual Double_t weightSquared() const =0
virtual void fill()
RooArgSet _vars
Definition RooAbsData.h:372
virtual void attachCache(const RooAbsArg *newOwner, const RooArgSet &cachedVars)
Internal method – Attach dataset copied with cache contents to copied instances of functions.
RooArgSet _cachedVars
Definition RooAbsData.h:373
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
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
RooAbsDataStore * _dstore
External variables cached with this data set.
Definition RooAbsData.h:375
Abstract base class for objects that are lvalues, i.e.
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 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:64
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:94
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:158
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.
TObject * getObject(const char *name, TObject *obj=0)
Return TObject property registered with name 'name'.
Bool_t defineInt(const char *name, const char *argName, Int_t intNum, Int_t defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
void defineMutex(const char *argName1, const char *argName2)
Define arguments named argName1 and argName2 mutually exclusive.
Bool_t defineObject(const char *name, const char *argName, Int_t setNum, const TObject *obj=0, Bool_t isArray=kFALSE)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", Bool_t convEmptyToNull=kFALSE)
Return string property registered with name 'name'.
Int_t getInt(const char *name, Int_t defaultValue=0)
Return integer property registered with name 'name'.
const RooLinkedList & getObjectList(const char *name)
Return list of objects registered with name 'name'.
Bool_t defineDouble(const char *name, const char *argName, Int_t doubleNum, Double_t defValue=0.)
Define Double_t property name 'name' mapped to Double_t in slot 'doubleNum' in RooCmdArg with name ar...
void defineDependency(const char *refArgName, const char *neededArgName)
Define that processing argument name refArgName requires processing of argument named neededArgName t...
Double_t getDouble(const char *name, Double_t defaultValue=0)
Return Double_t property registered with name 'name'.
Bool_t defineSet(const char *name, const char *argName, Int_t setNum, const RooArgSet *set=0)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
Bool_t defineString(const char *name, const char *argName, Int_t stringNum, const char *defValue="", Bool_t appendMode=kFALSE)
Define Double_t property name 'name' mapped to Double_t in slot 'stringNum' in RooCmdArg with name ar...
RooArgSet * getSet(const char *name, RooArgSet *set=0)
Return RooArgSet property registered with name 'name'.
Bool_t ok(Bool_t verbose) const
Return true of parsing was successful.
Bool_t process(const RooCmdArg &arg)
Process given RooCmdArg.
The RooDataHist is a container class to hold N-dimensional binned data.
Definition RooDataHist.h:45
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
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
void printDataHistogram(std::ostream &os, RooRealVar *obs) const
void SetNameTitle(const char *name, const char *title) override
Change the title of this RooDataHist.
std::vector< double > _maskedWeights
VarInfo _varInfo
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().
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.
RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len, bool sumW2=false) const override
Return event weights of all events in range [first, first+len).
std::unordered_map< int, std::vector< double > > _pbinvCache
void checkBinBounds() const
double weight(std::size_t i) const
Return weight of i-th bin.
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.
Double_t weightSquared() const override
Return squared weight of last bin that was requested with get().
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:74
void weightError(double &lo, double &hi, ErrorType etype=Poisson) const override
Return the asymmetric errors on the current weight.
double * _errHi
double * _binv
RooDataHist()
Default constructor.
Double_t get_curWgtErrLo() const
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const override
Print the details on the dataset contents.
ULong64_t _curIndex
Copy of _sumW2, but masked events have a weight of zero.
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
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.
double * _sumw2
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.
Int_t calcTreeIndex() const
Legacy overload to calculate the tree index from the current value of _vars.
Double_t get_curWgtErrHi() const
~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
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.
std::vector< RooAbsLValue * > _lvvars
Cache for arrays of partial bin volumes.
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.
std::vector< Int_t > _idxMult
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
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
std::vector< double > _maskedSumw2
Copy of _wgt, but masked events have a weight of zero.
CacheSumState_t
list of bin bounds per dimension
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.
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.
const RooArgSet * get() const override
Get bin centre of current bin.
Definition RooDataHist.h:84
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.
void removeFromDir(TObject *obj)
Remove object from directory it was added to.
TDirectory * _dir
Definition RooDirItem.h:33
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:33
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
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 ...
Int_t GetSize() const
TIterator * MakeIterator(Bool_t forward=kTRUE) const
Create a TIterator for this list.
virtual void Add(TObject *arg)
static Double_t interpolate(Double_t yArr[], Int_t nOrder, Double_t x)
Definition RooMath.cxx:79
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:136
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.
const RooAbsBinning & getBinning(const char *name=0, Bool_t verbose=kTRUE, Bool_t createOnTheFly=kFALSE) const
Return binning definition with name.
void setBinning(const RooAbsBinning &binning, const char *name=0)
Add given binning under name 'name' with this variable.
A simple container to hold a batch of data values.
Definition RooSpan.h:34
constexpr std::span< T >::pointer data() const
Definition RooSpan.h:106
constexpr bool empty() const noexcept
Definition RooSpan.h:125
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:2966
virtual TList * GetList() const
Definition TDirectory.h:222
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
TAxis * GetZaxis()
Definition TH1.h:322
virtual Int_t GetNbinsY() const
Definition TH1.h:297
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:8893
virtual Int_t GetNbinsZ() const
Definition TH1.h:298
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
virtual Int_t GetNbinsX() const
Definition TH1.h:296
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()
Iterator abstract base class.
Definition TIterator.h:30
virtual void Add(TObject *obj)
Definition TList.h:81
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
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
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
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition TMath.h:685
Definition first.py:1
RooAbsBinning * bins
Definition RooAbsData.h:212
Structure to cache information on the histogram variable that is frequently used for histogram weight...
auto * l
Definition textangle.C:4