Jpp 20.0.0-rc.9-29-gccc23c492-D
the software that should make you happy
Loading...
Searching...
No Matches
JShower3EZRegressor.hh
Go to the documentation of this file.
1#ifndef __JFIT__JSHOWER3EZREGRESSOR__
2#define __JFIT__JSHOWER3EZREGRESSOR__
3
4#include <array>
5
6#include "JPhysics/JPDFTypes.hh"
7#include "JPhysics/JPDFTable.hh"
8#include "JPhysics/JPDFToolkit.hh"
9#include "JPhysics/JNPETable.hh"
10
11#include "JTools/JFunction1D_t.hh"
12#include "JTools/JFunctionalMap_t.hh"
13#include "JPhysics/JConstants.hh"
14#include "JTools/JRange.hh"
15#include "JTools/JResult.hh"
16#include "JTools/JFunction1D_t.hh"
17#include "JTools/JFunctionalMap_t.hh"
18#include "JTools/JAbstractHistogram.hh"
19
20#include "JGeometry3D/JVector3D.hh"
21#include "JGeometry3D/JVersor3D.hh"
22#include "JGeometry3D/JDirection3D.hh"
23
24#include "JMath/JZero.hh"
25
26#include "JFit/JTimeRange.hh"
27#include "JFit/JPMTW0.hh"
28#include "JFit/JSimplex.hh"
29#include "JFit/JGandalf.hh"
30#include "JFit/JMEstimator.hh"
31#include "JFit/JRegressor.hh"
32#include "JFit/JShower3EZ.hh"
33#include "JFit/JFitToolkit.hh"
34#include "JFit/JLine3Z.hh"
35
36#include "Jeep/JMessage.hh"
37
38/**
39 * \file
40 * Data regression method for JFIT::JShower3EZ.
41 * \author mdejong, vcarretero
42 */
43
44
45namespace JFIT {
46
47 using JPHYSICS::JPDFType_t;
48 using JPHYSICS::DIRECT_LIGHT_FROM_EMSHOWER;
49 using JPHYSICS::SCATTERED_LIGHT_FROM_EMSHOWER;
50 using JTOOLS::get_value;
51
52 /**
53 * Constrain PMT angle to [0,pi].
54 *
55 * \param angle angle [rad]
56 * \return angle [rad]
57 */
58 inline double getPMTAngle(const double angle)
59 {
60 const double epsilon = 1.0e-6;
61 const JTOOLS::JRange<double> range(epsilon, JMATH::PI - epsilon);
62
63 return range.constrain(fabs(angle));
64 }
65
66
67 /**
68 * Function to constrain the versor and energy during the fit, to prevent unphysical values.
69 *
70 * \param value model (I/O)
71 */
72 void model(JShower3EZ& value)
73 {
74 using namespace std;
75
76
77 double Tx = value.getDX();
78 double Ty = value.getDY();
79 double E = max(0.0,value.getE());
80 const double u = hypot(Tx, Ty);
81
82 if (u > 1.0) {
83 Tx /= u;
84 Ty /= u;
85 }
86
87 value = JShower3EZ(static_cast<const JPoint4D&>(value), JVersor3Z(Tx,Ty), E, value.getBy());
88
89 }
90
91 /**
92 * Template specialisation for storage of PDF tables.
93 */
94 template<>
96 {
97 typedef JTOOLS::JPolint1Function1D_t JFunction1D_t;
98 typedef JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
99 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
100 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap,
101 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap> > > > JPDFMaplist_t;
102 typedef JPHYSICS::JPDFTable<JFunction1D_t, JPDFMaplist_t> JPDF_t;
103
104 typedef JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
105 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
106 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap,
107 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap> > > > JNPEMaplist_t;
108 typedef JPHYSICS::JNPETable<double, double, JNPEMaplist_t> JNPE_t;
109
110
111 static const int NUMBER_OF_PDFS = 2;
112
113 typedef std::array<JNPE_t, NUMBER_OF_PDFS> JNPEs_t; //!< NPEs
114
115 /**
116 * Default constructor.
117 */
120
121 /**
122 * Constructor
123 *
124 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
125 * will be replaced by the corresponding PDF types listed in JRegressorStorage<JShower3Z, JSimplex>::pdf_t.
126 *
127 * \param T_ns time range [ns]
128 * \param fileDescriptor PDF file descriptor
129 */
130
131 JRegressorStorage(const std::string& fileDescriptor, const JTimeRange& T_ns):
132 T_ns(T_ns)
133 {
134 using namespace std;
135 using namespace JPP;
136
137 const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(JMATH::zero));
138
139 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
140
141 const string file_name = getFilename(fileDescriptor, pdf_t[i]);
142
143 JPDF_t _pdf;
144 _pdf.load(file_name.c_str());
145
146 _pdf.setExceptionHandler(supervisor);
147
148 _npe[ i ] = JNPE_t(_pdf, T_ns);
149 }
150 // Add NPEs
151 for (int i = 1; i < NUMBER_OF_PDFS; i += 2) {
152
153 _npe[ i ].add(_npe[i-1]);
154
155 JNPE_t buffer;
156
157 _npe[i-1].swap(buffer);
158 }
159 }
160
161
162
163 /**
164 * Get NPEs.
165 *
166 * \return PDFs
167 */
168 const JNPEs_t& getNPE() const
169 {
170 return _npe;
171 }
172
173 /**
174 * PDF types.
175 */
176 static const JPDFType_t pdf_t[NUMBER_OF_PDFS];
177 JTimeRange T_ns; //!< Time window with respect to Cherenkov hypothesis [ns]
178
179 private:
180 JNPEs_t _npe; //!< PDFs
181 };
182
183 /**
184 * PDF types.
185 */
187 DIRECT_LIGHT_FROM_EMSHOWER,
188 SCATTERED_LIGHT_FROM_EMSHOWER
189 };
190
191 /**
192 * Regressor function object for JShower3EZ fit using JGandalf minimiser.
193 */
194 template<>
196 public JAbstractRegressor<JShower3EZ, JSimplex>,
197 public JRegressorStorage <JShower3EZ, JSimplex>
198 {
199 using JAbstractRegressor<JShower3EZ, JSimplex>::operator();
200
202
203 /**
204 * Default constructor
205 */
207 storage_type(),
208 npe(getNPE()),
209 estimator()
210 {}
211
212 /**
213 * Constructor.
214 *
215 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
216 * will be replaced by the PDF types listed in JRegressorStorage<JShower3EZ, JSimplex>::pdf_t.
217 *
218 * \param fileDescriptor PDF file descriptor
219 * \param T_ns time range [ns]
220 */
221 JRegressor(const std::string& fileDescriptor, const JTimeRange& T_ns) :
222 storage_type(fileDescriptor, T_ns),
223 npe(getNPE()),
224 estimator(new JMEstimatorNull())
225 {}
226
227 /**
228 * Constructor.
229 *
230 * \param storage PDF storage
231 */
232 JRegressor(const storage_type& storage) :
233 npe(storage.getNPE()),
234 estimator(new JMEstimatorNull())
235 {
236 T_ns = storage.T_ns;
237 }
238
239
240 /**
241 * Fit function.
242 * This method is used to determine the chi2 of given PMT with respect to shower hypothesis.
243 *
244 * \param shower shower
245 * \param pmt pmt
246 * \return chi2
247 */
248 double operator()(const JShower3EZ& shower, const JPMTW0& pmt) const
249 {
250 using namespace JPP;
251
252 JPosition3D D(pmt.getPosition());
253 JDirection3D U(pmt.getDirection());
254
255 D.sub(shower.getPosition());
256
257 const double z = D.getDot(shower.getDirection());
258 const double x = D.getX();
259 const double y = D.getY();
260 const double cd = z/D.getLength(); // cosine angle between shower direction and PMT position
261
262 U.rotate(JRotation3Z(-atan2(y,x))); // rotate PMT axis to x-z plane
263
264 const double theta = getPMTAngle(U.getTheta());
265 const double phi = getPMTAngle(U.getPhi());
266
267 JNPE_t::result_type H0 = getH0(pmt.getR()); // background hypothesis value for time integrated PDF.
268 JNPE_t::result_type H1 = getH1(D.getLength(), cd, theta, phi, shower.getE()); // signal hypothesis value for time integrated PDF.
269
270 if (get_value(H1) >= Vmax_npe) {
271 H1 *= Vmax_npe / get_value(H1);
272 }
273
274 H1 += H0; // now H1 is signal + background
275
276 const bool hit = pmt.getN() != 0;
277 const double u = getChi2(get_value(H1), hit) - getChi2(get_value(H0), hit); // - log likelihood ratio
278
279 return estimator->getRho(u);
280 }
281
282 /**
283 * Get background hypothesis value for time integrated PDF.
284 *
285 * \param R_Hz rate [Hz]
286 * \return hypothesis value
287 */
288 JNPE_t::result_type getH0(const double R_Hz) const
289 {
290 return JNPE_t::result_type(R_Hz * 1e-9 * T_ns.getLength());
291 }
292
293 /**
294 * Get signal hypothesis value for time integrated PDF.
295 *
296 * \param D PMT distance from shower [m]
297 * \param cd cosine angle between shower direction and PMT position
298 * \param theta PMT zenith angle [deg]
299 * \param phi PMT azimuth angle [deg]
300 * \param E shower energy [GeV]
301 * \return hypothesis value
302 */
303 JNPE_t::result_type getH1(const double D,
304 const double cd,
305 const double theta,
306 const double phi,
307 const double E) const
308 {
309 JNPE_t::result_type h1 = JMATH::zero;
310
311 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
312
313 if (!npe[i].empty() && D <= npe[i].getXmax()) {
314
315 try {
316
317 JNPE_t::result_type y1 = E * npe[i](std::max(D, npe[i].getXmin()), cd, theta, phi);
318
319 // safety measure
320
321 if(y1 < 0){
322 y1 = 0;
323 }
324
325 h1 += y1;
326
327 }
328 catch(JLANG::JException& error) {
329 ERROR(error << std::endl);
330 }
331 }
332 }
333
334 return h1;
335 }
336
337
338 static double Vmax_npe; //!< Maximal integral of PDF [npe]
339
340 const JNPEs_t& npe;
341
342 std::shared_ptr<JMEstimator> estimator; //!< M-Estimator function
343 };
344
345 /**
346 * Template specialisation for storage of PDF tables.
347 */
348 template<>
350 {
351 typedef JTOOLS::JPolint1Function1D_t JFunction1D_t;
352 typedef JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
353 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
354 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap,
355 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap> > > > JPDFMaplist_t;
356 typedef JPHYSICS::JPDFTable<JFunction1D_t, JPDFMaplist_t> JPDF_t;
357
358 typedef JTOOLS::JMapList<JTOOLS::JPolint1FunctionalMap,
359 JTOOLS::JMapList<JTOOLS::JPolint1FunctionalMapH,
360 JTOOLS::JMapList<JTOOLS::JPolint1FunctionalGridMap,
361 JTOOLS::JMapList<JTOOLS::JPolint1FunctionalGridMap> > > > JNPEMaplist_t;
362 typedef JPHYSICS::JNPETable<double, double, JNPEMaplist_t> JNPE_t;
363
364
365 static const int NUMBER_OF_PDFS = 2;
366
367 typedef std::array<JNPE_t, NUMBER_OF_PDFS> JNPEs_t; //!< NPEs
368
369 /**
370 * Default constructor.
371 */
374
375 /**
376 * Parameterized constructor
377 *
378 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
379 * will be replaced by the corresponding PDF types listed in JRegressorStorage<JShower3Z, JGandalf>::pdf_t.
380 *
381 * \param fileDescriptor PDF file descriptor
382 * \param T_ns time range [ns]
383
384 */
385
386 JRegressorStorage(const std::string& fileDescriptor, const JTimeRange& T_ns):
387 T_ns(T_ns)
388 {
389 using namespace std;
390 using namespace JPP;
391
392 const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(JMATH::zero));
393
394 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
395
396 const string file_name = getFilename(fileDescriptor, pdf_t[i]);
397
398 JPDF_t _pdf;
399 _pdf.load(file_name.c_str());
400
401 _pdf.setExceptionHandler(supervisor);
402
403 _npe[i] = JNPE_t(_pdf, T_ns);
404
405 }
406
407 // Add PDFs
408 for (int i = 1; i < NUMBER_OF_PDFS; i += 2) {
409
410 _npe[ i ].add(_npe[i-1]);
411
412 JNPE_t buffer;
413
414 _npe[i-1].swap(buffer);
415 }
416 }
417
418
419 /**
420 * Get NPEs.
421 *
422 * \return PDFs
423 */
424 const JNPEs_t& getNPE() const
425 {
426 return _npe;
427 }
428
429 /**
430 * PDF types.
431 */
432 static const JPDFType_t pdf_t[NUMBER_OF_PDFS];
433 JTimeRange T_ns; //!< Time window with respect to Cherenkov hypothesis [ns]
434
435 private:
436 JNPEs_t _npe; //!< PDFs
437 };
438
439 /**
440 * PDF types.
441 */
443 DIRECT_LIGHT_FROM_EMSHOWER,
444 SCATTERED_LIGHT_FROM_EMSHOWER
445 };
446
447 /**
448 * Regressor function object for JShower3EZ fit using JGandalf minimiser.
449 */
450 template<>
452 public JAbstractRegressor<JShower3EZ, JGandalf>,
453 public JRegressorStorage <JShower3EZ, JGandalf>
454 {
455 using JAbstractRegressor<JShower3EZ, JGandalf>::operator();
456
458
459 /**
460 * Default constructor
461 */
463 storage_type(),
464 npe(getNPE()),
465 estimator()
466 {}
467
468 /**
469 * Constructor.
470 *
471 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
472 * will be replaced by the PDF types listed in JRegressorStorage<JShower3EZ, JSimplex>::pdf_t.
473 *
474 * \param fileDescriptor PDF file descriptor
475 * \param T_ns time range [ns]
476 */
477 JRegressor(const std::string& fileDescriptor, const JTimeRange& T_ns) :
478 storage_type(fileDescriptor, T_ns),
479 npe(getNPE()),
480 estimator(new JMEstimatorNull())
481 {}
482
483 /**
484 * Constructor.
485 *
486 * \param storage PDF storage
487 */
488 JRegressor(const storage_type& storage) :
489 npe(storage.getNPE()),
490 estimator(new JMEstimatorNull())
491 {
492 T_ns = storage.T_ns;
493 }
494
495
496 /**
497 * Fit function.
498 * This method is used to determine the chi2 of given PMT with respect to shower hypothesis.
499 *
500 * \param shower shower
501 * \param pmt pmt
502 * \return chi2
503 */
504 result_type operator()(const JShower3EZ& shower, const JPMTW0& pmt) const
505 {
506 using namespace JPP;
507 using namespace std;
508
509 JPosition3D D(pmt.getPosition());
510 JDirection3D U(pmt.getDirection());
511
512 D.sub(shower.getPosition());
513
514 const double x = D.getX();
515 const double y = D.getY();
516 const double d = D.getLength();
517 const double cd = D.getDot(shower.getDirection())/d; // cosine angle between shower direction and PMT position
518
519 U.rotate(JRotation3Z(-atan2(y,x))); // rotate PMT axis to x-z plane
520
521 const double theta = getPMTAngle(U.getTheta());
522 const double phi = getPMTAngle(U.getPhi());
523
524 JNPE_t::result_type H0 = getH0(pmt.getR()); // background hypothesis value for time integrated PDF.
525 JNPE_t::result_type H1 = getH1(d, cd, theta, phi, shower.getE()); // signal hypothesis value for time integrated PDF.
526
527 if (get_value(H1) >= Vmax_npe) {
528 H1 *= Vmax_npe / get_value(H1);
529 }
530
531 double signal_npe = get_value(H1);
532
533 H1 += H0; // now H1 is signal + background
534
535 double expectation = get_value(H1);
536
537 const bool hit = pmt.getN() != 0;
538 const double u = H1.getChi2(hit) - H0.getChi2(hit);
539
540 result_type result;
541
542 result.chi2 = estimator->getRho(u);
543
544 double energy_gradient = signal_npe/shower.getE(); // dP/dE
545 if(hit) energy_gradient *= -exp(-expectation)/(1-exp(-expectation)); //dchi2/d(H1), if !hit is 1
546
547 result.gradient = JShower3EZ(JPoint4D(JVector3D(0, // d(cos_th0)/d(x)
548 0, // d(cos_th0)/d(y)
549 0), // d(cos_th0)/d(z)
550 0.0), // d(cos_th0)/d(t)
551 JVersor3Z(x/d, // d(cos_th0)/d(dx)
552 y/d), // d(cos_th0)/d(dy)
553 energy_gradient); // d(chi2)/d(E)
554
555 result.gradient.mul(estimator->getPsi(u));
556 static_cast<JShower3Z&>(result.gradient).mul(H1.getDerivativeOfChi2(hit) - H0.getDerivativeOfChi2(hit)); // x d(chi2)/d(cos_th0)
557
558 return result;
559 }
560
561 /**
562 * Get background hypothesis value for time integrated PDF.
563 *
564 * \param R_Hz rate [Hz]
565 * \return hypothesis value
566 */
567 JNPE_t::result_type getH0(const double R_Hz) const
568 {
569 return JNPE_t::result_type(R_Hz * 1e-9 * T_ns.getLength(), 0.0);
570 }
571
572 /**
573 * Get signal hypothesis value for time integrated PDF.
574 *
575 * \param D PMT distance from shower [m]
576 * \param cd cosine angle between shower direction and PMT position
577 * \param theta PMT zenith angle [deg]
578 * \param phi PMT azimuth angle [deg]
579 * \param E shower energy [GeV]
580 * \return hypothesis value
581 */
582 JNPE_t::result_type getH1(const double D,
583 const double cd,
584 const double theta,
585 const double phi,
586 const double E) const
587 {
588 JNPE_t::result_type h1 = JMATH::zero;
589
590 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
591
592 if (!npe[i].empty() && D <= npe[i].getXmax()) {
593
594 try {
595
596 JNPE_t::result_type y1 = E * npe[i](std::max(D, npe[i].getXmin()), cd, theta, phi);
597
598 if (get_value(y1) > 0.0) {
599 h1 += y1;
600 }
601
602 }
603 catch(JLANG::JException& error) {
604 ERROR(error << std::endl);
605 }
606 }
607 }
608
609 return h1;
610 }
611
612
613 static double Vmax_npe; //!< Maximal integral of PDF [npe]
614
615 const JNPEs_t& npe;
616
617 std::shared_ptr<JMEstimator> estimator; //!< M-Estimator function
618 };
619
620
621
622 /**
623 * Template specialisation for storage of PDF tables.
624 */
625 template<>
627 {
628 typedef JTOOLS::JPolint1Function1D_t JFunction1D_t;
629 typedef JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
630 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
631 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap,
632 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap> > > > JPDFMaplist_t;
633 typedef JPHYSICS::JPDFTable<JFunction1D_t, JPDFMaplist_t> JPDF_t;
634
635 typedef JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
636 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalMap,
637 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap,
638 JTOOLS::JMapList<JTOOLS::JPolint0FunctionalGridMap> > > > JNPEMaplist_t;
639 typedef JPHYSICS::JNPETable<double, double, JNPEMaplist_t> JNPE_t;
640
641
642 static const int NUMBER_OF_PDFS = 2;
643
644 typedef std::array<JNPE_t, NUMBER_OF_PDFS> JNPEs_t; //!< NPEs
645
646 /**
647 * Default constructor.
648 */
651
652 /**
653 * Parameterized constructor
654 *
655 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
656 * will be replaced by the corresponding PDF types listed in JRegressorStorage<JShower3Z, JAbstractMinimiser>::pdf_t.
657 *
658 * \param fileDescriptor PDF file descriptor
659 * \param T_ns time range [ns]
660
661 */
662
663 JRegressorStorage(const std::string& fileDescriptor, const JTimeRange& T_ns):
664 T_ns(T_ns)
665 {
666 using namespace std;
667 using namespace JPP;
668
669 const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(JMATH::zero));
670
671 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
672
673 const string file_name = getFilename(fileDescriptor, pdf_t[i]);
674
675 JPDF_t _pdf;
676 _pdf.load(file_name.c_str());
677
678 _pdf.setExceptionHandler(supervisor);
679
680 _npe[i] = JNPE_t(_pdf, T_ns);
681
682 }
683
684 // Add PDFs
685 for (int i = 1; i < NUMBER_OF_PDFS; i += 2) {
686
687 _npe[i].add(_npe[i-1]);
688
689 JNPE_t buffer;
690
691 _npe[i-1].swap(buffer);
692 }
693 }
694
695
696
697 /**
698 * Get NPEs.
699 *
700 * \return PDFs
701 */
702 const JNPEs_t& getNPE() const
703 {
704 return _npe;
705 }
706
707 /**
708 * PDF types.
709 */
710 static const JPDFType_t pdf_t[NUMBER_OF_PDFS];
711 JTimeRange T_ns; //!< Time window with respect to Cherenkov hypothesis [ns]
712
713 private:
714 JNPEs_t _npe; //!< PDFs
715 };
716
717 /**
718 * PDF types.
719 */
721 DIRECT_LIGHT_FROM_EMSHOWER,
722 SCATTERED_LIGHT_FROM_EMSHOWER
723 };
724
725 /**
726 * Regressor function object for JShower3EZ fit using JGandalf minimiser.
727 */
728 template<>
730 public JAbstractRegressor<JShower3EZ, JAbstractMinimiser>,
731 public JRegressorStorage <JShower3EZ, JAbstractMinimiser>
732 {
734
736
737 /**
738 * Default constructor
739 */
741 storage_type(),
742 npe(getNPE()),
743 estimator()
744 {}
745
746 /**
747 * Constructor.
748 *
749 * The PDF file descriptor should contain the wild card character JPHYSICS::WILDCARD which
750 * will be replaced by the PDF types listed in JRegressorStorage<JShower3EZ, JSimplex>::pdf_t.
751 *
752 * \param fileDescriptor PDF file descriptor
753 * \param T_ns time range [ns]
754
755 */
756 JRegressor(const std::string& fileDescriptor, const JTimeRange& T_ns) :
757 storage_type(fileDescriptor, T_ns),
758 npe(getNPE()),
759 estimator(new JMEstimatorNull())
760 {}
761
762 /**
763 * Constructor.
764 *
765 * \param storage PDF storage
766 */
767 JRegressor(const storage_type& storage) :
768 npe(storage.getNPE()),
769 estimator(new JMEstimatorNull())
770 {
771 T_ns = storage.T_ns;
772 }
773
774 /**
775 * Fit function.
776 * This method is used to determine the chi2 of given PMT with respect to shower hypothesis.
777 *
778 * \param shower shower
779 * \param pmt pmt
780 * \return chi2
781 */
782 double operator()(const JShower3EZ& shower, const JPMTW0& pmt) const
783 {
784 using namespace JPP;
785
786 JPosition3D D(pmt.getPosition());
787 JDirection3D U(pmt.getDirection());
788
789 D.sub(shower.getPosition());
790
791 const double z = D.getDot(shower.getDirection());
792 const double x = D.getX();
793 const double y = D.getY();
794 const double cd = z/D.getLength(); // cosine angle between shower direction and PMT position
795
796 U.rotate(JRotation3Z(-atan2(y,x))); // rotate PMT axis to x-z plane
797
798 const double theta = getPMTAngle(U.getTheta());
799 const double phi = getPMTAngle(U.getPhi());
800
801 JNPE_t::result_type H0 = getH0(pmt.getR()); // background hypothesis value for time integrated PDF.
802 JNPE_t::result_type H1 = getH1(D.getLength(), cd, theta, phi, shower.getE()); // signal hypothesis value for time integrated PDF.
803
804 if (get_value(H1) >= Vmax_npe) {
805 H1 *= Vmax_npe / get_value(H1);
806 }
807
808 H1 += H0; // now H1 is signal + background
809
810 const bool hit = pmt.getN() != 0;
811 const double u = getChi2(get_value(H1), hit) - getChi2(get_value(H0), hit); // -log likelihood ratio
812
813 return estimator->getRho(u);
814 }
815
816 /**
817 * Get background hypothesis value for time integrated PDF.
818 *
819 * \param R_Hz rate [Hz]
820 * \return hypothesis value
821 */
822 JNPE_t::result_type getH0(const double R_Hz) const
823 {
824 return JNPE_t::result_type(R_Hz * 1e-9 * T_ns.getLength());
825 }
826
827 /**
828 * Get signal hypothesis value for time integrated PDF.
829 *
830 * \param D PMT distance from shower [m]
831 * \param cd cosine angle between shower direction and PMT position
832 * \param theta PMT zenith angle [deg]
833 * \param phi PMT azimuth angle [deg]
834 * \param E shower energy [GeV]
835 * \return hypothesis value
836 */
837 JNPE_t::result_type getH1(const double D,
838 const double cd,
839 const double theta,
840 const double phi,
841 const double E) const
842 {
843 JNPE_t::result_type h1 = JMATH::zero;
844
845 for (int i = 0; i != NUMBER_OF_PDFS; ++i) {
846
847 if (!npe[i].empty() && D <= npe[i].getXmax()) {
848
849 try {
850
851 JNPE_t::result_type y1 = E * npe[i](std::max(D, npe[i].getXmin()), cd, theta, phi);
852
853 // safety measure
854
855 if(y1 < 0){
856 y1 = 0;
857 }
858
859 h1 += y1;
860
861 }
862 catch(JLANG::JException& error) {
863 ERROR(error << std::endl);
864 }
865 }
866 }
867
868 return h1;
869 }
870
871 /**
872 * Get signal hypothesis value for time integrated PDF.
873 *
874 * \param shower shower
875 * \param pmt pmt
876 * \return hypothesis value
877 */
878 JNPE_t::result_type getH1(const JShower3EZ& shower, const JPMTW0& pmt) const
879 {
880 using namespace JPP;
881
882 JPosition3D D(pmt.getPosition());
883 JDirection3D U(pmt.getDirection());
884
885
886 const double z = D.getDot(shower.getDirection());
887 const double x = D.getX();
888 const double y = D.getY();
889 const double cd = z/D.getLength(); // cosine angle between shower direction and PMT position
890
891 U.rotate(JRotation3Z(-atan2(y,x))); // rotate PMT axis to x-z plane
892
893 const double theta = getPMTAngle(U.getTheta());
894 const double phi = getPMTAngle(U.getPhi());
895
896 JNPE_t::result_type H1 = getH1(D.getLength(), cd, theta, phi, 1.0); // signal hypothesis value for time integrated PDF. E=1 because it is linear with E.
897
898 if (get_value(H1) >= Vmax_npe) {
899 H1 *= Vmax_npe / get_value(H1);
900 }
901
902 return H1;
903 }
904 static double Vmax_npe; //!< Maximal integral of PDF [npe]
905
906 const JNPEs_t& npe;
907
908 std::shared_ptr<JMEstimator> estimator; //!< M-Estimator function
909 };
910
911 /**
912 * Default values.
913 */
914 double JRegressor<JShower3EZ, JSimplex>::Vmax_npe = std::numeric_limits<double>::max();
915
916 double JRegressor<JShower3EZ, JGandalf>::Vmax_npe = std::numeric_limits<double>::max();
917
918 double JRegressor<JShower3EZ, JAbstractMinimiser>::Vmax_npe = std::numeric_limits<double>::max();
919
920
921
922}
923
924#endif
Auxiliary methods to evaluate Poisson probabilities and chi2.
Maximum likelihood estimator (M-estimators).
General purpose data regression method.
Abstract minimiser.
Definition JRegressor.hh:27
Fit method based on the Levenberg-Marquardt method.
Definition JGandalf.hh:87
Data structure for vertex fit.
Definition JPoint4D.hh:24
Data structure for fit of straight line in positive z-direction with energy.
Definition JShower3EZ.hh:30
double getBy() const
Get bjorken y.
Definition JShower3EZ.hh:76
double getE() const
Get E.
Definition JShower3EZ.hh:86
Data structure for cascade in positive z-direction.
Definition JShower3Z.hh:36
Simple fit method based on Powell's algorithm, see reference: Numerical Recipes in C++,...
Definition JSimplex.hh:44
Auxiliary classes and methods for linear and iterative data regression.
Definition JEnergy.hh:15
double getPMTAngle(const double angle)
Constrain PMT angle to [0,pi].
double getChi2(const double P)
Get chi2 corresponding to given probability.
void model(JModel_t &value)
Auxiliary function to constrain model during fit.
Definition JGandalf.hh:57
Abstract class for global fit method.
Definition JRegressor.hh:79
Data structure for return value of fit function.
Definition JGandalf.hh:102
JModel_t gradient
partial derivatives of chi2
Definition JGandalf.hh:137
Null M-estimator.
Auxiliary class for handling PMT geometry, rate and response.
Definition JPMTW0.hh:24
int getN() const
Get number of hits.
Definition JPMTW0.hh:67
double getR() const
Get rate.
Definition JPMTW0.hh:56
Template specialisation for storage of PDF tables.
JPHYSICS::JPDFTable< JFunction1D_t, JPDFMaplist_t > JPDF_t
JTimeRange T_ns
Time window with respect to Cherenkov hypothesis [ns].
JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap > > > > JPDFMaplist_t
JPHYSICS::JNPETable< double, double, JNPEMaplist_t > JNPE_t
JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap > > > > JNPEMaplist_t
JRegressorStorage(const std::string &fileDescriptor, const JTimeRange &T_ns)
Parameterized constructor.
Template specialisation for storage of PDF tables.
JTimeRange T_ns
Time window with respect to Cherenkov hypothesis [ns].
JPHYSICS::JPDFTable< JFunction1D_t, JPDFMaplist_t > JPDF_t
JPHYSICS::JNPETable< double, double, JNPEMaplist_t > JNPE_t
std::array< JNPE_t, NUMBER_OF_PDFS > JNPEs_t
NPEs.
JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap > > > > JPDFMaplist_t
JRegressorStorage(const std::string &fileDescriptor, const JTimeRange &T_ns)
Parameterized constructor.
JTOOLS::JMapList< JTOOLS::JPolint1FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint1FunctionalMapH, JTOOLS::JMapList< JTOOLS::JPolint1FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint1FunctionalGridMap > > > > JNPEMaplist_t
Template specialisation for storage of PDF tables.
JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap > > > > JNPEMaplist_t
JPHYSICS::JPDFTable< JFunction1D_t, JPDFMaplist_t > JPDF_t
std::array< JNPE_t, NUMBER_OF_PDFS > JNPEs_t
NPEs.
JPHYSICS::JNPETable< double, double, JNPEMaplist_t > JNPE_t
JTimeRange T_ns
Time window with respect to Cherenkov hypothesis [ns].
JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap, JTOOLS::JMapList< JTOOLS::JPolint0FunctionalGridMap > > > > JPDFMaplist_t
JRegressorStorage(const std::string &fileDescriptor, const JTimeRange &T_ns)
Constructor.
Template data structure for storage of internal data.
JNPE_t::result_type getH1(const double D, const double cd, const double theta, const double phi, const double E) const
Get signal hypothesis value for time integrated PDF.
static double Vmax_npe
Maximal integral of PDF [npe].
double operator()(const JShower3EZ &shower, const JPMTW0 &pmt) const
Fit function.
JRegressor(const std::string &fileDescriptor, const JTimeRange &T_ns)
Constructor.
JRegressorStorage< JShower3EZ, JAbstractMinimiser > storage_type
JNPE_t::result_type getH1(const JShower3EZ &shower, const JPMTW0 &pmt) const
Get signal hypothesis value for time integrated PDF.
JNPE_t::result_type getH0(const double R_Hz) const
Get background hypothesis value for time integrated PDF.
std::shared_ptr< JMEstimator > estimator
M-Estimator function
JRegressor(const storage_type &storage)
Constructor.
static double Vmax_npe
Maximal integral of PDF [npe].
JRegressor(const std::string &fileDescriptor, const JTimeRange &T_ns)
Constructor.
result_type operator()(const JShower3EZ &shower, const JPMTW0 &pmt) const
Fit function.
JNPE_t::result_type getH0(const double R_Hz) const
Get background hypothesis value for time integrated PDF.
JRegressorStorage< JShower3EZ, JGandalf > storage_type
JRegressor(const storage_type &storage)
Constructor.
JNPE_t::result_type getH1(const double D, const double cd, const double theta, const double phi, const double E) const
Get signal hypothesis value for time integrated PDF.
std::shared_ptr< JMEstimator > estimator
M-Estimator function.
JRegressor(const std::string &fileDescriptor, const JTimeRange &T_ns)
Constructor.
std::shared_ptr< JMEstimator > estimator
M-Estimator function.
static double Vmax_npe
Maximal integral of PDF [npe].
JNPE_t::result_type getH0(const double R_Hz) const
Get background hypothesis value for time integrated PDF.
JNPE_t::result_type getH1(const double D, const double cd, const double theta, const double phi, const double E) const
Get signal hypothesis value for time integrated PDF.
double operator()(const JShower3EZ &shower, const JPMTW0 &pmt) const
Fit function.
JRegressorStorage< JShower3EZ, JSimplex > storage_type
JRegressor(const storage_type &storage)
Constructor.
Template definition of a data regressor of given model.
Definition JRegressor.hh:70