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 <RooAddPdf.h>
16#include <RooBinSamplingPdf.h>
17#include <RooBinWidthFunction.h>
18#include <RooCategory.h>
19#include <RooDataHist.h>
20#include <RooExponential.h>
22#include <RooFitHS3/JSONIO.h>
23#include <RooFormulaVar.h>
24#include <RooGenericPdf.h>
25#include <RooHistFunc.h>
26#include <RooHistPdf.h>
27#include <RooLegacyExpPoly.h>
28#include <RooLognormal.h>
29#include <RooMultiVarGaussian.h>
30#include <RooPoisson.h>
31#include <RooPolynomial.h>
32#include <RooRealSumFunc.h>
33#include <RooRealSumPdf.h>
34#include <RooRealVar.h>
35#include <RooTFnBinding.h>
36#include <RooWorkspace.h>
37
38#include <TF1.h>
39#include <TH1.h>
40
41#include "JSONIOUtils.h"
42
43#include "static_execute.h"
44
45#include <algorithm>
46#include <cctype>
47
49
50///////////////////////////////////////////////////////////////////////////////////////////////////////
51// individually implemented importers
52///////////////////////////////////////////////////////////////////////////////////////////////////////
53
54namespace {
55/**
56 * Extracts arguments from a mathematical expression.
57 *
58 * This function takes a string representing a mathematical
59 * expression and extracts the arguments from it. The arguments are
60 * defined as sequences of characters that do not contain digits,
61 * spaces, or parentheses, and that start with a letter. Function
62 * calls such as "exp( ... )", identified as being followed by an
63 * opening parenthesis, are not treated as arguments. The extracted
64 * arguments are returned as a vector of strings.
65 *
66 * @param expr A string representing a mathematical expression.
67 * @return A vector of strings representing the extracted arguments.
68 */
69std::vector<std::string> extractArguments(std::string expr)
70{
71 // Get rid of whitespaces
72 expr.erase(std::remove_if(expr.begin(), expr.end(), [](unsigned char c) { return std::isspace(c); }), expr.end());
73
74 std::vector<std::string> arguments;
75 size_t startidx = expr.size();
76 for (size_t i = 0; i < expr.size(); ++i) {
77 if (startidx >= expr.size()) {
78 if (isalpha(expr[i])) {
79 startidx = i;
80 }
81 } else {
82 if (!isdigit(expr[i]) && !isalpha(expr[i]) && expr[i] != '_') {
83 if (expr[i] == '(') {
84 startidx = expr.size();
85 continue;
86 }
87 std::string arg(expr.substr(startidx, i - startidx));
88 startidx = expr.size();
89 arguments.push_back(arg);
90 }
91 }
92 }
93 if (startidx < expr.size()) {
94 arguments.push_back(expr.substr(startidx));
95 }
96 return arguments;
97}
98
99template <class RooArg_t>
100class RooFormulaArgFactory : public RooFit::JSONIO::Importer {
101public:
102 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
103 {
104 std::string name(RooJSONFactoryWSTool::name(p));
105 if (!p.has_child("expression")) {
106 RooJSONFactoryWSTool::error("no expression given for '" + name + "'");
107 }
108 TString formula(p["expression"].val());
109 RooArgList dependents;
110 for (const auto &d : extractArguments(formula.Data())) {
111 dependents.add(*tool->request<RooAbsReal>(d, name));
112 }
113 tool->wsImport(RooArg_t{name.c_str(), formula, dependents});
114 return true;
115 }
116};
117
118class RooAddPdfFactory : public RooFit::JSONIO::Importer {
119public:
120 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
121 {
122 std::string name(RooJSONFactoryWSTool::name(p));
123 tool->wsEmplace<RooAddPdf>(name, tool->requestArgList<RooAbsPdf>(p, "summands"),
124 tool->requestArgList<RooAbsReal>(p, "coefficients"));
125 return true;
126 }
127};
128
129class RooBinWidthFunctionFactory : public RooFit::JSONIO::Importer {
130public:
131 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
132 {
133 std::string name(RooJSONFactoryWSTool::name(p));
134 RooHistFunc *hf = static_cast<RooHistFunc *>(tool->request<RooAbsReal>(p["histogram"].val(), name));
135 tool->wsEmplace<RooBinWidthFunction>(name, *hf, p["divideByBinWidth"].val_bool());
136 return true;
137 }
138};
139
140class RooBinSamplingPdfFactory : public RooFit::JSONIO::Importer {
141public:
142 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
143 {
144 std::string name(RooJSONFactoryWSTool::name(p));
145
146 RooAbsPdf *pdf = tool->requestArg<RooAbsPdf>(p, "pdf");
147 RooRealVar *obs = tool->requestArg<RooRealVar>(p, "observable");
148
149 if (!pdf->dependsOn(*obs)) {
150 RooJSONFactoryWSTool::error(std::string("pdf '") + pdf->GetName() + "' does not depend on observable '" +
151 obs->GetName() + "' as indicated by parent RooBinSamplingPdf '" + name +
152 "', please check!");
153 }
154
155 if (!p.has_child("epsilon")) {
156 RooJSONFactoryWSTool::error("no epsilon given in '" + name + "'");
157 }
158 double epsilon(p["epsilon"].val_double());
159
160 tool->wsEmplace<RooBinSamplingPdf>(name, *obs, *pdf, epsilon);
161
162 return true;
163 }
164};
165
166class RooRealSumPdfFactory : public RooFit::JSONIO::Importer {
167public:
168 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
169 {
170 std::string name(RooJSONFactoryWSTool::name(p));
171
172 bool extended = false;
173 if (p.has_child("extended") && p["extended"].val_bool()) {
174 extended = true;
175 }
176 tool->wsEmplace<RooRealSumPdf>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
177 tool->requestArgList<RooAbsReal>(p, "coefficients"), extended);
178 return true;
179 }
180};
181
182class RooRealSumFuncFactory : public RooFit::JSONIO::Importer {
183public:
184 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
185 {
186 std::string name(RooJSONFactoryWSTool::name(p));
187 tool->wsEmplace<RooRealSumFunc>(name, tool->requestArgList<RooAbsReal>(p, "samples"),
188 tool->requestArgList<RooAbsReal>(p, "coefficients"));
189 return true;
190 }
191};
192
193class RooPolynomialFactory : public RooFit::JSONIO::Importer {
194public:
195 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
196 {
197 std::string name(RooJSONFactoryWSTool::name(p));
198 if (!p.has_child("coefficients")) {
199 RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
200 }
201 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
202 RooArgList coefs;
203 int order = 0;
204 int lowestOrder = 0;
205 for (const auto &coef : p["coefficients"].children()) {
206 // As long as the coefficients match the default coefficients in
207 // RooFit, we don't have to instantiate RooFit objects but can
208 // increase the lowestOrder flag.
209 if (order == 0 && coef.val() == "1.0") {
210 ++lowestOrder;
211 } else if (coefs.empty() && coef.val() == "0.0") {
212 ++lowestOrder;
213 } else {
214 coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
215 }
216 ++order;
217 }
218
219 tool->wsEmplace<RooPolynomial>(name, *x, coefs, lowestOrder);
220 return true;
221 }
222};
223
224class RooPoissonFactory : public RooFit::JSONIO::Importer {
225public:
226 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
227 {
228 std::string name(RooJSONFactoryWSTool::name(p));
229 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
230 RooAbsReal *mean = tool->requestArg<RooAbsReal>(p, "mean");
231 tool->wsEmplace<RooPoisson>(name, *x, *mean, !p["integer"].val_bool());
232 return true;
233 }
234};
235
236class RooLogNormalFactory : public RooFit::JSONIO::Importer {
237public:
238 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
239 {
240 std::string name(RooJSONFactoryWSTool::name(p));
241 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
242
243 // Same mechanism to undo the parameter transformation as in the
244 // RooExponentialFactory (see comments in that class for more info).
245 const std::string muName = p["mu"].val();
246 const std::string sigmaName = p["sigma"].val();
247 const bool isTransformed = endsWith(muName, "_lognormal_log");
248 const std::string suffixToRemove = isTransformed ? "_lognormal_log" : "";
249 RooAbsReal *mu = tool->request<RooAbsReal>(removeSuffix(muName, suffixToRemove), name);
250 RooAbsReal *sigma = tool->request<RooAbsReal>(removeSuffix(sigmaName, suffixToRemove), name);
251
252 tool->wsEmplace<RooLognormal>(name, *x, *mu, *sigma, !isTransformed);
253
254 return true;
255 }
256};
257
258class RooExponentialFactory : public RooFit::JSONIO::Importer {
259public:
260 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
261 {
262 std::string name(RooJSONFactoryWSTool::name(p));
263 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
264
265 // If the parameter name ends with the "_exponential_inverted" suffix,
266 // this means that it was exported from a RooFit object where the
267 // parameter first needed to be transformed on export to match the HS3
268 // specification. But when re-importing such a parameter, we can simply
269 // skip the transformation and use the original RooFit parameter without
270 // the suffix.
271 //
272 // A concrete example: take the following RooFit pdf in the factory language:
273 //
274 // "Exponential::exponential_1(x[0, 10], c[-0.1])"
275 //
276 // It defines en exponential exp(c * x). However, in HS3 the exponential
277 // is defined as exp(-c * x), to RooFit would export these dictionaries
278 // to the JSON:
279 //
280 // {
281 // "name": "exponential_1", // HS3 exponential_dist with transformed parameter
282 // "type": "exponential_dist",
283 // "x": "x",
284 // "c": "c_exponential_inverted"
285 // },
286 // {
287 // "name": "c_exponential_inverted", // transformation function created on-the-fly on export
288 // "type": "generic_function",
289 // "expression": "-c"
290 // }
291 //
292 // On import, we can directly take the non-transformed parameter, which is
293 // we check for the suffix and optionally remove it from the requested
294 // name next:
295
296 const std::string constParamName = p["c"].val();
297 const bool isInverted = endsWith(constParamName, "_exponential_inverted");
298 const std::string suffixToRemove = isInverted ? "_exponential_inverted" : "";
299 RooAbsReal *c = tool->request<RooAbsReal>(removeSuffix(constParamName, suffixToRemove), name);
300
301 tool->wsEmplace<RooExponential>(name, *x, *c, !isInverted);
302
303 return true;
304 }
305};
306
307class RooLegacyExpPolyFactory : public RooFit::JSONIO::Importer {
308public:
309 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
310 {
311 std::string name(RooJSONFactoryWSTool::name(p));
312 if (!p.has_child("coefficients")) {
313 RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
314 }
315 RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
316 RooArgList coefs;
317 int order = 0;
318 int lowestOrder = 0;
319 for (const auto &coef : p["coefficients"].children()) {
320 // As long as the coefficients match the default coefficients in
321 // RooFit, we don't have to instantiate RooFit objects but can
322 // increase the lowestOrder flag.
323 if (order == 0 && coef.val() == "1.0") {
324 ++lowestOrder;
325 } else if (coefs.empty() && coef.val() == "0.0") {
326 ++lowestOrder;
327 } else {
328 coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
329 }
330 ++order;
331 }
332
333 tool->wsEmplace<RooLegacyExpPoly>(name, *x, coefs, lowestOrder);
334 return true;
335 }
336};
337
338class RooMultiVarGaussianFactory : public RooFit::JSONIO::Importer {
339public:
340 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
341 {
342 std::string name(RooJSONFactoryWSTool::name(p));
343 bool has_cov = p.has_child("covariances");
344 bool has_corr = p.has_child("correlations") && p.has_child("standard_deviations");
345 if (!has_cov && !has_corr) {
346 RooJSONFactoryWSTool::error("no covariances or correlations+standard_deviations given in '" + name + "'");
347 }
348
349 TMatrixDSym covmat;
350
351 if (has_cov) {
352 int n = p["covariances"].num_children();
353 int i = 0;
354 covmat.ResizeTo(n, n);
355 for (const auto &row : p["covariances"].children()) {
356 int j = 0;
357 for (const auto &val : row.children()) {
358 covmat(i, j) = val.val_double();
359 ++j;
360 }
361 ++i;
362 }
363 } else {
364 std::vector<double> variances;
365 for (const auto &v : p["standard_deviations"].children()) {
366 variances.push_back(v.val_double());
367 }
368 covmat.ResizeTo(variances.size(), variances.size());
369 int i = 0;
370 for (const auto &row : p["correlations"].children()) {
371 int j = 0;
372 for (const auto &val : row.children()) {
373 covmat(i, j) = val.val_double() * variances[i] * variances[j];
374 ++j;
375 }
376 ++i;
377 }
378 }
380 tool->requestArgList<RooAbsReal>(p, "mean"), covmat);
381 return true;
382 }
383};
384
385///////////////////////////////////////////////////////////////////////////////////////////////////////
386// specialized exporter implementations
387///////////////////////////////////////////////////////////////////////////////////////////////////////
388
389class RooAddPdfStreamer : public RooFit::JSONIO::Exporter {
390public:
391 std::string const &key() const override;
392 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
393 {
394 const RooAddPdf *pdf = static_cast<const RooAddPdf *>(func);
395 elem["type"] << key();
396 RooJSONFactoryWSTool::fillSeq(elem["summands"], pdf->pdfList());
397 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
398 elem["extended"] << (pdf->extendMode() != RooAbsPdf::CanNotBeExtended);
399 return true;
400 }
401};
402
403class RooRealSumPdfStreamer : public RooFit::JSONIO::Exporter {
404public:
405 std::string const &key() const override;
406 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
407 {
408 const RooRealSumPdf *pdf = static_cast<const RooRealSumPdf *>(func);
409 elem["type"] << key();
410 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
411 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
412 elem["extended"] << (pdf->extendMode() != RooAbsPdf::CanNotBeExtended);
413 return true;
414 }
415};
416
417class RooRealSumFuncStreamer : public RooFit::JSONIO::Exporter {
418public:
419 std::string const &key() const override;
420 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
421 {
422 const RooRealSumFunc *pdf = static_cast<const RooRealSumFunc *>(func);
423 elem["type"] << key();
424 RooJSONFactoryWSTool::fillSeq(elem["samples"], pdf->funcList());
425 RooJSONFactoryWSTool::fillSeq(elem["coefficients"], pdf->coefList());
426 return true;
427 }
428};
429
430class RooHistFuncStreamer : public RooFit::JSONIO::Exporter {
431public:
432 std::string const &key() const override;
433 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
434 {
435 const RooHistFunc *hf = static_cast<const RooHistFunc *>(func);
436 elem["type"] << key();
437 RooDataHist const &dh = hf->dataHist();
438 tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
439 return true;
440 }
441};
442
443class RooHistFuncFactory : public RooFit::JSONIO::Importer {
444public:
445 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
446 {
447 std::string name(RooJSONFactoryWSTool::name(p));
448 if (!p.has_child("data")) {
449 RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
450 }
451 std::unique_ptr<RooDataHist> dataHist =
453 tool->wsEmplace<RooHistFunc>(name, *dataHist->get(), *dataHist);
454 return true;
455 }
456};
457
458class RooHistPdfStreamer : public RooFit::JSONIO::Exporter {
459public:
460 std::string const &key() const override;
461 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
462 {
463 const RooHistPdf *hf = static_cast<const RooHistPdf *>(func);
464 elem["type"] << key();
465 RooDataHist const &dh = hf->dataHist();
466 tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
467 return true;
468 }
469};
470
471class RooHistPdfFactory : public RooFit::JSONIO::Importer {
472public:
473 bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
474 {
475 std::string name(RooJSONFactoryWSTool::name(p));
476 if (!p.has_child("data")) {
477 RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
478 }
479 std::unique_ptr<RooDataHist> dataHist =
481 tool->wsEmplace<RooHistPdf>(name, *dataHist->get(), *dataHist);
482 return true;
483 }
484};
485
486class RooBinSamplingPdfStreamer : public RooFit::JSONIO::Exporter {
487public:
488 std::string const &key() const override;
489 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
490 {
491 const RooBinSamplingPdf *pdf = static_cast<const RooBinSamplingPdf *>(func);
492 elem["type"] << key();
493 elem["pdf"] << pdf->pdf().GetName();
494 elem["observable"] << pdf->observable().GetName();
495 elem["epsilon"] << pdf->epsilon();
496 return true;
497 }
498};
499
500class RooBinWidthFunctionStreamer : public RooFit::JSONIO::Exporter {
501public:
502 std::string const &key() const override;
503 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
504 {
505 const RooBinWidthFunction *pdf = static_cast<const RooBinWidthFunction *>(func);
506 elem["type"] << key();
507 elem["histogram"] << pdf->histFunc().GetName();
508 elem["divideByBinWidth"] << pdf->divideByBinWidth();
509 return true;
510 }
511};
512
513template <class RooArg_t>
514class RooFormulaArgStreamer : public RooFit::JSONIO::Exporter {
515public:
516 std::string const &key() const override;
517 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
518 {
519 const RooArg_t *pdf = static_cast<const RooArg_t *>(func);
520 elem["type"] << key();
521 TString expression(pdf->expression());
522 std::vector<std::pair<RooAbsArg *, std::size_t>> paramsWithIndex;
523 paramsWithIndex.reserve(pdf->nParameters());
524 for (size_t i = 0; i < pdf->nParameters(); ++i) {
525 paramsWithIndex.emplace_back(pdf->getParameter(i), i);
526 }
527 std::sort(paramsWithIndex.begin(), paramsWithIndex.end());
528 for (auto [par, idx] : paramsWithIndex) {
529 expression.ReplaceAll(("x[" + std::to_string(idx) + "]").c_str(), par->GetName());
530 expression.ReplaceAll(("@" + std::to_string(idx)).c_str(), par->GetName());
531 }
532 elem["expression"] << expression.Data();
533 return true;
534 }
535};
536
537class RooPolynomialStreamer : public RooFit::JSONIO::Exporter {
538public:
539 std::string const &key() const override;
540 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
541 {
542 auto *pdf = static_cast<const RooPolynomial *>(func);
543 elem["type"] << key();
544 elem["x"] << pdf->x().GetName();
545 auto &coefs = elem["coefficients"].set_seq();
546 // Write out the default coefficient that RooFit uses for the lower
547 // orders before the order of the first coefficient. Like this, the
548 // output is more self-documenting.
549 for (int i = 0; i < pdf->lowestOrder(); ++i) {
550 coefs.append_child() << (i == 0 ? "1.0" : "0.0");
551 }
552 for (const auto &coef : pdf->coefList()) {
553 coefs.append_child() << coef->GetName();
554 }
555 return true;
556 }
557};
558
559class RooLegacyExpPolyStreamer : public RooFit::JSONIO::Exporter {
560public:
561 std::string const &key() const override;
562 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
563 {
564 auto *pdf = static_cast<const RooLegacyExpPoly *>(func);
565 elem["type"] << key();
566 elem["x"] << pdf->x().GetName();
567 auto &coefs = elem["coefficients"].set_seq();
568 // Write out the default coefficient that RooFit uses for the lower
569 // orders before the order of the first coefficient. Like this, the
570 // output is more self-documenting.
571 for (int i = 0; i < pdf->lowestOrder(); ++i) {
572 coefs.append_child() << (i == 0 ? "1.0" : "0.0");
573 }
574 for (const auto &coef : pdf->coefList()) {
575 coefs.append_child() << coef->GetName();
576 }
577 return true;
578 }
579};
580
581class RooPoissonStreamer : public RooFit::JSONIO::Exporter {
582public:
583 std::string const &key() const override;
584 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
585 {
586 auto *pdf = static_cast<const RooPoisson *>(func);
587 elem["type"] << key();
588 elem["x"] << pdf->getX().GetName();
589 elem["mean"] << pdf->getMean().GetName();
590 elem["integer"] << !pdf->getNoRounding();
591 return true;
592 }
593};
594
595class RooLogNormalStreamer : public RooFit::JSONIO::Exporter {
596public:
597 std::string const &key() const override;
598 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
599 {
600 auto *pdf = static_cast<const RooLognormal *>(func);
601
602 elem["type"] << key();
603 elem["x"] << pdf->getX().GetName();
604
605 auto &m0 = pdf->getMedian();
606 auto &k = pdf->getShapeK();
607
608 if (pdf->useStandardParametrization()) {
609 elem["mu"] << m0.GetName();
610 elem["sigma"] << k.GetName();
611 } else {
612 elem["mu"] << tool->exportTransformed(&m0, "_lognormal_log", "log(%s)");
613 elem["sigma"] << tool->exportTransformed(&k, "_lognormal_log", "log(%s)");
614 }
615
616 return true;
617 }
618};
619
620class RooExponentialStreamer : public RooFit::JSONIO::Exporter {
621public:
622 std::string const &key() const override;
623 bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
624 {
625 auto *pdf = static_cast<const RooExponential *>(func);
626 elem["type"] << key();
627 elem["x"] << pdf->variable().GetName();
628 auto &c = pdf->coefficient();
629 if (pdf->negateCoefficient()) {
630 elem["c"] << c.GetName();
631 } else {
632 elem["c"] << tool->exportTransformed(&c, "_exponential_inverted", "-%s");
633 }
634
635 return true;
636 }
637};
638
639class RooMultiVarGaussianStreamer : public RooFit::JSONIO::Exporter {
640public:
641 std::string const &key() const override;
642 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
643 {
644 auto *pdf = static_cast<const RooMultiVarGaussian *>(func);
645 elem["type"] << key();
646 RooJSONFactoryWSTool::fillSeq(elem["x"], pdf->xVec());
647 RooJSONFactoryWSTool::fillSeq(elem["mean"], pdf->muVec());
648 elem["covariances"].fill_mat(pdf->covarianceMatrix());
649 return true;
650 }
651};
652
653class RooTFnBindingStreamer : public RooFit::JSONIO::Exporter {
654public:
655 std::string const &key() const override;
656 bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
657 {
658 auto *pdf = static_cast<const RooTFnBinding *>(func);
659 elem["type"] << key();
660
661 TString formula(pdf->function().GetExpFormula());
662 formula.ReplaceAll("x", pdf->observables()[0].GetName());
663 formula.ReplaceAll("y", pdf->observables()[1].GetName());
664 formula.ReplaceAll("z", pdf->observables()[2].GetName());
665 for (size_t i = 0; i < pdf->parameters().size(); ++i) {
666 TString pname(TString::Format("[%d]", (int)i));
667 formula.ReplaceAll(pname, pdf->parameters()[i].GetName());
668 }
669 elem["expression"] << formula.Data();
670 return true;
671 }
672};
673
674#define DEFINE_EXPORTER_KEY(class_name, name) \
675 std::string const &class_name::key() const \
676 { \
677 const static std::string keystring = name; \
678 return keystring; \
679 }
680
681DEFINE_EXPORTER_KEY(RooAddPdfStreamer, "mixture_dist");
682DEFINE_EXPORTER_KEY(RooBinSamplingPdfStreamer, "binsampling");
683DEFINE_EXPORTER_KEY(RooBinWidthFunctionStreamer, "binwidth");
684DEFINE_EXPORTER_KEY(RooLegacyExpPolyStreamer, "legacy_exp_poly_dist");
685DEFINE_EXPORTER_KEY(RooExponentialStreamer, "exponential_dist");
686template <>
687DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooFormulaVar>, "generic_function");
688template <>
689DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooGenericPdf>, "generic_dist");
690DEFINE_EXPORTER_KEY(RooHistFuncStreamer, "histogram");
691DEFINE_EXPORTER_KEY(RooHistPdfStreamer, "histogram_dist");
692DEFINE_EXPORTER_KEY(RooLogNormalStreamer, "lognormal_dist");
693DEFINE_EXPORTER_KEY(RooMultiVarGaussianStreamer, "multivariate_normal_dist");
694DEFINE_EXPORTER_KEY(RooPoissonStreamer, "poisson_dist");
695DEFINE_EXPORTER_KEY(RooPolynomialStreamer, "polynomial_dist");
696DEFINE_EXPORTER_KEY(RooRealSumFuncStreamer, "weighted_sum");
697DEFINE_EXPORTER_KEY(RooRealSumPdfStreamer, "weighted_sum_dist");
698DEFINE_EXPORTER_KEY(RooTFnBindingStreamer, "generic_function");
699
700///////////////////////////////////////////////////////////////////////////////////////////////////////
701// instantiate all importers and exporters
702///////////////////////////////////////////////////////////////////////////////////////////////////////
703
704STATIC_EXECUTE([]() {
705 using namespace RooFit::JSONIO;
706
707 registerImporter<RooAddPdfFactory>("mixture_dist", false);
708 registerImporter<RooBinSamplingPdfFactory>("binsampling_dist", false);
709 registerImporter<RooBinWidthFunctionFactory>("binwidth", false);
710 registerImporter<RooLegacyExpPolyFactory>("legacy_exp_poly_dist", false);
711 registerImporter<RooExponentialFactory>("exponential_dist", false);
712 registerImporter<RooFormulaArgFactory<RooFormulaVar>>("generic_function", false);
713 registerImporter<RooFormulaArgFactory<RooGenericPdf>>("generic_dist", false);
714 registerImporter<RooHistFuncFactory>("histogram", false);
715 registerImporter<RooHistPdfFactory>("histogram_dist", false);
716 registerImporter<RooLogNormalFactory>("lognormal_dist", false);
717 registerImporter<RooMultiVarGaussianFactory>("multivariate_normal_dist", false);
718 registerImporter<RooPoissonFactory>("poisson_dist", false);
719 registerImporter<RooPolynomialFactory>("polynomial_dist", false);
720 registerImporter<RooRealSumPdfFactory>("weighted_sum_dist", false);
721 registerImporter<RooRealSumFuncFactory>("weighted_sum", false);
722
723 registerExporter<RooAddPdfStreamer>(RooAddPdf::Class(), false);
724 registerExporter<RooBinSamplingPdfStreamer>(RooBinSamplingPdf::Class(), false);
725 registerExporter<RooBinWidthFunctionStreamer>(RooBinWidthFunction::Class(), false);
726 registerExporter<RooLegacyExpPolyStreamer>(RooLegacyExpPoly::Class(), false);
727 registerExporter<RooExponentialStreamer>(RooExponential::Class(), false);
728 registerExporter<RooFormulaArgStreamer<RooFormulaVar>>(RooFormulaVar::Class(), false);
729 registerExporter<RooFormulaArgStreamer<RooGenericPdf>>(RooGenericPdf::Class(), false);
730 registerExporter<RooHistFuncStreamer>(RooHistFunc::Class(), false);
731 registerExporter<RooHistPdfStreamer>(RooHistPdf::Class(), false);
732 registerExporter<RooLogNormalStreamer>(RooLognormal::Class(), false);
733 registerExporter<RooMultiVarGaussianStreamer>(RooMultiVarGaussian::Class(), false);
734 registerExporter<RooPoissonStreamer>(RooPoisson::Class(), false);
735 registerExporter<RooPolynomialStreamer>(RooPolynomial::Class(), false);
736 registerExporter<RooRealSumFuncStreamer>(RooRealSumFunc::Class(), false);
737 registerExporter<RooRealSumPdfStreamer>(RooRealSumPdf::Class(), false);
738 registerExporter<RooTFnBindingStreamer>(RooTFnBinding::Class(), false);
739});
740
741} // 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 c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
char name[80]
Definition TGX11.cxx:110
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
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 Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
@ CanNotBeExtended
Definition RooAbsPdf.h:213
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
Efficient implementation of a sum of PDFs of the form.
Definition RooAddPdf.h:33
const RooArgList & coefList() const
Definition RooAddPdf.h:74
ExtendMode extendMode() const override
Returns ability of PDF to provide extended likelihood terms.
Definition RooAddPdf.h:60
static TClass * Class()
const RooArgList & pdfList() const
Definition RooAddPdf.h:70
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
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()
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:39
double const * weightArray() const
const RooArgSet * get() const override
Get bin centre of current bin.
Definition RooDataHist.h:76
Exponential PDF.
static TClass * Class()
virtual JSONNode & append_child()=0
virtual JSONNode & set_seq()=0
void fill_mat(Matrix const &mat)
virtual std::string const & key() const =0
virtual bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *, RooFit::Detail::JSONNode &) const
Definition JSONIO.h:59
virtual bool importArg(RooJSONFactoryWSTool *tool, const RooFit::Detail::JSONNode &node) const
Definition JSONIO.h:37
static TClass * Class()
static TClass * Class()
A real-valued function sampled from a multidimensional histogram.
Definition RooHistFunc.h:31
RooDataHist & dataHist()
Return RooDataHist that is represented.
Definition RooHistFunc.h:45
static TClass * Class()
A propability density function sampled from a multidimensional histogram.
Definition RooHistPdf.h:30
static TClass * Class()
RooDataHist & dataHist()
Definition RooHistPdf.h:42
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)
T * requestArg(const RooFit::Detail::JSONNode &node, const std::string &key)
T * request(const std::string &objname, const std::string &requestAuthor)
Obj_t & wsImport(Obj_t const &obj)
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 void exportHisto(RooArgSet const &vars, std::size_t n, double const *contents, RooFit::Detail::JSONNode &output)
Export histogram data to a JSONNode.
RooArgList requestArgList(const RooFit::Detail::JSONNode &node, const std::string &seqName)
std::string exportTransformed(const RooAbsReal *original, const std::string &suffix, const std::string &formula)
static void error(const char *s)
Writes an error message to the RooFit message service and throws a runtime_error.
Obj_t & wsEmplace(RooStringView name, Args_t &&...args)
static std::string name(const RooFit::Detail::JSONNode &n)
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()
Poisson pdf.
Definition RooPoisson.h:19
static TClass * Class()
RooPolynomial implements a polynomial p.d.f of the form.
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
Use TF1, TF2, TF3 functions as RooFit objects.
static TClass * Class()
TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1) override
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Basic string class.
Definition TString.h:139
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:2378
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)