Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
HistFactoryJSONTool.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
15
19
20#ifdef ROOFIT_HS3_WITH_RYML
21#include "RYMLParser.h"
22typedef TRYMLTree tree_t;
23#else
24#include "JSONParser.h"
26#endif
27
29
30namespace {
31
32void exportSample(const RooStats::HistFactory::Sample &sample, JSONNode &s)
33{
34 const std::vector<std::string> obsnames{"obs_x_" + sample.GetChannelName(), "obs_y_" + sample.GetChannelName(),
35 "obs_z_" + sample.GetChannelName()};
36
37 s.set_map();
38 s["type"] << "hist-sample";
39
40 if (sample.GetOverallSysList().size() > 0) {
41 auto &overallSys = s["overallSystematics"];
42 overallSys.set_map();
43 for (const auto &sys : sample.GetOverallSysList()) {
44 auto &node = overallSys[sys.GetName()];
45 node.set_map();
46 node["low"] << sys.GetLow();
47 node["high"] << sys.GetHigh();
48 }
49 }
50
51 if (sample.GetNormFactorList().size() > 0) {
52 auto &normFactors = s["normFactors"];
53 normFactors.set_seq();
54 for (auto &sys : sample.GetNormFactorList()) {
55 normFactors.append_child() << sys.GetName();
56 }
57 }
58
59 if (sample.GetHistoSysList().size() > 0) {
60 auto &histoSys = s["histogramSystematics"];
61 histoSys.set_map();
62 for (size_t i = 0; i < sample.GetHistoSysList().size(); ++i) {
63 auto &sys = sample.GetHistoSysList()[i];
64 auto &node = histoSys[sys.GetName()];
65 node.set_map();
66 RooJSONFactoryWSTool::exportHistogram(*(sys.GetHistoLow()), node["dataLow"], obsnames);
67 RooJSONFactoryWSTool::exportHistogram(*(sys.GetHistoHigh()), node["dataHigh"], obsnames);
68 }
69 }
70
71 auto &tags = s["dict"];
72 tags.set_map();
73 tags["normalizeByTheory"] << sample.GetNormalizeByTheory();
74
75 s["statError"] << sample.GetStatError().GetActivate();
76
77 auto &data = s["data"];
78 RooJSONFactoryWSTool::exportHistogram(*sample.GetHisto(), data, obsnames,
79 sample.GetStatError().GetActivate() && sample.GetStatError().GetUseHisto()
80 ? sample.GetStatError().GetErrorHist()
81 : nullptr);
82}
83
84void exportChannel(const RooStats::HistFactory::Channel &c, JSONNode &ch)
85{
86 ch.set_map();
87 ch["type"] << "histfactory";
88
89 auto &staterr = ch["statError"];
90 staterr.set_map();
91 staterr["relThreshold"] << c.GetStatErrorConfig().GetRelErrorThreshold();
92 staterr["constraint"] << RooStats::HistFactory::Constraint::Name(c.GetStatErrorConfig().GetConstraintType());
93
94 auto &samples = ch["samples"];
95 samples.set_map();
96 for (const auto &s : c.GetSamples()) {
97 auto &sample = samples[s.GetName()];
98 exportSample(s, sample);
99 auto &ns = sample["namespaces"];
100 ns.set_seq();
101 ns.append_child() << c.GetName();
102 }
103}
104
105void exportMeasurement(RooStats::HistFactory::Measurement &measurement, JSONNode &n)
106{
107 using namespace RooStats::HistFactory;
108
109 for (const auto &ch : measurement.GetChannels()) {
110 if (!ch.CheckHistograms())
111 throw std::runtime_error("unable to export histograms, please call CollectHistograms first");
112 }
113
114 auto &pdflist = n["pdfs"];
115 pdflist.set_map();
116
117 // collect information
118 std::map<std::string, RooStats::HistFactory::Constraint::Type> constraints;
119 std::map<std::string, NormFactor> normfactors;
120 for (const auto &ch : measurement.GetChannels()) {
121 for (const auto &s : ch.GetSamples()) {
122 for (const auto &sys : s.GetOverallSysList()) {
123 constraints[sys.GetName()] = RooStats::HistFactory::Constraint::Gaussian;
124 }
125 for (const auto &sys : s.GetHistoSysList()) {
126 constraints[sys.GetName()] = RooStats::HistFactory::Constraint::Gaussian;
127 }
128 for (const auto &sys : s.GetShapeSysList()) {
129 constraints[sys.GetName()] = sys.GetConstraintType();
130 }
131 for (const auto &norm : s.GetNormFactorList()) {
132 normfactors[norm.GetName()] = norm;
133 }
134 }
135 }
136
137 // preprocess functions
138 if (!measurement.GetFunctionObjects().empty()) {
139 auto &funclist = n["functions"];
140 funclist.set_map();
141 for (const auto &func : measurement.GetFunctionObjects()) {
142 auto &f = funclist[func.GetName()];
143 f.set_map();
144 f["name"] << func.GetName();
145 f["expression"] << func.GetExpression();
146 f["dependents"] << func.GetDependents();
147 f["command"] << func.GetCommand();
148 }
149 }
150
151 // the simpdf
152 auto &sim = pdflist[measurement.GetName()];
153 sim.set_map();
154 sim["type"] << "simultaneous";
155 sim["index"] << "channelCat";
156 auto &simdict = sim["dict"];
157 simdict.set_map();
158 simdict["InterpolationScheme"] << measurement.GetInterpolationScheme();
159 auto &simtags = sim["tags"];
160 simtags.set_seq();
161 simtags.append_child() << "toplevel";
162 auto &ch = sim["channels"];
163 ch.set_map();
164 for (const auto &c : measurement.GetChannels()) {
165 auto &thisch = ch[c.GetName()];
166 exportChannel(c, thisch);
167 }
168
169 // the variables
170 auto &varlist = n["variables"];
171 varlist.set_map();
172 for (const auto &c : measurement.GetChannels()) {
173 for (const auto &s : c.GetSamples()) {
174 for (const auto &norm : s.GetNormFactorList()) {
175 if (!varlist.has_child(norm.GetName())) {
176 auto &v = varlist[norm.GetName()];
177 v.set_map();
178 v["value"] << norm.GetVal();
179 v["min"] << norm.GetLow();
180 v["max"] << norm.GetHigh();
181 if (norm.GetConst()) {
182 v["const"] << true;
183 }
184 }
185 }
186 for (const auto &sys : s.GetOverallSysList()) {
187 std::string parname("alpha_");
188 parname += sys.GetName();
189 if (!varlist.has_child(parname)) {
190 auto &v = varlist[parname];
191 v.set_map();
192 v["value"] << 0.;
193 v["min"] << -5.;
194 v["max"] << 5.;
195 }
196 }
197 }
198 }
199 for (const auto &sys : measurement.GetConstantParams()) {
200 std::string parname = "alpha_" + sys;
201 if (!varlist.has_child(parname)) {
202 auto &v = varlist[parname];
203 v.set_map();
204 }
205 varlist[parname]["const"] << true;
206 }
207
208 for (const auto &poi : measurement.GetPOIList()) {
209 if (!varlist[poi].has_child("tags")) {
210 auto &tags = varlist[poi]["tags"];
211 tags.set_seq();
212 }
213 varlist[poi]["tags"].append_child() << "poi";
214 }
215
216 // the data
217 auto &datalist = n["data"];
218 datalist.set_map();
219 auto &obsdata = datalist["obsData"];
220 obsdata.set_map();
221 obsdata["index"] << "channelCat";
222 for (const auto &c : measurement.GetChannels()) {
223 const std::vector<std::string> obsnames{"obs_x_" + c.GetName(), "obs_y_" + c.GetName(), "obs_z_" + c.GetName()};
224
225 auto &chdata = obsdata[c.GetName()];
226 RooJSONFactoryWSTool::exportHistogram(*c.GetData().GetHisto(), chdata, obsnames);
227 }
228}
229
230} // namespace
231
233{
234 tree_t p;
235 auto &n = p.rootnode();
236 n.set_map();
237 exportMeasurement(_measurement, n);
238 n.writeJSON(os);
239}
240void RooStats::HistFactory::JSONTool::PrintJSON(std::string const &filename)
241{
242 std::ofstream out(filename);
243 this->PrintJSON(out);
244}
245
246#ifdef ROOFIT_HS3_WITH_RYML
248{
249 TRYMLTree p;
250 auto &n = p.rootnode();
251 n.set_map();
252 exportMeasurement(_measurement, n);
253 n.writeYML(os);
254}
255#else
257{
258 std::cerr << "YAML export only support with rapidyaml!" << std::endl;
259}
260#endif
261
262void RooStats::HistFactory::JSONTool::PrintYAML(std::string const &filename)
263{
264 std::ofstream out(filename);
265 this->PrintYAML(out);
266}
TJSONTree tree_t
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
static void exportHistogram(const TH1 &h, RooFit::Experimental::JSONNode &n, const std::vector< std::string > &obsnames, const TH1 *errH=0, bool writeObservables=true, bool writeErrors=true)
This class encapsulates all information for the statistical interpretation of one experiment.
Definition Channel.h:30
void PrintYAML(std::ostream &os=std::cout)
RooStats::HistFactory::Measurement & _measurement
void PrintJSON(std::ostream &os=std::cout)
The RooStats::HistFactory::Measurement class can be used to construct a model by combining multiple R...
Definition Measurement.h:30
std::vector< std::string > & GetPOIList()
get vector of PoI names
Definition Measurement.h:50
std::vector< std::string > & GetConstantParams()
get vector of all constant parameters
Definition Measurement.h:59
std::vector< RooStats::HistFactory::Channel > & GetChannels()
std::vector< RooStats::HistFactory::PreprocessFunction > & GetFunctionObjects()
get vector of defined function objects
Definition Measurement.h:74
std::vector< RooStats::HistFactory::OverallSys > & GetOverallSysList()
Definition Sample.h:109
std::string GetName() const
get name of sample
Definition Sample.h:83
const TH1 * GetHisto() const
Definition Sample.cxx:99
RooStats::HistFactory::StatError & GetStatError()
Definition Sample.h:125
std::string GetChannelName() const
get name of associated channel
Definition Sample.h:103
std::vector< RooStats::HistFactory::NormFactor > & GetNormFactorList()
Definition Sample.h:110
std::vector< RooStats::HistFactory::HistoSys > & GetHistoSysList()
Definition Sample.h:111
bool GetNormalizeByTheory() const
does the normalization scale with luminosity
Definition Sample.h:79
const TH1 * GetErrorHist() const
virtual Node & rootnode() override
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
Node & rootnode()
const Int_t n
Definition legend1.C:16
std::string Name(Type type)