Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
20
21#include <RooMsgService.h>
22
23#include "MinuitFcnGrad.h"
24
25// including derived classes for factory method
26#include "LikelihoodSerial.h"
27#ifdef ROOFIT_MULTIPROCESS
28#include "LikelihoodJob.h"
29#endif // ROOFIT_MULTIPROCESS
30
31namespace RooFit {
32namespace TestStatistics {
33
34/** \class LikelihoodWrapper
35 * \brief Virtual base class for implementation of likelihood calculation strategies
36 *
37 * This class provides the interface necessary for RooMinimizer (through MinuitFcnGrad) to get the likelihood values it
38 * needs for fitting the pdf to the data. The strategy by which these values are obtained is up to the implementer of
39 * this class. Its intended purpose was mainly to allow for parallel calculation strategies, but serial strategies are
40 * possible too, as illustrated in LikelihoodSerial.
41 *
42 * \note The class is not intended for use by end-users. We recommend to either use RooMinimizer with a RooAbsL derived
43 * likelihood object, or to use a higher level entry point like RooAbsPdf::fitTo() or RooAbsPdf::createNLL().
44 */
45
46/*
47 * \param[in] likelihood Shared pointer to the likelihood that must be evaluated
48 * \param[in] calculation_is_clean Shared pointer to the object that keeps track of what has been evaluated for the
49 * current parameter set provided by Minuit. This information can be used by different calculators, so must be shared
50 * between them.
51 */
52LikelihoodWrapper::LikelihoodWrapper(std::shared_ptr<RooAbsL> likelihood,
53 std::shared_ptr<WrapperCalculationCleanFlags> calculation_is_clean,
55 : likelihood_(std::move(likelihood)),
56 calculation_is_clean_(std::move(calculation_is_clean)),
57 shared_offset_(std::move(offset))
58{
59 // determine likelihood type
60 if (dynamic_cast<RooUnbinnedL *>(likelihood_.get()) != nullptr) {
62 } else if (dynamic_cast<RooBinnedL *>(likelihood_.get()) != nullptr) {
64 } else if (dynamic_cast<RooSumL *>(likelihood_.get()) != nullptr) {
66 } else if (dynamic_cast<RooSubsidiaryL *>(likelihood_.get()) != nullptr) {
68 } else {
69 throw std::logic_error("in LikelihoodWrapper constructor: _likelihood is not of a valid subclass!");
70 }
71}
72
74
76 const std::vector<ROOT::Fit::ParameterSettings> & /*parameter_settings*/)
77{
78}
79
81{
82 likelihood_->constOptimizeTestStatistic(opcode, doAlsoTrackingOpt);
83}
84
86{
87 return likelihood_->defaultErrorLevel();
88}
89std::string LikelihoodWrapper::GetName() const
90{
91 return likelihood_->GetName();
92}
93std::string LikelihoodWrapper::GetTitle() const
94{
95 return likelihood_->GetTitle();
96}
97
99{
100 do_offset_ = flag;
101 // Clear offsets if feature is disabled so that it is recalculated next time it is enabled
102 if (!do_offset_) {
104 }
105}
106
108{
110 if (isOffsetting()) {
111 oocoutI(nullptr, Minimization)
112 << "LikelihoodWrapper::setOffsettingMode(" << GetName()
113 << "): changed offsetting mode while offsetting was enabled; resetting offset values" << std::endl;
115 }
116}
117
118/// (Re)calculate (on each worker) all component offsets.
119///
120/// Note that these are calculated over the full event range! This will decrease the effectiveness of offsetting
121/// proportionally to the number of splits over the event range. The alternative, however, becomes very complex to
122/// implement and maintain, so this is a compromise.
124{
126
127 switch (likelihood_type_) {
129 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
130 shared_offset_.offsets_save().emplace_back();
131 break;
132 }
134 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
135 break;
136 }
139 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
140 } else {
141 shared_offset_.offsets().emplace_back();
142 }
143 break;
144 }
145 case LikelihoodType::sum: {
146 auto sum_likelihood = dynamic_cast<RooSumL *>(likelihood_.get());
147 assert(sum_likelihood != nullptr);
148 for (std::size_t comp_ix = 0; comp_ix < likelihood_->getNComponents(); ++comp_ix) {
149 auto component_subsidiary_cast =
150 dynamic_cast<RooSubsidiaryL *>(sum_likelihood->GetComponents()[comp_ix].get());
151 if (offsetting_mode_ == OffsettingMode::full || component_subsidiary_cast == nullptr) {
152 // Note: we leave out here the check for whether the calculated value is zero to reduce complexity, which
153 // RooNLLVar does do at this (equivalent) point. Instead, we check whether the offset is zero when
154 // subtracting it in evaluations.
155 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, comp_ix, comp_ix + 1));
156 oocoutI(nullptr, Minimization)
157 << "LikelihoodSerial::evaluate(" << GetName() << "): Likelihood offset now set to "
158 << shared_offset_.offsets().back().Sum() << std::endl;
159 } else {
160 shared_offset_.offsets().emplace_back();
161 }
162 // default initialize the save offsets, just in case we have an unbinned component
163 shared_offset_.offsets_save().emplace_back();
164 }
165 break;
166 }
167 }
168}
169
170/// \note Currently we do not recalculate the offset value, so in practice swapped offsets
171/// are zero/disabled. This differs from using RooNLLVar, so your fit may yield slightly
172/// different values.
174{
175 std::vector<std::size_t> comp_was_changed;
176 switch (likelihood_type_) {
178 auto unbinned_likelihood = dynamic_cast<RooUnbinnedL *>(likelihood_.get());
179 assert(unbinned_likelihood != nullptr);
180 if (unbinned_likelihood->setApplyWeightSquared(flag))
181 comp_was_changed.emplace_back(0);
182 break;
183 }
184 case LikelihoodType::sum: {
185 auto sum_likelihood = dynamic_cast<RooSumL *>(likelihood_.get());
186 assert(sum_likelihood != nullptr);
187 for (std::size_t comp_ix = 0; comp_ix < likelihood_->getNComponents(); ++comp_ix) {
188 auto component_unbinned_cast = dynamic_cast<RooUnbinnedL *>(sum_likelihood->GetComponents()[comp_ix].get());
189 if (component_unbinned_cast != nullptr) {
190 if (component_unbinned_cast->setApplyWeightSquared(flag))
191 comp_was_changed.emplace_back(comp_ix);
192 }
193 }
194 break;
195 }
196 default: {
197 throw std::logic_error("LikelihoodWrapper::setApplyWeightSquared can only be used on unbinned likelihoods, but "
198 "the wrapped likelihood_ member is not a RooUnbinnedL nor a RooSumL containing an unbinned"
199 "component!");
200 }
201 }
202 if (!comp_was_changed.empty()) {
203 shared_offset_.swap(comp_was_changed);
204 }
205}
206
207void LikelihoodWrapper::updateMinuitInternalParameterValues(const std::vector<double> & /*minuit_internal_x*/) {}
208void LikelihoodWrapper::updateMinuitExternalParameterValues(const std::vector<double> & /*minuit_external_x*/) {}
209
210/// Factory method.
211std::unique_ptr<LikelihoodWrapper>
212LikelihoodWrapper::create(LikelihoodMode likelihoodMode, std::shared_ptr<RooAbsL> likelihood,
213 std::shared_ptr<WrapperCalculationCleanFlags> calculationIsClean, SharedOffset offset)
214{
215 switch (likelihoodMode) {
217 return std::make_unique<LikelihoodSerial>(std::move(likelihood), std::move(calculationIsClean),
218 std::move(offset));
219 }
221#ifdef ROOFIT_MULTIPROCESS
222 return std::make_unique<LikelihoodJob>(std::move(likelihood), std::move(calculationIsClean), std::move(offset));
223#else
224 throw std::runtime_error("MinuitFcnGrad ctor with LikelihoodMode::multiprocess is not available in this build "
225 "without RooFit::Multiprocess!");
226#endif
227 }
228 default: {
229 throw std::logic_error("In MinuitFcnGrad constructor: likelihoodMode has an unsupported value!");
230 }
231 }
232}
233
234} // namespace TestStatistics
235} // namespace RooFit
#define oocoutI(o, a)
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char mode
virtual void synchronizeParameterSettings(const std::vector< ROOT::Fit::ParameterSettings > &parameter_settings)
void constOptimizeTestStatistic(RooAbsArg::ConstOpCode opcode, bool doAlsoTrackingOpt)
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...
void calculate_offsets()
(Re)calculate (on each worker) all component offsets.
static std::unique_ptr< LikelihoodWrapper > create(LikelihoodMode likelihoodMode, std::shared_ptr< RooAbsL > likelihood, std::shared_ptr< WrapperCalculationCleanFlags > calculationIsClean, SharedOffset offset)
Factory method.
LikelihoodWrapper(std::shared_ptr< RooAbsL > likelihood, std::shared_ptr< WrapperCalculationCleanFlags > calculation_is_clean, SharedOffset offset)
virtual void synchronizeWithMinimizer(const ROOT::Math::MinimizerOptions &options)
Synchronize minimizer settings with calculators in child classes.
Likelihood class that sums over multiple -log components.
Definition RooSumL.h:25
void swap(const std::vector< std::size_t > &component_keys)
When calculating an unbinned likelihood with square weights applied, a different offset is necessary.
OffsetVec & offsets_save()
OffsetVec & offsets()
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 CodegenImpl.h:64