Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RF] Several improvements in RooFit chi-square fitting #13651

Merged
merged 4 commits into from Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -43,7 +43,7 @@ def _pack_cmd_args(*args, **kwargs):
class RooAbsPdf(RooAbsReal):
r"""Some member functions of RooAbsPdf that take a RooCmdArg as argument also support keyword arguments.
So far, this applies to RooAbsPdf::fitTo, RooAbsPdf::plotOn, RooAbsPdf::generate, RooAbsPdf::paramOn, RooAbsPdf::createCdf,
RooAbsPdf::generateBinned, RooAbsPdf::createChi2, RooAbsPdf::prepareMultiGen and RooAbsPdf::createNLL.
RooAbsPdf::generateBinned, RooAbsPdf::prepareMultiGen and RooAbsPdf::createNLL.
For example, the following code is equivalent in PyROOT:
\code{.py}
# Directly passing a RooCmdArg:
Expand Down Expand Up @@ -115,19 +115,6 @@ def createNLL(self, *args, **kwargs):
# Redefinition of `RooAbsPdf.createNLL` for keyword arguments.
return self._createNLL(args[0], _pack_cmd_args(*args[1:], **kwargs))

@cpp_signature(
"RooAbsReal *RooAbsPdf::createChi2(RooDataHist& data, const RooCmdArg& arg1={}, const RooCmdArg& arg2={},"
" const RooCmdArg& arg3={}, const RooCmdArg& arg4={}, const RooCmdArg& arg5={},"
" const RooCmdArg& arg6={}, const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) ;"
)
def createChi2(self, *args, **kwargs):
r"""The RooAbsPdf::createChi2() function is pythonized with the command argument pythonization.
The keywords must correspond to the CmdArgs of the function.
"""
# Redefinition of `RooAbsPdf.createChi2` for keyword arguments.
args, kwargs = _kwargs_to_roocmdargs(*args, **kwargs)
return self._createChi2(*args, **kwargs)

@cpp_signature(
"RooAbsReal *RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2={},"
" const RooCmdArg& arg3={}, const RooCmdArg& arg4={},"
Expand Down
17 changes: 0 additions & 17 deletions roofit/roofitcore/inc/RooAbsPdf.h
Expand Up @@ -202,23 +202,6 @@ class RooAbsPdf : public RooAbsReal {
return createNLL(data, *RooFit::Detail::createCmdList(&arg1, &args...));
}

// Chi^2 fits to histograms
using RooAbsReal::createChi2 ;
RooFit::OwningPtr<RooAbsReal> createChi2(RooDataHist& data, const RooCmdArg& arg1={}, const RooCmdArg& arg2={},
const RooCmdArg& arg3={}, const RooCmdArg& arg4={}, const RooCmdArg& arg5={},
const RooCmdArg& arg6={}, const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) override ;

// Chi^2 fits to X-Y datasets
RooFit::OwningPtr<RooAbsReal> createChi2(RooDataSet& data, const RooLinkedList& cmdList) override ;

/// \cond ROOFIT_INTERNAL
std::string createChi2DataHistCmdArgs() const override
{
return "Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,"
"AddCoefRange,SplitRange,DataError,Extended,IntegrateBins";
}
/// \endcond ROOFIT_INTERNAL

// Constraint management
virtual RooArgSet* getConstraints(const RooArgSet& /*observables*/, RooArgSet& /*constrainedParams*/,
bool /*stripDisconnected*/, bool /*removeConstraintsFromPdf*/=false) const
Expand Down
7 changes: 0 additions & 7 deletions roofit/roofitcore/inc/RooAbsReal.h
Expand Up @@ -195,13 +195,6 @@ class RooAbsReal : public RooAbsArg {
const RooCmdArg& arg3={}, const RooCmdArg& arg4={}, const RooCmdArg& arg5={},
const RooCmdArg& arg6={}, const RooCmdArg& arg7={}, const RooCmdArg& arg8={}) ;

/// \cond ROOFIT_INTERNAL
/// If the overriding classes support more command args in the createChi2()
/// overload for RooDataHist, they can override this (like RooAbsPdf).
virtual std::string createChi2DataHistCmdArgs() const {return "Range,RangeWithName,NumCPU,Optimize,IntegrateBins"; }
/// \endcond ROOFIT_INTERNAL


virtual RooFit::OwningPtr<RooAbsReal> createProfile(const RooArgSet& paramsOfInterest) ;


Expand Down
5 changes: 0 additions & 5 deletions roofit/roofitcore/inc/RooChi2Var.h
Expand Up @@ -31,11 +31,6 @@ class RooChi2Var : public RooAbsOptTestStatistic {
const RooCmdArg& arg4={}, const RooCmdArg& arg5={},const RooCmdArg& arg6={},
const RooCmdArg& arg7={}, const RooCmdArg& arg8={},const RooCmdArg& arg9={}) ;

RooChi2Var(const char *name, const char* title, RooAbsPdf& pdf, RooDataHist& data,
const RooCmdArg& arg1={}, const RooCmdArg& arg2={},const RooCmdArg& arg3={},
const RooCmdArg& arg4={}, const RooCmdArg& arg5={},const RooCmdArg& arg6={},
const RooCmdArg& arg7={}, const RooCmdArg& arg8={},const RooCmdArg& arg9={}) ;

enum FuncMode { Function, Pdf, ExtendedPdf } ;

RooChi2Var(const RooChi2Var& other, const char* name=nullptr);
Expand Down
3 changes: 0 additions & 3 deletions roofit/roofitcore/inc/RooDataSet.h
Expand Up @@ -166,9 +166,6 @@ class RooDataSet : public RooAbsData, public RooDirItem {
// Cache copy feature is not publicly accessible
std::unique_ptr<RooAbsData> reduceEng(const RooArgSet& varSubset, const RooFormulaVar* cutVar, const char* cutRange=nullptr,
std::size_t nStart=0, std::size_t nStop = std::numeric_limits<std::size_t>::max()) override;
RooDataSet(RooStringView name, RooStringView title, RooDataSet *ntuple,
const RooArgSet& vars, const RooFormulaVar* cutVar, const char* cutRange,
std::size_t nStart, std::size_t nStop);

RooArgSet _varsNoWgt; ///< Vars without weight variable
RooRealVar *_wgtVar = nullptr; ///< Pointer to weight variable (if set)
Expand Down
7 changes: 5 additions & 2 deletions roofit/roofitcore/inc/RooXYChi2Var.h
Expand Up @@ -32,8 +32,11 @@ class RooXYChi2Var : public RooAbsOptTestStatistic {
// Constructors, assignment etc
RooXYChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataSet& data, bool integrate=false) ;
RooXYChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataSet& data, RooRealVar& yvar, bool integrate=false) ;
RooXYChi2Var(const char *name, const char* title, RooAbsPdf& extPdf, RooDataSet& data, bool integrate=false) ;
RooXYChi2Var(const char *name, const char* title, RooAbsPdf& extPdf, RooDataSet& data, RooRealVar& yvar, bool integrate=false) ;
/// \cond ROOFIT_INTERNAL
// For internal use in RooAbsReal::createChi2().
RooXYChi2Var(const char *name, const char *title, RooAbsReal& func, RooAbsData& data, RooRealVar *yvar, bool integrate,
RooAbsTestStatistic::Configuration const& cfg);
/// \endcond ROOFIT_INTERNAL

RooXYChi2Var(const RooXYChi2Var& other, const char* name=nullptr);
TObject* clone(const char* newname) const override { return new RooXYChi2Var(*this,newname); }
Expand Down
114 changes: 0 additions & 114 deletions roofit/roofitcore/src/RooAbsPdf.cxx
Expand Up @@ -161,7 +161,6 @@ called for each data event.
#include "RooFitResult.h"
#include "RooNumGenConfig.h"
#include "RooCachedReal.h"
#include "RooXYChi2Var.h"
#include "RooChi2Var.h"
#include "RooMinimizer.h"
#include "RooRealIntegral.h"
Expand Down Expand Up @@ -1796,119 +1795,6 @@ RooFit::OwningPtr<RooFitResult> RooAbsPdf::fitTo(RooAbsData& data, const RooLink
}


////////////////////////////////////////////////////////////////////////////////
/// Create a \f$ \chi^2 \f$ from a histogram and this function.
///
/// Options to control construction of the chi-square
/// ------------------------------------------
/// The list of supported command arguments is given in the documentation for
/// RooChi2Var::RooChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataHist& hdata, const RooCmdArg&,const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,const RooCmdArg&,const RooCmdArg&).

RooFit::OwningPtr<RooAbsReal> RooAbsPdf::createChi2(RooDataHist& data, const RooCmdArg& arg1, const RooCmdArg& arg2,
const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
{
RooLinkedList cmdList ;
cmdList.Add((TObject*)&arg1) ; cmdList.Add((TObject*)&arg2) ;
cmdList.Add((TObject*)&arg3) ; cmdList.Add((TObject*)&arg4) ;
cmdList.Add((TObject*)&arg5) ; cmdList.Add((TObject*)&arg6) ;
cmdList.Add((TObject*)&arg7) ; cmdList.Add((TObject*)&arg8) ;

RooCmdConfig pc("RooAbsPdf::createChi2(" + std::string(GetName()) + ")");
pc.defineString("rangeName","RangeWithName",0,"",true) ;
pc.allowUndefined(true) ;
pc.process(cmdList) ;
if (!pc.ok(true)) {
return nullptr;
}
const char* rangeName = pc.getString("rangeName",0,true) ;

// Construct Chi2
RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
RooAbsReal* chi2 ;
std::string baseName = "chi2_" + std::string(GetName()) + "_" + std::string(data.GetName());

// Clear possible range attributes from previous fits.
removeStringAttribute("fitrange");

if (!rangeName || strchr(rangeName,',')==0) {
// Simple case: default range, or single restricted range

chi2 = new RooChi2Var(baseName.c_str(),baseName.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;

} else {

// Find which argument is RangeWithName
const RooCmdArg* rarg(0) ;
string rcmd = "RangeWithName" ;
if (arg1.GetName()==rcmd) rarg = &arg1 ;
if (arg2.GetName()==rcmd) rarg = &arg2 ;
if (arg3.GetName()==rcmd) rarg = &arg3 ;
if (arg4.GetName()==rcmd) rarg = &arg4 ;
if (arg5.GetName()==rcmd) rarg = &arg5 ;
if (arg6.GetName()==rcmd) rarg = &arg6 ;
if (arg7.GetName()==rcmd) rarg = &arg7 ;
if (arg8.GetName()==rcmd) rarg = &arg8 ;

// Composite case: multiple ranges
RooArgList chi2List ;
for (std::string& token : ROOT::Split(rangeName, ",")) {
RooCmdArg subRangeCmd = RooFit::Range(token.c_str()) ;
// Construct chi2 while substituting original RangeWithName argument with subrange argument created above
auto chi2Comp = std::make_unique<RooChi2Var>((baseName + "_" + token).c_str(), "chi^2", *this, data,
&arg1==rarg?subRangeCmd:arg1,&arg2==rarg?subRangeCmd:arg2,
&arg3==rarg?subRangeCmd:arg3,&arg4==rarg?subRangeCmd:arg4,
&arg5==rarg?subRangeCmd:arg5,&arg6==rarg?subRangeCmd:arg6,
&arg7==rarg?subRangeCmd:arg7,&arg8==rarg?subRangeCmd:arg8) ;
chi2List.addOwned(std::move(chi2Comp));
}
chi2 = new RooAddition(baseName.c_str(),"chi^2",chi2List);
chi2->addOwnedComponents(std::move(chi2List));
}
RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;


return RooFit::Detail::owningPtr(std::unique_ptr<RooAbsReal>{chi2});
}




////////////////////////////////////////////////////////////////////////////////
/// Argument-list version of RooAbsPdf::createChi2()

RooFit::OwningPtr<RooAbsReal> RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList)
{
// Select the pdf-specific commands
RooCmdConfig pc("RooAbsPdf::createChi2(" + std::string(GetName()) + ")");

pc.defineInt("integrate","Integrate",0,0) ;
pc.defineObject("yvar","YVar",0,0) ;

// Process and check varargs
pc.process(cmdList) ;
if (!pc.ok(true)) {
return nullptr;
}

// Decode command line arguments
bool integrate = pc.getInt("integrate") ;
RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;

std::string name = "chi2_" + std::string(GetName()) + "_" + std::string(data.GetName());

std::unique_ptr<RooAbsReal> out;
if (yvar) {
out = std::make_unique<RooXYChi2Var>(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
} else {
out = std::make_unique<RooXYChi2Var>(name.c_str(),name.c_str(),*this,data,integrate) ;
}
return RooFit::Detail::owningPtr(std::move(out));
}




////////////////////////////////////////////////////////////////////////////////
/// Print value of p.d.f, also print normalization integral that was last used, if any

Expand Down