Jpp 20.0.0-rc.6
the software that should make you happy
Loading...
Searching...
No Matches
JPseudoExperimentUpperLimit.cc File Reference

Test application for pseudo experiment generation and upper limit evaluations. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <vector>
#include <map>
#include <exception>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TH3D.h"
#include "TRandom3.h"
#include "JAstronomy/JPseudoExperiment.hh"
#include "JAstronomy/JGarage.hh"
#include "JAstronomy/JAstronomyToolkit.hh"
#include "JLang/JVectorize.hh"
#include "JGizmo/JGizmoToolkit.hh"
#include "JTools/JAbstractHistogram.hh"
#include "JROOT/JRandom.hh"
#include "JMath/JMathSupportkit.hh"
#include "Jeep/JContainer.hh"
#include "Jeep/JParser.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Test application for pseudo experiment generation and upper limit evaluations.

Author
mdejong

Definition in file JPseudoExperimentUpperLimit.cc.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 127 of file JPseudoExperimentUpperLimit.cc.

128{
129 using namespace std;
130 using namespace JPP;
131
132 typedef JAbstractHistogram<double> histogram_type;
133
135 string outputFile;
136 size_t numberOfTests;
137 double boost;
138 size_t M;
139 double SNR;
140 histogram_type X;
141 JRandom seed;
142 double precision;
143 int debug;
144
145 try {
146
147 JParser<> zap;
148
149 zap['E'] = make_field(setup,
150 "douplets of signal and background histograms, "
151 << "each of which defined by <file name>:<histogram name>");
152 zap['o'] = make_field(outputFile, "output file with histograms") = "benchmark.root";
153 zap['n'] = make_field(numberOfTests, "number of tests");
154 zap['B'] = make_field(boost, "boost livetime of experiment") = 1.0;
155 zap['M'] = make_field(M, "lookup table for CDFs") = 0;
156 zap['R'] = make_field(SNR, "signal-to-noise ratio") = 0.0;
157 zap['x'] = make_field(X, "x-axis signal histogram") = histogram_type(100, -1.0e3, +1.0e3);
158 zap['p'] = make_field(precision, "precision") = 1.0e-4;
159 zap['S'] = make_field(seed) = 0;
160 zap['d'] = make_field(debug) = 1;
161
162 zap(argc, argv);
163 }
164 catch(const exception& error) {
165 FATAL(error.what() << endl);
166 }
167
168
169 seed.set(gRandom);
170
171 JExperiment::setSNR(SNR);
172
173 const double Q = 0.9; // probability limit
174 const double MUMIN = 1.0e-10; // minimal signal
175 const double MUMAX = 1.0e+10; // maximal signal
176 const size_t N = numberOfTests * 5; // statistics for probability calculation
177
179
180 for (const auto& i : setup) {
181
182 TObject* ps = getObject(i.Hs);
183 TObject* pb = getObject(i.Hb);
184
185 dynamic_cast<TH1*>(ps)->Scale(boost);
186 dynamic_cast<TH1*>(pb)->Scale(boost);
187
188 STATUS(printer("Signal:", ps) << endl);
189 STATUS(printer("Background:", pb) << endl);
190
191 px.add(ps, pb);
192 }
193
194 if (M != 0) {
195 px.configure(M);
196 }
197
198 STATUS("Signal: " << FIXED(10,3) << px.getSignal() << endl);
199 STATUS("Background: " << FIXED(10,3) << px.getBackground() << endl);
200 STATUS("Number of tests: " << setw(10) << numberOfTests << endl);
201
202
203 TFile out(outputFile.c_str(), "recreate");
204
205 out << *gRandom;
206
207 TH1D h0("h0", NULL, X.getNumberOfBins(), X.getLowerLimit(), X.getUpperLimit());
208 TH1D h1("h1", NULL, X.getNumberOfBins(), X.getLowerLimit(), X.getUpperLimit());
209
210
211 // generate background only pseudo experiments and store fitted signals
212
213 px.set(0.0);
214
215 const JPseudoExperiment::h0_type mu_0(px, numberOfTests);
216
217 for (const double x : mu_0) {
218 h0.Fill(x);
219 }
220
221
222 vector<double> mu_up;
223
224 for (size_t i = 0; i != numberOfTests; ++i) {
225
226 if ((i*10) < numberOfTests || (i*10)%numberOfTests == 0) {
227 STATUS(setw(6) << i << '\r'); DEBUG(endl);
228 }
229
230 JAspera aspera;
231
232 px.set(0.0);
233
234 px.run(aspera);
235
236 const JAspera::fit_type result = aspera(true);
237
238 DEBUG("pseudo experiment " << setw(3) << aspera.size() << ' ' << FIXED(12,5) << result.signal << ' ' << FIXED(12,5) << result.likelihood << endl);
239
240 double mu = 0.0;
241
242 if (mu_0.getFractionBelow(result.signal) > 1.0 - Q) {
243
244 double mumin = 1.0;
245 double mumax = 1.0;
246
247 {
248 for ( ; ; mumax *= 2.0) {
249
250 const double ts = aspera.getTestStatisticForUpperLimit(mumax);
251
252 px.set(mumax);
253
254 const double ps = px.getProbabilityForUpperLimit(mumax, ts, N);
255
256 DEBUG("maximal value " << SCIENTIFIC(12,3) << mumax << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
257
258 if (ps < 1.0 - Q || mumax > MUMAX) {
259 break;
260 }
261 }
262 }
263
264 if (mumax == 1.0) {
265
266 mumin = 0.5*mumax;
267
268 for ( ; ; mumin *= 0.5) {
269
270 const double ts = aspera.getTestStatisticForUpperLimit(mumin);
271
272 px.set(mumin);
273
274 const double ps = px.getProbabilityForUpperLimit(mumin, ts, N);
275
276 DEBUG("minimal value " << SCIENTIFIC(12,3) << mumin << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
277
278 if (ps > 1.0 - Q || mumin < MUMIN) {
279 break;
280 }
281 }
282
283 mumax = 2.0*mumin;
284
285 } else {
286
287 mumin = 0.5*mumax;
288 }
289
290 if (mumin < MUMIN)
291 mu = mumin;
292 else if (mumax > MUMAX)
293 mu = mumax;
294 else {
295
296 for ( ; ; ) { // binary search
297
298 mu = 0.5 * (mumin + mumax);
299
300 const double ts = aspera.getTestStatisticForUpperLimit(mu);
301
302 px.set(mu);
303
304 const double ps = px.getProbabilityForUpperLimit(mu, ts, N);
305
306 DEBUG("current value " << SCIENTIFIC(12,3) << mu << ' ' << FIXED(12,5) << ts << ' ' << FIXED(12,5) << ps << endl);
307
308 if (fabs(ps - (1.0 - Q)) <= precision) {
309 break;
310 }
311
312 if (ps >= 1.0 - Q)
313 mumin = mu;
314 else
315 mumax = mu;
316 }
317 }
318 }
319
320 mu_up.push_back(mu);
321 }
322 STATUS(endl);
323
324 for (const double x : mu_up) {
325 h1.Fill(x);
326 }
327
328 sort(mu_up.begin(), mu_up.end());
329
330 cout << "<mu> " << FIXED(7,3) << mu_up[mu_up.size() / 2] << endl;
331
332 out.Write();
333 out.Close();
334}
string outputFile
#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
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Utility class to parse command line options.
Definition JParser.hh:1698
TObject * getObject(const JRootObjectID &id)
Get first TObject with given identifier.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
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
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.
void add(const TObject *ps, const TObject *pb)
Add objects with PDFs of signal and background.
virtual stats_type run(JAspera &out) const
Generate pseudo experiment and transfer values to fit method.
double getSignal() const
Get total signal.
virtual void set(const double fS, const double fB=1.0) override
Set scaling factors of signal and background strengths.
double getBackground() const
Get total background.
void configure(size_t N)
Configure lookup tables.
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