Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooUnbinnedL.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 RooUnbinnedL.cxx
15\class RooUnbinnedL
16\ingroup Roofitcore
17
18Class RooUnbinnedL implements a -log(likelihood) calculation from a dataset
19(assumed to be unbinned) 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 "RooNLLVar.h" // RooNLLVar::ComputeScalar
33#include "RooChangeTracker.h"
34#include "RooNaNPacker.h"
35#include "../RooFitDriver.h"
36
37namespace RooFit {
38namespace TestStatistics {
39
40namespace {
41
42RooAbsL::ClonePdfData clonePdfData(RooAbsPdf &pdf, RooAbsData &data, RooFit::BatchModeOption batchMode)
43{
44 if (batchMode == RooFit::BatchModeOption::Off) {
45 return {&pdf, &data};
46 }
47 // For the evaluation with the BatchMode, the pdf needs to be "compiled" for
48 // a given normalization set.
49 return {RooFit::Detail::compileForNormSet(pdf, *data.get()), &data};
50}
51
52} // namespace
53
56 : RooAbsL(clonePdfData(*pdf, *data, batchMode), data->numEntries(), 1, extended)
57{
58 std::unique_ptr<RooArgSet> params(pdf->getParameters(data));
59 paramTracker_ = std::make_unique<RooChangeTracker>("chtracker", "change tracker", *params, true);
60
61 if (batchMode != RooFit::BatchModeOption::Off) {
62 driver_ = std::make_unique<ROOT::Experimental::RooFitDriver>(*pdf_, batchMode);
63 driver_->setData(*data_, "");
64 }
65}
66
68 : RooAbsL(other),
69 apply_weight_squared(other.apply_weight_squared),
70 _first(other._first),
71 lastSection_(other.lastSection_),
72 cachedResult_(other.cachedResult_),
73 driver_(other.driver_)
74{
75 paramTracker_ = std::make_unique<RooChangeTracker>(*other.paramTracker_);
76}
77
79
80//////////////////////////////////////////////////////////////////////////////////
81
82/// Returns true if value was changed, false otherwise.
84{
85 if (apply_weight_squared != flag) {
87 return true;
88 }
89 // setValueDirty();
90 return false;
91}
92
93namespace {
94
95// For now, almost exact copy of RooNLLVar::computeScalarFunc.
96RooNLLVar::ComputeResult computeBatchFunc(std::span<const double> probas, RooAbsData *dataClone, bool weightSq,
97 std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent)
98{
101 RooNaNPacker packedNaN(0.f);
102
103 for (auto i = firstEvent; i < lastEvent; i += stepSize) {
104 dataClone->get(i);
105
106 double weight = dataClone->weight();
107
108 if (0. == weight * weight)
109 continue;
110 if (weightSq)
111 weight = dataClone->weightSquared();
112
113 double logProba = std::log(probas[i]);
114 const double term = -weight * logProba;
115
116 kahanWeight.Add(weight);
117 kahanProb.Add(term);
118 packedNaN.accumulate(term);
119 }
120
121 if (packedNaN.getPayload() != 0.) {
122 // Some events with evaluation errors. Return "badness" of errors.
123 return {ROOT::Math::KahanSum<double>{packedNaN.getNaNWithPayload()}, kahanWeight.Sum()};
124 }
125
126 return {kahanProb, kahanWeight.Sum()};
127}
128
129} // namespace
130
131//////////////////////////////////////////////////////////////////////////////////
132/// Calculate and return likelihood on subset of data from firstEvent to lastEvent
133/// processed with a step size of 'stepSize'. If this an extended likelihood and
134/// and the zero event is processed the extended term is added to the return
135/// likelihood.
136///
138RooUnbinnedL::evaluatePartition(Section events, std::size_t /*components_begin*/, std::size_t /*components_end*/)
139{
140 // Throughout the calculation, we use Kahan's algorithm for summing to
141 // prevent loss of precision - this is a factor four more expensive than
142 // straight addition, but since evaluating the PDF is usually much more
143 // expensive than that, we tolerate the additional cost...
145 double sumWeight;
146
147 // Do not reevaluate likelihood if parameters nor event range have changed
148 if (!paramTracker_->hasChanged(true) && events == lastSection_ && (cachedResult_.Sum() != 0 || cachedResult_.Carry() != 0)) return cachedResult_;
149
150 if (driver_) {
151 // Here, we have a memory allocation that should be avoided when this
152 // code needs to be optimized.
153 std::vector<double> probas = driver_->getValues();
154 std::tie(result, sumWeight) =
155 computeBatchFunc(probas, data_.get(), apply_weight_squared, 1, events.begin(N_events_), events.end(N_events_));
156 } else {
157 data_->store()->recalculateCache(nullptr, events.begin(N_events_), events.end(N_events_), 1, true);
158 std::tie(result, sumWeight) =
160 events.begin(N_events_), events.end(N_events_));
161 }
162
163 // include the extended maximum likelihood term, if requested
164 if (extended_ && events.begin_fraction == 0) {
165 result += pdf_->extendedTerm(*data_, apply_weight_squared);
166 }
167
168 // If part of simultaneous PDF normalize probability over
169 // number of simultaneous PDFs: -sum(log(p/n)) = -sum(log(p)) + N*log(n)
170 if (sim_count_ > 1) {
171 result += sumWeight * log(1.0 * sim_count_);
172 }
173
174 // At the end of the first full calculation, wire the caches. This doesn't
175 // need to be done in BatchMode with the RooFit driver.
176 if (_first && !driver_) {
177 _first = false;
178 pdf_->wireAllCaches();
179 }
180
182 lastSection_ = events;
183 return result;
184}
185
186} // namespace TestStatistics
187} // namespace RooFit
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:122
T Sum() const
Definition Util.h:240
T Carry() const
Definition Util.h:250
void Add(T x)
Single-element accumulation. Will not vectorise.
Definition Util.h:165
RooFit::OwningPtr< 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:59
virtual double weight() const =0
virtual const RooArgSet * get() const
Definition RooAbsData.h:103
virtual double weightSquared() const =0
std::shared_ptr< RooAbsData > data_
Definition RooAbsL.h:143
std::unique_ptr< RooArgSet > normSet_
Pointer to set with observables used for normalization.
Definition RooAbsL.h:144
std::shared_ptr< RooAbsPdf > pdf_
Definition RooAbsL.h:142
ROOT::Math::KahanSum< double > cachedResult_
bool setApplyWeightSquared(bool flag)
Returns true if value was changed, false otherwise.
ROOT::Math::KahanSum< double > evaluatePartition(Section events, 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 ...
std::unique_ptr< RooChangeTracker > paramTracker_
std::shared_ptr< ROOT::Experimental::RooFitDriver > driver_
! For batched evaluation
bool apply_weight_squared
Apply weights squared?
RooUnbinnedL(RooAbsPdf *pdf, RooAbsData *data, RooAbsL::Extended extended=RooAbsL::Extended::Auto, RooFit::BatchModeOption batchMode=RooFit::BatchModeOption::Off)
static RooNLLVar::ComputeResult computeScalarFunc(const RooAbsPdf *pdfClone, RooAbsData *dataClone, RooArgSet *normSet, bool weightSq, std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent, bool doBinOffset=false)
std::pair< ROOT::Math::KahanSum< double >, double > ComputeResult
Definition RooNLLVar.h:68
std::unique_ptr< T > compileForNormSet(T const &arg, RooArgSet const &normSet)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18
BatchModeOption
For setting the batch mode flag with the BatchMode() command argument to RooAbsPdf::fitTo()
A part of some range delimited by two fractional points between 0 and 1 (inclusive).
Definition RooAbsL.h:65
std::size_t begin(std::size_t N_total) const
Definition RooAbsL.h:73
std::size_t end(std::size_t N_total) const
Definition RooAbsL.h:75
Little struct that can pack a float into the unused bits of the mantissa of a NaN double.