Jpp test-rotations-old-533-g2bdbdb559
the software that should make you happy
Loading...
Searching...
No Matches
JPseudoExperiment.hh
Go to the documentation of this file.
1#ifndef __JASTRONOMY__JPSEUDOEXPERIMENT__
2#define __JASTRONOMY__JPSEUDOEXPERIMENT__
3
4#include <istream>
5#include <ostream>
6#include <vector>
7
8#include "TObject.h"
9#include "TH1.h"
10#include "TH2.h"
11#include "TH3.h"
12#include "TRandom3.h"
13
14#include "JLang/JException.hh"
15
17#include "JAstronomy/JAspera.hh"
19
20
21/**
22 * \file
23 *
24 * Pseudo experiment.
25 * \author mdejong
26 */
27namespace JASTRONOMY {}
28namespace JPP { using namespace JASTRONOMY; }
29
30namespace JASTRONOMY {
31
32
34
35 /**
36 * Auxiliary interface for pseudo experiment.
37 */
39 public JExperiment
40 {
41 /**
42 * Statistics of pseudo experiment.
43 */
44 struct stats_type {
45
47 {
48 this->ns += px.ns;
49 this->nb += px.nb;
50
51 return *this;
52 }
53
54 size_t ns = 0; //!< number of generated signal events
55 size_t nb = 0; //!< number of generated background events
56 };
57
58
59 typedef JAspera::fit_type fit_type; //!< fit type
60
61
62 /**
63 * Result of combined pseudo experiment and fit.
64 */
65 struct result_type :
66 public stats_type,
67 public fit_type
68 {};
69
70
71 /**
72 * Get fit method.
73 *
74 * \return fit
75 */
76 virtual JAspera& getAspera() = 0;
77
78
79 /*
80 * Generate pseudo experiment and transfer S/N values to fit method.
81 *
82 * \param out output
83 * \return result
84 */
85 virtual stats_type run(JAspera& out) const = 0;
86
87
88 /**
89 * Generate pseudo experiment and fit signal strength.
90 *
91 * \return result
92 */
94 {
95 JAspera& aspera = getAspera();
96
97 // reset
98
99 aspera.clear();
100 aspera.setSignal(0.0);
101
102 return { run(aspera), aspera() };
103 }
104
105
106 /**
107 * Run pseudo experiments using given storage.
108 *
109 * \param storage storage
110 */
112 {
113 for (auto& i : storage) {
114 i = (*this)();
115 }
116 }
117
118
119 /**
120 * Run pseudo experiments using given storage.
121 *
122 * \param pm pointer to data member of result
123 * \param storage storage
124 */
125 template<class T, class JValue_t>
126 inline void operator()(JValue_t result_type::*pm, std::vector<T>& storage)
127 {
128 for (auto& i : storage) {
129 i = (*this)().*pm;
130 }
131 }
132
133
134 /**
135 * Run pseudo experiments using given storage.
136 *
137 * \param pm pointer to data member of result
138 * \param storage storage
139 */
140 template<class T, class JValue_t>
141 inline void operator()(JValue_t JAspera::fit_type::*pm, std::vector<T>& storage)
142 {
143 (*this)(static_cast<JValue_t result_type::*>(pm), storage);
144 }
145 };
146
147
148 /**
149 * Pseudo experiment using CDF for combined generation and likelihood evaluation.
150 */
153 {
154 /**
155 * Default constructor.
156 */
159
160
161 /**
162 * Constructor.
163 *
164 * \param hs histogram with PDF of signal
165 * \param hb histogram with PDF of background
166 */
167 template<class H_t>
168 JPseudoExperiment(const H_t& hs,
169 const H_t& hb)
170 {
171 add(hs, hb);
172 }
173
174
175 /**
176 * Constructor.
177 *
178 * \param hS histogram with PDF for generation of signal
179 * \param hB histogram with PDF for generation of background
180 * \param hs histogram with PDF for evaluation of signal
181 * \param hb histogram with PDF for evaluation of background
182 */
183 template<class H_t>
184 JPseudoExperiment(const H_t& hS,
185 const H_t& hB,
186 const H_t& hs,
187 const H_t& hb)
188 {
189 add(hS, hB, hs, hb);
190 }
191
192
193 /**
194 * Add objects with PDFs of signal and background.
195 *
196 * \param ps pointer to object with PDF of signal
197 * \param pb pointer to object with PDF of background
198 */
199 void add(const TObject* ps,
200 const TObject* pb)
201 {
202 if (add<TH3>(ps, pb)) { return; }
203 if (add<TH2>(ps, pb)) { return; }
204 if (add<TH1>(ps, pb)) { return; }
205 }
206
207
208 /**
209 * Add objects with PDFs of signal and background.
210 *
211 * \param pS pointer to object with PDF for generation of signal
212 * \param pB pointer to object with PDF for generation of background
213 * \param ps pointer to object with PDF for evaluation of signal
214 * \param pb pointer to object with PDF for evaluation of background
215 */
216 void add(const TObject* pS,
217 const TObject* pB,
218 const TObject* ps,
219 const TObject* pb)
220 {
221 if (add<TH3>(pS, pB, ps, pb)) { return; }
222 if (add<TH2>(pS, pB, ps, pb)) { return; }
223 if (add<TH1>(pS, pB, ps, pb)) { return; }
224 }
225
226
227 /**
228 * Add histograms with PDFs of signal and background.
229 *
230 * \param hs histogram with PDF of signal
231 * \param hb histogram with PDF of background
232 */
233 void add(const TH1& hs,
234 const TH1& hb)
235 {
236 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
237 add(hs.GetBinContent(ix),
238 hb.GetBinContent(ix));
239 }
240 }
241
242
243 /**
244 * Add histograms with PDFs of signal and background.
245 *
246 * \param hS histogram with PDF for generation of signal
247 * \param hB histogram with PDF for generation of background
248 * \param hs histogram with PDF for evaluation of signal
249 * \param hb histogram with PDF for evaluation of background
250 */
251 void add(const TH1& hS,
252 const TH1& hB,
253 const TH1& hs,
254 const TH1& hb)
255 {
256 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
257 add(hS.GetBinContent(ix),
258 hB.GetBinContent(ix),
259 hs.GetBinContent(ix),
260 hb.GetBinContent(ix));
261 }
262 }
263
264
265 /**
266 * Add histograms with PDFs of signal and background.
267 *
268 * \param hs histogram with PDF of signal
269 * \param hb histogram with PDF of background
270 */
271 void add(const TH2& hs,
272 const TH2& hb)
273 {
274 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
275 for (Int_t iy = 1; iy <= hs.GetYaxis()->GetNbins(); ++iy) {
276 add(hs.GetBinContent(ix, iy),
277 hb.GetBinContent(ix, iy));
278 }
279 }
280 }
281
282
283 /**
284 * Add histograms with PDFs of signal and background.
285 *
286 * \param hS histogram with PDF for generation of signal
287 * \param hB histogram with PDF for generation of background
288 * \param hs histogram with PDF for evaluation of signal
289 * \param hb histogram with PDF for evaluation of background
290 */
291 void add(const TH2& hS,
292 const TH2& hB,
293 const TH2& hs,
294 const TH2& hb)
295 {
296 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
297 for (Int_t iy = 1; iy <= hs.GetYaxis()->GetNbins(); ++iy) {
298 add(hS.GetBinContent(ix, iy),
299 hB.GetBinContent(ix, iy),
300 hs.GetBinContent(ix, iy),
301 hb.GetBinContent(ix, iy));
302 }
303 }
304 }
305
306
307 /**
308 * Add histograms with PDFs of signal and background.
309 *
310 * \param hs histogram with PDF of signal
311 * \param hb histogram with PDF of background
312 */
313 void add(const TH3& hs,
314 const TH3& hb)
315 {
316 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
317 for (Int_t iy = 1; iy <= hs.GetYaxis()->GetNbins(); ++iy) {
318 for (Int_t iz = 1; iz <= hs.GetZaxis()->GetNbins(); ++iz) {
319 add(hs.GetBinContent(ix, iy, iz),
320 hb.GetBinContent(ix, iy, iz));
321 }
322 }
323 }
324 }
325
326
327 /**
328 * Add histograms with PDFs of signal and background.
329 *
330 * \param hS histogram with PDF for generation of signal
331 * \param hB histogram with PDF for generation of background
332 * \param hs histogram with PDF for evaluation of signal
333 * \param hb histogram with PDF for evaluation of background
334 */
335 void add(const TH3& hS,
336 const TH3& hB,
337 const TH3& hs,
338 const TH3& hb)
339 {
340 for (Int_t ix = 1; ix <= hs.GetXaxis()->GetNbins(); ++ix) {
341 for (Int_t iy = 1; iy <= hs.GetYaxis()->GetNbins(); ++iy) {
342 for (Int_t iz = 1; iz <= hs.GetZaxis()->GetNbins(); ++iz) {
343 add(hS.GetBinContent(ix, iy, iz),
344 hB.GetBinContent(ix, iy, iz),
345 hs.GetBinContent(ix, iy, iz),
346 hb.GetBinContent(ix, iy, iz));
347 }
348 }
349 }
350 }
351
352
353 /**
354 * Add signal and background.
355 *
356 * \param s signal
357 * \param b background
358 */
359 void add(const double s,
360 const double b)
361 {
362 if (check(s, b)) {
363
364 cs.put(s);
365 cb.put(b);
366
367 aspera.put(s, b);
368 }
369 }
370
371
372 /**
373 * Add signal and background.
374 *
375 * \param S signal for generation
376 * \param B background for generation
377 * \param s signal for evaluation
378 * \param b background for evaluation
379 */
380 void add(const double S,
381 const double B,
382 const double s,
383 const double b)
384 {
385 if (//check(S, B) &&
386 check(s, b)) {
387
388 cs.put(S);
389 cb.put(B);
390
391 aspera.put(s, b);
392 }
393 }
394
395
396 /**
397 * Get total signal.
398 *
399 * \return signal
400 */
401 double getSignal() const
402 {
403 return cs.back() * this->fs;
404 }
405
406
407 /**
408 * Get total background.
409 *
410 * \return background
411 */
412 double getBackground() const
413 {
414 return cb.back() * this->fb;
415 }
416
417
418 /**
419 * Set scaling factors of signal and background strengths.
420 *
421 * \param fS signal strength
422 * \param fB background strength
423 */
424 void set(const double fS, const double fB)
425 {
426 for (auto& i : aspera) {
427 i *= fB / this->fb;
428 }
429
430 this->fs = fS;
431 this->fb = fB;
432 }
433
434
435 /**
436 * Get fit method.
437 *
438 * \return fit
439 */
440 virtual JAspera& getAspera() override
441 {
442 return this->fit;
443 }
444
445
446 /*
447 * Generate pseudo experiment and transfer values to fit method.
448 *
449 * \param out output
450 * \return result
451 */
452 virtual stats_type run(JAspera& out) const
453 {
455
456 const size_t ns = gRandom->Poisson(getSignal() * nuisance.signal ->get()); // number of signal events
457 const size_t nb = gRandom->Poisson(getBackground() * nuisance.background->get()); // number of background events
458
459 for (size_t i = ns; i != 0; --i) { out.push_back(aspera[cs.get_index(gRandom->Rndm())]); } // store distributed signal events
460 for (size_t i = nb; i != 0; --i) { out.push_back(aspera[cb.get_index(gRandom->Rndm())]); } // store distributed background events
461
462 return { ns, nb };
463 }
464
465
466 /**
467 * Nuisance parameters.
468 */
470
471 /**
472 * Read parameters from input stream.
473 *
474 * \param in input stream
475 * \param parameters parameters
476 * \return input stream
477 */
478 friend inline std::istream& operator>>(std::istream& in, parameters_type& parameters)
479 {
480 return in >> parameters.signal
481 >> parameters.background;
482 }
483
484
485 /**
486 * Write parameters to output stream.
487 *
488 * \param out output stream
489 * \param parameters parameters
490 * \return output stream
491 */
492 friend inline std::ostream& operator<<(std::ostream& out, const parameters_type& parameters)
493 {
494 return out << parameters.signal << ' '
495 << parameters.background;
496 }
497
500
502
503 protected:
504 /**
505 * Add objects with PDF of signal and background.
506 *
507 * \param ps pointer to object with PDF of signal
508 * \param pb pointer to object with PDF of background
509 * \return true if added; else false
510 */
511 template<class H_t>
512 bool add(const TObject* ps,
513 const TObject* pb)
514 {
515 if (dynamic_cast<const H_t*>(ps) != NULL &&
516 dynamic_cast<const H_t*>(pb) != NULL) {
517
518 const H_t& hs = dynamic_cast<const H_t&>(*ps);
519 const H_t& hb = dynamic_cast<const H_t&>(*pb);
520
521 if (check(hs, hb)) {
522
523 add(hs, hb);
524
525 return true;
526 }
527 }
528
529 return false;
530 }
531
532
533 /**
534 * Add objects with PDF of signal and background.
535 *
536 * \param pS pointer to object with PDF for generation of signal
537 * \param pB pointer to object with PDF for generation of background
538 * \param ps pointer to object with PDF for evaluation of signal
539 * \param pb pointer to object with PDF for evaluation of background
540 * \return true if added; else false
541 */
542 template<class H_t>
543 bool add(const TObject* pS,
544 const TObject* pB,
545 const TObject* ps,
546 const TObject* pb)
547 {
548 if (dynamic_cast<const H_t*>(pS) != NULL &&
549 dynamic_cast<const H_t*>(pB) != NULL &&
550 dynamic_cast<const H_t*>(ps) != NULL &&
551 dynamic_cast<const H_t*>(pb) != NULL) {
552
553 const H_t& hS = dynamic_cast<const H_t&>(*pS);
554 const H_t& hB = dynamic_cast<const H_t&>(*pB);
555 const H_t& hs = dynamic_cast<const H_t&>(*ps);
556 const H_t& hb = dynamic_cast<const H_t&>(*pb);
557
558 if (check(hS, hB) && check(hB, hs) && check(hs, hb)) {
559
560 add(hS, hB, hs, hb);
561
562 return true;
563 }
564 }
565
566 return false;
567 }
568
569
570 /**
571 * Auxiliary data structure for CDF.
572 */
573 struct cdf_type :
574 public std::vector<double>
575 {
576 /**
577 * Get index corresponding to given random value.
578 *
579 * \param rv random value [0,1>
580 * \return index
581 */
582 inline size_t get_index(const double rv) const
583 {
584 const double value = this->back() * rv;
585
586 size_t first = 0;
587 size_t count = this->size();
588
589 for (size_t i, step; count != 0; ) {
590
591 step = count / 2;
592 i = first + step;
593
594 if ((*this)[i] < value) {
595 first = ++i;
596 count -= step + 1;
597 } else {
598 count = step;
599 }
600 }
601
602 return first;
603 }
604
605
606 /**
607 * Put given value.
608 *
609 * \param x value
610 */
611 void put(const double x)
612 {
613 if (this->empty())
614 this->push_back(x);
615 else
616 this->push_back(this->back() + x);
617 }
618 };
619
620
621 cdf_type cs; //!< CDF of signal
622 cdf_type cb; //!< CDF of background
623
624 JAspera aspera; //!< pre-computed N/S values
625
626 double fs = 1.0; //!< scaling factor signal strength
627 double fb = 1.0; //!< scaling factor background strength
628
629 JAspera fit; //!< fit
630 };
631}
632
633#endif
Per aspera ad astra.
Exceptions.
Experiment.
Nuisance parameter.
Exception for accessing a value in a collection that is outside of its range.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure to fit signal strength using likelihood ratio.
Definition JAspera.hh:24
void addSignal(const double wS)
Add signal strength.
Definition JAspera.hh:220
double getSignal() const
Get total signal strength.
Definition JAspera.hh:198
void setSignal(const double wS)
Set signal strength.
Definition JAspera.hh:209
void put(const double s, const double b)
Put signal and background to list of pre-computed N/S values.
Definition JAspera.hh:44
Auxiliary base class for experiment.
static bool check(const double s, const double b)
Check validity of signal and background.
Helper for nuisance I/O.
Definition JNuisance.hh:349
Auxiliary data structure for CDF.
void put(const double x)
Put given value.
size_t get_index(const double rv) const
Get index corresponding to given random value.
friend std::ostream & operator<<(std::ostream &out, const parameters_type &parameters)
Write parameters to output stream.
friend std::istream & operator>>(std::istream &in, parameters_type &parameters)
Read parameters from input stream.
Result of combined pseudo experiment and fit.
size_t ns
number of generated signal events
size_t nb
number of generated background events
stats_type & operator+=(const stats_type &px)
Auxiliary interface for pseudo experiment.
result_type operator()()
Generate pseudo experiment and fit signal strength.
virtual JAspera & getAspera()=0
Get fit method.
void operator()(JValue_t JAspera::fit_type::*pm, std::vector< T > &storage)
Run pseudo experiments using given storage.
void operator()(JValue_t result_type::*pm, std::vector< T > &storage)
Run pseudo experiments using given storage.
void operator()(std::vector< result_type > &storage)
Run pseudo experiments using given storage.
virtual stats_type run(JAspera &out) const =0
JAspera::fit_type fit_type
fit type
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.
struct JASTRONOMY::JPseudoExperiment::parameters_type nuisance
virtual stats_type run(JAspera &out) const
void add(const TH3 &hS, const TH3 &hB, const TH3 &hs, const TH3 &hb)
Add histograms with PDFs of signal and background.
void add(const TH1 &hS, const TH1 &hB, const TH1 &hs, const TH1 &hb)
Add histograms with PDFs of signal and background.
bool add(const TObject *ps, const TObject *pb)
Add objects with PDF of signal and background.
virtual JAspera & getAspera() override
Get fit method.
bool add(const TObject *pS, const TObject *pB, const TObject *ps, const TObject *pb)
Add objects with PDF of signal and background.
double getSignal() const
Get total signal.
void add(const TH2 &hS, const TH2 &hB, const TH2 &hs, const TH2 &hb)
Add histograms with PDFs of signal and background.
void add(const TH3 &hs, const TH3 &hb)
Add histograms with PDFs of signal and background.
JPseudoExperiment(const H_t &hS, const H_t &hB, const H_t &hs, const H_t &hb)
Constructor.
void set(const double fS, const double fB)
Set scaling factors of signal and background strengths.
double fb
scaling factor background strength
cdf_type cb
CDF of background.
void add(const double S, const double B, const double s, const double b)
Add signal and background.
void add(const TH2 &hs, const TH2 &hb)
Add histograms with PDFs of signal and background.
JPseudoExperiment(const H_t &hs, const H_t &hb)
Constructor.
JAspera aspera
pre-computed N/S values
double getBackground() const
Get total background.
void add(const TObject *pS, const TObject *pB, const TObject *ps, const TObject *pb)
Add objects with PDFs of signal and background.
void add(const TH1 &hs, const TH1 &hb)
Add histograms with PDFs of signal and background.
double fs
scaling factor signal strength
void add(const double s, const double b)
Add signal and background.
JPseudoExperiment()
Default constructor.