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 return likelihood_->defaultErrorLevel();
83}
84std::string LikelihoodWrapper::GetName() const
85{
86 return likelihood_->GetName();
87}
88std::string LikelihoodWrapper::GetTitle() const
89{
90 return likelihood_->GetTitle();
91}
92
94{
96 // Clear offsets if feature is disabled so that it is recalculated next time it is enabled
97 if (!do_offset_) {
99 }
100}
101
103{
105 if (isOffsetting()) {
106 oocoutI(nullptr, Minimization)
107 << "LikelihoodWrapper::setOffsettingMode(" << GetName()
108 << "): changed offsetting mode while offsetting was enabled; resetting offset values" << std::endl;
110 }
111}
112
113/// (Re)calculate (on each worker) all component offsets.
114///
115/// Note that these are calculated over the full event range! This will decrease the effectiveness of offsetting
116/// proportionally to the number of splits over the event range. The alternative, however, becomes very complex to
117/// implement and maintain, so this is a compromise.
119{
121
122 switch (likelihood_type_) {
124 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
125 shared_offset_.offsets_save().emplace_back();
126 break;
127 }
129 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
130 break;
131 }
134 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, 0, 0));
135 } else {
136 shared_offset_.offsets().emplace_back();
137 }
138 break;
139 }
140 case LikelihoodType::sum: {
141 auto sum_likelihood = dynamic_cast<RooSumL *>(likelihood_.get());
142 assert(sum_likelihood != nullptr);
143 for (std::size_t comp_ix = 0; comp_ix < likelihood_->getNComponents(); ++comp_ix) {
145 dynamic_cast<RooSubsidiaryL *>(sum_likelihood->GetComponents()[comp_ix].get());
147 // Note: we leave out here the check for whether the calculated value is zero to reduce complexity, which
148 // RooNLLVar does do at this (equivalent) point. Instead, we check whether the offset is zero when
149 // subtracting it in evaluations.
150 shared_offset_.offsets().push_back(likelihood_->evaluatePartition({0, 1}, comp_ix, comp_ix + 1));
151 oocoutI(nullptr, Minimization)
152 << "LikelihoodSerial::evaluate(" << GetName() << "): Likelihood offset now set to "
153 << shared_offset_.offsets().back().Sum() << std::endl;
154 } else {
155 shared_offset_.offsets().emplace_back();
156 }
157 // default initialize the save offsets, just in case we have an unbinned component
158 shared_offset_.offsets_save().emplace_back();
159 }
160 break;
161 }
162 }
163}
164
165/// \note Currently we do not recalculate the offset value, so in practice swapped offsets
166/// are zero/disabled. This differs from using RooNLLVar, so your fit may yield slightly
167/// different values.
169{
170 std::vector<std::size_t> comp_was_changed;
171 switch (likelihood_type_) {
173 auto unbinned_likelihood = dynamic_cast<RooUnbinnedL *>(likelihood_.get());
174 assert(unbinned_likelihood != nullptr);
175 if (unbinned_likelihood->setApplyWeightSquared(flag))
176 comp_was_changed.emplace_back(0);
177 break;
178 }
179 case LikelihoodType::sum: {
180 auto sum_likelihood = dynamic_cast<RooSumL *>(likelihood_.get());
181 assert(sum_likelihood != nullptr);
182 for (std::size_t comp_ix = 0; comp_ix < likelihood_->getNComponents(); ++comp_ix) {
183 auto component_unbinned_cast = dynamic_cast<RooUnbinnedL *>(sum_likelihood->GetComponents()[comp_ix].get());
184 if (component_unbinned_cast != nullptr) {
185 if (component_unbinned_cast->setApplyWeightSquared(flag))
186 comp_was_changed.emplace_back(comp_ix);
187 }
188 }
189 break;
190 }
191 default: {
192 throw std::logic_error("LikelihoodWrapper::setApplyWeightSquared can only be used on unbinned likelihoods, but "
193 "the wrapped likelihood_ member is not a RooUnbinnedL nor a RooSumL containing an unbinned"
194 "component!");
195 }
196 }
197 if (!comp_was_changed.empty()) {
199 }
200}
201
202void LikelihoodWrapper::updateMinuitInternalParameterValues(const std::vector<double> & /*minuit_internal_x*/) {}
203void LikelihoodWrapper::updateMinuitExternalParameterValues(const std::vector<double> & /*minuit_external_x*/) {}
204
205/// Factory method.
206std::unique_ptr<LikelihoodWrapper>
207LikelihoodWrapper::create(LikelihoodMode likelihoodMode, std::shared_ptr<RooAbsL> likelihood,
208 std::shared_ptr<WrapperCalculationCleanFlags> calculationIsClean, SharedOffset offset)
209{
210 switch (likelihoodMode) {
212 return std::make_unique<LikelihoodSerial>(std::move(likelihood), std::move(calculationIsClean),
213 std::move(offset));
214 }
216#ifdef ROOFIT_MULTIPROCESS
217 return std::make_unique<LikelihoodJob>(std::move(likelihood), std::move(calculationIsClean), std::move(offset));
218#else
219 throw std::runtime_error("MinuitFcnGrad ctor with LikelihoodMode::multiprocess is not available in this build "
220 "without RooFit::Multiprocess!");
221#endif
222 }
223 default: {
224 throw std::logic_error("In MinuitFcnGrad constructor: likelihoodMode has an unsupported value!");
225 }
226 }
227}
228
229} // namespace TestStatistics
230} // namespace RooFit
#define oocoutI(o, a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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)
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:73