Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooNLLVar.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 RooNLLVar.cxx
19\class RooNLLVar
20\ingroup Roofitcore
21
22Class RooNLLVar implements a -log(likelihood) calculation from a dataset
23and a PDF. The NLL is calculated as
24\f[
25 \sum_\mathrm{data} -\log( \mathrm{pdf}(x_\mathrm{data}))
26\f]
27In extended mode, a
28\f$ N_\mathrm{expect} - N_\mathrm{observed}*log(N_\mathrm{expect}) \f$ term is added.
29**/
30
31#include "RooNLLVar.h"
32
33#include "RooAbsData.h"
34#include "RooAbsPdf.h"
35#include "RooCmdConfig.h"
36#include "RooMsgService.h"
37#include "RooAbsDataStore.h"
38#include "RooRealMPFE.h"
39#include "RooRealSumPdf.h"
40#include "RooRealVar.h"
41#include "RooProdPdf.h"
42#include "RooNaNPacker.h"
43#include "RunContext.h"
44
45#ifdef ROOFIT_CHECK_CACHED_VALUES
46#include <iomanip>
47#endif
48
49#include "TMath.h"
50#include "Math/Util.h"
51
52#include <algorithm>
53
55
57
59{ }
60
61////////////////////////////////////////////////////////////////////////////////
62/// Construct likelihood from given p.d.f and (binned or unbinned dataset)
63///
64/// Argument | Description
65/// -------------------------|------------
66/// Extended() | Include extended term in calculation
67/// NumCPU() | Activate parallel processing feature
68/// Range() | Fit only selected region
69/// SumCoefRange() | Set the range in which to interpret the coefficients of RooAddPdf components
70/// SplitRange() | Fit range is split by index category of simultaneous PDF
71/// ConditionalObservables() | Define conditional observables
72/// Verbose() | Verbose output of GOF framework classes
73/// CloneData() | Clone input dataset for internal use (default is kTRUE)
74/// BatchMode() | Evaluate batches of data events (faster if PDFs support it)
75/// IntegrateBins() | Integrate PDF within each bin. This sets the desired precision. Only useful for binned fits.
76RooNLLVar::RooNLLVar(const char *name, const char* title, RooAbsPdf& pdf, RooAbsData& indata,
77 const RooCmdArg& arg1, const RooCmdArg& arg2,const RooCmdArg& arg3,
78 const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6,
79 const RooCmdArg& arg7, const RooCmdArg& arg8,const RooCmdArg& arg9) :
80 RooAbsOptTestStatistic(name,title,pdf,indata,
81 *(const RooArgSet*)RooCmdConfig::decodeObjOnTheFly("RooNLLVar::RooNLLVar","ProjectedObservables",0,&_emptySet
82 ,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
83 RooCmdConfig::decodeStringOnTheFly("RooNLLVar::RooNLLVar","RangeWithName",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9).c_str(),
84 RooCmdConfig::decodeStringOnTheFly("RooNLLVar::RooNLLVar","AddCoefRange",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9).c_str(),
85 RooCmdConfig::decodeIntOnTheFly("RooNLLVar::RooNLLVar","NumCPU",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
86 RooFit::BulkPartition,
87 RooCmdConfig::decodeIntOnTheFly("RooNLLVar::RooNLLVar","Verbose",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
88 RooCmdConfig::decodeIntOnTheFly("RooNLLVar::RooNLLVar","SplitRange",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
89 RooCmdConfig::decodeIntOnTheFly("RooNLLVar::RooNLLVar","CloneData",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
90 RooCmdConfig::decodeDoubleOnTheFly("RooNLLVar::RooNLLVar", "IntegrateBins", 0, -1., {arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9}))
91{
92 RooCmdConfig pc("RooNLLVar::RooNLLVar") ;
93 pc.allowUndefined() ;
94 pc.defineInt("extended","Extended",0,kFALSE) ;
95 pc.defineInt("BatchMode", "BatchMode", 0, false);
96
97 pc.process(arg1) ; pc.process(arg2) ; pc.process(arg3) ;
98 pc.process(arg4) ; pc.process(arg5) ; pc.process(arg6) ;
99 pc.process(arg7) ; pc.process(arg8) ; pc.process(arg9) ;
100
101 _extended = pc.getInt("extended") ;
102 _batchEvaluations = pc.getInt("BatchMode");
103 _weightSq = kFALSE ;
104 _first = kTRUE ;
105 _offset = 0.;
106 _offsetCarry = 0.;
107 _offsetSaveW2 = 0.;
109
110 _binnedPdf = 0 ;
111}
112
113
114
115////////////////////////////////////////////////////////////////////////////////
116/// Construct likelihood from given p.d.f and (binned or unbinned dataset)
117/// For internal use.
118
119RooNLLVar::RooNLLVar(const char *name, const char *title, RooAbsPdf& pdf, RooAbsData& indata,
120 Bool_t extended, const char* rangeName, const char* addCoefRangeName,
121 Int_t nCPU, RooFit::MPSplit interleave, Bool_t verbose, Bool_t splitRange, Bool_t cloneData, Bool_t binnedL,
122 double integrateBinsPrecision) :
123 RooAbsOptTestStatistic(name,title,pdf,indata,RooArgSet(),rangeName,addCoefRangeName,nCPU,interleave,verbose,splitRange,cloneData,
124 integrateBinsPrecision),
125 _extended(extended),
126 _weightSq(kFALSE),
127 _first(kTRUE), _offsetSaveW2(0.), _offsetCarrySaveW2(0.)
128{
129 // If binned likelihood flag is set, pdf is a RooRealSumPdf representing a yield vector
130 // for a binned likelihood calculation
131 _binnedPdf = binnedL ? (RooRealSumPdf*)_funcClone : 0 ;
132
133 // Retrieve and cache bin widths needed to convert un-normalized binnedPdf values back to yields
134 if (_binnedPdf) {
135
136 // The Active label will disable pdf integral calculations
137 _binnedPdf->setAttribute("BinnedLikelihoodActive") ;
138
140 if (obs->getSize()!=1) {
141 _binnedPdf = 0 ;
142 } else {
143 RooRealVar* var = (RooRealVar*) obs->first() ;
144 std::list<Double_t>* boundaries = _binnedPdf->binBoundaries(*var,var->getMin(),var->getMax()) ;
145 std::list<Double_t>::iterator biter = boundaries->begin() ;
146 _binw.resize(boundaries->size()-1) ;
147 Double_t lastBound = (*biter) ;
148 ++biter ;
149 int ibin=0 ;
150 while (biter!=boundaries->end()) {
151 _binw[ibin] = (*biter) - lastBound ;
152 lastBound = (*biter) ;
153 ibin++ ;
154 ++biter ;
155 }
156 }
157 }
158}
159
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Construct likelihood from given p.d.f and (binned or unbinned dataset)
164/// For internal use.
165
166RooNLLVar::RooNLLVar(const char *name, const char *title, RooAbsPdf& pdf, RooAbsData& indata,
167 const RooArgSet& projDeps, Bool_t extended, const char* rangeName,const char* addCoefRangeName,
168 Int_t nCPU,RooFit::MPSplit interleave,Bool_t verbose, Bool_t splitRange, Bool_t cloneData, Bool_t binnedL,
169 double integrateBinsPrecision) :
170 RooAbsOptTestStatistic(name,title,pdf,indata,projDeps,rangeName,addCoefRangeName,nCPU,interleave,verbose,splitRange,cloneData,
171 integrateBinsPrecision),
172 _extended(extended),
173 _weightSq(kFALSE),
174 _first(kTRUE), _offsetSaveW2(0.), _offsetCarrySaveW2(0.)
175{
176 // If binned likelihood flag is set, pdf is a RooRealSumPdf representing a yield vector
177 // for a binned likelihood calculation
178 _binnedPdf = binnedL ? (RooRealSumPdf*)_funcClone : 0 ;
179
180 // Retrieve and cache bin widths needed to convert un-normalized binnedPdf values back to yields
181 if (_binnedPdf) {
182
184 if (obs->getSize()!=1) {
185 _binnedPdf = 0 ;
186 } else {
187 RooRealVar* var = (RooRealVar*) obs->first() ;
188 std::list<Double_t>* boundaries = _binnedPdf->binBoundaries(*var,var->getMin(),var->getMax()) ;
189 std::list<Double_t>::iterator biter = boundaries->begin() ;
190 _binw.resize(boundaries->size()-1) ;
191 Double_t lastBound = (*biter) ;
192 ++biter ;
193 int ibin=0 ;
194 while (biter!=boundaries->end()) {
195 _binw[ibin] = (*biter) - lastBound ;
196 lastBound = (*biter) ;
197 ibin++ ;
198 ++biter ;
199 }
200 }
201 }
202}
203
204
205
206////////////////////////////////////////////////////////////////////////////////
207/// Copy constructor
208
209RooNLLVar::RooNLLVar(const RooNLLVar& other, const char* name) :
211 _extended(other._extended),
212 _batchEvaluations(other._batchEvaluations),
213 _weightSq(other._weightSq),
214 _first(kTRUE), _offsetSaveW2(other._offsetSaveW2),
215 _offsetCarrySaveW2(other._offsetCarrySaveW2),
216 _binw(other._binw) {
218}
219
220
221////////////////////////////////////////////////////////////////////////////////
222/// Create a test statistic using several properties of the current instance. This is used to duplicate
223/// the test statistic in multi-processing scenarios.
224RooAbsTestStatistic* RooNLLVar::create(const char *name, const char *title, RooAbsReal& pdf, RooAbsData& adata,
225 const RooArgSet& projDeps, const char* rangeName, const char* addCoefRangeName,
226 Int_t nCPU, RooFit::MPSplit interleave, bool verbose, bool splitRange, bool binnedL) {
227 RooAbsPdf & thePdf = dynamic_cast<RooAbsPdf&>(pdf);
228 // check if pdf can be extended
229 bool extendedPdf = _extended && thePdf.canBeExtended();
230 auto testStat = new RooNLLVar(name, title, thePdf, adata,
231 projDeps, extendedPdf , rangeName, addCoefRangeName, nCPU, interleave, verbose, splitRange, false, binnedL,
233 testStat->batchMode(_batchEvaluations);
234 return testStat;
235}
236
237
238////////////////////////////////////////////////////////////////////////////////
239/// Destructor
240
242{
243}
244
245
246
247
248////////////////////////////////////////////////////////////////////////////////
249
251{
252 if (_gofOpMode==Slave) {
253 if (flag != _weightSq) {
254 _weightSq = flag;
255 std::swap(_offset, _offsetSaveW2);
257 }
259 } else if ( _gofOpMode==MPMaster) {
260 for (Int_t i=0 ; i<_nCPU ; i++)
261 _mpfeArray[i]->applyNLLWeightSquared(flag);
262 } else if ( _gofOpMode==SimMaster) {
263 for (Int_t i=0 ; i<_nGof ; i++)
264 ((RooNLLVar*)_gofArray[i])->applyWeightSquared(flag);
265 }
266}
267
268
269////////////////////////////////////////////////////////////////////////////////
270/// Calculate and return likelihood on subset of data.
271/// \param[in] firstEvent First event to be processed.
272/// \param[in] lastEvent First event not to be processed, any more.
273/// \param[in] stepSize Steps between events.
274/// \note For batch computations, the step size **must** be one.
275///
276/// If this an extended likelihood, the extended term is added to the return likelihood
277/// in the batch that encounters the event with index 0.
278
279Double_t RooNLLVar::evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
280{
281 // Throughout the calculation, we use Kahan's algorithm for summing to
282 // prevent loss of precision - this is a factor four more expensive than
283 // straight addition, but since evaluating the PDF is usually much more
284 // expensive than that, we tolerate the additional cost...
285 double result(0), carry(0), sumWeight(0);
286
287 RooAbsPdf* pdfClone = (RooAbsPdf*) _funcClone ;
288
289 // cout << "RooNLLVar::evaluatePartition(" << GetName() << ") projDeps = " << (_projDeps?*_projDeps:RooArgSet()) << endl ;
290
291 _dataClone->store()->recalculateCache( _projDeps, firstEvent, lastEvent, stepSize, (_binnedPdf?kFALSE:kTRUE) ) ;
292
293
294
295 // If pdf is marked as binned - do a binned likelihood calculation here (sum of log-Poisson for each bin)
296 if (_binnedPdf) {
297 double sumWeightCarry = 0.;
298 for (auto i=firstEvent ; i<lastEvent ; i+=stepSize) {
299
300 _dataClone->get(i) ;
301
302 if (!_dataClone->valid()) continue;
303
304 Double_t eventWeight = _dataClone->weight();
305
306
307 // Calculate log(Poisson(N|mu) for this bin
308 Double_t N = eventWeight ;
309 Double_t mu = _binnedPdf->getVal()*_binw[i] ;
310 //cout << "RooNLLVar::binnedL(" << GetName() << ") N=" << N << " mu = " << mu << endl ;
311
312 if (mu<=0 && N>0) {
313
314 // Catch error condition: data present where zero events are predicted
315 logEvalError(Form("Observed %f events in bin %lu with zero event yield",N,(unsigned long)i)) ;
316
317 } else if (fabs(mu)<1e-10 && fabs(N)<1e-10) {
318
319 // Special handling of this case since log(Poisson(0,0)=0 but can't be calculated with usual log-formula
320 // since log(mu)=0. No update of result is required since term=0.
321
322 } else {
323
324 Double_t term = -1*(-mu + N*log(mu) - TMath::LnGamma(N+1)) ;
325
326 // TODO replace by Math::KahanSum
327 // Kahan summation of sumWeight
328 Double_t y = eventWeight - sumWeightCarry;
329 Double_t t = sumWeight + y;
330 sumWeightCarry = (t - sumWeight) - y;
331 sumWeight = t;
332
333 // Kahan summation of result
334 y = term - carry;
335 t = result + y;
336 carry = (t - result) - y;
337 result = t;
338 }
339 }
340
341
342 } else { //unbinned PDF
343
344 if (_batchEvaluations) {
345 std::tie(result, carry, sumWeight) = computeBatched(stepSize, firstEvent, lastEvent);
346#ifdef ROOFIT_CHECK_CACHED_VALUES
347
348 double resultScalar, carryScalar, sumWeightScalar;
349 std::tie(resultScalar, carryScalar, sumWeightScalar) =
350 computeScalar(stepSize, firstEvent, lastEvent);
351
352 constexpr bool alwaysPrint = false;
353
354 if (alwaysPrint || fabs(result - resultScalar)/resultScalar > 5.E-15) {
355 std::cerr << "RooNLLVar: result is off\n\t" << std::setprecision(15) << result
356 << "\n\t" << resultScalar << std::endl;
357 }
358
359 if (alwaysPrint || fabs(carry - carryScalar)/carryScalar > 500.) {
360 std::cerr << "RooNLLVar: carry is far off\n\t" << std::setprecision(15) << carry
361 << "\n\t" << carryScalar << std::endl;
362 }
363
364 if (alwaysPrint || fabs(sumWeight - sumWeightScalar)/sumWeightScalar > 1.E-15) {
365 std::cerr << "RooNLLVar: sumWeight is off\n\t" << std::setprecision(15) << sumWeight
366 << "\n\t" << sumWeightScalar << std::endl;
367 }
368
369#endif
370 } else { //scalar mode
371 std::tie(result, carry, sumWeight) = computeScalar(stepSize, firstEvent, lastEvent);
372 }
373
374 // include the extended maximum likelihood term, if requested
375 if(_extended && _setNum==_extSet) {
376 if (_weightSq) {
377
378 // TODO Batch this up
379 // Calculate sum of weights-squared here for extended term
380 Double_t sumW2(0), sumW2carry(0);
381 for (decltype(_dataClone->numEntries()) i = 0; i < _dataClone->numEntries() ; i++) {
382 _dataClone->get(i);
383 Double_t y = _dataClone->weightSquared() - sumW2carry;
384 Double_t t = sumW2 + y;
385 sumW2carry = (t - sumW2) - y;
386 sumW2 = t;
387 }
388
389 Double_t expected= pdfClone->expectedEvents(_dataClone->get());
390
391 // Adjust calculation of extended term with W^2 weighting: adjust poisson such that
392 // estimate of Nexpected stays at the same value, but has a different variance, rescale
393 // both the observed and expected count of the Poisson with a factor sum[w] / sum[w^2] which is
394 // the effective weight of the Poisson term.
395 // i.e. change Poisson(Nobs = sum[w]| Nexp ) --> Poisson( sum[w] * sum[w] / sum[w^2] | Nexp * sum[w] / sum[w^2] )
396 // weighted by the effective weight sum[w^2]/ sum[w] in the likelihood.
397 // Since here we compute the likelihood with the weight square we need to multiply by the
398 // square of the effective weight
399 // expectedW = expected * sum[w] / sum[w^2] : effective expected entries
400 // observedW = sum[w] * sum[w] / sum[w^2] : effective observed entries
401 // The extended term for the likelihood weighted by the square of the weight will be then:
402 // (sum[w^2]/ sum[w] )^2 * expectedW - (sum[w^2]/ sum[w] )^2 * observedW * log (expectedW) and this is
403 // using the previous expressions for expectedW and observedW
404 // sum[w^2] / sum[w] * expected - sum[w^2] * log (expectedW)
405 // and since the weights are constants in the likelihood we can use log(expected) instead of log(expectedW)
406
407 Double_t expectedW2 = expected * sumW2 / _dataClone->sumEntries() ;
408 Double_t extra= expectedW2 - sumW2*log(expected );
409
410 // Double_t y = pdfClone->extendedTerm(sumW2, _dataClone->get()) - carry;
411
412 Double_t y = extra - carry ;
413
414 Double_t t = result + y;
415 carry = (t - result) - y;
416 result = t;
417 } else {
418 Double_t y = pdfClone->extendedTerm(_dataClone->sumEntries(), _dataClone->get()) - carry;
419 Double_t t = result + y;
420 carry = (t - result) - y;
421 result = t;
422 }
423 }
424 } //unbinned PDF
425
426
427 // If part of simultaneous PDF normalize probability over
428 // number of simultaneous PDFs: -sum(log(p/n)) = -sum(log(p)) + N*log(n)
429 if (_simCount>1) {
430 Double_t y = sumWeight*log(1.0*_simCount) - carry;
431 Double_t t = result + y;
432 carry = (t - result) - y;
433 result = t;
434 }
435
436
437 // At the end of the first full calculation, wire the caches
438 if (_first) {
439 _first = kFALSE ;
441 }
442
443
444 // Check if value offset flag is set.
445 if (_doOffset) {
446
447 // If no offset is stored enable this feature now
448 if (_offset==0 && result !=0 ) {
449 coutI(Minimization) << "RooNLLVar::evaluatePartition(" << GetName() << ") first = "<< firstEvent << " last = " << lastEvent << " Likelihood offset now set to " << result << std::endl ;
450 _offset = result ;
451 _offsetCarry = carry;
452 }
453
454 // Subtract offset
455 Double_t y = -_offset - (carry + _offsetCarry);
456 Double_t t = result + y;
457 carry = (t - result) - y;
458 result = t;
459 }
460
461
462 _evalCarry = carry;
463 return result ;
464}
465
466
467////////////////////////////////////////////////////////////////////////////////
468/// Compute probabilites of all data events. Use faster batch interface.
469/// \param[in] stepSize Stride when moving through the dataset.
470/// \note For batch computations, the step size **must** be one.
471/// \param[in] firstEvent First event to be processed.
472/// \param[in] lastEvent First event not to be processed.
473/// \return Tuple with (Kahan sum of probabilities, carry of kahan sum, sum of weights)
474std::tuple<double, double, double> RooNLLVar::computeBatched(std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent) const
475{
476 const auto nEvents = lastEvent - firstEvent;
477
478 if (stepSize != 1) {
479 throw std::invalid_argument(std::string("Error in ") + __FILE__ + ": Step size for batch computations can only be 1.");
480 }
481
482 auto pdfClone = static_cast<const RooAbsPdf*>(_funcClone);
483
484 // Create a RunContext that will own the memory where computation results are stored.
485 // Holding on to this struct in between function calls will make sure that the memory
486 // is only allocated once.
487 if (!_evalData) {
489 }
490 _evalData->clear();
491 _dataClone->getBatches(*_evalData, firstEvent, nEvents);
492
493 auto results = pdfClone->getLogProbabilities(*_evalData, _normSet);
494
495#ifdef ROOFIT_CHECK_CACHED_VALUES
496
497 for (std::size_t evtNo = firstEvent; evtNo < std::min(lastEvent, firstEvent + 10); ++evtNo) {
498 _dataClone->get(evtNo);
499 assert(_dataClone->valid());
500 try {
501 // Cross check results with strict tolerance and complain
502 BatchInterfaceAccessor::checkBatchComputation(*pdfClone, *_evalData, evtNo-firstEvent, _normSet, 1.E-13);
503 } catch (std::exception& e) {
504 std::cerr << __FILE__ << ":" << __LINE__ << " ERROR when checking batch computation for event " << evtNo << ":\n"
505 << e.what() << std::endl;
506
507 // It becomes a real problem if it's very wrong. We fail in this case:
508 try {
509 BatchInterfaceAccessor::checkBatchComputation(*pdfClone, *_evalData, evtNo-firstEvent, _normSet, 1.E-9);
510 } catch (std::exception& e2) {
511 assert(false);
512 }
513 }
514 }
515
516#endif
517
518
519 // Compute sum of event weights. First check if we need squared weights
520 const RooSpan<const double> eventWeights = _dataClone->getWeightBatch(firstEvent, nEvents);
521 //Capture member for lambda:
522 const bool retrieveSquaredWeights = _weightSq;
523 auto retrieveWeight = [&eventWeights, retrieveSquaredWeights](std::size_t i) {
524 return retrieveSquaredWeights ? eventWeights[i] * eventWeights[i] : eventWeights[i];
525 };
526
527 //Sum the event weights and probabilities
529 double uniformSingleEventWeight{0.0};
530 double sumOfWeights;
531 if (eventWeights.empty()) {
532 uniformSingleEventWeight = retrieveSquaredWeights ? _dataClone->weightSquared() : _dataClone->weight();
533 sumOfWeights = nEvents * uniformSingleEventWeight;
534 for (std::size_t i = 0; i < results.size(); ++i) { //CHECK_VECTORISE
535 kahanProb.AddIndexed(-uniformSingleEventWeight * results[i], i);
536 }
537 } else {
538 assert(results.size() == eventWeights.size());
540 for (std::size_t i = 0; i < results.size(); ++i) { //CHECK_VECTORISE
541 const double weight = retrieveWeight(i);
542 kahanProb.AddIndexed(-weight * results[i], i);
543 kahanWeight.AddIndexed(weight, i);
544 }
545 sumOfWeights = kahanWeight.Sum();
546 }
547
548 if (std::isnan(kahanProb.Sum())) {
549 // Special handling of evaluation errors.
550 // We can recover if the bin/event that results in NaN has a weight of zero:
552 RooNaNPacker nanPacker;
553 for (std::size_t i = 0; i < results.size(); ++i) {
554 double weight = eventWeights.empty() ? uniformSingleEventWeight : retrieveWeight(i);
555
556 if (weight == 0.)
557 continue;
558
559 if (std::isnan(results[i])) {
560 nanPacker.accumulate(results[i]);
561 } else {
562 kahanSanitised += -weight * results[i];
563 }
564 }
565
566 // Some events with evaluation errors. Return "badness" of errors.
567 if (nanPacker.getPayload() > 0.) {
568 return std::tuple<double, double, double>{nanPacker.getNaNWithPayload(), 0., sumOfWeights};
569 } else {
570 return std::tuple<double, double, double>{kahanSanitised.Sum(), kahanSanitised.Carry(), sumOfWeights};
571 }
572 }
573
574 return std::tuple<double, double, double>{kahanProb.Sum(), kahanProb.Carry(), sumOfWeights};
575}
576
577
578std::tuple<double, double, double> RooNLLVar::computeScalar(std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent) const {
579 auto pdfClone = static_cast<const RooAbsPdf*>(_funcClone);
580
583 RooNaNPacker packedNaN(0.f);
584
585 for (auto i=firstEvent; i<lastEvent; i+=stepSize) {
586 _dataClone->get(i) ;
587
588 if (!_dataClone->valid()) continue;
589
590 Double_t eventWeight = _dataClone->weight(); //FIXME
591 if (0. == eventWeight * eventWeight) continue ;
592 if (_weightSq) eventWeight = _dataClone->weightSquared() ;
593
594 const double term = -eventWeight * pdfClone->getLogVal(_normSet);
595
596 kahanWeight.Add(eventWeight);
597 kahanProb.Add(term);
598 packedNaN.accumulate(term);
599 }
600
601 if (packedNaN.getPayload() != 0.) {
602 // Some events with evaluation errors. Return "badness" of errors.
603 return std::tuple<double, double, double>{packedNaN.getNaNWithPayload(), 0., kahanWeight.Sum()};
604 }
605
606 return std::tuple<double, double, double>{kahanProb.Sum(), kahanProb.Carry(), kahanWeight.Sum()};
607}
#define e(i)
Definition RSha256.hxx:103
#define coutI(a)
const Bool_t kFALSE
Definition RtypesCore.h:92
double Double_t
Definition RtypesCore.h:59
const Bool_t kTRUE
Definition RtypesCore.h:91
#define ClassImp(name)
Definition Rtypes.h:364
#define N
char name[80]
Definition TGX11.cxx:110
double log(double)
char * Form(const char *fmt,...)
static void checkBatchComputation(const RooAbsReal &theReal, const RooBatchCompute::RunContext &evalData, std::size_t evtNo, const RooArgSet *normSet=nullptr, double relAccuracy=1.E-13)
Definition RooAbsReal.h:586
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:122
T Sum() const
Definition Util.h:208
T Carry() const
Definition Util.h:223
void AddIndexed(T input, std::size_t index)
Add input to the sum.
Definition Util.h:199
void Add(T x)
Single-element accumulation. Will not vectorise.
Definition Util.h:133
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:313
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
void wireAllCaches()
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:508
Int_t getSize() const
RooAbsArg * first() const
virtual void recalculateCache(const RooArgSet *, Int_t, Int_t, Int_t, Bool_t)
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:49
virtual const RooArgSet * get() const
Definition RooAbsData.h:92
RooAbsDataStore * store()
Definition RooAbsData.h:68
virtual void getBatches(RooBatchCompute::RunContext &evalData, std::size_t first=0, std::size_t len=std::numeric_limits< std::size_t >::max()) const =0
Retrieve batches of data for each real-valued variable in this dataset.
virtual RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len) const =0
Return event weights of all events in range [first, first+len).
virtual Double_t sumEntries() const =0
Return effective number of entries in dataset, i.e., sum all weights.
virtual Bool_t valid() const
Definition RooAbsData.h:98
virtual Double_t weight() const =0
virtual Double_t weightSquared() const =0
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a functio...
Bool_t canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition RooAbsPdf.h:238
virtual Double_t extendedTerm(Double_t observedEvents, const RooArgSet *nset=0) const
Return the extended likelihood term ( ) of this PDF for the given number of observed events.
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events from this p.d.f for use in extended likelihood calculations.
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.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition RooAbsReal.h:61
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:91
void logEvalError(const char *message, const char *serverValueString=0) const
Log evaluation error message.
RooAbsTestStatistic is the abstract base class for all test statistics.
Int_t _nGof
Number of designated set to calculated extended term.
Int_t _nCPU
GOF MP Split mode specified by component (when Auto is active)
pRooAbsTestStatistic * _gofArray
GOFOpMode _gofOpMode
Is object initialized
Double_t _evalCarry
avoids loss of precision
Double_t _offsetCarry
Offset.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:29
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.
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition RooNLLVar.h:30
void applyWeightSquared(Bool_t flag)
RooRealSumPdf * _binnedPdf
Definition RooNLLVar.h:89
virtual RooAbsTestStatistic * create(const char *name, const char *title, RooAbsReal &pdf, RooAbsData &adata, const RooArgSet &projDeps, const char *rangeName, const char *addCoefRangeName=0, Int_t nCPU=1, RooFit::MPSplit interleave=RooFit::BulkPartition, Bool_t verbose=kTRUE, Bool_t splitRange=kFALSE, Bool_t binnedL=kFALSE)
Create a test statistic using several properties of the current instance.
Bool_t _extended
Definition RooNLLVar.h:81
bool _batchEvaluations
Definition RooNLLVar.h:82
static RooArgSet _emptySet
Definition RooNLLVar.h:72
virtual ~RooNLLVar()
Destructor.
Bool_t _first
Definition RooNLLVar.h:84
std::vector< Double_t > _binw
Definition RooNLLVar.h:88
Double_t _offsetCarrySaveW2
Definition RooNLLVar.h:86
virtual Double_t evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
Calculate and return likelihood on subset of data.
Double_t _offsetSaveW2
Definition RooNLLVar.h:85
std::tuple< double, double, double > computeBatched(std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent) const
Compute probabilites of all data events.
std::tuple< double, double, double > computeScalar(std::size_t stepSize, std::size_t firstEvent, std::size_t lastEvent) const
std::unique_ptr< RooBatchCompute::RunContext > _evalData
Definition RooNLLVar.h:90
Bool_t _weightSq
Definition RooNLLVar.h:83
The class RooRealSumPdf implements a PDF constructed from a sum of functions:
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Retrieve bin boundaries if this distribution is binned in obs.
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:39
A simple container to hold a batch of data values.
Definition RooSpan.h:34
constexpr std::span< T >::index_type size() const noexcept
Definition RooSpan.h:121
constexpr bool empty() const noexcept
Definition RooSpan.h:125
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
Double_t y[n]
Definition legend1.C:17
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition TMath.cxx:486
This struct enables passing computation data around between elements of a computation graph.
Definition RunContext.h:31
Little struct that can pack a float into the unused bits of the mantissa of a NaN double.
float getPayload() const
Retrieve packed float.
double getNaNWithPayload() const
Retrieve a NaN with the current float payload packed into the mantissa.
void accumulate(double val)
Accumulate a packed float from another NaN into this.