44 std::unique_ptr<RooFitResult> rw(minimizer.
save());
48 <<
"RooAbsPdf::fitTo(" << pdf.
GetName()
49 <<
") Calculating covariance matrix according to the asymptotically correct approach. If you find this "
50 "method useful please consider citing https://arxiv.org/abs/1911.01303.\n";
53 auto nFloatPars = rw->floatParsFinal().getSize();
55 for (
int k = 0; k < nFloatPars; k++) {
56 for (
int l = 0;
l < nFloatPars;
l++) {
63 std::vector<std::unique_ptr<RooDerivative>> derivatives;
64 const RooArgList &floated = rw->floatParsFinal();
65 std::unique_ptr<RooArgSet> floatingparams{
67 for (
const auto paramresult : floated) {
68 auto paraminternal =
static_cast<RooRealVar *
>(floatingparams->find(*paramresult));
70 derivatives.emplace_back(pdf.
derivative(*paraminternal, obs, 1));
74 for (
int j = 0; j <
data.numEntries(); j++) {
78 std::vector<double> diffs(floated.
getSize(), 0.0);
79 for (
int k = 0; k < floated.
getSize(); k++) {
80 const auto paramresult =
static_cast<RooRealVar *
>(floated.
at(k));
81 auto paraminternal =
static_cast<RooRealVar *
>(floatingparams->find(*paramresult));
83 double diff = derivatives[k]->
getVal();
85 *paraminternal = paramresult->getVal();
89 double prob = pdf.
getVal(&obs);
90 for (
int k = 0; k < floated.
getSize(); k++) {
92 num(k,
l) +=
data.weightSquared() * diffs[k] * diffs[
l] / (prob * prob);
104 return rw->covQual();
122 std::unique_ptr<RooFitResult> rw{minimizer.
save()};
125 <<
") Calculating sum-of-weights-squared correction matrix for covariance matrix\n";
127 std::unique_ptr<RooFitResult> rw2{minimizer.
save()};
136 <<
") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction "
137 "matrix calculated with weight-squared is singular\n";
145 for (
int i = 0; i < matC.
GetNrows(); ++i) {
146 for (
int j = 0; j < i; ++j) {
147 matC(j, i) = matC(i, j);
155 return std::min(rw->covQual(), rw2->covQual());
162struct MinimizerConfig {
163 double recoverFromNaN = 10.;
177 int doAsymptotic = -1;
181 bool enableParallelGradient =
true;
182 bool enableParallelDescent =
false;
183 bool timingAnalysis =
false;
186 std::string minAlg =
"minuit";
195 MinimizerConfig minimizerDefaults;
197 pc.
defineDouble(
"RecoverFromUndefinedRegions",
"RecoverFromUndefinedRegions", 0, minimizerDefaults.recoverFromNaN);
198 pc.
defineInt(
"optConst",
"Optimize", 0, minimizerDefaults.optConst);
199 pc.
defineInt(
"verbose",
"Verbose", 0, minimizerDefaults.verbose);
200 pc.
defineInt(
"doSave",
"Save", 0, minimizerDefaults.doSave);
201 pc.
defineInt(
"doTimer",
"Timer", 0, minimizerDefaults.doTimer);
202 pc.
defineInt(
"printLevel",
"PrintLevel", 0, minimizerDefaults.printLevel);
203 pc.
defineInt(
"strategy",
"Strategy", 0, minimizerDefaults.strategy);
204 pc.
defineInt(
"initHesse",
"InitialHesse", 0, minimizerDefaults.initHesse);
205 pc.
defineInt(
"hesse",
"Hesse", 0, minimizerDefaults.hesse);
206 pc.
defineInt(
"minos",
"Minos", 0, minimizerDefaults.minos);
207 pc.
defineInt(
"numee",
"PrintEvalErrors", 0, minimizerDefaults.numee);
208 pc.
defineInt(
"doEEWall",
"EvalErrorWall", 0, minimizerDefaults.doEEWall);
209 pc.
defineInt(
"doWarn",
"Warnings", 0, minimizerDefaults.doWarn);
210 pc.
defineInt(
"doSumW2",
"SumW2Error", 0, minimizerDefaults.doSumW2);
211 pc.
defineInt(
"doAsymptoticError",
"AsymptoticError", 0, minimizerDefaults.doAsymptotic);
212 pc.
defineInt(
"maxCalls",
"MaxCalls", 0, minimizerDefaults.maxCalls);
213 pc.
defineInt(
"doOffset",
"OffsetLikelihood", 0, 0);
214 pc.
defineInt(
"parallelize",
"Parallelize", 0, 0);
215 pc.
defineInt(
"enableParallelGradient",
"ParallelGradientOptions", 0, 0);
216 pc.
defineInt(
"enableParallelDescent",
"ParallelDescentOptions", 0, 0);
217 pc.
defineInt(
"timingAnalysis",
"TimingAnalysis", 0, 0);
218 pc.
defineString(
"mintype",
"Minimizer", 0, minimizerDefaults.minType.c_str());
219 pc.
defineString(
"minalg",
"Minimizer", 1, minimizerDefaults.minAlg.c_str());
220 pc.
defineSet(
"minosSet",
"Minos", 0, minimizerDefaults.minosSet);
237 cfg.recoverFromNaN = pc.
getDouble(
"RecoverFromUndefinedRegions");
238 cfg.optConst = pc.
getInt(
"optConst");
239 cfg.verbose = pc.
getInt(
"verbose");
240 cfg.doSave = pc.
getInt(
"doSave");
241 cfg.doTimer = pc.
getInt(
"doTimer");
242 cfg.printLevel = pc.
getInt(
"printLevel");
243 cfg.strategy = pc.
getInt(
"strategy");
244 cfg.initHesse = pc.
getInt(
"initHesse");
245 cfg.hesse = pc.
getInt(
"hesse");
246 cfg.minos = pc.
getInt(
"minos");
247 cfg.numee = pc.
getInt(
"numee");
248 cfg.doEEWall = pc.
getInt(
"doEEWall");
249 cfg.doWarn = pc.
getInt(
"doWarn");
250 cfg.doSumW2 = pc.
getInt(
"doSumW2");
251 cfg.doAsymptotic = pc.
getInt(
"doAsymptoticError");
252 cfg.maxCalls = pc.
getInt(
"maxCalls");
253 cfg.minosSet = pc.
getSet(
"minosSet");
254 cfg.minType = pc.
getString(
"mintype",
"");
255 cfg.minAlg = pc.
getString(
"minalg",
"minuit");
256 cfg.doOffset = pc.
getInt(
"doOffset");
257 cfg.parallelize = pc.
getInt(
"parallelize");
258 cfg.enableParallelGradient = pc.
getInt(
"enableParallelGradient");
259 cfg.enableParallelDescent = pc.
getInt(
"enableParallelDescent");
260 cfg.timingAnalysis = pc.
getInt(
"timingAnalysis");
263 bool weightedData =
data.isNonPoissonWeighted();
265 std::string msgPrefix = std::string{
"RooAbsPdf::fitTo("} + pdf.
GetName() +
"): ";
268 if (weightedData && cfg.doSumW2 == -1 && cfg.doAsymptotic == -1) {
270 R
"(WARNING: a likelihood fit is requested of what appears to be weighted data.
271 While the estimated values of the parameters will always be calculated taking the weights into account,
272 there are multiple ways to estimate the errors of the parameters. You are advised to make an
273 explicit choice for the error calculation:
274 - Either provide SumW2Error(true), to calculate a sum-of-weights-corrected HESSE error matrix
275 (error will be proportional to the number of events in MC).
276 - Or provide SumW2Error(false), to return errors from original HESSE error matrix
277 (which will be proportional to the sum of the weights, i.e., a dataset with <sum of weights> events).
278 - Or provide AsymptoticError(true), to use the asymptotically correct expression
279 (for details see https://arxiv.org/abs/1911.01303)."
283 if (cfg.minos && (cfg.doSumW2 == 1 || cfg.doAsymptotic == 1)) {
286 <<
" sum-of-weights and asymptotic error correction do not work with MINOS errors. Not fitting.\n";
289 if (cfg.doAsymptotic == 1 && cfg.minos) {
290 oocoutW(&pdf,
InputArguments) << msgPrefix <<
"WARNING: asymptotic correction does not apply to MINOS errors\n";
294 if (cfg.doSumW2 == 1 && cfg.doAsymptotic == 1) {
296 <<
"ERROR: Cannot compute both asymptotically correct and SumW2 errors.\n";
309 m.setMinimizerType(cfg.minType);
310 m.setEvalErrorWall(cfg.doEEWall);
311 m.setRecoverFromNaNStrength(cfg.recoverFromNaN);
312 m.setPrintEvalErrors(cfg.numee);
313 if (cfg.maxCalls > 0)
314 m.setMaxFunctionCalls(cfg.maxCalls);
315 if (cfg.printLevel != 1)
316 m.setPrintLevel(cfg.printLevel);
318 m.optimizeConst(cfg.optConst);
323 if (cfg.strategy != 1)
324 m.setStrategy(cfg.strategy);
327 m.minimize(cfg.minType.c_str(), cfg.minAlg.c_str());
331 int corrCovQual = -1;
333 if (
m.getNPar() > 0) {
334 if (cfg.doAsymptotic == 1)
336 if (cfg.doSumW2 == 1)
341 cfg.minosSet ?
m.minos(*cfg.minosSet) :
m.minos();
344 std::unique_ptr<RooFitResult> ret;
346 auto name = std::string(
"fitresult_") + pdf.
GetName() +
"_" +
data.GetName();
347 auto title = std::string(
"Result of fit of p.d.f. ") + pdf.
GetName() +
" to dataset " +
data.GetName();
348 ret = std::unique_ptr<RooFitResult>{
m.save(
name.c_str(), title.c_str())};
349 if ((cfg.doSumW2 == 1 || cfg.doAsymptotic == 1) &&
m.getNPar() > 0)
350 ret->setCovQual(corrCovQual);
header file containing the templated implementation of matrix inversion routines for use with ROOT's ...
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
class to compute the Cholesky decomposition of a matrix
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...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
virtual void applyWeightSquared(bool flag)
Disables or enables the usage of squared weights.
Int_t getSize() const
Return the number of elements in the collection.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
Abstract base class for binned and unbinned datasets.
Abstract base class for objects that represent a real value and implements functionality common to al...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
RooDerivative * derivative(RooRealVar &obs, Int_t order=1, double eps=0.001)
Return function representing first, second or third order derivative of this function.
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
RooArgSet * getSet(const char *name, RooArgSet *set=nullptr) const
Return RooArgSet property registered with name 'name'.
bool defineSet(const char *name, const char *argName, int setNum, const RooArgSet *set=nullptr)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
RooFit::OwningPtr< RooFitResult > save(const char *name=nullptr, const char *title=nullptr)
Save and return a RooFitResult snapshot of current minimizer status.
int hesse()
Execute HESSE.
void applyCovarianceMatrix(TMatrixDSym const &V)
Apply results of given external covariance matrix.
RooRealVar represents a variable that can be changed from the outside.
TMatrixTSym< Element > & Similarity(const TMatrixT< Element > &n)
Calculate B * (*this) * B^T , final matrix will be (nrowsb x nrowsb) This is a similarity transform w...
const char * GetName() const override
Returns name of object.
void defineMinimizationOptions(RooCmdConfig &pc)
std::unique_ptr< RooFitResult > minimize(RooAbsReal &model, RooAbsReal &nll, RooAbsData const &data, RooCmdConfig const &pc)
int calcSumW2CorrectedCovariance(RooAbsPdf const &pdf, RooMinimizer &minimizer, RooAbsReal &nll)
int calcAsymptoticCorrectedCovariance(RooAbsPdf &pdf, RooMinimizer &minimizer, RooAbsData const &data)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Config argument to RooMinimizer ctor.
bool enableParallelDescent
bool enableParallelGradient