Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ConstraintHelpers.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Jonas Rembser, CERN 2021
5 *
6 * Copyright (c) 2022, 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#include "ConstraintHelpers.h"
14
15#include <RooAbsData.h>
16#include <RooAbsPdf.h>
17#include <RooConstraintSum.h>
18#include <RooMsgService.h>
19
20#include "RooFitImplHelpers.h"
21
22namespace {
23
24std::unique_ptr<RooArgSet>
25getGlobalObservables(RooAbsPdf const &pdf, RooArgSet const *globalObservables, const char *globalObservablesTag)
26{
27
28 if (globalObservables && globalObservablesTag) {
29 // error!
30 std::string errMsg = "RooAbsPdf::fitTo: GlobalObservables and GlobalObservablesTag options mutually exclusive!";
31 oocoutE(&pdf, Minimization) << errMsg << std::endl;
32 throw std::invalid_argument(errMsg);
33 }
34 if (globalObservables) {
35 // pass-through of global observables
36 return std::make_unique<RooArgSet>(*globalObservables);
37 }
38
39 if (globalObservablesTag) {
40 oocoutI(&pdf, Minimization) << "User-defined specification of global observables definition with tag named '"
41 << globalObservablesTag << "'" << std::endl;
42 } else {
43 // Neither GlobalObservables nor GlobalObservablesTag has been processed -
44 // try if a default tag is defined in the head node Check if head not
45 // specifies default global observable tag
46 if (auto defaultGlobalObservablesTag = pdf.getStringAttribute("DefaultGlobalObservablesTag")) {
47 oocoutI(&pdf, Minimization) << "p.d.f. provides built-in specification of global observables definition "
48 << "with tag named '" << defaultGlobalObservablesTag << "'" << std::endl;
49 globalObservablesTag = defaultGlobalObservablesTag;
50 }
51 }
52
53 if (globalObservablesTag) {
54 std::unique_ptr<RooArgSet> allVars{pdf.getVariables()};
55 return std::unique_ptr<RooArgSet>{static_cast<RooArgSet *>(allVars->selectByAttrib(globalObservablesTag, true))};
56 }
57
58 // no global observables specified
59 return nullptr;
60}
61
62} // namespace
63
64////////////////////////////////////////////////////////////////////////////////
65/// Create the parameter constraint sum to add to the negative log-likelihood.
66/// \return If there are constraints, returns a pointer to the constraint NLL.
67/// Returns a `nullptr` if the parameters are unconstrained.
68/// \param[in] name Name of the created RooConstraintSum object.
69/// \param[in] pdf The PDF model whose parameters should be constrained.
70/// Constraint terms will be extracted from RooProdPdf instances
71/// that are servers of the PDF (internal constraints).
72/// \param[in] data Dataset used in the fit with the constraint sum. It is
73/// used to figure out which are the observables and also to get the
74/// global observables definition and values if they are stored in
75/// the dataset.
76/// \param[in] constrainedParameters Set of parameters to constrain. If `nullptr`, all
77/// parameters will be considered.
78/// \param[in] externalConstraints Set of constraint terms that are not
79/// embedded in the PDF (external constraints).
80/// \param[in] globalObservables The normalization set for the constraint terms.
81/// If it is `nullptr`, the set of all constrained parameters will
82/// be used as the normalization set.
83/// \param[in] globalObservablesTag Alternative to define the normalization set
84/// for the constraint terms. All constrained parameters that have
85/// the attribute with the tag defined by `globalObservablesTag` are
86/// used. The `globalObservables` and `globalObservablesTag`
87/// parameters are mutually exclusive, meaning at least one of them
88/// has to be `nullptr`.
89/// \param[in] takeGlobalObservablesFromData If the dataset should be used to automatically
90/// define the set of global observables. If this is the case and the
91/// set of global observables is still defined manually with the
92/// `globalObservables` or `globalObservablesTag` parameters, the
93/// values of all global observables that are not stored in the
94/// dataset are taken from the model.
95/// \param[in] removeConstraintsPdf If true, the constraints that are extracted
96/// from the PDF are removed from the original PDF.
97std::unique_ptr<RooAbsReal> createConstraintTerm(std::string const &name, RooAbsPdf const &pdf, RooAbsData const &data,
98 RooArgSet const *constrainedParameters,
99 RooArgSet const *externalConstraints,
100 RooArgSet const *globalObservables, const char *globalObservablesTag,
101 bool takeGlobalObservablesFromData, bool removeConstraintsFromPdf)
102{
103 RooArgSet const &observables = *data.get();
104
105 bool doStripDisconnected = false;
106
107 // If no explicit list of parameters to be constrained is specified apply default algorithm
108 // All terms of RooProdPdfs that do not contain observables and share a parameters with one or more
109 // terms that do contain observables are added as constrainedParameters.
110 RooArgSet cPars;
111 if (constrainedParameters) {
112 cPars.add(*constrainedParameters);
113 } else {
114 pdf.getParameters(&observables, cPars, false);
115 doStripDisconnected = true;
116 }
117
118 // Collect internal and external constraint specifications
119 RooArgSet allConstraints;
120
121 auto observableNames = RooHelpers::getColonSeparatedNameString(observables);
122 auto constraintSetCacheName = std::string("CACHE_CONSTR_OF_PDF_") + pdf.GetName() + "_FOR_OBS_" + observableNames;
123
124 if (!cPars.empty()) {
125 std::unique_ptr<RooArgSet> internalConstraints{
126 pdf.getAllConstraints(observables, cPars, doStripDisconnected, removeConstraintsFromPdf)};
127 allConstraints.add(*internalConstraints);
128 }
129 if (externalConstraints) {
130 allConstraints.add(*externalConstraints);
131 }
132
133 if (!allConstraints.empty()) {
134
135 oocoutI(&pdf, Minimization) << " Including the following constraint terms in minimization: " << allConstraints
136 << std::endl;
137
138 // Identify global observables in the model.
139 auto glObs = getGlobalObservables(pdf, globalObservables, globalObservablesTag);
140 if (data.getGlobalObservables() && takeGlobalObservablesFromData) {
141 if (!glObs) {
142 // There were no global observables specified, but there are some in the
143 // dataset. We will just take them from the dataset.
144 oocoutI(&pdf, Minimization)
145 << "The following global observables have been automatically defined according to the dataset "
146 << "which also provides their values: " << *data.getGlobalObservables() << std::endl;
147 glObs = std::make_unique<RooArgSet>(*data.getGlobalObservables());
148 } else {
149 // There are global observables specified by the user and also some in
150 // the dataset.
151 RooArgSet globalsFromDataset;
152 data.getGlobalObservables()->selectCommon(*glObs, globalsFromDataset);
153 oocoutI(&pdf, Minimization) << "The following global observables have been defined: " << *glObs << ","
154 << " with the values of " << globalsFromDataset
155 << " obtained from the dataset and the other values from the model."
156 << std::endl;
157 }
158 } else if (glObs) {
159 oocoutI(&pdf, Minimization)
160 << "The following global observables have been defined and their values are taken from the model: "
161 << *glObs << std::endl;
162 // In this case we don't take global observables from data
163 takeGlobalObservablesFromData = false;
164 } else {
165 if (!glObs) {
166 oocoutI(&pdf, Minimization)
167 << "The global observables are not defined , normalize constraints with respect to the parameters "
168 << cPars << std::endl;
169 }
170 takeGlobalObservablesFromData = false;
171 }
172
173 return std::make_unique<RooConstraintSum>(name.c_str(), "nllCons", allConstraints, glObs ? *glObs : cPars,
174 takeGlobalObservablesFromData);
175 }
176
177 // no constraints
178 return nullptr;
179}
std::unique_ptr< RooAbsReal > createConstraintTerm(std::string const &name, RooAbsPdf const &pdf, RooAbsData const &data, RooArgSet const *constrainedParameters, RooArgSet const *externalConstraints, RooArgSet const *globalObservables, const char *globalObservablesTag, bool takeGlobalObservablesFromData, bool removeConstraintsFromPdf)
Create the parameter constraint sum to add to the negative log-likelihood.
#define oocoutE(o, a)
#define oocoutI(o, a)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
char name[80]
Definition TGX11.cxx:110
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...
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
RooFit::OwningPtr< RooArgSet > getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expression tree)
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
RooArgSet * getAllConstraints(const RooArgSet &observables, RooArgSet &constrainedParams, bool stripDisconnected=true, bool removeConstraintsFromPdf=false) const
This helper function finds and collects all constraints terms of all component p.d....
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
std::string getColonSeparatedNameString(RooArgSet const &argSet, char delim=':')