Logo ROOT  
Reference Guide
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"];
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 }
182 }
183 for (const auto &sys : s.GetOverallSysList()) {
184 std::string parname("alpha_");
185 parname += sys.GetName();
186 if (!varlist.has_child(parname)) {
187 auto &v = varlist[parname];
188 v.set_map();
189 v["value"] << 0.;
190 v["min"] << -5.;
191 v["max"] << 5.;
192 }
193 }
194 }
195 }
196 for (const auto &sys : measurement.GetConstantParams()) {
197 std::string parname = "alpha_" + sys;
198 if (!varlist.has_child(parname)) {
199 auto &v = varlist[parname];
200 v.set_map();
201 }
202 varlist[parname]["const"] << true;
203 }
204
205 for (const auto &poi : measurement.GetPOIList()) {
206 if (!varlist[poi].has_child("tags")) {
207 auto &tags = varlist[poi]["tags"];
208 tags.set_seq();
209 }
210 varlist[poi]["tags"].append_child() << "poi";
211 }
212
213 // the data
214 auto &datalist = n["data"];
215 datalist.set_map();
216 auto &obsdata = datalist["obsData"];
217 obsdata.set_map();
218 obsdata["index"] << "channelCat";
219 for (const auto &c : measurement.GetChannels()) {
220 const std::vector<std::string> obsnames{"obs_x_" + c.GetName(), "obs_y_" + c.GetName(), "obs_z_" + c.GetName()};
221
222 auto &chdata = obsdata[c.GetName()];
223 RooJSONFactoryWSTool::exportHistogram(*c.GetData().GetHisto(), chdata, obsnames);
224 }
225}
226
227} // namespace
228
230{
231 tree_t p;
232 auto &n = p.rootnode();
233 n.set_map();
234 exportMeasurement(_measurement, n);
235 n.writeJSON(os);
236}
238{
239 std::ofstream out(filename);
240 this->PrintJSON(out);
241}
242
243#ifdef ROOFIT_HS3_WITH_RYML
245{
246 TRYMLTree p;
247 auto &n = p.rootnode();
248 n.set_map();
249 exportMeasurement(_measurement, n);
250 n.writeYML(os);
251}
252#else
254{
255 std::cerr << "YAML export only support with rapidyaml!" << std::endl;
256}
257#endif
258
260{
261 std::ofstream out(filename);
262 this->PrintYAML(out);
263}
TJSONTree tree_t
#define f(i)
Definition: RSha256.hxx:104
#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
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 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 filename
static void exportHistogram(const TH1 &h, RooFit::Experimental::JSONNode &n, const std::vector< std::string > &obsnames, const TH1 *errH=nullptr, 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:31
std::vector< std::string > & GetPOIList()
get vector of PoI names
Definition: Measurement.h:51
std::vector< std::string > & GetConstantParams()
get vector of all constant parameters
Definition: Measurement.h:60
std::vector< RooStats::HistFactory::Channel > & GetChannels()
Definition: Measurement.h:105
std::vector< RooStats::HistFactory::PreprocessFunction > & GetFunctionObjects()
get vector of defined function objects
Definition: Measurement.h:75
std::vector< RooStats::HistFactory::OverallSys > & GetOverallSysList()
Definition: Sample.h:108
const TH1 * GetHisto() const
Definition: Sample.cxx:88
RooStats::HistFactory::StatError & GetStatError()
Definition: Sample.h:124
std::string GetChannelName() const
get name of associated channel
Definition: Sample.h:102
std::vector< RooStats::HistFactory::NormFactor > & GetNormFactorList()
Definition: Sample.h:109
std::vector< RooStats::HistFactory::HistoSys > & GetHistoSysList()
Definition: Sample.h:110
bool GetNormalizeByTheory() const
does the normalization scale with luminosity
Definition: Sample.h:78
const TH1 * GetErrorHist() const
Definition: Systematics.h:352
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
const Int_t n
Definition: legend1.C:16
std::string Name(Type type)
Definition: Systematics.cxx:27
static constexpr double s
static constexpr double ns