34 if (std::isinf(
value)) {
41void writeStrings(
JSONNode &node, std::vector<std::string>
const &values)
47void writeRefs(
JSONNode &node, std::vector<Ref<Tag>>
const &refs)
50 for (
auto const &ref : refs) {
64 if (
auto const *edges = std::get_if<EdgesBinning>(&binning)) {
65 node[
"edges"].
fill_seq(edges->edges);
67 node[
"nbins"] << std::get<RegularBinning>(binning).nbins;
71void writeAxis(
JSONNode &node, BinnedAxis
const &axis)
74 node[
"name"] << axis.name;
76 node[
"min"] << axis.min;
77 node[
"max"] << axis.max;
78 writeBinning(node, axis.binning);
81void writeAxis(
JSONNode &node, ContinuousAxis
const &axis)
84 node[
"name"] << axis.name;
86 writeBound(node[
"min"], *axis.min);
89 writeBound(node[
"max"], *axis.max);
93void writeAxis(
JSONNode &node, CategoricalAxis
const &axis)
96 node[
"name"] << axis.name;
97 writeStrings(node[
"categories"], axis.categories);
101void writeAxis(
JSONNode &node, DomainAxis
const &axis)
104 node[
"name"] << axis.name;
105 if (axis.fixedValue) {
109 if (axis.min && !std::isinf(*axis.min)) {
110 node[
"min"] << *axis.min;
112 if (axis.max && !std::isinf(*axis.max)) {
113 node[
"max"] << *axis.max;
116 writeBinning(node, *axis.binning);
120template <
class... Axes>
121void writeAxes(
JSONNode &node, std::vector<std::variant<Axes...>>
const &axes)
124 for (
auto const &axis : axes) {
125 std::visit([&](
auto const &
a) { writeAxis(node.
append_child(),
a); }, axis);
130void writeAxes(
JSONNode &node, std::vector<Axis>
const &axes)
133 for (
auto const &axis : axes) {
145 [&](ConstraintPdf
const &pdf) { mod[
"constraints"].
set_seq().
append_child() << pdf.pdf.name; }},
152 [&](ConstantGammas) { node[typeKey] <<
"Const"; },
153 [&](GammaConstraintPdfs
const &pdfs) {
155 for (
auto const &pdf : pdfs.pdfs) {
177 [&](NormFactor
const &
m) {
178 JSONNode &mod = appendModifier(modifiers,
m.name,
"normfactor");
179 writeParameter(mod,
m.parameter,
m.constraint);
181 [&](NormSys
const &
m) {
182 JSONNode &mod = appendModifier(modifiers,
m.name,
"normsys");
183 writeParameter(mod,
m.parameter,
m.constraint);
184 if (
m.interpolation) {
191 [&](HistoSys
const &
m) {
192 JSONNode &mod = appendModifier(modifiers,
m.name,
"histosys");
193 writeParameter(mod,
m.parameter,
m.constraint);
194 if (
m.interpolation) {
201 [&](ShapeSys
const &
m) {
202 JSONNode &mod = appendModifier(modifiers,
m.name,
"shapefactor");
203 writeRefs(mod[
"parameters"],
m.parameters);
204 writeGammaConstraint(mod,
m.constraint,
"constraint");
206 if (!
m.vals.empty()) {
210 [&](StatError
const &
m) {
211 JSONNode &mod = appendModifier(modifiers,
m.name,
"staterror");
212 writeRefs(mod[
"parameters"],
m.parameters);
213 writeGammaConstraint(mod,
m.constraint,
"constraint");
215 [&](CustomModifier
const &
m) { appendModifier(modifiers,
m.name,
"custom"); },
220void writeParameterPoint(
JSONNode &
points, ParameterPoint
const &point)
223 for (
auto const &
p : point.parameters) {
224 JSONNode &node = appendNamed(parameters,
p.name);
226 std::visit([&](
auto const &
value) { node[
"value"] <<
value; }, *
p.value);
229 node[
"const"] <<
true;
238 [&](BinnedData
const &
d) {
239 node[
"type"] <<
"binned";
240 writeAxes(node[
"axes"],
d.axes);
244 uncertainty[
"type"] <<
"gaussian_uncertainty";
245 uncertainty[
"sigma"].
fill_seq(
d.uncertainty->sigma);
248 [&](UnbinnedData
const &
d) {
249 node[
"type"] <<
"unbinned";
250 writeAxes(node[
"axes"],
d.axes);
252 const std::size_t nAxes =
d.axes.size();
253 for (std::size_t i = 0; i <
d.numEntries(); ++i) {
255 for (std::size_t j = 0; j < nAxes; ++j) {
256 const double value =
d.entries[i * nAxes + j];
257 if (
auto const *category = std::get_if<CategoricalAxis>(&
d.axes[j])) {
268 [&](PointData
const &
d) {
269 node[
"type"] <<
"point";
270 node[
"value"] <<
d.value;
272 node[
"uncertainty"] << *
d.uncertainty;
274 if (!
d.axes.empty()) {
275 writeAxes(node[
"axes"],
d.axes);
282void writeLikelihood(
JSONNode &likelihoods, Likelihood
const &likelihood)
284 JSONNode &node = appendNamed(likelihoods, likelihood.name);
287 for (
auto const &term : likelihood.terms) {
293 if (!likelihood.auxDistributions.empty()) {
294 writeRefs(node[
"aux_distributions"], likelihood.auxDistributions);
298void writeAnalysis(
JSONNode &analyses, Analysis
const &analysis)
300 JSONNode &node = appendNamed(analyses, analysis.name);
301 writeRefs(node[
"domains"], analysis.domains);
302 node[
"likelihood"] << analysis.likelihood.name;
303 if (!analysis.parametersOfInterest.empty()) {
304 writeRefs(node[
"parameters_of_interest"], analysis.parametersOfInterest);
307 node[
"init"] << analysis.init->name;
309 if (analysis.prior) {
310 node[
"prior"] << analysis.prior->name;
314void writeRooFitInternal(
JSONNode &root, RooFitInternal
const &internal)
316 auto rootInternal = [&]() ->
JSONNode & {
return root.
get(
"misc",
"ROOT_internal"); };
317 if (!internal.attributes.empty()) {
319 for (
auto const &item : internal.attributes) {
321 if (!item.second.dict.empty()) {
323 for (
auto const &entry : item.second.dict) {
324 dict[entry.first] << entry.second;
327 if (!item.second.tags.empty()) {
328 writeStrings(node[
"tags"], item.second.tags);
332 if (!internal.combinedDistributions.empty()) {
333 JSONNode &combined = rootInternal()[
"combined_distributions"].
set_map();
334 for (
auto const &item : internal.combinedDistributions) {
336 node[
"index_cat"] << item.second.indexCat;
337 writeStrings(node[
"labels"], item.second.labels);
338 node[
"indices"].
fill_seq(item.second.indices);
339 writeRefs(node[
"distributions"], item.second.distributions);
342 if (!internal.combinedDatasets.empty()) {
344 for (
auto const &item : internal.combinedDatasets) {
346 node[
"index_cat"] << item.second.indexCat;
347 writeStrings(node[
"labels"], item.second.labels);
348 node[
"indices"].
fill_seq(item.second.indices);
351 if (!internal.modelConfigs.empty()) {
353 for (
auto const &item : internal.modelConfigs) {
355 if (item.second.mcName) {
356 node[
"mcName"] << *item.second.mcName;
358 if (item.second.pdfName) {
359 node[
"pdfName"] << *item.second.pdfName;
361 if (item.second.combinedDataName) {
362 node[
"combined_data_name"] << *item.second.combinedDataName;
366 if (!internal.channelConstraints.empty()) {
367 JSONNode &constraints = rootInternal()[
"histfactory_constraints"].
set_map();
368 for (
auto const &item : internal.channelConstraints) {
369 writeRefs(constraints[item.first], item.second);
372 if (!internal.stepWidths.empty()) {
373 JSONNode &stepWidths = root.
get(
"misc",
"minimization")[
"parameter_stepwidths"].
set_seq();
374 for (
auto const &stepWidth : internal.stepWidths) {
375 appendNamed(stepWidths, stepWidth.name)[
"step_width"] << stepWidth.width;
386 node << static_cast<int>(
value);
395 for (
double value : values) {
405 if (interpolation.
out) {
416 std::visit([&](
auto const &
v) { node <<
v; },
value);
426void writeList(
JSONNode &node, std::vector<T>
const &values)
429 for (
auto const &
value : values) {
434template <
class Function_t>
435void writeInterpolated(
JSONNode &node, Function_t
const &function,
char const *
type)
437 node[
"type"] <<
type;
438 auto const &interpolations = function.interpolations;
439 const bool allEqual = std::all_of(interpolations.begin(), interpolations.end(),
440 [&](Interpolation
const &i) { return i == interpolations.front(); });
442 for (std::size_t i = 0; i < (allEqual ? std::min<std::size_t>(interpolations.size(), 1) : interpolations.
size());
446 writeList(node[
"vars"], function.parameters);
447 node[
"nom"] << function.nominal;
448 writeList(node[
"high"], function.high);
449 writeList(node[
"low"], function.low);
456 writeInterpolated(node, function,
"interpolation");
462 writeInterpolated(node, function,
"interpolation0d");
468 node[
"type"] <<
"histfactory_dist";
469 if (!std::holds_alternative<Unconstrained>(dist.statError.constraint)) {
470 writeGammaConstraint(node[
"staterror"].set_map(), dist.statError.constraint,
"constraint_type");
472 if (dist.defaultInterpolation) {
475 writeAxes(node[
"axes"], dist.axes);
477 for (
auto const &sample : dist.samples) {
478 JSONNode &s = appendNamed(samples, sample.name);
480 for (
auto const &
modifier : sample.modifiers) {
497 appendNamed(metadata[
"packages"], package.name)[
"version"] << package.version;
501 writeParameterPoint(root[
"parameter_points"], point);
503 for (
auto const &domain : doc.
domains) {
504 JSONNode &node = appendNamed(root[
"domains"], domain.name);
505 node[
"type"] <<
"product_domain";
506 writeAxes(node[
"axes"], domain.axes);
509 writeData(root[
"data"],
data);
512 writeLikelihood(root[
"likelihoods"], likelihood);
514 for (
auto const &analysis : doc.
analyses) {
515 writeAnalysis(root[
"analyses"], analysis);
517 writeRooFitInternal(root, doc.
rooFit);
constexpr const char * fixedValueKey
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
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 child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t modifier
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
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 winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
JSONNode & get(std::string const &key)
void fill_seq(Collection const &coll)
JSONNode & append_child()
An HS3 document. It is move-only, because generic objects refer to the JSON tree that the document wa...
std::vector< HS3::Analysis > analyses
std::vector< HS3::Data > data
std::vector< HS3::Likelihood > likelihoods
std::vector< HS3::ParameterPoint > parameterPoints
HS3::RooFitInternal rooFit
std::vector< HS3::Domain > domains
Types that represent an HS3 document.
std::variant< std::string, double > NameOrNumber
A name, or a number for a constant.
void writeNumber(Detail::JSONNode &node, double value)
Writes a number, as an integer if it has no fractional part.
void writeInterpolatedFunction(Detail::JSONNode &node, InterpolatedFunction const &function)
Writes the functions "interpolation" and "interpolation0d", with a single interpolation if they are a...
std::variant< NormFactor, NormSys, HistoSys, ShapeSys, StatError, CustomModifier > Modifier
std::variant< RegularBinning, EdgesBinning > Binning
ConstraintType
The constraint types that older documents named, for which RooFit creates the constraint terms.
Ref< struct DataTag > DataRef
char const * toString(InterpolationType type)
void writeDocument(Detail::JSONNode &root, HS3Document const &doc)
Writes everything but the distributions and functions, which are written one by one while they are ex...
void writeContents(Detail::JSONNode &node, std::vector< double > const &values)
Writes an array of numbers, each as an integer if it has no fractional part.
void writeInterpolatedNumber(Detail::JSONNode &node, InterpolatedNumber const &function)
void writeHistFactoryDist(Detail::JSONNode &node, HistFactoryDist const &dist)
Writes a HistFactory distribution, without its name.
Ref< struct ParameterTag > ParameterRef
void writeInterpolation(Detail::JSONNode &node, Interpolation const &interpolation)
std::variant< Unconstrained, ConstraintType, ConstantGammas, GammaConstraintPdfs > GammaConstraint
overloaded(Ts...) -> overloaded< Ts... >
std::variant< Unconstrained, ConstraintType, ConstraintPdf > Constraint
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
The function "interpolation" of RooFit, implemented by PiecewiseInterpolation: a nominal function plu...
The function "interpolation0d" of RooFit, implemented by FlexibleInterpVar: a nominal value plus the ...
How a modifier of a HistFactory distribution interpolates and extrapolates its effect.
std::optional< InterpolationFunction > out
If not set, the function inside the bounds is used outside as well.