Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
JSONFactories_RooFitCore.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Carsten D. Burgard, DESY/ATLAS, Dec 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
14
15#include <RooAbsCachedPdf.h>
16#include <RooAddPdf.h>
17#include <RooAddModel.h>
18#include <RooBinning.h>
19#include <RooBinSamplingPdf.h>
20#include <RooBinWidthFunction.h>
21#include <RooCategory.h>
22#include <RooDataHist.h>
23#include <RooDecay.h>
24#include <RooDerivative.h>
25#include <RooExponential.h>
26#include <RooExtendPdf.h>
27#include <RooFFTConvPdf.h>
29#include <RooFitHS3/JSONIO.h>
30#include <RooFormulaVar.h>
31#include <RooGenericPdf.h>
32#include <RooHistFunc.h>
33#include <RooHistPdf.h>
34#include <RooLegacyExpPoly.h>
35#include <RooLognormal.h>
36#include <RooMultiVarGaussian.h>
38#include <RooPoisson.h>
39#include <RooPolynomial.h>
40#include <RooPolyVar.h>
41#include <RooRealSumFunc.h>
42#include <RooRealSumPdf.h>
43#include <RooRealVar.h>
44#include <RooResolutionModel.h>
45#include <RooTFnBinding.h>
46#include <RooTruthModel.h>
47#include <RooGaussModel.h>
48#include <RooWorkspace.h>
49#include <RooRealIntegral.h>
50
51#include <TF1.h>
52#include <TH1.h>
53
54#include "JSONIOUtils.h"
55
56#include "static_execute.h"
57
58#include <algorithm>
59#include <cctype>
60
62
63///////////////////////////////////////////////////////////////////////////////////////////////////////
64// individually implemented importers
65///////////////////////////////////////////////////////////////////////////////////////////////////////
66
67namespace {
68/**
69 * Extracts arguments from a mathematical expression.
70 *
71 * This function takes a string representing a mathematical
72 * expression and extracts the arguments from it. The arguments are
73 * defined as sequences of characters that do not contain digits,
74 * spaces, or parentheses, and that start with a letter. Function
75 * calls such as "exp( ... )", identified as being followed by an
76 * opening parenthesis, are not treated as arguments. The extracted
77 * arguments are returned as a vector of strings.
78 *
79 * @param expr A string representing a mathematical expression.
80 * @return A set of unique strings representing the extracted arguments.
81 */
82std::set<std::string> extractArguments(std::string expr)
83{
84 // Get rid of whitespaces
85 expr.erase(std::remove_if(expr.begin(), expr.end(), [](unsigned char c) { return std::isspace(c); }), expr.end());
86
87 std::set<std::string> arguments;
88 size_t startidx = expr.size();
89 for (size_t i = 0; i < expr.size(); ++i) {
90 if (startidx >= expr.size()) {
91 if (isalpha(expr[i])) {
92 startidx = i;
93 // check this character is not part of scientific notation, e.g. 2e-5
95 // if it is, we ignore this character
96 startidx = expr.size();
97 }
98 }
99 } else {
100 if (!isdigit(expr[i]) && !isalpha(expr[i]) && expr[i] != '_') {
101 if (expr[i] == '(') {
102 startidx = expr.size();
103 continue;
104 }
105 std::string arg(expr.substr(startidx, i - startidx));
106 startidx = expr.size();
107 arguments.insert(arg);
108 }
109 }
110 }
111 if (startidx < expr.size()) {
112 arguments.insert(expr.substr(startidx));
113 }
114 return arguments;
115}
116
117template <class RooArg_t>
118class RooFormulaArgFactory : public RooFit::JSONIO::Importer {
119public:
120 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
121 {
122 std::string name(RooJSONFactoryWSTool::name(p));
123 if (!p.has_child("expression")) {
124 RooJSONFactoryWSTool::error("no expression given for '" + name + "'");
125 }
126 TString formula(p["expression"].val());
127 RooArgList dependents;
128 for (const auto &d : extractArguments(formula.Data())) {
129 dependents.add(*tool->request<RooAbsReal>(d, name));
130 }
131 tool->wsImport(RooArg_t{name.c_str(), formula, dependents});
132 return true;
133 }
134};
135
136class RooAddPdfFactory : public RooFit::JSONIO::Importer {
137public:
138 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
139 {
140 std::string name(RooJSONFactoryWSTool::name(p));
141 if (!tool->requestArgList<RooAbsReal>(p, "coefficients").empty()) {
142 tool->wsEmplace<RooAddPdf>(name, tool->requestArgList<RooAbsPdf>(p, "summands"),
143 tool->requestArgList<RooAbsReal>(p, "coefficients"));
144 return true;
145 }
146 tool->wsEmplace<RooAddPdf>(name, tool->requestArgList<RooAbsPdf>(p, "summands"));
147 return true;
148 }
149};
150
151class RooAddModelFactory : public RooFit::JSONIO::Importer {
152public:
153 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
154 {
155 std::string name(RooJSONFactoryWSTool::name(p));
156 tool->wsEmplace<RooAddModel>(name, tool->requestArgList<RooAbsPdf>(p, "summands"),
157 tool->requestArgList<RooAbsReal>(p, "coefficients"));
158 return true;
159 }
160};
161
162class RooBinWidthFunctionFactory : public RooFit::JSONIO::Importer {
163public:
164 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
165 {
166 std::string name(RooJSONFactoryWSTool::name(p));
167 RooHistFunc *hf = static_cast<RooHistFunc *>(tool->request<RooAbsReal>(p["histogram"].val(), name));
168 tool->wsEmplace<RooBinWidthFunction>(name, *hf, p["divideByBinWidth"].val_bool());
169 return true;
170 }
171};
172
173class RooBinSamplingPdfFactory : public RooFit::JSONIO::Importer {
174public:
175 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
176 {
177 std::string name(RooJSONFactoryWSTool::name(p));
178
179 RooAbsPdf *pdf = tool->requestArg<RooAbsPdf>(p, "pdf");
180 RooRealVar *obs = tool->requestArg<RooRealVar>(p, "observable");
181
182 if (!pdf->dependsOn(*obs)) {
183 RooJSONFactoryWSTool::error(std::string("pdf '") + pdf->GetName() + "' does not depend on observable '" +
184 obs->GetName() + "' as indicated by parent RooBinSamplingPdf '" + name +
185 "', please check!");
186 }
187
188 if (!p.has_child("epsilon")) {
189 RooJSONFactoryWSTool::error("no epsilon given in '" + name + "'");
190 }
191 double epsilon(p["epsilon"].val_double());
192
193 tool->wsEmplace<RooBinSamplingPdf>(name, *obs, *pdf, epsilon);
194
195 return true;
196 }
197};
198
199class RooRealSumPdfFactory : public RooFit::JSONIO::Importer {
200public:
201 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
202 {
203 std::string name(RooJSONFactoryWSTool::name(p));
204
205 bool extended = false;
206 if (p.has_child("extended") && p["extended"].val_bool()) {
207 extended = true;
208 }
209 tool->wsEmplace<RooRealSumPdf>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
210 tool->requestArgList<RooAbsReal>(p, "coefficients"), extended);
211 return true;
212 }
213};
214
215class RooRealSumFuncFactory : public RooFit::JSONIO::Importer {
216public:
217 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
218 {
219 std::string name(RooJSONFactoryWSTool::name(p));
220 tool->wsEmplace<RooRealSumFunc>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
221 tool->requestArgList<RooAbsReal>(p, "coefficients"));
222 return true;
223 }
224};
225template <class RooArg_t>
226class RooPolynomialFactory : public RooFit::JSONIO::Importer {
227public:
228 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
229 {
230 std::string name(RooJSONFactoryWSTool::name(p));
231 if (!p.has_child("coefficients")) {
232 RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
233 }
234 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
235 RooArgList coefs;
236 int order = 0;
237 int lowestOrder = 0;
238 for (const auto &coef : p["coefficients"].children()) {
239 // As long as the coefficients match the default coefficients in
240 // RooFit, we don't have to instantiate RooFit objects but can
241 // increase the lowestOrder flag.
242 if (order == 0 && coef.val() == "1.0") {
243 ++lowestOrder;
244 } else if (coefs.empty() && coef.val() == "0.0") {
245 ++lowestOrder;
246 } else {
247 coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
248 }
249 ++order;
250 }
251
252 tool->wsEmplace<RooArg_t>(name, *x, coefs, lowestOrder);
253 return true;
254 }
255};
256
257class RooPoissonFactory : public RooFit::JSONIO::Importer {
258public:
259 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
260 {
261 std::string name(RooJSONFactoryWSTool::name(p));
262 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
263 RooAbsReal *mean = tool->requestArg<RooAbsReal>(p, "mean");
264 tool->wsEmplace<RooPoisson>(name, *x, *mean, !p["integer"].val_bool());
265 return true;
266 }
267};
268
269class RooDecayFactory : public RooFit::JSONIO::Importer {
270public:
271 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
272 {
273 std::string name(RooJSONFactoryWSTool::name(p));
274 RooRealVar *t = tool->requestArg<RooRealVar>(p, "t");
275 RooAbsReal *tau = tool->requestArg<RooAbsReal>(p, "tau");
276 RooResolutionModel *model = dynamic_cast<RooResolutionModel *>(tool->requestArg<RooAbsPdf>(p, "resolutionModel"));
277 RooDecay::DecayType decayType = static_cast<RooDecay::DecayType>(p["decayType"].val_int());
278 tool->wsEmplace<RooDecay>(name, *t, *tau, *model, decayType);
279 return true;
280 }
281};
282
283class RooTruthModelFactory : public RooFit::JSONIO::Importer {
284public:
285 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
286 {
287 std::string name(RooJSONFactoryWSTool::name(p));
288 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
289 tool->wsEmplace<RooTruthModel>(name, *x);
290 return true;
291 }
292};
293
294class RooGaussModelFactory : public RooFit::JSONIO::Importer {
295public:
296 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
297 {
298 std::string name(RooJSONFactoryWSTool::name(p));
299 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
300 RooRealVar *mean = tool->requestArg<RooRealVar>(p, "mean");
301 RooRealVar *sigma = tool->requestArg<RooRealVar>(p, "sigma");
302 tool->wsEmplace<RooGaussModel>(name, *x, *mean, *sigma);
303 return true;
304 }
305};
306
307class RooRealIntegralFactory : public RooFit::JSONIO::Importer {
308public:
309 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
310 {
311 std::string name(RooJSONFactoryWSTool::name(p));
312 RooAbsReal *func = tool->requestArg<RooAbsReal>(p, "integrand");
313 auto vars = tool->requestArgList<RooAbsReal>(p, "variables");
315 RooArgSet const *normSetPtr = nullptr;
316 if (p.has_child("normalization")) {
317 normSet.add(tool->requestArgSet<RooAbsReal>(p, "normalization"));
319 }
320 std::string domain;
321 bool hasDomain = p.has_child("domain");
322 if (hasDomain) {
323 domain = p["domain"].val();
324 }
325 // todo: at some point, take care of integrator configurations
326 tool->wsEmplace<RooRealIntegral>(name, *func, vars, normSetPtr, static_cast<RooNumIntConfig *>(nullptr),
327 hasDomain ? domain.c_str() : nullptr);
328 return true;
329 }
330};
331
332class RooDerivativeFactory : public RooFit::JSONIO::Importer {
333public:
334 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
335 {
336 std::string name(RooJSONFactoryWSTool::name(p));
337 RooAbsReal *func = tool->requestArg<RooAbsReal>(p, "function");
338 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
339 Int_t order = p["order"].val_int();
340 double eps = p["eps"].val_double();
341 if (p.has_child("normalization")) {
343 normSet.add(tool->requestArgSet<RooAbsReal>(p, "normalization"));
344 tool->wsEmplace<RooDerivative>(name, *func, *x, normSet, order, eps);
345 return true;
346 }
347 tool->wsEmplace<RooDerivative>(name, *func, *x, order, eps);
348 return true;
349 }
350};
351
352class RooFFTConvPdfFactory : public RooFit::JSONIO::Importer {
353public:
354 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
355 {
356 std::string name(RooJSONFactoryWSTool::name(p));
357 RooRealVar *convVar = tool->requestArg<RooRealVar>(p, "conv_var");
358 Int_t order = p["ipOrder"].val_int();
359 RooAbsPdf *pdf1 = tool->requestArg<RooAbsPdf>(p, "pdf1");
360 RooAbsPdf *pdf2 = tool->requestArg<RooAbsPdf>(p, "pdf2");
361 if (p.has_child("conv_func")) {
362 RooAbsReal *convFunc = tool->requestArg<RooAbsReal>(p, "conv_func");
363 tool->wsEmplace<RooFFTConvPdf>(name, *convFunc, *convVar, *pdf1, *pdf2, order);
364 return true;
365 }
366 tool->wsEmplace<RooFFTConvPdf>(name, *convVar, *pdf1, *pdf2, order);
367 return true;
368 }
369};
370
371class RooExtendPdfFactory : public RooFit::JSONIO::Importer {
372public:
373 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
374 {
375 std::string name(RooJSONFactoryWSTool::name(p));
376 RooAbsPdf *pdf = tool->requestArg<RooAbsPdf>(p, "pdf");
377 RooAbsReal *norm = tool->requestArg<RooAbsReal>(p, "norm");
378 if (p.has_child("range")) {
379 std::string rangeName = p["range"].val();
380 tool->wsEmplace<RooExtendPdf>(name, *pdf, *norm, rangeName.c_str());
381 return true;
382 }
383 tool->wsEmplace<RooExtendPdf>(name, *pdf, *norm);
384 return true;
385 }
386};
387
388class RooLogNormalFactory : public RooFit::JSONIO::Importer {
389public:
390 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
391 {
392 std::string name(RooJSONFactoryWSTool::name(p));
393 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
394
395 // Same mechanism to undo the parameter transformation as in the
396 // RooExponentialFactory (see comments in that class for more info).
397 const std::string muName = p["mu"].val();
398 const std::string sigmaName = p["sigma"].val();
399 const bool isTransformed = endsWith(muName, "_lognormal_log");
400 const std::string suffixToRemove = isTransformed ? "_lognormal_log" : "";
403
404 tool->wsEmplace<RooLognormal>(name, *x, *mu, *sigma, !isTransformed);
405
406 return true;
407 }
408};
409
410class RooExponentialFactory : public RooFit::JSONIO::Importer {
411public:
412 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
413 {
414 std::string name(RooJSONFactoryWSTool::name(p));
415 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
416
417 // If the parameter name ends with the "_exponential_inverted" suffix,
418 // this means that it was exported from a RooFit object where the
419 // parameter first needed to be transformed on export to match the HS3
420 // specification. But when re-importing such a parameter, we can simply
421 // skip the transformation and use the original RooFit parameter without
422 // the suffix.
423 //
424 // A concrete example: take the following RooFit pdf in the factory language:
425 //
426 // "Exponential::exponential_1(x[0, 10], c[-0.1])"
427 //
428 // It defines en exponential exp(c * x). However, in HS3 the exponential
429 // is defined as exp(-c * x), to RooFit would export these dictionaries
430 // to the JSON:
431 //
432 // {
433 // "name": "exponential_1", // HS3 exponential_dist with transformed parameter
434 // "type": "exponential_dist",
435 // "x": "x",
436 // "c": "c_exponential_inverted"
437 // },
438 // {
439 // "name": "c_exponential_inverted", // transformation function created on-the-fly on export
440 // "type": "generic_function",
441 // "expression": "-c"
442 // }
443 //
444 // On import, we can directly take the non-transformed parameter, which is
445 // we check for the suffix and optionally remove it from the requested
446 // name next:
447
448 const std::string constParamName = p["c"].val();
449 const bool isInverted = endsWith(constParamName, "_exponential_inverted");
450 const std::string suffixToRemove = isInverted ? "_exponential_inverted" : "";
452
453 tool->wsEmplace<RooExponential>(name, *x, *c, !isInverted);
454
455 return true;
456 }
457};
458
459class RooLegacyExpPolyFactory : public RooFit::JSONIO::Importer {
460public:
461 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
462 {
463 std::string name(RooJSONFactoryWSTool::name(p));
464 if (!p.has_child("coefficients")) {
465 RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
466 }
467 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
468 RooArgList coefs;
469 int order = 0;
470 int lowestOrder = 0;
471 for (const auto &coef : p["coefficients"].children()) {
472 // As long as the coefficients match the default coefficients in
473 // RooFit, we don't have to instantiate RooFit objects but can
474 // increase the lowestOrder flag.
475 if (order == 0 && coef.val() == "1.0") {
476 ++lowestOrder;
477 } else if (coefs.empty() && coef.val() == "0.0") {
478 ++lowestOrder;
479 } else {
480 coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
481 }
482 ++order;
483 }
484
485 tool->wsEmplace<RooLegacyExpPoly>(name, *x, coefs, lowestOrder);
486 return true;
487 }
488};
489
490class RooMultiVarGaussianFactory : public RooFit::JSONIO::Importer {
491public:
492 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
493 {
494 std::string name(RooJSONFactoryWSTool::name(p));
495 bool has_cov = p.has_child("covariances");
496 bool has_corr = p.has_child("correlations") && p.has_child("standard_deviations");
497 if (!has_cov && !has_corr) {
498 RooJSONFactoryWSTool::error("no covariances or correlations+standard_deviations given in '" + name + "'");
499 }
500
502
503 if (has_cov) {
504 int n = p["covariances"].num_children();
505 int i = 0;
506 covmat.ResizeTo(n, n);
507 for (const auto &row : p["covariances"].children()) {
508 int j = 0;
509 for (const auto &val : row.children()) {
510 covmat(i, j) = val.val_double();
511 ++j;
512 }
513 ++i;
514 }
515 } else {
516 std::vector<double> variances;
517 for (const auto &v : p["standard_deviations"].children()) {
518 variances.push_back(v.val_double());
519 }
520 covmat.ResizeTo(variances.size(), variances.size());
521 int i = 0;
522 for (const auto &row : p["correlations"].children()) {
523 int j = 0;
524 for (const auto &val : row.children()) {
525 covmat(i, j) = val.val_double() * variances[i] * variances[j];
526 ++j;
527 }
528 ++i;
529 }
530 }
531 tool->wsEmplace<RooMultiVarGaussian>(name, tool->requestArgList<RooAbsReal>(p, "x"),
532 tool->requestArgList<RooAbsReal>(p, "mean"), covmat);
533 return true;
534 }
535};
536
537class ParamHistFuncFactory : public RooFit::JSONIO::Importer {
538public:
539 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
540 {
541 std::string name(RooJSONFactoryWSTool::name(p));
542 RooArgList varList = tool->requestArgList<RooRealVar>(p, "variables");
543 if (!p.has_child("axes")) {
544 std::stringstream ss;
545 ss << "No axes given in '" << name << "'"
546 << ". Using default binning (uniform; nbins=100). If needed, export the Workspace to JSON with a newer "
547 << "Root version that supports custom ParamHistFunc binnings(>=6.38.00)." << std::endl;
549 tool->wsEmplace<ParamHistFunc>(name, varList, tool->requestArgList<RooAbsReal>(p, "parameters"));
550 return true;
551 }
552 tool->wsEmplace<ParamHistFunc>(name, readBinning(p, varList), tool->requestArgList<RooAbsReal>(p, "parameters"));
553 return true;
554 }
555
556private:
558 {
559 // Temporary map from variable name → RooRealVar
560 std::map<std::string, std::unique_ptr<RooRealVar>> varMap;
561
562 // Build variables from JSON
563 for (const JSONNode &node : topNode["axes"].children()) {
564 const std::string name = node["name"].val();
565 std::unique_ptr<RooRealVar> obs;
566
567 if (node.has_child("edges")) {
568 std::vector<double> edges;
569 for (const auto &bound : node["edges"].children()) {
570 edges.push_back(bound.val_double());
571 }
572 obs = std::make_unique<RooRealVar>(name.c_str(), name.c_str(), edges.front(), edges.back());
573 RooBinning bins(obs->getMin(), obs->getMax());
574 for (auto b : edges)
575 bins.addBoundary(b);
576 obs->setBinning(bins);
577 } else {
578 obs = std::make_unique<RooRealVar>(name.c_str(), name.c_str(), node["min"].val_double(),
579 node["max"].val_double());
580 obs->setBins(node["nbins"].val_int());
581 }
582
583 varMap[name] = std::move(obs);
584 }
585
586 // Now build the final list following the order in varList
587 RooArgList vars;
588 for (int i = 0; i < varList.getSize(); ++i) {
589 const auto *refVar = dynamic_cast<RooRealVar *>(varList.at(i));
590 if (!refVar)
591 continue;
592
593 auto it = varMap.find(refVar->GetName());
594 if (it != varMap.end()) {
595 vars.addOwned(std::move(it->second)); // preserve ownership
596 }
597 }
598 return vars;
599 }
600};
601
602///////////////////////////////////////////////////////////////////////////////////////////////////////
603// specialized exporter implementations
604///////////////////////////////////////////////////////////////////////////////////////////////////////
605template <class RooArg_t>
606class RooAddPdfStreamer : public RooFit::JSONIO::Exporter {
607public:
608 std::string const &key() const override;
609 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
610 {
611 const RooArg_t *pdf = static_cast<const RooArg_t *>(func);
612 elem["type"] << key();
613 RooJSONFactoryWSTool::fillSeq(elem["summands"], pdf->pdfList());
614 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
615 elem["extended"] << (pdf->extendMode() != RooArg_t::CanNotBeExtended);
616 return true;
617 }
618};
619
620class RooRealSumPdfStreamer : public RooFit::JSONIO::Exporter {
621public:
622 std::string const &key() const override;
623 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
624 {
625 const RooRealSumPdf *pdf = static_cast<const RooRealSumPdf *>(func);
626 elem["type"] << key();
627 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
628 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
629 elem["extended"] << (pdf->extendMode() != RooAbsPdf::CanNotBeExtended);
630 return true;
631 }
632};
633
634class RooRealSumFuncStreamer : public RooFit::JSONIO::Exporter {
635public:
636 std::string const &key() const override;
637 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
638 {
639 const RooRealSumFunc *pdf = static_cast<const RooRealSumFunc *>(func);
640 elem["type"] << key();
641 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
642 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
643 return true;
644 }
645};
646
647class RooHistFuncStreamer : public RooFit::JSONIO::Exporter {
648public:
649 std::string const &key() const override;
650 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
651 {
652 const RooHistFunc *hf = static_cast<const RooHistFunc *>(func);
653 elem["type"] << key();
654 RooDataHist const &dh = hf->dataHist();
655 tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
656 return true;
657 }
658};
659
660class RooHistFuncFactory : public RooFit::JSONIO::Importer {
661public:
662 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
663 {
664 std::string name(RooJSONFactoryWSTool::name(p));
665 if (!p.has_child("data")) {
666 RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
667 }
668 std::unique_ptr<RooDataHist> dataHist =
670 tool->wsEmplace<RooHistFunc>(name, *dataHist->get(), *dataHist);
671 return true;
672 }
673};
674
675class RooHistPdfStreamer : public RooFit::JSONIO::Exporter {
676public:
677 std::string const &key() const override;
678 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
679 {
680 const RooHistPdf *hf = static_cast<const RooHistPdf *>(func);
681 elem["type"] << key();
682 RooDataHist const &dh = hf->dataHist();
683 tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
684 return true;
685 }
686};
687
688class RooHistPdfFactory : public RooFit::JSONIO::Importer {
689public:
690 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
691 {
692 std::string name(RooJSONFactoryWSTool::name(p));
693 if (!p.has_child("data")) {
694 RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
695 }
696 std::unique_ptr<RooDataHist> dataHist =
698 tool->wsEmplace<RooHistPdf>(name, *dataHist->get(), *dataHist);
699 return true;
700 }
701};
702
703class RooBinSamplingPdfStreamer : public RooFit::JSONIO::Exporter {
704public:
705 std::string const &key() const override;
706 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
707 {
708 const RooBinSamplingPdf *pdf = static_cast<const RooBinSamplingPdf *>(func);
709 elem["type"] << key();
710 elem["pdf"] << pdf->pdf().GetName();
711 elem["observable"] << pdf->observable().GetName();
712 elem["epsilon"] << pdf->epsilon();
713 return true;
714 }
715};
716
717class RooBinWidthFunctionStreamer : public RooFit::JSONIO::Exporter {
718public:
719 std::string const &key() const override;
720 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
721 {
722 const RooBinWidthFunction *pdf = static_cast<const RooBinWidthFunction *>(func);
723 elem["type"] << key();
724 elem["histogram"] << pdf->histFunc().GetName();
725 elem["divideByBinWidth"] << pdf->divideByBinWidth();
726 return true;
727 }
728};
729
730template <class RooArg_t>
731class RooFormulaArgStreamer : public RooFit::JSONIO::Exporter {
732public:
733 std::string const &key() const override;
734 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
735 {
736 const RooArg_t *pdf = static_cast<const RooArg_t *>(func);
737 elem["type"] << key();
738 TString expression(pdf->expression());
739 cleanExpression(expression);
740 // If the tokens follow the "x[#]" convention, the square braces enclosing each number
741 // ensures that there is a unique mapping between the token and parameter name
742 // If the tokens follow the "@#" convention, the numbers are not enclosed by braces.
743 // So there may be tokens with numbers whose lower place value forms a subset string of ones with a higher place
744 // value, e.g. "@1" is a subset of "@10". So the names of these parameters must be applied descending from the
745 // highest place value in order to ensure each parameter name is uniquely applied to its token.
746 for (size_t idx = pdf->nParameters(); idx--;) {
747 const RooAbsArg *par = pdf->getParameter(idx);
748 expression.ReplaceAll(("x[" + std::to_string(idx) + "]").c_str(), par->GetName());
749 expression.ReplaceAll(("@" + std::to_string(idx)).c_str(), par->GetName());
750 }
751 elem["expression"] << expression.Data();
752 return true;
753 }
754
755private:
756 void cleanExpression(TString &expr) const
757 {
758 expr.ReplaceAll("TMath::Exp", "exp");
759 expr.ReplaceAll("TMath::Min", "min");
760 expr.ReplaceAll("TMath::Max", "max");
761 expr.ReplaceAll("TMath::Log", "log");
762 expr.ReplaceAll("TMath::Cos", "cos");
763 expr.ReplaceAll("TMath::Sin", "sin");
764 expr.ReplaceAll("TMath::Sqrt", "sqrt");
765 expr.ReplaceAll("TMath::Power", "pow");
766 expr.ReplaceAll("TMath::Erf", "erf");
767 }
768};
769template <class RooArg_t>
770class RooPolynomialStreamer : public RooFit::JSONIO::Exporter {
771public:
772 std::string const &key() const override;
773 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
774 {
775 auto *pdf = static_cast<const RooArg_t *>(func);
776 elem["type"] << key();
777 elem["x"] << pdf->x().GetName();
778 auto &coefs = elem["coefficients"].set_seq();
779 // Write out the default coefficient that RooFit uses for the lower
780 // orders before the order of the first coefficient. Like this, the
781 // output is more self-documenting.
782 for (int i = 0; i < pdf->lowestOrder(); ++i) {
783 coefs.append_child() << (i == 0 ? "1.0" : "0.0");
784 }
785 for (const auto &coef : pdf->coefList()) {
786 coefs.append_child() << coef->GetName();
787 }
788 return true;
789 }
790};
791
792class RooLegacyExpPolyStreamer : public RooFit::JSONIO::Exporter {
793public:
794 std::string const &key() const override;
795 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
796 {
797 auto *pdf = static_cast<const RooLegacyExpPoly *>(func);
798 elem["type"] << key();
799 elem["x"] << pdf->x().GetName();
800 auto &coefs = elem["coefficients"].set_seq();
801 // Write out the default coefficient that RooFit uses for the lower
802 // orders before the order of the first coefficient. Like this, the
803 // output is more self-documenting.
804 for (int i = 0; i < pdf->lowestOrder(); ++i) {
805 coefs.append_child() << (i == 0 ? "1.0" : "0.0");
806 }
807 for (const auto &coef : pdf->coefList()) {
808 coefs.append_child() << coef->GetName();
809 }
810 return true;
811 }
812};
813
814class RooPoissonStreamer : public RooFit::JSONIO::Exporter {
815public:
816 std::string const &key() const override;
817 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
818 {
819 auto *pdf = static_cast<const RooPoisson *>(func);
820 elem["type"] << key();
821 elem["x"] << pdf->getX().GetName();
822 elem["mean"] << pdf->getMean().GetName();
823 elem["integer"] << !pdf->getNoRounding();
824 return true;
825 }
826};
827
828class RooDecayStreamer : public RooFit::JSONIO::Exporter {
829public:
830 std::string const &key() const override;
831 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
832 {
833 auto *pdf = static_cast<const RooDecay *>(func);
834 elem["type"] << key();
835 elem["t"] << pdf->getT().GetName();
836 elem["tau"] << pdf->getTau().GetName();
837 elem["resolutionModel"] << pdf->getModel().GetName();
838 elem["decayType"] << pdf->getDecayType();
839
840 return true;
841 }
842};
843
844class RooTruthModelStreamer : public RooFit::JSONIO::Exporter {
845public:
846 std::string const &key() const override;
847 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
848 {
849 auto *pdf = static_cast<const RooTruthModel *>(func);
850 elem["type"] << key();
851 elem["x"] << pdf->convVar().GetName();
852
853 return true;
854 }
855};
856
857class RooGaussModelStreamer : public RooFit::JSONIO::Exporter {
858public:
859 std::string const &key() const override;
860 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
861 {
862 auto *pdf = static_cast<const RooGaussModel *>(func);
863 elem["type"] << key();
864 elem["x"] << pdf->convVar().GetName();
865 elem["mean"] << pdf->getMean().GetName();
866 elem["sigma"] << pdf->getSigma().GetName();
867 return true;
868 }
869};
870
871class RooLogNormalStreamer : public RooFit::JSONIO::Exporter {
872public:
873 std::string const &key() const override;
874 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
875 {
876 auto *pdf = static_cast<const RooLognormal *>(func);
877
878 elem["type"] << key();
879 elem["x"] << pdf->getX().GetName();
880
881 auto &m0 = pdf->getMedian();
882 auto &k = pdf->getShapeK();
883
884 if (pdf->useStandardParametrization()) {
885 elem["mu"] << m0.GetName();
886 elem["sigma"] << k.GetName();
887 } else {
888 elem["mu"] << tool->exportTransformed(&m0, "_lognormal_log", "log(%s)");
889 elem["sigma"] << tool->exportTransformed(&k, "_lognormal_log", "log(%s)");
890 }
891
892 return true;
893 }
894};
895
896class RooExponentialStreamer : public RooFit::JSONIO::Exporter {
897public:
898 std::string const &key() const override;
899 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
900 {
901 auto *pdf = static_cast<const RooExponential *>(func);
902 elem["type"] << key();
903 elem["x"] << pdf->variable().GetName();
904 auto &c = pdf->coefficient();
905 if (pdf->negateCoefficient()) {
906 elem["c"] << c.GetName();
907 } else {
908 elem["c"] << tool->exportTransformed(&c, "_exponential_inverted", "-%s");
909 }
910
911 return true;
912 }
913};
914
915class RooMultiVarGaussianStreamer : public RooFit::JSONIO::Exporter {
916public:
917 std::string const &key() const override;
918 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
919 {
920 auto *pdf = static_cast<const RooMultiVarGaussian *>(func);
921 elem["type"] << key();
922 RooJSONFactoryWSTool::fillSeq(elem["x"], pdf->xVec());
923 RooJSONFactoryWSTool::fillSeq(elem["mean"], pdf->muVec());
924 elem["covariances"].fill_mat(pdf->covarianceMatrix());
925 return true;
926 }
927};
928
929class RooTFnBindingStreamer : public RooFit::JSONIO::Exporter {
930public:
931 std::string const &key() const override;
932 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
933 {
934 auto *pdf = static_cast<const RooTFnBinding *>(func);
935 elem["type"] << key();
936
937 TString formula(pdf->function().GetExpFormula());
938 formula.ReplaceAll("x", pdf->observables()[0].GetName());
939 formula.ReplaceAll("y", pdf->observables()[1].GetName());
940 formula.ReplaceAll("z", pdf->observables()[2].GetName());
941 for (size_t i = 0; i < pdf->parameters().size(); ++i) {
942 TString pname(TString::Format("[%d]", (int)i));
943 formula.ReplaceAll(pname, pdf->parameters()[i].GetName());
944 }
945 elem["expression"] << formula.Data();
946 return true;
947 }
948};
949
950class RooDerivativeStreamer : public RooFit::JSONIO::Exporter {
951public:
952 std::string const &key() const override;
953 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
954 {
955 auto *pdf = static_cast<const RooDerivative *>(func);
956 elem["type"] << key();
957 elem["x"] << pdf->getX().GetName();
958 elem["function"] << pdf->getFunc().GetName();
959 if (!pdf->getNset().empty()) {
960 RooJSONFactoryWSTool::fillSeq(elem["normalization"], pdf->getNset());
961 }
962 elem["order"] << pdf->order();
963 elem["eps"] << pdf->eps();
964 return true;
965 }
966};
967
968class RooRealIntegralStreamer : public RooFit::JSONIO::Exporter {
969public:
970 std::string const &key() const override;
971 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
972 {
973 auto *integral = static_cast<const RooRealIntegral *>(func);
974 elem["type"] << key();
975 std::string integrand = integral->integrand().GetName();
976 // elem["integrand"] << RooJSONFactoryWSTool::sanitizeName(integrand);
977 elem["integrand"] << integrand;
978 if (integral->intRange()) {
979 elem["domain"] << integral->intRange();
980 }
981 RooJSONFactoryWSTool::fillSeq(elem["variables"], integral->intVars());
982 if (RooArgSet const *funcNormSet = integral->funcNormSet()) {
983 RooJSONFactoryWSTool::fillSeq(elem["normalization"], *funcNormSet);
984 }
985 return true;
986 }
987};
988
989class RooFFTConvPdfStreamer : public RooFit::JSONIO::Exporter {
990public:
991 std::string const &key() const override;
992 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
993 {
994 auto *pdf = static_cast<const RooFFTConvPdf *>(func);
995 elem["type"] << key();
996 if (auto convFunc = pdf->getPdfConvVar()) {
997 elem["conv_func"] << convFunc->GetName();
998 }
999 elem["conv_var"] << pdf->getConvVar().GetName();
1000 elem["pdf1"] << pdf->getPdf1().GetName();
1001 elem["pdf2"] << pdf->getPdf2().GetName();
1002 elem["ipOrder"] << pdf->getInterpolationOrder();
1003 return true;
1004 }
1005};
1006
1007class RooExtendPdfStreamer : public RooFit::JSONIO::Exporter {
1008public:
1009 std::string const &key() const override;
1010 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
1011 {
1012 auto *pdf = static_cast<const RooExtendPdf *>(func);
1013 elem["type"] << key();
1014 if (auto rangeName = pdf->getRangeName()) {
1015 elem["range"] << rangeName->GetName();
1016 }
1017 elem["pdf"] << pdf->pdf().GetName();
1018 elem["norm"] << pdf->getN().GetName();
1019 return true;
1020 }
1021};
1022
1023class ParamHistFuncStreamer : public RooFit::JSONIO::Exporter {
1024public:
1025 std::string const &key() const override;
1026 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
1027 {
1028 auto *pdf = static_cast<const ParamHistFunc *>(func);
1029 elem["type"] << key();
1030 RooJSONFactoryWSTool::fillSeq(elem["variables"], pdf->dataVars());
1031 RooJSONFactoryWSTool::fillSeq(elem["parameters"], pdf->paramList());
1032 writeBinningInfo(pdf, elem);
1033 return true;
1034 }
1035
1036private:
1037 void writeBinningInfo(const ParamHistFunc *pdf, JSONNode &elem) const
1038 {
1039 auto &observablesNode = elem["axes"].set_seq();
1040 // axes have to be ordered to get consistent bin indices
1041 for (auto *var : static_range_cast<RooRealVar *>(pdf->dataVars())) {
1042 std::string name = var->GetName();
1044 JSONNode &obsNode = observablesNode.append_child().set_map();
1045 obsNode["name"] << name;
1046 if (var->getBinning().isUniform()) {
1047 obsNode["min"] << var->getMin();
1048 obsNode["max"] << var->getMax();
1049 obsNode["nbins"] << var->getBins();
1050 } else {
1051 auto &edges = obsNode["edges"];
1052 edges.set_seq();
1053 double val = var->getBinning().binLow(0);
1054 edges.append_child() << val;
1055 for (int i = 0; i < var->getBinning().numBins(); ++i) {
1056 val = var->getBinning().binHigh(i);
1057 edges.append_child() << val;
1058 }
1059 }
1060 }
1061 }
1062};
1063
1064#define DEFINE_EXPORTER_KEY(class_name, name) \
1065 std::string const &class_name::key() const \
1066 { \
1067 const static std::string keystring = name; \
1068 return keystring; \
1069 }
1070template <>
1072template <>
1074DEFINE_EXPORTER_KEY(RooBinSamplingPdfStreamer, "binsampling");
1075DEFINE_EXPORTER_KEY(RooBinWidthFunctionStreamer, "binwidth");
1076DEFINE_EXPORTER_KEY(RooLegacyExpPolyStreamer, "legacy_exp_poly_dist");
1077DEFINE_EXPORTER_KEY(RooExponentialStreamer, "exponential_dist");
1078template <>
1080template <>
1082DEFINE_EXPORTER_KEY(RooHistFuncStreamer, "histogram");
1083DEFINE_EXPORTER_KEY(RooHistPdfStreamer, "histogram_dist");
1084DEFINE_EXPORTER_KEY(RooLogNormalStreamer, "lognormal_dist");
1085DEFINE_EXPORTER_KEY(RooMultiVarGaussianStreamer, "multivariate_normal_dist");
1086DEFINE_EXPORTER_KEY(RooPoissonStreamer, "poisson_dist");
1087DEFINE_EXPORTER_KEY(RooDecayStreamer, "decay_dist");
1088DEFINE_EXPORTER_KEY(RooTruthModelStreamer, "truth_model_function");
1089DEFINE_EXPORTER_KEY(RooGaussModelStreamer, "gauss_model_function");
1090template <>
1092template <>
1094DEFINE_EXPORTER_KEY(RooRealSumFuncStreamer, "weighted_sum");
1095DEFINE_EXPORTER_KEY(RooRealSumPdfStreamer, "weighted_sum_dist");
1096DEFINE_EXPORTER_KEY(RooTFnBindingStreamer, "generic_function");
1097DEFINE_EXPORTER_KEY(RooRealIntegralStreamer, "integral");
1098DEFINE_EXPORTER_KEY(RooDerivativeStreamer, "derivative");
1099DEFINE_EXPORTER_KEY(RooFFTConvPdfStreamer, "fft_conv_pdf");
1100DEFINE_EXPORTER_KEY(RooExtendPdfStreamer, "extend_pdf");
1101DEFINE_EXPORTER_KEY(ParamHistFuncStreamer, "step");
1102
1103///////////////////////////////////////////////////////////////////////////////////////////////////////
1104// instantiate all importers and exporters
1105///////////////////////////////////////////////////////////////////////////////////////////////////////
1106
1107STATIC_EXECUTE([]() {
1108 using namespace RooFit::JSONIO;
1109
1110 registerImporter<RooAddPdfFactory>("mixture_dist", false);
1111 registerImporter<RooAddModelFactory>("mixture_model", false);
1112 registerImporter<RooBinSamplingPdfFactory>("binsampling_dist", false);
1114 registerImporter<RooLegacyExpPolyFactory>("legacy_exp_poly_dist", false);
1115 registerImporter<RooExponentialFactory>("exponential_dist", false);
1116 registerImporter<RooFormulaArgFactory<RooFormulaVar>>("generic_function", false);
1118 registerImporter<RooHistFuncFactory>("histogram", false);
1119 registerImporter<RooHistPdfFactory>("histogram_dist", false);
1120 registerImporter<RooLogNormalFactory>("lognormal_dist", false);
1121 registerImporter<RooMultiVarGaussianFactory>("multivariate_normal_dist", false);
1122 registerImporter<RooPoissonFactory>("poisson_dist", false);
1123 registerImporter<RooDecayFactory>("decay_dist", false);
1124 registerImporter<RooTruthModelFactory>("truth_model_function", false);
1125 registerImporter<RooGaussModelFactory>("gauss_model_function", false);
1128 registerImporter<RooRealSumPdfFactory>("weighted_sum_dist", false);
1129 registerImporter<RooRealSumFuncFactory>("weighted_sum", false);
1131 registerImporter<RooDerivativeFactory>("derivative", false);
1132 registerImporter<RooFFTConvPdfFactory>("fft_conv_pdf", false);
1133 registerImporter<RooExtendPdfFactory>("extend_pdf", false);
1135
1162});
1163
1164} // namespace
#define DEFINE_EXPORTER_KEY(class_name, name)
bool endsWith(std::string_view str, std::string_view suffix)
std::string removeSuffix(std::string_view str, std::string_view suffix)
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
ROOT::RRangeCast< T, false, Range_t > static_range_cast(Range_t &&coll)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
char name[80]
Definition TGX11.cxx:110
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
static TClass * Class()
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
@ CanNotBeExtended
Definition RooAbsPdf.h:208
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
RooAddModel is an efficient implementation of a sum of PDFs of the form.
Definition RooAddModel.h:27
static TClass * Class()
Efficient implementation of a sum of PDFs of the form.
Definition RooAddPdf.h:33
static TClass * Class()
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
The RooBinSamplingPdf is supposed to be used as an adapter between a continuous PDF and a binned dist...
static TClass * Class()
double epsilon() const
const RooAbsPdf & pdf() const
const RooAbsReal & observable() const
Returns the bin width (or volume) given a RooHistFunc.
const RooHistFunc & histFunc() const
static TClass * Class()
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Definition RooBinning.h:27
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
Single or double sided decay function that can be analytically convolved with any RooResolutionModel ...
Definition RooDecay.h:22
static TClass * Class()
Represents the first, second, or third order derivative of any RooAbsReal as calculated (numerically)...
static TClass * Class()
Exponential PDF.
static TClass * Class()
RooExtendPdf is a wrapper around an existing PDF that adds a parameteric extended likelihood term to ...
static TClass * Class()
PDF for the numerical (FFT) convolution of two PDFs.
static TClass * Class()
static TClass * Class()
Class RooGaussModel implements a RooResolutionModel that models a Gaussian distribution.
static TClass * Class()
static TClass * Class()
A real-valued function sampled from a multidimensional histogram.
Definition RooHistFunc.h:31
static TClass * Class()
A probability density function sampled from a multidimensional histogram.
Definition RooHistPdf.h:30
static TClass * Class()
When using RooFit, statistical models can be conveniently handled and stored as a RooWorkspace.
static void fillSeq(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax=-1)
static std::unique_ptr< RooDataHist > readBinnedData(const RooFit::Detail::JSONNode &n, const std::string &namecomp, RooArgSet const &vars)
Read binned data from the JSONNode and create a RooDataHist object.
static bool testValidName(const std::string &str, bool forcError)
static void error(const char *s)
Writes an error message to the RooFit message service and throws a runtime_error.
static std::string name(const RooFit::Detail::JSONNode &n)
static std::ostream & warning(const std::string &s)
Writes a warning message to the RooFit message service.
static RooArgSet readAxes(const RooFit::Detail::JSONNode &node)
Read axes from the JSONNode and create a RooArgSet representing them.
RooLegacyExpPoly implements a polynomial PDF of the form.
static TClass * Class()
RooFit Lognormal PDF.
static TClass * Class()
Multivariate Gaussian p.d.f.
static TClass * Class()
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
Poisson pdf.
Definition RooPoisson.h:19
static TClass * Class()
static TClass * Class()
static TClass * Class()
Performs hybrid numerical/analytical integrals of RooAbsReal objects.
static TClass * Class()
const RooArgList & coefList() const
const RooArgList & funcList() const
static TClass * Class()
Implements a PDF constructed from a sum of functions:
const RooArgList & funcList() const
static TClass * Class()
ExtendMode extendMode() const override
Returns ability of PDF to provide extended likelihood terms.
const RooArgList & coefList() const
Variable that can be changed from the outside.
Definition RooRealVar.h:37
RooResolutionModel is the base class for PDFs that represent a resolution model that can be convolute...
Use TF1, TF2, TF3 functions as RooFit objects.
static TClass * Class()
Implements a RooResolution model that corresponds to a delta function.
static TClass * Class()
static Bool_t IsScientificNotation(const TString &formula, int ipos)
Definition TFormula.cxx:329
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
const Double_t sigma
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
#define STATIC_EXECUTE(MY_FUNC)