Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooBinnedL.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * PB, Patrick Bos, Netherlands eScience Center, p.bos@esciencecenter.nl
5 *
6 * Copyright (c) 2021, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13/**
14\file RooBinnedL.cxx
15\class RooBinnedL
16\ingroup Roofitcore
17
18Class RooBinnedL implements a -log(likelihood) calculation from a dataset
19(assumed to be binned) and a PDF. The NLL is calculated as
20\f
21 \sum_\mathrm{data} -\log( \mathrm{pdf}(x_\mathrm{data}))
22\f]
23In extended mode, a
24\f$ N_\mathrm{expect} - N_\mathrm{observed}*log(N_\mathrm{expect}) \f$ term is added.
25**/
26
28
29#include "RooAbsData.h"
30#include "RooAbsPdf.h"
31#include "RooAbsDataStore.h"
32#include "RooRealSumPdf.h"
33#include "RooRealVar.h"
34#include "RooChangeTracker.h"
35
36#include "TMath.h"
37
38namespace RooFit {
39namespace TestStatistics {
40
42 : RooAbsL(RooAbsL::ClonePdfData{pdf, data}, data->numEntries(), 1)
43{
44 // pdf must be a RooRealSumPdf representing a yield vector for a binned likelihood calculation
45 if (!dynamic_cast<RooRealSumPdf *>(pdf)) {
46 throw std::logic_error("RooBinnedL can only be created from pdf of type RooRealSumPdf!");
47 }
48
49 // Retrieve and cache bin widths needed to convert unnormalized binned pdf values back to yields
50
51 // The Active label will disable pdf integral calculations
52 pdf->setAttribute("BinnedLikelihoodActive");
53
54 RooArgSet params;
55 pdf->getParameters(data->get(), params) ;
56 paramTracker_ = std::make_unique<RooChangeTracker>("chtracker","change tracker",params,true);
57
58 std::unique_ptr<RooArgSet> obs(pdf->getObservables(data));
59 if (obs->getSize() != 1) {
60 throw std::logic_error(
61 "RooBinnedL can only be created from combination of pdf and data which has exactly one observable!");
62 } else {
63 RooRealVar *var = (RooRealVar *)obs->first();
64 std::list<Double_t> *boundaries = pdf->binBoundaries(*var, var->getMin(), var->getMax());
65 std::list<Double_t>::iterator biter = boundaries->begin();
66 _binw.resize(boundaries->size() - 1);
67 Double_t lastBound = (*biter);
68 ++biter;
69 int ibin = 0;
70 while (biter != boundaries->end()) {
71 _binw[ibin] = (*biter) - lastBound;
72 lastBound = (*biter);
73 ibin++;
74 ++biter;
75 }
76 }
77}
78
79RooBinnedL::~RooBinnedL() = default;
80
81//////////////////////////////////////////////////////////////////////////////////
82/// Calculate and return likelihood on subset of data from firstEvent to lastEvent
83/// processed with a step size of 'stepSize'. If this an extended likelihood and
84/// and the zero event is processed the extended term is added to the return
85/// likelihood.
86//
88RooBinnedL::evaluatePartition(Section bins, std::size_t /*components_begin*/, std::size_t /*components_end*/)
89{
90 // Throughout the calculation, we use Kahan's algorithm for summing to
91 // prevent loss of precision - this is a factor four more expensive than
92 // straight addition, but since evaluating the PDF is usually much more
93 // expensive than that, we tolerate the additional cost...
95
96 // Do not reevaluate likelihood if parameters have not changed
97 if (!paramTracker_->hasChanged(true) & (cachedResult_ != 0)) return cachedResult_;
98
99// data->store()->recalculateCache(_projDeps, firstEvent, lastEvent, stepSize, (_binnedPdf?false:true));
100 // TODO: check when we might need _projDeps (it seems to be mostly empty); ties in with TODO below
101 data_->store()->recalculateCache(nullptr, bins.begin(N_events_), bins.end(N_events_), 1, kFALSE);
102
104
105 for (std::size_t i = bins.begin(N_events_); i < bins.end(N_events_); ++i) {
106
107 data_->get(i);
108
109 if (!data_->valid())
110 continue;
111
112 Double_t eventWeight = data_->weight();
113
114 // Calculate log(Poisson(N|mu) for this bin
115 Double_t N = eventWeight;
116 Double_t mu = pdf_->getVal() * _binw[i];
117
118 if (mu <= 0 && N > 0) {
119
120 // Catch error condition: data present where zero events are predicted
121// logEvalError(Form("Observed %f events in bin %d with zero event yield", N, i));
122 // TODO: check if using regular stream vs logEvalError error gathering is ok
123 oocoutI(static_cast<RooAbsArg *>(nullptr), Minimization)
124 << "Observed " << N << " events in bin " << i << " with zero event yield" << std::endl;
125
126 } else if (fabs(mu) < 1e-10 && fabs(N) < 1e-10) {
127
128 // Special handling of this case since log(Poisson(0,0)=0 but can't be calculated with usual log-formula
129 // since log(mu)=0. No update of result is required since term=0.
130
131 } else {
132
133 Double_t term = -1 * (-mu + N * log(mu) - TMath::LnGamma(N + 1));
134
135 sumWeight += eventWeight;
136 result += term;
137 }
138 }
139
140 // If part of simultaneous PDF normalize probability over
141 // number of simultaneous PDFs: -sum(log(p/n)) = -sum(log(p)) + N*log(n)
142 if (sim_count_ > 1) {
143 result += sumWeight * log(1.0 * sim_count_);
144 }
145
146 // At the end of the first full calculation, wire the caches
147 if (_first) {
148 _first = false;
149 pdf_->wireAllCaches();
150 }
151
152 cachedResult_ = result;
153 return result;
154}
155
156} // namespace TestStatistics
157} // namespace RooFit
#define e(i)
Definition RSha256.hxx:103
#define oocoutI(o, a)
const Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
#define N
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:122
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:69
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition RooAbsArg.h:309
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
RooArgSet * getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
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
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Retrieve bin boundaries if this distribution is binned in obs.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:35
std::shared_ptr< RooAbsData > data_
Definition RooAbsL.h:130
std::shared_ptr< RooAbsPdf > pdf_
Definition RooAbsL.h:129
ROOT::Math::KahanSum< double > evaluatePartition(Section bins, std::size_t components_begin, std::size_t components_end) override
Calculate and return likelihood on subset of data from firstEvent to lastEvent processed with a step ...
ROOT::Math::KahanSum< double > cachedResult_
Definition RooBinnedL.h:42
std::unique_ptr< RooChangeTracker > paramTracker_
Definition RooBinnedL.h:41
RooBinnedL(RooAbsPdf *pdf, RooAbsData *data)
std::vector< double > _binw
!
Definition RooBinnedL.h:40
The class RooRealSumPdf implements a PDF constructed from a sum of functions:
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:39
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition TMath.cxx:486
Convenience wrapper class used to distinguish between pdf/data owning and non-owning constructors.
Definition RooAbsL.h:38
A part of some range delimited by two fractional points between 0 and 1 (inclusive).
Definition RooAbsL.h:57
std::size_t begin(std::size_t N_total) const
Definition RooAbsL.h:67
std::size_t end(std::size_t N_total) const
Definition RooAbsL.h:69