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 <RooAddition.h>
39#include <RooProduct.h>
40#include <RooProdPdf.h>
41#include <RooPoisson.h>
42#include <RooPolynomial.h>
43#include <RooPolyVar.h>
44#include <RooRealSumFunc.h>
45#include <RooRealSumPdf.h>
46#include <RooRealVar.h>
47#include <RooResolutionModel.h>
48#include <RooTFnBinding.h>
49#include <RooTruthModel.h>
50#include <RooGaussModel.h>
51#include <RooWrapperPdf.h>
52#include <RooWorkspace.h>
53#include <RooRealIntegral.h>
54#include <RooSpline.h>
55#include <TSpline.h>
56
57#include <TF1.h>
58#include <TH1.h>
59
60#include "JSONIOUtils.h"
61
62#include "static_execute.h"
63
64#include <algorithm>
65#include <cctype>
66
68
69///////////////////////////////////////////////////////////////////////////////////////////////////////
70// individually implemented importers
71///////////////////////////////////////////////////////////////////////////////////////////////////////
72
73namespace {
74/**
75 * Extracts arguments from a mathematical expression.
76 *
77 * This function takes a string representing a mathematical
78 * expression and extracts the arguments from it. The arguments are
79 * defined as sequences of characters that do not contain digits,
80 * spaces, or parentheses, and that start with a letter. Function
81 * calls such as "exp( ... )", identified as being followed by an
82 * opening parenthesis, are not treated as arguments. The extracted
83 * arguments are returned as a vector of strings.
84 *
85 * @param expr A string representing a mathematical expression.
86 * @return A set of unique strings representing the extracted arguments.
87 */
88std::set<std::string> extractArguments(std::string expr)
89{
90 // Get rid of whitespaces
91 expr.erase(std::remove_if(expr.begin(), expr.end(), [](unsigned char c) { return std::isspace(c); }), expr.end());
92
93 std::set<std::string> arguments;
94 size_t startidx = expr.size();
95 for (size_t i = 0; i < expr.size(); ++i) {
96 if (startidx >= expr.size()) {
97 if (isalpha(expr[i])) {
98 startidx = i;
99 // check this character is not part of scientific notation, e.g. 2e-5
101 // if it is, we ignore this character
102 startidx = expr.size();
103 }
104 }
105 } else {
106 if (!isdigit(expr[i]) && !isalpha(expr[i]) && expr[i] != '_') {
107 if (expr[i] == '(') {
108 startidx = expr.size();
109 continue;
110 }
111 std::string arg(expr.substr(startidx, i - startidx));
112 startidx = expr.size();
113 arguments.insert(arg);
114 }
115 }
116 }
117 if (startidx < expr.size()) {
118 arguments.insert(expr.substr(startidx));
119 }
120 return arguments;
121}
122
123template <class RooArg_t>
124class RooFormulaArgFactory : public RooFit::JSONIO::Importer {
125public:
126 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
127 {
128 std::string name(RooJSONFactoryWSTool::name(p));
129 if (!p.has_child("expression")) {
130 RooJSONFactoryWSTool::error("no expression given for '" + name + "'");
131 }
132 TString formula(p["expression"].val());
133 RooArgList dependents;
134 for (const auto &d : extractArguments(formula.Data())) {
135 dependents.add(*tool->request<RooAbsReal>(d, name));
136 }
137 tool->wsImport(RooArg_t{name.c_str(), formula, dependents});
138 return true;
139 }
140};
141
142// Fast-path importers for RooProduct, RooAddition, and RooProdPdf that
143// bypass the generic factory-expression mechanism. The default path
144// generates a string expression and passes it to gROOT->ProcessLineFast(),
145// which invokes the Cling JIT for every single call. For workspaces with
146// thousands of product/sum nodes (a common shape for HistFactory models)
147// that JIT cost dominates JSON import time. Constructing the RooFit object
148// directly here keeps the work O(N) of cheap C++ calls.
149class RooProductFactory : public RooFit::JSONIO::Importer {
150public:
151 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
152 {
153 std::string name(RooJSONFactoryWSTool::name(p));
154 tool->wsEmplace<RooProduct>(name, tool->requestArgList<RooAbsReal>(p, "factors"));
155 return true;
156 }
157};
158
159class RooProdPdfFactory : public RooFit::JSONIO::Importer {
160public:
161 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
162 {
163 std::string name(RooJSONFactoryWSTool::name(p));
164 tool->wsEmplace<RooProdPdf>(name, tool->requestArgList<RooAbsPdf>(p, "factors"));
165 return true;
166 }
167};
168
169class RooAdditionFactory : public RooFit::JSONIO::Importer {
170public:
171 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
172 {
173 std::string name(RooJSONFactoryWSTool::name(p));
174 tool->wsEmplace<RooAddition>(name, tool->requestArgList<RooAbsReal>(p, "summands"));
175 return true;
176 }
177};
178
179class RooAddPdfFactory : public RooFit::JSONIO::Importer {
180public:
181 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
182 {
183 std::string name(RooJSONFactoryWSTool::name(p));
184 if (!tool->requestArgList<RooAbsReal>(p, "coefficients").empty()) {
185 tool->wsEmplace<RooAddPdf>(name, tool->requestArgList<RooAbsPdf>(p, "summands"),
186 tool->requestArgList<RooAbsReal>(p, "coefficients"));
187 return true;
188 }
189 tool->wsEmplace<RooAddPdf>(name, tool->requestArgList<RooAbsPdf>(p, "summands"));
190 return true;
191 }
192};
193
194class RooAddModelFactory : public RooFit::JSONIO::Importer {
195public:
196 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
197 {
198 std::string name(RooJSONFactoryWSTool::name(p));
199 tool->wsEmplace<RooAddModel>(name, tool->requestArgList<RooAbsPdf>(p, "summands"),
200 tool->requestArgList<RooAbsReal>(p, "coefficients"));
201 return true;
202 }
203};
204
205class RooBinWidthFunctionFactory : public RooFit::JSONIO::Importer {
206public:
207 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
208 {
209 std::string name(RooJSONFactoryWSTool::name(p));
210 RooHistFunc *hf = static_cast<RooHistFunc *>(tool->request<RooAbsReal>(p["histogram"].val(), name));
211 tool->wsEmplace<RooBinWidthFunction>(name, *hf, p["divideByBinWidth"].val_bool());
212 return true;
213 }
214};
215
216class RooBinSamplingPdfFactory : public RooFit::JSONIO::Importer {
217public:
218 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
219 {
220 std::string name(RooJSONFactoryWSTool::name(p));
221
222 RooAbsPdf *pdf = tool->requestArg<RooAbsPdf>(p, "pdf");
223 RooRealVar *obs = tool->requestArg<RooRealVar>(p, "observable");
224
225 if (!pdf->dependsOn(*obs)) {
226 RooJSONFactoryWSTool::error(std::string("pdf '") + pdf->GetName() + "' does not depend on observable '" +
227 obs->GetName() + "' as indicated by parent RooBinSamplingPdf '" + name +
228 "', please check!");
229 }
230
231 if (!p.has_child("epsilon")) {
232 RooJSONFactoryWSTool::error("no epsilon given in '" + name + "'");
233 }
234 double epsilon(p["epsilon"].val_double());
235
236 tool->wsEmplace<RooBinSamplingPdf>(name, *obs, *pdf, epsilon);
237
238 return true;
239 }
240};
241
242class RooRealSumPdfFactory : public RooFit::JSONIO::Importer {
243public:
244 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
245 {
246 std::string name(RooJSONFactoryWSTool::name(p));
247
248 bool extended = false;
249 if (p.has_child("extended") && p["extended"].val_bool()) {
250 extended = true;
251 }
252 tool->wsEmplace<RooRealSumPdf>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
253 tool->requestArgList<RooAbsReal>(p, "coefficients"), extended);
254 return true;
255 }
256};
257
258class RooRealSumFuncFactory : public RooFit::JSONIO::Importer {
259public:
260 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
261 {
262 std::string name(RooJSONFactoryWSTool::name(p));
263 tool->wsEmplace<RooRealSumFunc>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
264 tool->requestArgList<RooAbsReal>(p, "coefficients"));
265 return true;
266 }
267};
268template <class RooArg_t>
269class RooPolynomialFactory : public RooFit::JSONIO::Importer {
270public:
271 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
272 {
273 std::string name(RooJSONFactoryWSTool::name(p));
274 if (!p.has_child("coefficients")) {
275 RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
276 }
277 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
278 RooArgList coefs;
279 int order = 0;
280 int lowestOrder = 0;
281 for (const auto &coef : p["coefficients"].children()) {
282 // As long as the coefficients match the default coefficients in
283 // RooFit, we don't have to instantiate RooFit objects but can
284 // increase the lowestOrder flag.
285 if (order == 0 && coef.val() == "1.0") {
286 ++lowestOrder;
287 } else if (coefs.empty() && coef.val() == "0.0") {
288 ++lowestOrder;
289 } else {
290 coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
291 }
292 ++order;
293 }
294
295 tool->wsEmplace<RooArg_t>(name, *x, coefs, lowestOrder);
296 return true;
297 }
298};
299
300class RooPoissonFactory : public RooFit::JSONIO::Importer {
301public:
302 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
303 {
304 std::string name(RooJSONFactoryWSTool::name(p));
305 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
306 RooAbsReal *mean = tool->requestArg<RooAbsReal>(p, "mean");
307 tool->wsEmplace<RooPoisson>(name, *x, *mean, !p["integer"].val_bool());
308 return true;
309 }
310};
311
312class RooDecayFactory : public RooFit::JSONIO::Importer {
313public:
314 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
315 {
316 std::string name(RooJSONFactoryWSTool::name(p));
317 RooRealVar *t = tool->requestArg<RooRealVar>(p, "t");
318 RooAbsReal *tau = tool->requestArg<RooAbsReal>(p, "tau");
319 RooResolutionModel *model = dynamic_cast<RooResolutionModel *>(tool->requestArg<RooAbsPdf>(p, "resolutionModel"));
320 RooDecay::DecayType decayType = static_cast<RooDecay::DecayType>(p["decayType"].val_int());
321 tool->wsEmplace<RooDecay>(name, *t, *tau, *model, decayType);
322 return true;
323 }
324};
325
326class RooTruthModelFactory : public RooFit::JSONIO::Importer {
327public:
328 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
329 {
330 std::string name(RooJSONFactoryWSTool::name(p));
331 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
332 tool->wsEmplace<RooTruthModel>(name, *x);
333 return true;
334 }
335};
336
337class RooGaussModelFactory : public RooFit::JSONIO::Importer {
338public:
339 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
340 {
341 std::string name(RooJSONFactoryWSTool::name(p));
342 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
343 RooRealVar *mean = tool->requestArg<RooRealVar>(p, "mean");
344 RooRealVar *sigma = tool->requestArg<RooRealVar>(p, "sigma");
345 tool->wsEmplace<RooGaussModel>(name, *x, *mean, *sigma);
346 return true;
347 }
348};
349
350class RooRealIntegralFactory : public RooFit::JSONIO::Importer {
351public:
352 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
353 {
354 std::string name(RooJSONFactoryWSTool::name(p));
355 RooAbsReal *func = tool->requestArg<RooAbsReal>(p, "integrand");
356 auto vars = tool->requestArgList<RooAbsReal>(p, "variables");
358 RooArgSet const *normSetPtr = nullptr;
359 if (p.has_child("normalization")) {
360 normSet.add(tool->requestArgSet<RooAbsReal>(p, "normalization"));
362 }
363 std::string domain;
364 bool hasDomain = p.has_child("domain");
365 if (hasDomain) {
366 domain = p["domain"].val();
367 }
368 // todo: at some point, take care of integrator configurations
369 tool->wsEmplace<RooRealIntegral>(name, *func, vars, normSetPtr, static_cast<RooNumIntConfig *>(nullptr),
370 hasDomain ? domain.c_str() : nullptr);
371 return true;
372 }
373};
374
375class RooDerivativeFactory : public RooFit::JSONIO::Importer {
376public:
377 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
378 {
379 std::string name(RooJSONFactoryWSTool::name(p));
380 RooAbsReal *func = tool->requestArg<RooAbsReal>(p, "function");
381 RooRealVar *x = tool->requestArg<RooRealVar>(p, "x");
382 Int_t order = p["order"].val_int();
383 double eps = p["eps"].val_double();
384 if (p.has_child("normalization")) {
386 normSet.add(tool->requestArgSet<RooAbsReal>(p, "normalization"));
387 tool->wsEmplace<RooDerivative>(name, *func, *x, normSet, order, eps);
388 return true;
389 }
390 tool->wsEmplace<RooDerivative>(name, *func, *x, order, eps);
391 return true;
392 }
393};
394
395class RooFFTConvPdfFactory : public RooFit::JSONIO::Importer {
396public:
397 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
398 {
399 std::string name(RooJSONFactoryWSTool::name(p));
400 RooRealVar *convVar = tool->requestArg<RooRealVar>(p, "conv_var");
401 Int_t order = p["ipOrder"].val_int();
402 RooAbsPdf *pdf1 = tool->requestArg<RooAbsPdf>(p, "pdf1");
403 RooAbsPdf *pdf2 = tool->requestArg<RooAbsPdf>(p, "pdf2");
404 if (p.has_child("conv_func")) {
405 RooAbsReal *convFunc = tool->requestArg<RooAbsReal>(p, "conv_func");
406 tool->wsEmplace<RooFFTConvPdf>(name, *convFunc, *convVar, *pdf1, *pdf2, order);
407 return true;
408 }
409 tool->wsEmplace<RooFFTConvPdf>(name, *convVar, *pdf1, *pdf2, order);
410 return true;
411 }
412};
413
414class RooExtendPdfFactory : public RooFit::JSONIO::Importer {
415public:
416 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
417 {
418 std::string name(RooJSONFactoryWSTool::name(p));
419 RooAbsPdf *pdf = tool->requestArg<RooAbsPdf>(p, "pdf");
420 RooAbsReal *norm = tool->requestArg<RooAbsReal>(p, "norm");
421 if (p.has_child("range")) {
422 std::string rangeName = p["range"].val();
423 tool->wsEmplace<RooExtendPdf>(name, *pdf, *norm, rangeName.c_str());
424 return true;
425 }
426 tool->wsEmplace<RooExtendPdf>(name, *pdf, *norm);
427 return true;
428 }
429};
430
431class RooLogNormalFactory : public RooFit::JSONIO::Importer {
432public:
433 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
434 {
435 std::string name(RooJSONFactoryWSTool::name(p));
436 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
437
438 // Same mechanism to undo the parameter transformation as in the
439 // RooExponentialFactory (see comments in that class for more info).
440 const std::string muName = p["mu"].val();
441 const std::string sigmaName = p["sigma"].val();
442 const bool isTransformed = endsWith(muName, "_lognormal_log");
443 const std::string suffixToRemove = isTransformed ? "_lognormal_log" : "";
446
447 tool->wsEmplace<RooLognormal>(name, *x, *mu, *sigma, !isTransformed);
448
449 return true;
450 }
451};
452
453class RooExponentialFactory : public RooFit::JSONIO::Importer {
454public:
455 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
456 {
457 std::string name(RooJSONFactoryWSTool::name(p));
458 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
459
460 // If the parameter name ends with the "_exponential_inverted" suffix,
461 // this means that it was exported from a RooFit object where the
462 // parameter first needed to be transformed on export to match the HS3
463 // specification. But when re-importing such a parameter, we can simply
464 // skip the transformation and use the original RooFit parameter without
465 // the suffix.
466 //
467 // A concrete example: take the following RooFit pdf in the factory language:
468 //
469 // "Exponential::exponential_1(x[0, 10], c[-0.1])"
470 //
471 // It defines en exponential exp(c * x). However, in HS3 the exponential
472 // is defined as exp(-c * x), to RooFit would export these dictionaries
473 // to the JSON:
474 //
475 // {
476 // "name": "exponential_1", // HS3 exponential_dist with transformed parameter
477 // "type": "exponential_dist",
478 // "x": "x",
479 // "c": "c_exponential_inverted"
480 // },
481 // {
482 // "name": "c_exponential_inverted", // transformation function created on-the-fly on export
483 // "type": "generic_function",
484 // "expression": "-c"
485 // }
486 //
487 // On import, we can directly take the non-transformed parameter, which is
488 // we check for the suffix and optionally remove it from the requested
489 // name next:
490
491 const std::string constParamName = p["c"].val();
492 const bool isInverted = endsWith(constParamName, "_exponential_inverted");
493 const std::string suffixToRemove = isInverted ? "_exponential_inverted" : "";
495
496 tool->wsEmplace<RooExponential>(name, *x, *c, !isInverted);
497
498 return true;
499 }
500};
501
502class RooMultiVarGaussianFactory : public RooFit::JSONIO::Importer {
503public:
504 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
505 {
506 std::string name(RooJSONFactoryWSTool::name(p));
507 bool has_cov = p.has_child("covariances");
508 bool has_corr = p.has_child("correlations") && p.has_child("standard_deviations");
509 if (!has_cov && !has_corr) {
510 RooJSONFactoryWSTool::error("no covariances or correlations+standard_deviations given in '" + name + "'");
511 }
512
514
515 if (has_cov) {
516 int n = p["covariances"].num_children();
517 int i = 0;
518 covmat.ResizeTo(n, n);
519 for (const auto &row : p["covariances"].children()) {
520 int j = 0;
521 for (const auto &val : row.children()) {
522 covmat(i, j) = val.val_double();
523 ++j;
524 }
525 ++i;
526 }
527 } else {
528 std::vector<double> variances;
529 for (const auto &v : p["standard_deviations"].children()) {
530 variances.push_back(v.val_double());
531 }
532 covmat.ResizeTo(variances.size(), variances.size());
533 int i = 0;
534 for (const auto &row : p["correlations"].children()) {
535 int j = 0;
536 for (const auto &val : row.children()) {
537 covmat(i, j) = val.val_double() * variances[i] * variances[j];
538 ++j;
539 }
540 ++i;
541 }
542 }
543 tool->wsEmplace<RooMultiVarGaussian>(name, tool->requestArgList<RooAbsReal>(p, "x"),
544 tool->requestArgList<RooAbsReal>(p, "mean"), covmat);
545 return true;
546 }
547};
548
549class ParamHistFuncFactory : public RooFit::JSONIO::Importer {
550public:
551 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
552 {
553 std::string name(RooJSONFactoryWSTool::name(p));
554 RooArgList varList = tool->requestArgList<RooRealVar>(p, "variables");
555 if (!p.has_child("axes")) {
556 std::stringstream ss;
557 ss << "No axes given in '" << name << "'"
558 << ". Using default binning (uniform; nbins=100). If needed, export the Workspace to JSON with a newer "
559 << "Root version that supports custom ParamHistFunc binnings(>=6.38.00)." << std::endl;
561 tool->wsEmplace<ParamHistFunc>(name, varList, tool->requestArgList<RooAbsReal>(p, "parameters"));
562 return true;
563 }
564 tool->wsEmplace<ParamHistFunc>(name, readBinning(p, varList), tool->requestArgList<RooAbsReal>(p, "parameters"));
565 return true;
566 }
567
568private:
570 {
571 // Temporary map from variable name → RooRealVar
572 std::map<std::string, std::unique_ptr<RooRealVar>> varMap;
573
574 // Build variables from JSON
575 for (const JSONNode &node : topNode["axes"].children()) {
576 const std::string name = node["name"].val();
577 std::unique_ptr<RooRealVar> obs;
578
579 if (node.has_child("edges")) {
580 std::vector<double> edges;
581 for (const auto &bound : node["edges"].children()) {
582 edges.push_back(bound.val_double());
583 }
584 obs = std::make_unique<RooRealVar>(name.c_str(), name.c_str(), edges.front(), edges.back());
585 RooBinning bins(obs->getMin(), obs->getMax());
586 for (auto b : edges)
587 bins.addBoundary(b);
588 obs->setBinning(bins);
589 } else {
590 obs = std::make_unique<RooRealVar>(name.c_str(), name.c_str(), node["min"].val_double(),
591 node["max"].val_double());
592 obs->setBins(node["nbins"].val_int());
593 }
594
595 varMap[name] = std::move(obs);
596 }
597
598 // Now build the final list following the order in varList
599 RooArgList vars;
600 for (auto *refVar : dynamic_range_cast<RooRealVar *>(varList)) {
601 if (!refVar)
602 continue;
603
604 auto it = varMap.find(refVar->GetName());
605 if (it != varMap.end()) {
606 vars.addOwned(std::move(it->second)); // preserve ownership
607 }
608 }
609 return vars;
610 }
611};
612
613class RooSplineFactory : public RooFit::JSONIO::Importer {
614public:
615 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
616 {
617 const std::string name(RooJSONFactoryWSTool::name(p));
618
619 // Mandatory fields
620 if (!p.has_child("x")) {
621 RooJSONFactoryWSTool::error("no x given in '" + name + "'");
622 }
623 if (!p.has_child("x0") || !p.has_child("y0")) {
624 RooJSONFactoryWSTool::error("no x0/y0 given in '" + name + "'");
625 }
626
627 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
628
629 // Optional fields (defaults follow RooSpline ctor defaults)
630 std::string algo = p.has_child("interpolation") ? p["interpolation"].val() : "poly3";
631 int order = 0;
632 if (algo == "poly3")
633 order = 3;
634 else if (algo == "poly5")
635 order = 5;
636 else {
637 RooJSONFactoryWSTool::error("unsupported algo '" + algo + "' for RooSpline in '" + name +
638 "': allowed are 'poly3' and 'poly5'");
639 }
640 const bool logx = p.has_child("logx") ? p["logx"].val_bool() : false;
641 const bool logy = p.has_child("logy") ? p["logy"].val_bool() : false;
642
643 // Read knots
644 std::vector<double> x0;
645 std::vector<double> y0;
646 x0.reserve(p["x0"].num_children());
647 y0.reserve(p["y0"].num_children());
648
649 for (const auto &v : p["x0"].children())
650 x0.push_back(v.val_double());
651 for (const auto &v : p["y0"].children())
652 y0.push_back(v.val_double());
653
654 if (x0.size() != y0.size()) {
655 RooJSONFactoryWSTool::error("x0/y0 size mismatch in '" + name + "': x0 has " + std::to_string(x0.size()) +
656 ", y0 has " + std::to_string(y0.size()));
657 }
658 if (x0.size() < 2) {
659 RooJSONFactoryWSTool::error("need at least 2 knots in '" + name + "'");
660 }
661
662 // Construct RooSpline(name,title, x, x0, y0, order, logx, logy)
663 tool->wsEmplace<::RooSpline>(name.c_str(), *x, std::span<const double>(x0.data(), x0.size()),
664 std::span<const double>(y0.data(), y0.size()), order, logx, logy);
665
666 return true;
667 }
668};
669
670///////////////////////////////////////////////////////////////////////////////////////////////////////
671// specialized exporter implementations
672///////////////////////////////////////////////////////////////////////////////////////////////////////
673template <class RooArg_t>
674class RooAddPdfStreamer : public RooFit::JSONIO::Exporter {
675public:
676 std::string const &key() const override;
677 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
678 {
679 const RooArg_t *pdf = static_cast<const RooArg_t *>(func);
680 elem["type"] << key();
681 RooJSONFactoryWSTool::fillSeq(elem["summands"], pdf->pdfList());
682 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
683 elem["extended"] << (pdf->extendMode() != RooArg_t::CanNotBeExtended);
684 return true;
685 }
686};
687
688class RooRealSumPdfStreamer : public RooFit::JSONIO::Exporter {
689public:
690 std::string const &key() const override;
691 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
692 {
693 const RooRealSumPdf *pdf = static_cast<const RooRealSumPdf *>(func);
694 elem["type"] << key();
695 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
696 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
697 elem["extended"] << (pdf->extendMode() != RooAbsPdf::CanNotBeExtended);
698 return true;
699 }
700};
701
702class RooRealSumFuncStreamer : public RooFit::JSONIO::Exporter {
703public:
704 std::string const &key() const override;
705 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
706 {
707 const RooRealSumFunc *pdf = static_cast<const RooRealSumFunc *>(func);
708 elem["type"] << key();
709 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
710 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
711 return true;
712 }
713};
714
715template <class RooArg_t>
716class RooHistStreamer : public RooFit::JSONIO::Exporter {
717public:
718 std::string const &key() const override;
719 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
720 {
721 const RooArg_t *hf = static_cast<const RooArg_t *>(func);
722 elem["type"] << key();
723 RooDataHist const &dh = hf->dataHist();
724 tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
725 return true;
726 }
727};
728
729template <class RooArg_t>
730class RooHistFactory : public RooFit::JSONIO::Importer {
731public:
732 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
733 {
734 std::string name(RooJSONFactoryWSTool::name(p));
735 if (!p.has_child("data")) {
736 RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
737 }
738 std::unique_ptr<RooDataHist> dataHist =
740 tool->wsEmplace<RooArg_t>(name, *dataHist->get(), *dataHist);
741 return true;
742 }
743};
744
745class RooBinSamplingPdfStreamer : public RooFit::JSONIO::Exporter {
746public:
747 std::string const &key() const override;
748 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
749 {
750 const RooBinSamplingPdf *pdf = static_cast<const RooBinSamplingPdf *>(func);
751 elem["type"] << key();
752 elem["pdf"] << pdf->pdf().GetName();
753 elem["observable"] << pdf->observable().GetName();
754 elem["epsilon"] << pdf->epsilon();
755 return true;
756 }
757};
758
759class RooBinWidthFunctionStreamer : public RooFit::JSONIO::Exporter {
760public:
761 std::string const &key() const override;
762 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
763 {
764 const RooBinWidthFunction *pdf = static_cast<const RooBinWidthFunction *>(func);
765 elem["type"] << key();
766 elem["histogram"] << pdf->histFunc().GetName();
767 elem["divideByBinWidth"] << pdf->divideByBinWidth();
768 return true;
769 }
770};
771
772template <class RooArg_t>
773class RooFormulaArgStreamer : public RooFit::JSONIO::Exporter {
774public:
775 std::string const &key() const override;
776 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
777 {
778 const RooArg_t *pdf = static_cast<const RooArg_t *>(func);
779 elem["type"] << key();
780 TString expression(pdf->expression());
781 cleanExpression(expression);
782 // If the tokens follow the "x[#]" convention, the square braces enclosing each number
783 // ensures that there is a unique mapping between the token and parameter name
784 // If the tokens follow the "@#" convention, the numbers are not enclosed by braces.
785 // So there may be tokens with numbers whose lower place value forms a subset string of ones with a higher place
786 // value, e.g. "@1" is a subset of "@10". So the names of these parameters must be applied descending from the
787 // highest place value in order to ensure each parameter name is uniquely applied to its token.
788 for (size_t idx = pdf->nParameters(); idx--;) {
789 const RooAbsArg *par = pdf->getParameter(idx);
790 expression.ReplaceAll(("x[" + std::to_string(idx) + "]").c_str(), par->GetName());
791 expression.ReplaceAll(("@" + std::to_string(idx)).c_str(), par->GetName());
792 }
793 elem["expression"] << expression.Data();
794 return true;
795 }
796
797private:
798 void cleanExpression(TString &expr) const
799 {
800 expr.ReplaceAll("TMath::Exp", "exp");
801 expr.ReplaceAll("TMath::Min", "min");
802 expr.ReplaceAll("TMath::Max", "max");
803 expr.ReplaceAll("TMath::Log", "log");
804 expr.ReplaceAll("TMath::Cos", "cos");
805 expr.ReplaceAll("TMath::Sin", "sin");
806 expr.ReplaceAll("TMath::Sqrt", "sqrt");
807 expr.ReplaceAll("TMath::Power", "pow");
808 expr.ReplaceAll("TMath::Erf", "erf");
809 }
810};
811// Write the "x" reference and the coefficient list for polynomial-like
812// pdfs/funcs, including the implicit defaults below "lowestOrder" so that the
813// output is self-documenting.
814template <class Pdf>
815void writePolynomialBody(const Pdf *pdf, JSONNode &elem)
816{
817 elem["x"] << pdf->x().GetName();
818 auto &coefs = elem["coefficients"].set_seq();
819 for (int i = 0; i < pdf->lowestOrder(); ++i) {
820 coefs.append_child() << (i == 0 ? "1.0" : "0.0");
821 }
822 for (const auto &coef : pdf->coefList()) {
823 coefs.append_child() << coef->GetName();
824 }
825}
826
827template <class RooArg_t>
828class RooPolynomialStreamer : 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 elem["type"] << key();
834 writePolynomialBody(static_cast<const RooArg_t *>(func), elem);
835 return true;
836 }
837};
838
839class RooPoissonStreamer : public RooFit::JSONIO::Exporter {
840public:
841 std::string const &key() const override;
842 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
843 {
844 auto *pdf = static_cast<const RooPoisson *>(func);
845 elem["type"] << key();
846 elem["x"] << pdf->getX().GetName();
847 elem["mean"] << pdf->getMean().GetName();
848 elem["integer"] << !pdf->getNoRounding();
849 return true;
850 }
851};
852
853class RooDecayStreamer : public RooFit::JSONIO::Exporter {
854public:
855 std::string const &key() const override;
856 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
857 {
858 auto *pdf = static_cast<const RooDecay *>(func);
859 elem["type"] << key();
860 elem["t"] << pdf->getT().GetName();
861 elem["tau"] << pdf->getTau().GetName();
862 elem["resolutionModel"] << pdf->getModel().GetName();
863 elem["decayType"] << pdf->getDecayType();
864
865 return true;
866 }
867};
868
869class RooTruthModelStreamer : public RooFit::JSONIO::Exporter {
870public:
871 std::string const &key() const override;
872 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
873 {
874 auto *pdf = static_cast<const RooTruthModel *>(func);
875 elem["type"] << key();
876 elem["x"] << pdf->convVar().GetName();
877
878 return true;
879 }
880};
881
882class RooGaussModelStreamer : public RooFit::JSONIO::Exporter {
883public:
884 std::string const &key() const override;
885 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
886 {
887 auto *pdf = static_cast<const RooGaussModel *>(func);
888 elem["type"] << key();
889 elem["x"] << pdf->convVar().GetName();
890 elem["mean"] << pdf->getMean().GetName();
891 elem["sigma"] << pdf->getSigma().GetName();
892 return true;
893 }
894};
895
896class RooLogNormalStreamer : 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 RooLognormal *>(func);
902
903 elem["type"] << key();
904 elem["x"] << pdf->getX().GetName();
905
906 auto &m0 = pdf->getMedian();
907 auto &k = pdf->getShapeK();
908
909 if (pdf->useStandardParametrization()) {
910 elem["mu"] << m0.GetName();
911 elem["sigma"] << k.GetName();
912 } else {
913 elem["mu"] << tool->exportTransformed(&m0, "_lognormal_log", "log(%s)");
914 elem["sigma"] << tool->exportTransformed(&k, "_lognormal_log", "log(%s)");
915 }
916
917 return true;
918 }
919};
920
921class RooExponentialStreamer : public RooFit::JSONIO::Exporter {
922public:
923 std::string const &key() const override;
924 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
925 {
926 auto *pdf = static_cast<const RooExponential *>(func);
927 elem["type"] << key();
928 elem["x"] << pdf->variable().GetName();
929 auto &c = pdf->coefficient();
930 if (pdf->negateCoefficient()) {
931 elem["c"] << c.GetName();
932 } else {
933 elem["c"] << tool->exportTransformed(&c, "_exponential_inverted", "-%s");
934 }
935
936 return true;
937 }
938};
939
940class RooMultiVarGaussianStreamer : public RooFit::JSONIO::Exporter {
941public:
942 std::string const &key() const override;
943 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
944 {
945 auto *pdf = static_cast<const RooMultiVarGaussian *>(func);
946 elem["type"] << key();
947 RooJSONFactoryWSTool::fillSeq(elem["x"], pdf->xVec());
948 RooJSONFactoryWSTool::fillSeq(elem["mean"], pdf->muVec());
949 elem["covariances"].fill_mat(pdf->covarianceMatrix());
950 return true;
951 }
952};
953
954class RooTFnBindingStreamer : public RooFit::JSONIO::Exporter {
955public:
956 std::string const &key() const override;
957 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
958 {
959 auto *pdf = static_cast<const RooTFnBinding *>(func);
960 elem["type"] << key();
961
962 TString formula(pdf->function().GetExpFormula());
963 formula.ReplaceAll("x", pdf->observables()[0].GetName());
964 formula.ReplaceAll("y", pdf->observables()[1].GetName());
965 formula.ReplaceAll("z", pdf->observables()[2].GetName());
966 for (size_t i = 0; i < pdf->parameters().size(); ++i) {
967 TString pname(TString::Format("[%d]", (int)i));
968 formula.ReplaceAll(pname, pdf->parameters()[i].GetName());
969 }
970 elem["expression"] << formula.Data();
971 return true;
972 }
973};
974
975class RooDerivativeStreamer : public RooFit::JSONIO::Exporter {
976public:
977 std::string const &key() const override;
978 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
979 {
980 auto *pdf = static_cast<const RooDerivative *>(func);
981 elem["type"] << key();
982 elem["x"] << pdf->getX().GetName();
983 elem["function"] << pdf->getFunc().GetName();
984 if (!pdf->getNset().empty()) {
985 RooJSONFactoryWSTool::fillSeq(elem["normalization"], pdf->getNset());
986 }
987 elem["order"] << pdf->order();
988 elem["eps"] << pdf->eps();
989 return true;
990 }
991};
992
993class RooRealIntegralStreamer : public RooFit::JSONIO::Exporter {
994public:
995 std::string const &key() const override;
996 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
997 {
998 auto *integral = static_cast<const RooRealIntegral *>(func);
999 elem["type"] << key();
1000 std::string integrand = integral->integrand().GetName();
1001 // elem["integrand"] << RooJSONFactoryWSTool::sanitizeName(integrand);
1002 elem["integrand"] << integrand;
1003 if (integral->intRange()) {
1004 elem["domain"] << integral->intRange();
1005 }
1006 RooJSONFactoryWSTool::fillSeq(elem["variables"], integral->intVars());
1007 if (RooArgSet const *funcNormSet = integral->funcNormSet()) {
1008 RooJSONFactoryWSTool::fillSeq(elem["normalization"], *funcNormSet);
1009 }
1010 return true;
1011 }
1012};
1013
1014class RooFFTConvPdfStreamer : public RooFit::JSONIO::Exporter {
1015public:
1016 std::string const &key() const override;
1017 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
1018 {
1019 auto *pdf = static_cast<const RooFFTConvPdf *>(func);
1020 elem["type"] << key();
1021 if (auto convFunc = pdf->getPdfConvVar()) {
1022 elem["conv_func"] << convFunc->GetName();
1023 }
1024 elem["conv_var"] << pdf->getConvVar().GetName();
1025 elem["pdf1"] << pdf->getPdf1().GetName();
1026 elem["pdf2"] << pdf->getPdf2().GetName();
1027 elem["ipOrder"] << pdf->getInterpolationOrder();
1028 return true;
1029 }
1030};
1031
1032class RooExtendPdfStreamer : public RooFit::JSONIO::Exporter {
1033public:
1034 std::string const &key() const override;
1035 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
1036 {
1037 auto *pdf = static_cast<const RooExtendPdf *>(func);
1038 elem["type"] << key();
1039 if (auto rangeName = pdf->getRangeName()) {
1040 elem["range"] << rangeName->GetName();
1041 }
1042 elem["pdf"] << pdf->pdf().GetName();
1043 elem["norm"] << pdf->getN().GetName();
1044 return true;
1045 }
1046};
1047
1048class ParamHistFuncStreamer : public RooFit::JSONIO::Exporter {
1049public:
1050 std::string const &key() const override;
1051 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
1052 {
1053 auto *pdf = static_cast<const ParamHistFunc *>(func);
1054 elem["type"] << key();
1055 RooJSONFactoryWSTool::fillSeq(elem["variables"], pdf->dataVars());
1056 RooJSONFactoryWSTool::fillSeq(elem["parameters"], pdf->paramList());
1057 writeBinningInfo(pdf, elem);
1058 return true;
1059 }
1060
1061private:
1062 void writeBinningInfo(const ParamHistFunc *pdf, JSONNode &elem) const
1063 {
1064 auto &observablesNode = elem["axes"].set_seq();
1065 // axes have to be ordered to get consistent bin indices
1066 for (auto *var : static_range_cast<RooRealVar *>(pdf->dataVars())) {
1067 std::string name = var->GetName();
1069 JSONNode &obsNode = observablesNode.append_child().set_map();
1070 obsNode["name"] << name;
1071 auto const &binning = var->getBinning();
1072 if (binning.isUniform()) {
1073 obsNode["min"] << var->getMin();
1074 obsNode["max"] << var->getMax();
1075 obsNode["nbins"] << var->getBins();
1076 } else {
1077 auto &edges = obsNode["edges"].set_seq();
1078 edges.append_child() << binning.binLow(0);
1079 for (int i = 0; i < binning.numBins(); ++i) {
1080 edges.append_child() << binning.binHigh(i);
1081 }
1082 }
1083 }
1084 }
1085};
1086
1087class RooSplineStreamer : public RooFit::JSONIO::Exporter {
1088public:
1089 std::string const &key() const override;
1090
1091 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, RooFit::Detail::JSONNode &elem) const override
1092 {
1093 auto const *rs = static_cast<RooSpline const *>(func);
1094
1095 elem["type"] << key();
1096
1097 // Independent variable
1098 elem["x"] << rs->x().GetName();
1099
1100 // Spline configuration
1101 // Canonical algo for RooSpline
1102 elem["interpolation"] << (rs->order() == 5 ? "poly5" : "poly3");
1103 elem["logx"] << rs->logx();
1104 elem["logy"] << rs->logy();
1105
1106 // Serialize knots as primitive arrays
1107 TSpline const &sp = rs->spline();
1108 auto &x0 = elem["x0"].set_seq();
1109 auto &y0 = elem["y0"].set_seq();
1110
1111 const int np = sp.GetNp();
1112 for (int i = 0; i < np; ++i) {
1113 double xk = 0.0, yk = 0.0;
1114 sp.GetKnot(i, xk, yk);
1115 x0.append_child() << xk;
1116 y0.append_child() << yk;
1117 }
1118
1119 return true;
1120 }
1121};
1122
1123class RooWrapperPdfImporter : public RooFit::JSONIO::Importer {
1124public:
1125 bool importArg(RooJSONFactoryWSTool *tool, const RooFit::Detail::JSONNode &node) const override
1126 {
1127 if (node["type"].val() != "density_function_dist")
1128 return false;
1129
1130 auto name = RooJSONFactoryWSTool::name(node);
1131 auto *func = tool->requestArg<RooAbsReal>(node, "function");
1132
1133 bool selfNormalized = false;
1134
1135 if (auto sn = node.find("selfNormalized"))
1136 selfNormalized = sn->val_bool();
1137
1138 tool->wsEmplace<RooWrapperPdf>(name, *func, selfNormalized);
1139 return true;
1140 }
1141};
1142
1143class RooWrapperPdfStreamer : public RooFit::JSONIO::Exporter {
1144public:
1145 std::string const &key() const override;
1146
1147 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *arg, RooFit::Detail::JSONNode &node) const override
1148 {
1149 auto const *pdf = dynamic_cast<RooWrapperPdf const *>(arg);
1150 if (!pdf)
1151 return false;
1152
1153 node["type"] << "density_function_dist";
1154
1155 // Proxy name in RooWrapperPdf is "_func" / "func" depending on accessor/proxy export.
1156 // Prefer a public accessor if one exists; otherwise inspect proxies as below.
1157 auto const *funcProxy = dynamic_cast<RooRealProxy const *>(pdf->getProxy(0));
1158 if (!funcProxy || !funcProxy->absArg())
1159 return false;
1160
1161 node["function"] << funcProxy->absArg()->GetName();
1162 if (pdf->selfNormalized())
1163 node["selfnormalized"] << true;
1164
1165 return true;
1166 }
1167};
1168
1169#define DEFINE_EXPORTER_KEY(class_name, name) \
1170 std::string const &class_name::key() const \
1171 { \
1172 const static std::string keystring = name; \
1173 return keystring; \
1174 }
1175
1176template <>
1178template <>
1180DEFINE_EXPORTER_KEY(RooBinSamplingPdfStreamer, "binsampling");
1181DEFINE_EXPORTER_KEY(RooWrapperPdfStreamer, "density_function_dist");
1182DEFINE_EXPORTER_KEY(RooBinWidthFunctionStreamer, "binwidth");
1183template <>
1185DEFINE_EXPORTER_KEY(RooExponentialStreamer, "exponential_dist");
1186template <>
1188template <>
1190template <>
1192template <>
1194DEFINE_EXPORTER_KEY(RooLogNormalStreamer, "lognormal_dist");
1195DEFINE_EXPORTER_KEY(RooMultiVarGaussianStreamer, "multivariate_normal_dist");
1196DEFINE_EXPORTER_KEY(RooPoissonStreamer, "poisson_dist");
1197DEFINE_EXPORTER_KEY(RooDecayStreamer, "decay_dist");
1198DEFINE_EXPORTER_KEY(RooTruthModelStreamer, "truth_model_function");
1199DEFINE_EXPORTER_KEY(RooGaussModelStreamer, "gauss_model_function");
1200template <>
1202template <>
1204DEFINE_EXPORTER_KEY(RooRealSumFuncStreamer, "weighted_sum");
1205DEFINE_EXPORTER_KEY(RooRealSumPdfStreamer, "weighted_sum_dist");
1206DEFINE_EXPORTER_KEY(RooTFnBindingStreamer, "generic_function");
1207DEFINE_EXPORTER_KEY(RooRealIntegralStreamer, "integral");
1208DEFINE_EXPORTER_KEY(RooDerivativeStreamer, "derivative");
1209DEFINE_EXPORTER_KEY(RooFFTConvPdfStreamer, "fft_conv_pdf");
1210DEFINE_EXPORTER_KEY(RooExtendPdfStreamer, "rate_extended_dist");
1211DEFINE_EXPORTER_KEY(ParamHistFuncStreamer, "step");
1212DEFINE_EXPORTER_KEY(RooSplineStreamer, "spline");
1213
1214///////////////////////////////////////////////////////////////////////////////////////////////////////
1215// instantiate all importers and exporters
1216///////////////////////////////////////////////////////////////////////////////////////////////////////
1217
1218STATIC_EXECUTE([]() {
1219 using namespace RooFit::JSONIO;
1220
1221 registerImporter<RooWrapperPdfImporter>("density_function_dist");
1222 registerImporter<RooExtendPdfFactory>("rate_extended_dist");
1223 registerImporter<RooProductFactory>("product", false);
1224 registerImporter<RooProdPdfFactory>("product_dist", false);
1226 registerImporter<RooAddPdfFactory>("mixture_dist", false);
1227 registerImporter<RooAddModelFactory>("mixture_model", false);
1228 registerImporter<RooBinSamplingPdfFactory>("binsampling_dist", false);
1230 registerImporter<RooPolynomialFactory<RooLegacyExpPoly>>("legacy_exp_poly_dist", false);
1231 registerImporter<RooExponentialFactory>("exponential_dist", false);
1232 registerImporter<RooFormulaArgFactory<RooFormulaVar>>("generic_function", false);
1235 registerImporter<RooHistFactory<RooHistPdf>>("histogram_dist", false);
1236 registerImporter<RooLogNormalFactory>("lognormal_dist", false);
1237 registerImporter<RooMultiVarGaussianFactory>("multivariate_normal_dist", false);
1238 registerImporter<RooPoissonFactory>("poisson_dist", false);
1239 registerImporter<RooDecayFactory>("decay_dist", false);
1240 registerImporter<RooTruthModelFactory>("truth_model_function", false);
1241 registerImporter<RooGaussModelFactory>("gauss_model_function", false);
1244 registerImporter<RooRealSumPdfFactory>("weighted_sum_dist", false);
1245 registerImporter<RooRealSumFuncFactory>("weighted_sum", false);
1247 registerImporter<RooDerivativeFactory>("derivative", false);
1248 registerImporter<RooFFTConvPdfFactory>("fft_conv_pdf", false);
1249 registerImporter<RooExtendPdfFactory>("extend_pdf", false);
1251 registerImporter<RooSplineFactory>("spline", false);
1252
1281});
1282
1283} // 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, true, Range_t > dynamic_range_cast(Range_t &&coll)
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
char name[80]
Definition TGX11.cxx:145
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.
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
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()
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
Definition RooAddition.h:27
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()
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.
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()
Efficient implementation of a product of PDFs of the form.
Definition RooProdPdf.h:36
Represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
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...
A RooFit class for creating spline functions.
Definition RooSpline.h:27
static TClass * Class()
Use TF1, TF2, TF3 functions as RooFit objects.
static TClass * Class()
Implements a RooResolution model that corresponds to a delta function.
static TClass * Class()
The RooWrapperPdf is a class that can be used to convert a function into a PDF.
static TClass * Class()
static Bool_t IsScientificNotation(const TString &formula, int ipos)
Definition TFormula.cxx:383
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Base class for spline implementation containing the Draw/Paint methods.
Definition TSpline.h:31
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:2385
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)