Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooBinWidthFunction.cxx
Go to the documentation of this file.
1// Author Stephan Hageboeck, CERN, 10/2020
2/*****************************************************************************
3 * Project: RooFit *
4 * Package: RooFitCore *
5 * File: $Id$
6 * Authors: *
7 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
8 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
9 * *
10 * Copyright (c) 2000-2020, Regents of the University of California *
11 * and Stanford University. All rights reserved. *
12 * *
13 * Redistribution and use in source and binary forms, *
14 * with or without modification, are permitted according to the terms *
15 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
16 *****************************************************************************/
17
18
19/**
20 * \class RooBinWidthFunction
21 * \ingroup Roofitcore
22 *
23 * Returns the bin width (or volume) given a RooHistFunc.
24 * It can be used to normalise by bin width or to compute event densities. Using the extra
25 * argument of the constructor, it can also return the inverse of the bin width (or volume).
26 */
27
28#include "RooBinWidthFunction.h"
29
30#include "RooConstVar.h"
31#include "RooDataHist.h"
32#include "RooGlobalFunc.h"
33
35
36/// Globally enable bin-width corrections by this class.
38 _enabled = true;
39}
40
41/// Returns `true` if bin-width corrections by this class are globally enabled, `false` otherwise.
43 return _enabled;
44}
45
46/// Globally disable bin-width corrections by this class.
48 _enabled = false;
49}
50
51/// Create an instance.
52/// \param name Name to identify the object.
53/// \param title Title for e.g. plotting.
54/// \param histFunc RooHistFunc object whose bin widths should be returned.
55/// \param divideByBinWidth If true, return inverse bin width.
56RooBinWidthFunction::RooBinWidthFunction(const char *name, const char *title, const RooHistFunc &histFunc, bool divideByBinWidth)
57 : RooAbsReal(name, title),
58 _histFunc("HistFuncForBinWidth", "Handle to a RooHistFunc, whose bin volumes should be returned.", this, histFunc,
59 /*valueServer=*/false, /*shapeServer=*/false),
60 _divideByBinWidth(divideByBinWidth)
61{
62 // The RooHistFunc is only used to access this histogram observables in a
63 // convenient way. That's why this proxy is not "serving" this
64 // RooBinWidthFunction in any way (see proxy constructor arguments in the
65 // initializer list above).
66 //
67 // However, the variables of the histFunc **need to be** value servers,
68 // because the width of the current bin depends on the values of the
69 // observables:
70 for (RooAbsArg * server : histFunc.servers()) {
71 addServer(*server, /*valueServer=*/true, /*shapeServer=*/false);
72 }
73 // The reason why we can't simply use the histFunc as an "indirect proxy" is
74 // the way HistFactory is implemented. The same RooBinWidthFunction is used
75 // for all samples (e.g. signal and backgrounds), but uses the RooHistFunc
76 // of only one of the samples (this is okay because the binnings for all
77 // samples in the template histogram stack is the same). This entangling of
78 // the computation graph for the different samples messes up the component
79 // selection when plotting only some samples with
80 // `plotOn(..., RooFit::Components(...))`.
81}
82
83/// Compute current bin of observable, and return its volume or inverse volume, depending
84/// on configuration chosen in the constructor.
85/// If the bin is not valid, return a volume of 1.
87 if(!_enabled) return 1.;
88 const RooDataHist& dataHist = _histFunc->dataHist();
89 const auto idx = _histFunc->getBin();
90 auto volumes = dataHist.binVolumes(0, dataHist.numEntries());
91 const double volume = idx >= 0 ? volumes[idx] : 1.;
92
93 return _divideByBinWidth ? 1./volume : volume;
94}
95
96
97/// Compute bin index for all values of the observable(s) in `evalData`, and return their volumes or inverse volumes, depending
98/// on the configuration chosen in the constructor.
99/// If a bin is not valid, return a volume of 1.
100void RooBinWidthFunction::computeBatch(double* output, size_t, RooFit::Detail::DataMap const& dataMap) const {
101 const RooDataHist& dataHist = _histFunc->dataHist();
102 std::vector<Int_t> bins = _histFunc->getBins(dataMap);
103 auto volumes = dataHist.binVolumes(0, dataHist.numEntries());
104
105 if(!_enabled){
106 for (std::size_t i=0; i < bins.size(); ++i) {
107 output[i] = 1.;
108 }
109 } else {
110 if (_divideByBinWidth) {
111 for (std::size_t i=0; i < bins.size(); ++i) {
112 output[i] = bins[i] >= 0 ? 1./volumes[bins[i]] : 1.;
113 }
114 } else {
115 for (std::size_t i=0; i < bins.size(); ++i) {
116 output[i] = bins[i] >= 0 ? volumes[bins[i]] : 1.;
117 }
118 }
119 }
120}
121
122
123std::unique_ptr<RooAbsArg>
125{
126 // If this is a binned likelihood, the pdf values can be directly
127 // interpreted as yields for Poisson terms in the NLL, and it doesn't make
128 // sense to divide them by the bin width to get a probability density. The
129 // NLL would only have to multiply by the bin with again.
130 if (ctx.binnedLikelihoodMode()) {
131 auto newArg = std::unique_ptr<RooAbsReal>{static_cast<RooAbsReal *>(RooFit::RooConst(1.0).Clone())};
132 ctx.markAsCompiled(*newArg);
133 // To propagate the information to the NLL that the pdf values can
134 // directly be interpreted as yields.
135 ctx.setBinWidthFuncFlag(true);
136 return newArg;
137 }
138 return RooAbsReal::compileForNormSet(normSet, ctx);
139}
char name[80]
Definition TGX11.cxx:110
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
TIterator Use servers() and begin()
virtual std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const
void addServer(RooAbsArg &server, bool valueProp=true, bool shapeProp=false, std::size_t refCount=1)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:89
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
const RooHistFunc & histFunc() const
RooBinWidthFunction()
Create an empty instance.
static void disableClass()
Globally disable bin-width corrections by this class.
double evaluate() const override
Compute current bin of observable, and return its volume or inverse volume, depending on configuratio...
RooTemplateProxy< const RooHistFunc > _histFunc
void computeBatch(double *output, size_t size, RooFit::Detail::DataMap const &) const override
Compute bin index for all values of the observable(s) in evalData, and return their volumes or invers...
static bool isClassEnabled()
Returns true if bin-width corrections by this class are globally enabled, false otherwise.
static void enableClass()
Globally enable bin-width corrections by this class.
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:39
std::span< const double > binVolumes(std::size_t first, std::size_t len) const
Retrieve all bin volumes. Bins are indexed according to getIndex().
Definition RooDataHist.h:89
void markAsCompiled(RooAbsArg &arg) const
A real-valued function sampled from a multidimensional histogram.
Definition RooHistFunc.h:31
std::vector< Int_t > getBins(RooFit::Detail::DataMap const &dataMap) const
Compute bin numbers corresponding to all coordinates in evalData.
Int_t getBin() const
Compute bin number corresponding to current coordinates.
RooDataHist & dataHist()
Return RooDataHist that is represented.
Definition RooHistFunc.h:45
RooConstVar & RooConst(double val)
static void output()