Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[RF] Consider global observables stored in dataset in fits
Adapt `RooConstraintSum::createConstraintTerm` to consider when the
dataset stores global observables.

The RooFit behavior changes in two ways:

  * If no global observables are specified with `GlobalObservables` in
    the `RooAbsPdf::fitTo()` command arguments, the set of global
    observables is automatically detected from the dataset and the
    values from the dataset are used.
  * If the global observables are specified with `GlobalObservables`,
    their values are taken from the dataset if they are stored in it,
    otherwise they are taken from the model as before. It's also
    supported that only a subset of the specified global observables is
    stored in the data.
  • Loading branch information
guitargeek committed Sep 14, 2021
commit 7b915d76eddd4c062f3a367e1a4c5d5f372f259e
2 changes: 1 addition & 1 deletion roofit/roofitcore/inc/RooConstraintSum.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RooConstraintSum : public RooAbsReal {
static std::unique_ptr<RooAbsReal> createConstraintTerm(
std::string const& name,
RooAbsPdf const& pdf,
RooArgSet const& observables,
RooAbsData const& data,
RooArgSet const* constrainedParameters,
RooArgSet const* externalConstraints,
RooArgSet const* globalObservables,
Expand Down
2 changes: 1 addition & 1 deletion roofit/roofitcore/src/RooAbsPdf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooLinkedList& cmdList)
auto constraintTerm = RooConstraintSum::createConstraintTerm(
baseName + "_constr", // name
*this, // pdf
*data.get(), // observables
data, // data
pc.getSet("cPars"), // Constrain RooCmdArg
pc.getSet("extCons"), // ExternalConstraints RooCmdArg
pc.getSet("glObs"), // GlobalObservables RooCmdArg
Expand Down
71 changes: 60 additions & 11 deletions roofit/roofitcore/src/RooConstraintSum.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ arguments.


#include "RooConstraintSum.h"
#include "RooAbsData.h"
#include "RooAbsReal.h"
#include "RooAbsPdf.h"
#include "RooErrorHandler.h"
#include "RooArgSet.h"
#include "RooMsgService.h"
#include "RooHelpers.h"
#include "RooWorkspace.h"
#include "RooAbsRealLValue.h"
#include "RooAbsCategoryLValue.h"

#include <memory>

Expand Down Expand Up @@ -155,8 +158,10 @@ RooArgSet const* tryToGetConstraintSetFromWorkspace(
/// \param[in] pdf The pdf model whose parameters should be constrained.
/// Constraint terms will be extracted from RooProdPdf instances
/// that are servers of the pdf (internal constraints).
/// \param[in] observables Observable variables (used to determine which model
/// variables are parameters).
/// \param[in] data Dataset used in the fit with the constraint sum. It is
/// used to figure out which are the observables and also to get the
/// global observables definition and values if they are stored in
/// the dataset.
/// \param[in] constraints Set of parameters to constrain. If `nullptr`, all
/// parameters will be considered.
/// \param[in] externalConstraints Set of constraint terms that are not
Expand All @@ -174,13 +179,15 @@ RooArgSet const* tryToGetConstraintSetFromWorkspace(
std::unique_ptr<RooAbsReal> RooConstraintSum::createConstraintTerm(
std::string const& name,
RooAbsPdf const& pdf,
RooArgSet const& observables,
RooAbsData const& data,
RooArgSet const* constrainedParameters,
RooArgSet const* externalConstraints,
RooArgSet const* globalObservables,
const char* globalObservablesTag,
RooWorkspace * workspace)
{
RooArgSet const& observables = *data.get();

bool doStripDisconnected = false ;

// If no explicit list of parameters to be constrained is specified apply default algorithm
Expand Down Expand Up @@ -221,17 +228,59 @@ std::unique_ptr<RooAbsReal> RooConstraintSum::createConstraintTerm(
}
}

auto glObs = getGlobalObservables(pdf, globalObservables, globalObservablesTag);

if (!allConstraints.empty()) {

oocoutI(&pdf, Minimization) << " Including the following constraint terms in minimization: " << allConstraints << std::endl ;
if (glObs) {
oocoutI(&pdf, Minimization) << "The following global observables have been defined: " << *glObs << std::endl ;
oocoutI(&pdf, Minimization) << " Including the following constraint terms in minimization: "
<< allConstraints << std::endl ;

// Identify global observables in the model.
auto glObs = getGlobalObservables(pdf, globalObservables, globalObservablesTag);
if(data.getGlobalObservables()) {
if(!glObs) {
// There were no global observables specified, but there are some in the
// dataset. We will just take them from the dataset.
oocoutI(&pdf, Minimization)
<< "The following global observables have been automatically defined according to the dataset "
<< "which also provides their values: " << *data.getGlobalObservables() << std::endl;
glObs = std::make_unique<RooArgSet>(*data.getGlobalObservables());
} else {
// There are global observables specified by the user and also some in
// the dataset.
RooArgSet globalsFromDataset;
data.getGlobalObservables()->selectCommon(*glObs, globalsFromDataset);
oocoutI(&pdf, Minimization)
<< "The following global observables have been defined: " << *glObs
<< "," << " with the values of " << globalsFromDataset << " obtained from the dataset." << std::endl;
}
} else if(glObs) {
oocoutI(&pdf, Minimization)
<< "The following global observables have been defined: " << *glObs << std::endl;
}
auto constraintTerm = std::make_unique<RooConstraintSum>(name.c_str(),"nllCons",allConstraints,glObs ? *glObs : cPars) ;
constraintTerm->setOperMode(RooAbsArg::ADirty) ;
return constraintTerm;

// The constraint terms need to be cloned, because the global observables
// might be changed to have the same values as stored in data.
RooConstraintSum constraintTerm{name.c_str(),"nllCons", allConstraints, glObs ? *glObs : cPars};
std::unique_ptr<RooAbsReal> constraintTermClone{static_cast<RooAbsReal*>(constraintTerm.cloneTree())};

// Set the global observables values from the dataset if applicable
// Redirect the global observables to the ones from the dataset if applicable.
if(data.getGlobalObservables()) {
constraintTermClone->recursiveRedirectServers(*data.getGlobalObservables()) ;
}

// The parameters that are not connected to global observables from data
// need to be redirected to the original args to get the changes made by
// the minimizer. This excludes the global observables, where we take the
// clones with the values set to the values from the dataset if available.
RooArgSet allOriginalParams;
constraintTerm.getParameters(data.getGlobalObservables(),allOriginalParams);
constraintTermClone->recursiveRedirectServers(allOriginalParams) ;

// The computation graph for the constraints is very small, no need to do
// the tracking of clean and dirty nodes here.
constraintTermClone->setOperMode(RooAbsArg::ADirty) ;

return constraintTermClone;
}

// no constraints
Expand Down