Jpp 20.0.0-rc.6
the software that should make you happy
Loading...
Searching...
No Matches
JGen2UpperLimit.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <chrono>
5#include <vector>
6#include <map>
7#include <exception>
8#include <algorithm>
9
10#include "TROOT.h"
11#include "TFile.h"
12#include "TH1D.h"
13#include "TH2D.h"
14#include "TH3D.h"
15#include "TRandom3.h"
16
17#include "JAstronomy/JGen2.hh"
18#include "JAstronomy/JGarage.hh"
20
23#include "JROOT/JRandom.hh"
24
25#include "Jeep/JContainer.hh"
26#include "Jeep/JParser.hh"
27
28
29namespace {
30
31 /**
32 * Auxiliary data structure for experiment.
33 */
34 struct experiment_type {
35
36 JGIZMO::JRootObjectID HS; //!< signal for generation
37 JGIZMO::JRootObjectID HB; //!< background for generation
38 JGIZMO::JRootObjectID Hs; //!< signal for evaluation
39 JGIZMO::JRootObjectID Hb; //!< background for evaluation
40
42
43 /**
44 * Read experiment from input stream.
45 *
46 * \param in input stream
47 * \param experiment experiment
48 * \return input stream
49 */
50 friend inline std::istream& operator>>(std::istream& in, experiment_type& experiment)
51 {
52 return in >> experiment.HS
53 >> experiment.HB
54 >> experiment.Hs
55 >> experiment.Hb
56 >> experiment.nuisance;
57 }
58
59
60 /**
61 * Write experiment to output stream.
62 *
63 * \param out output stream
64 * \param experiment experiment
65 * \return output stream
66 */
67 friend inline std::ostream& operator<<(std::ostream& out, const experiment_type& experiment)
68 {
69 return out << experiment.HS << ' '
70 << experiment.HB << ' '
71 << experiment.Hs << ' '
72 << experiment.Hb << ' '
73 << experiment.nuisance;
74 }
75 };
76
77
78 /**
79 * Auxiliary data structure for printing.
80 */
81 struct printer {
82 /**
83 * Constructor.
84 *
85 * \param title title
86 * \param ps pointer to object
87 */
88 printer(const char* const title,
89 const TObject* ps) :
90 title(title),
91 ps(ps)
92 {}
93
94 /**
95 * Write printer to output stream.
96 *
97 * \param out output stream
98 * \param printer printer
99 * \return output stream
100 */
101 friend inline std::ostream& operator<<(std::ostream& out, const printer& printer)
102 {
103 using namespace std;
104 using namespace JPP;
105
106 out << setw(16) << left << printer.title << right;
107
108 if (printer.ps != NULL) {
109
110 out << ' ' << setw(16) << left << printer.ps->GetName() << right;
111
112 const TH1* h1 = dynamic_cast<const TH1*>(printer.ps);
113
114 if (h1 != NULL) {
115 out << ' ' << FIXED(10,3) << h1->GetSumOfWeights();
116 }
117 }
118
119 return out;
120 }
121
122 private:
123 const char* const title;
124 const TObject* ps;
125 };
126}
127
128
129/**
130 * \file
131 * Test application for pseudo experiment generation and likelihood ratio evaluations.
132 *
133 * \author mdejong
134 */
135int main(int argc, char **argv)
136{
137 using namespace std;
138 using namespace JPP;
139
140 typedef JAbstractHistogram<double> histogram_type;
141
143 string outputFile;
144 size_t numberOfTests;
145 size_t M;
146 double SNR;
147 histogram_type X;
148 JRandom seed;
149 double precision;
150 int debug;
151
152 try {
153
154 JParser<> zap;
155
157
158 zap['E'] = make_field(setup,
159 "douplets of signal and background histograms and doublets of signal and background nuisances, \n"
160 << "\teach of which defined by <file name>:<histogram name> and <type> (values), respectively, \n"
161 << "\twhere <type> can be:" << get_keys(px.nuisance.signal.getDictionary()));
162 zap['o'] = make_field(outputFile, "output file with histograms") = "benchmark.root";
163 zap['n'] = make_field(numberOfTests, "number of tests");
164 zap['M'] = make_field(M, "lookup table for CDFs") = 0;
165 zap['R'] = make_field(SNR, "signal-to-noise ratio") = 0.0;
166 zap['x'] = make_field(X, "x-axis likelihood histogram") = histogram_type(100, -1.0e3, +1.0e3);
167 zap['p'] = make_field(precision, "precision") = 1.0e-4;
168 zap['S'] = make_field(seed) = 0;
169 zap['d'] = make_field(debug) = 1;
170
171 zap(argc, argv);
172 }
173 catch(const exception& error) {
174 FATAL(error.what() << endl);
175 }
176
177
178 seed.set(gRandom);
179
180 JExperiment::setSNR(SNR);
181
182 const double Q = 0.9; // probability limit
183 const double MUMIN = 1.0e-10; // minimal signal
184 const double MUMAX = 1.0e+10; // maximal signal
185 const size_t N = numberOfTests * 5; // statistics for probability calculation
186
187 JGen2 px;
188
189 for (const auto& i : setup) {
190
191 const TObject* pS = getObject(i.HS);
192 const TObject* pB = getObject(i.HB);
193 const TObject* ps = getObject(i.Hs);
194 const TObject* pb = getObject(i.Hb);
195
196 STATUS(printer("Signal for generation:", pS) << endl);
197 STATUS(printer("Background for generation:", pB) << endl);
198 STATUS(printer("Signal for evaluation:", ps) << endl);
199 STATUS(printer("Background for evaluation:", pb) << endl);
200
201 JPseudoExperiment pi(pS, pB, ps, pb);
202
203 pi.nuisance = i.nuisance;
204
205 px.push_back(pi);
206 }
207
208 if (M != 0) {
209 px.configure(M);
210 }
211
212 STATUS("Signal: " << FIXED(10,3) << px.getSignal() << endl);
213 STATUS("Background: " << FIXED(10,3) << px.getBackground() << endl);
214 STATUS("Number of tests: " << setw(10) << numberOfTests << endl);
215
216
217 TFile out(outputFile.c_str(), "recreate");
218
219 out << *gRandom;
220
221 TH1D h0("h0", NULL, X.getNumberOfBins(), X.getLowerLimit(), X.getUpperLimit());
222 TH1D h1("h1", NULL, X.getNumberOfBins(), X.getLowerLimit(), X.getUpperLimit());
223
224
225 // generate background only pseudo experiments and store fitted signals
226
227 px.set(0.0);
228
229 const JPseudoExperiment::h0_type mu_0(px, numberOfTests);
230
231 for (const double x : mu_0) {
232 h0.Fill(x);
233 }
234
235
236 vector<double> mu_up;
237
238 for (size_t i = 0; i != numberOfTests; ++i) {
239
240 if ((i*10) < numberOfTests || (i*10)%numberOfTests == 0) {
241 STATUS(setw(6) << i << '\r'); DEBUG(endl);
242 }
243
244 JAspera aspera;
245
246 px.set(0.0);
247
248 px.run(aspera);
249
250 const JAspera::fit_type result = aspera(true);
251
252 DEBUG("pseudo experiment " << setw(3) << aspera.size() << ' ' << FIXED(12,5) << result.signal << ' ' << FIXED(12,5) << result.likelihood << endl);
253
254 double mu = 0.0;
255
256 if (mu_0.getFractionBelow(result.signal) > 1.0 - Q) {
257
258 double mumin = 1.0;
259 double mumax = 1.0;
260
261 {
262 for ( ; ; mumax *= 2.0) {
263
264 const double ts = aspera.getTestStatisticForUpperLimit(mumax);
265
266 px.set(mumax);
267
268 const double ps = px.getProbabilityForUpperLimit(mumax, ts, N);
269
270 DEBUG("maximal value " << SCIENTIFIC(12,3) << mumax << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
271
272 if (ps < 1.0 - Q || mumax > MUMAX) {
273 break;
274 }
275 }
276 }
277
278 if (mumax == 1.0) {
279
280 mumin = 0.5*mumax;
281
282 for ( ; ; mumin *= 0.5) {
283
284 const double ts = aspera.getTestStatisticForUpperLimit(mumin);
285
286 px.set(mumin);
287
288 const double ps = px.getProbabilityForUpperLimit(mumin, ts, N);
289
290 DEBUG("minimal value " << SCIENTIFIC(12,3) << mumin << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
291
292 if (ps > 1.0 - Q || mumin < MUMIN) {
293 break;
294 }
295 }
296
297 mumax = 2.0*mumin;
298
299 } else {
300
301 mumin = 0.5*mumax;
302 }
303
304 if (mumin < MUMIN)
305 mu = mumin;
306 else if (mumax > MUMAX)
307 mu = mumax;
308 else {
309
310 for ( ; ; ) { // binary search
311
312 mu = 0.5 * (mumin + mumax);
313
314 const double ts = aspera.getTestStatisticForUpperLimit(mu);
315
316 px.set(mu);
317
318 const double ps = px.getProbabilityForUpperLimit(mu, ts, N);
319
320 DEBUG("current value " << SCIENTIFIC(12,3) << mu << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
321
322 if (fabs(ps - (1.0 - Q)) <= precision) {
323 break;
324 }
325
326 if (ps >= 1.0 - Q)
327 mumin = mu;
328 else
329 mumax = mu;
330 }
331 }
332 }
333
334 mu_up.push_back(mu);
335 }
336 STATUS(endl);
337
338 for (const double x : mu_up) {
339 h1.Fill(x);
340 }
341
342 sort(mu_up.begin(), mu_up.end());
343
344 cout << "<mu> " << FIXED(7,3) << mu_up[mu_up.size() / 2] << endl;
345
346 out.Write();
347 out.Close();
348}
349
Container I/O.
string outputFile
int main(int argc, char **argv)
Set of pseudo experments.
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition JHead.hh:1850
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define STATUS(A)
Definition JMessage.hh:63
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Auxiliary class to handle file name, ROOT directory and object name.
Utility class to parse command line options.
Definition JParser.hh:1698
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
JWriter & operator<<(JWriter &out, const JDAQChronometer &chronometer)
Write DAQ chronometer to output.
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Auxiliary data structure to fit signal strength using likelihood ratio.
Definition JAspera.hh:24
double getTestStatisticForUpperLimit(const double ps) const
Get test statistic for given signal strength.
Definition JAspera.hh:218
Auxiliary data structure to fit signal strength using likelihood ratio for multiple pseudo experiment...
Definition JGen2.hh:28
virtual stats_type run(JAspera &out) const
Generate pseudo experiment and transfer S/N values to fit method.
Definition JGen2.hh:95
double getSignal() const
Get total signal.
Definition JGen2.hh:47
virtual void set(const double fS, const double fB=1.0) override
Set scaling factors of signal and background strengths.
Definition JGen2.hh:70
void configure(size_t N)
Configure lookup tables.
Definition JGen2.hh:34
double getBackground() const
Get total background.
Definition JGen2.hh:58
dictionary_type & getDictionary()
Get dictionary.
Definition JNuisance.hh:372
double getProbabilityForUpperLimit(const double ps, const double ts, const size_t nx) const
Get probability for given pseudo experiment and signal strength to exceed minimal test statistic for ...
Pseudo experiment using CDF for combined generation and likelihood evaluation.
struct JASTRONOMY::JPseudoExperiment::parameters_type nuisance
Auxiliary wrapper for I/O of container with optional comment (see JComment).
Definition JContainer.hh:42
Template definition of random value generator.
Simple data structure for histogram binning.
Auxiliary data structure for floating point format specification.
Definition JManip.hh:488