Logo ROOT  
Reference Guide
LikelihoodWrapper.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
14
15#include <RooFit/TestStatistics/RooAbsL.h> // need complete type for likelihood->...
17#include <RooFit/TestStatistics/RooSumL.h> // need complete type for dynamic cast
18
19#include <RooMsgService.h>
20
21#include "MinuitFcnGrad.h"
22
23// including derived classes for factory method
24#include "LikelihoodSerial.h"
25#ifdef R__HAS_ROOFIT_MULTIPROCESS
26#include "LikelihoodJob.h"
27#endif // R__HAS_ROOFIT_MULTIPROCESS
28
29namespace RooFit {
30namespace TestStatistics {
31
32/** \class LikelihoodWrapper
33 * \brief Virtual base class for implementation of likelihood calculation strategies
34 *
35 * This class provides the interface necessary for RooMinimizer (through MinuitFcnGrad) to get the likelihood values it
36 * needs for fitting the pdf to the data. The strategy by which these values are obtained is up to the implementer of
37 * this class. Its intended purpose was mainly to allow for parallel calculation strategies, but serial strategies are
38 * possible too, as illustrated in LikelihoodSerial.
39 *
40 * \note The class is not intended for use by end-users. We recommend to either use RooMinimizer with a RooAbsL derived
41 * likelihood object, or to use a higher level entry point like RooAbsPdf::fitTo() or RooAbsPdf::createNLL().
42 */
43
44/*
45 * \param[in] likelihood Shared pointer to the likelihood that must be evaluated
46 * \param[in] calculation_is_clean Shared pointer to the object that keeps track of what has been evaluated for the
47 * current parameter set provided by Minuit. This information can be used by different calculators, so must be shared
48 * between them.
49 */
50LikelihoodWrapper::LikelihoodWrapper(std::shared_ptr<RooAbsL> likelihood,
51 std::shared_ptr<WrapperCalculationCleanFlags> calculation_is_clean)
52 : likelihood_(std::move(likelihood)), calculation_is_clean_(std::move(calculation_is_clean))
53{
54 // Note to future maintainers: take care when storing the minimizer_fcn pointer. The
55 // RooAbsMinimizerFcn subclasses may get cloned inside MINUIT, which means the pointer
56 // should also somehow be updated in this class.
57}
58
60
62 const std::vector<ROOT::Fit::ParameterSettings> & /*parameter_settings*/)
63{
64}
65
67{
68 likelihood_->constOptimizeTestStatistic(opcode, doAlsoTrackingOpt);
69}
70
72{
73 return likelihood_->defaultErrorLevel();
74}
75std::string LikelihoodWrapper::GetName() const
76{
77 return likelihood_->GetName();
78}
79std::string LikelihoodWrapper::GetTitle() const
80{
81 return likelihood_->GetTitle();
82}
83
85{
86 do_offset_ = flag;
87 // Clear offset if feature is disabled so that it is recalculated next time it is enabled
88 if (!do_offset_) {
89 offset_ = {};
90 }
91}
92
94{
96 if (isOffsetting()) {
97 oocoutI(nullptr, Minimization)
98 << "LikelihoodWrapper::setOffsettingMode(" << GetName()
99 << "): changed offsetting mode while offsetting was enabled; resetting offset values" << std::endl;
100 offset_ = {};
101 }
102}
103
105{
106 if (do_offset_) {
107
108 // If no offset is stored enable this feature now
109 if (offset_ == 0 && current_value != 0) {
110 offset_ = current_value;
112 auto sum_likelihood = dynamic_cast<RooSumL *>(likelihood_.get());
113 if (sum_likelihood != nullptr) {
114 auto subsidiary_value = sum_likelihood->getSubsidiaryValue();
115 // "undo" the addition of the subsidiary value to emulate legacy behavior
116 offset_ -= subsidiary_value;
117 // manually calculate result with zero carry, again to emulate legacy behavior
118 return {current_value.Result() - offset_.Result()};
119 }
120 }
121 oocoutI(nullptr, Minimization)
122 << "LikelihoodWrapper::applyOffsetting(" << GetName() << "): Likelihood offset now set to " << offset_
123 << std::endl;
124 }
125
126 return current_value - offset_;
127 } else {
128 return current_value;
129 }
130}
131
132/// When calculating an unbinned likelihood with square weights applied, a different offset
133/// is necessary. Similar situations may ask for a separate offset as well. This function
134/// switches between the two sets of offset values.
136{
138}
139
141{
142 RooUnbinnedL *unbinned_likelihood = dynamic_cast<RooUnbinnedL *>(likelihood_.get());
143 if (unbinned_likelihood == nullptr) {
144 throw std::logic_error("LikelihoodWrapper::setApplyWeightSquared can only be used on unbinned likelihoods, but "
145 "the wrapped likelihood_ member is not a RooUnbinnedL!");
146 }
147 bool flag_was_changed = unbinned_likelihood->setApplyWeightSquared(flag);
148
149 if (flag_was_changed) {
150 swapOffsets();
151 }
152}
153
154void LikelihoodWrapper::updateMinuitInternalParameterValues(const std::vector<double> & /*minuit_internal_x*/) {}
155void LikelihoodWrapper::updateMinuitExternalParameterValues(const std::vector<double> & /*minuit_external_x*/) {}
156
157/// Factory method.
158std::unique_ptr<LikelihoodWrapper>
159LikelihoodWrapper::create(LikelihoodMode likelihoodMode, std::shared_ptr<RooAbsL> likelihood,
160 std::shared_ptr<WrapperCalculationCleanFlags> calculationIsClean)
161{
162 switch (likelihoodMode) {
164 return std::make_unique<LikelihoodSerial>(std::move(likelihood), std::move(calculationIsClean));
165 }
167#ifdef R__HAS_ROOFIT_MULTIPROCESS
168 return std::make_unique<LikelihoodJob>(std::move(likelihood), std::move(calculationIsClean));
169#else
170 throw std::runtime_error("MinuitFcnGrad ctor with LikelihoodMode::multiprocess is not available in this build "
171 "without RooFit::Multiprocess!");
172#endif
173 }
174 default: {
175 throw std::logic_error("In MinuitFcnGrad constructor: likelihoodMode has an unsupported value!");
176 }
177 }
178}
179
180} // namespace TestStatistics
181} // namespace RooFit
#define oocoutI(o, a)
Definition: RooMsgService.h:49
Option_t Option_t TPoint TPoint const char mode
T Result() const
Definition: Util.h:245
virtual void synchronizeParameterSettings(const std::vector< ROOT::Fit::ParameterSettings > &parameter_settings)
void constOptimizeTestStatistic(RooAbsArg::ConstOpCode opcode, bool doAlsoTrackingOpt)
LikelihoodWrapper(std::shared_ptr< RooAbsL > likelihood, std::shared_ptr< WrapperCalculationCleanFlags > calculation_is_clean)
ROOT::Math::KahanSum< double > applyOffsetting(ROOT::Math::KahanSum< double > current_value)
ROOT::Math::KahanSum< double > offset_save_
!
ROOT::Math::KahanSum< double > offset_
void swapOffsets()
When calculating an unbinned likelihood with square weights applied, a different offset is necessary.
virtual void updateMinuitExternalParameterValues(const std::vector< double > &minuit_external_x)
virtual void updateMinuitInternalParameterValues(const std::vector< double > &minuit_internal_x)
Minuit passes in parameter values that may not conform to RooFit internal standards (like applying ra...
virtual void synchronizeWithMinimizer(const ROOT::Math::MinimizerOptions &options)
Synchronize minimizer settings with calculators in child classes.
static std::unique_ptr< LikelihoodWrapper > create(LikelihoodMode likelihoodMode, std::shared_ptr< RooAbsL > likelihood, std::shared_ptr< WrapperCalculationCleanFlags > calculationIsClean)
Factory method.
Likelihood class that sums over multiple -log components.
Definition: RooSumL.h:26
ROOT::Math::KahanSum< double > getSubsidiaryValue()
Definition: RooSumL.cxx:102
bool setApplyWeightSquared(bool flag)
Returns true if value was changed, false otherwise.
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
OffsettingMode
Previously, offsetting was only implemented for RooNLLVar components of a likelihood,...
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition: Common.h:18
@ Minimization
Definition: RooGlobalFunc.h:61