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.
95std::unique_ptr<RooAbsReal> createConstraintTerm(std::string const &name, RooAbsPdf const &pdf, RooAbsData const &data,
96 RooArgSet const *constrainedParameters,
97 RooArgSet const *externalConstraints,
98 RooArgSet const *globalObservables, const char *globalObservablesTag,
99 bool takeGlobalObservablesFromData)
100{
101 RooArgSet const &observables = *data.get();
102
103 bool doStripDisconnected = false;
104
105 // If no explicit list of parameters to be constrained is specified apply default algorithm
106 // All terms of RooProdPdfs that do not contain observables and share a parameters with one or more
107 // terms that do contain observables are added as constrainedParameters.
108 RooArgSet cPars;
109 if (constrainedParameters) {
110 cPars.add(*constrainedParameters);
111 } else {
112 pdf.getParameters(&observables, cPars, false);
113 doStripDisconnected = true;
114 }
115
116 // Collect internal and external constraint specifications
117 RooArgSet allConstraints;
118
119 auto observableNames = RooHelpers::getColonSeparatedNameString(observables);
120 auto constraintSetCacheName = std::string("CACHE_CONSTR_OF_PDF_") + pdf.GetName() + "_FOR_OBS_" + observableNames;
121
122 if (!cPars.empty()) {
123 std::unique_ptr<RooArgSet> internalConstraints{
124 pdf.getAllConstraints(observables, cPars, doStripDisconnected)};
125 allConstraints.add(*internalConstraints);
126 }
127 if (externalConstraints) {
128 allConstraints.add(*externalConstraints);
129 }
130
131 if (!allConstraints.empty()) {
132
133 oocoutI(&pdf, Minimization) << " Including the following constraint terms in minimization: " << allConstraints
134 << std::endl;
135
136 // Identify global observables in the model.
137 auto glObs = getGlobalObservables(pdf, globalObservables, globalObservablesTag);
138 if (data.getGlobalObservables() && takeGlobalObservablesFromData) {
139 if (!glObs) {
140 // There were no global observables specified, but there are some in the
141 // dataset. We will just take them from the dataset.
142 oocoutI(&pdf, Minimization)
143 << "The following global observables have been automatically defined according to the dataset "
144 << "which also provides their values: " << *data.getGlobalObservables() << std::endl;
145 glObs = std::make_unique<RooArgSet>(*data.getGlobalObservables());
146 } else {
147 // There are global observables specified by the user and also some in
148 // the dataset.
149 RooArgSet globalsFromDataset;
150 data.getGlobalObservables()->selectCommon(*glObs, globalsFromDataset);
151 oocoutI(&pdf, Minimization) << "The following global observables have been defined: " << *glObs << ","
152 << " with the values of " << globalsFromDataset
153 << " obtained from the dataset and the other values from the model."
154 << std::endl;
155 }
156 } else if (glObs) {
157 oocoutI(&pdf, Minimization)
158 << "The following global observables have been defined and their values are taken from the model: "
159 << *glObs << std::endl;
160 // In this case we don't take global observables from data
161 takeGlobalObservablesFromData = false;
162 } else {
163 if (!glObs) {
164 oocoutI(&pdf, Minimization)
165 << "The global observables are not defined , normalize constraints with respect to the parameters "
166 << cPars << std::endl;
167 }
168 takeGlobalObservablesFromData = false;
169 }
170
171 return std::make_unique<RooConstraintSum>(name.c_str(), "nllCons", allConstraints, glObs ? *glObs : cPars,
172 takeGlobalObservablesFromData);
173 }
174
175 // no constraints
176 return nullptr;
177}
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)
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) 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:24
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
std::string getColonSeparatedNameString(RooArgSet const &argSet, char delim=':')