Jpp  18.2.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JFitK40.hh
Go to the documentation of this file.
1 #ifndef __JCALIBRATE_JGANDALFK40__
2 #define __JCALIBRATE_JGANDALFK40__
3 
4 #include <vector>
5 #include <map>
6 #include <memory>
7 #include <limits>
8 #include <cmath>
9 
11 
12 #include "JLang/JException.hh"
13 #include "JLang/JManip.hh"
14 
15 #include "JTools/JRange.hh"
16 
17 #include "JDetector/JModule.hh"
18 
19 #include "JMath/JVectorND.hh"
20 #include "JMath/JMatrixNS.hh"
21 #include "JMath/JMath.hh"
22 #include "JMath/JGauss.hh"
23 #include "JMath/JMathToolkit.hh"
24 
25 #include "JFit/JMEstimator.hh"
26 
28 #include "JCalibrate/JTDC_t.hh"
29 
30 
31 /**
32  * \author mdejong
33  */
34 
35 namespace JCALIBRATE {}
36 namespace JPP { using namespace JCALIBRATE; }
37 
38 namespace JCALIBRATE {
39 
42  using JDETECTOR::JModule;
43  using JMATH::JMath;
44  using JFIT::JMEstimator;
45 
46 
47  /**
48  * Fit options.
49  */
50  enum JOption_t {
51  FIT_PMTS_t = 1, //!< fit parameters of PMTs
52  FIT_MODEL_t = 2, //!< fit parameters of K40 rate and TTSs of PMTs
53  FIT_PMTS_AND_ANGULAR_DEPENDENCE_t = 3 //!< fit parameters of PMTs and angular dependence of K40 rate
54  };
55 
56  static const int INVALID_INDEX = -1; //!< invalid index
57 
58 
59  /**
60  * Data structure for measured coincidence rate of pair of PMTs.
61  */
62  struct rate_type {
63  /**
64  * Default constructor.
65  */
67  dt_ns(0.0),
68  value(0.0),
69  error(0.0)
70  {}
71 
72 
73  /**
74  * Constructor.
75  *
76  * \param dt_ns time difference [ns]
77  * \param value value of rate [Hz/ns]
78  * \param error error of rate [Hz/ns]
79  */
80  rate_type(double dt_ns,
81  double value,
82  double error) :
83  dt_ns(dt_ns),
84  value(value),
85  error(error)
86  {}
87 
88 
89  double dt_ns;
90  double value;
91  double error;
92  };
93 
94 
95  /**
96  * Data structure for measured coincidence rates of all pairs of PMTs in optical module.
97  */
98  struct data_type :
99  public std::map<pair_type, std::vector<rate_type> >
100  {};
101 
102 
103  /**
104  * Auxiliary class for fit parameter with optional limits.
105  */
106  class JParameter_t :
107  public JMath<JParameter_t>
108  {
109  public:
110  /**
111  * Fit options.
112  */
113  enum FIT_t {
114  FREE_t = 0, //!< free
115  FIXED_t //!< fixed
116  };
117 
118 
119  /**
120  * Type definition for range of parameter values.
121  */
123 
124 
125  /**
126  * Default constructor.
127  */
129  {
130  set(0.0);
131  }
132 
133 
134  /**
135  * Constructor.
136  *
137  * \param value value
138  * \param range range
139  */
140  JParameter_t(const double value,
142  range(range)
143  {
144  set(value);
145  }
146 
147 
148  /**
149  * Negate parameter.
150  *
151  * \return this parameter
152  */
154  {
155  set(-get());
156 
157  return *this;
158  }
159 
160 
161  /**
162  * Add parameter.
163  *
164  * \param parameter parameter
165  * \return this parameter
166  */
167  JParameter_t& add(const JParameter_t& parameter)
168  {
169  set(get() + parameter.get());
170 
171  return *this;
172  }
173 
174 
175  /**
176  * Subtract parameter.
177  *
178  * \param parameter parameter
179  * \return this parameter
180  */
181  JParameter_t& sub(const JParameter_t& parameter)
182  {
183  set(get() - parameter.get());
184 
185  return *this;
186  }
187 
188 
189  /**
190  * Scale parameter.
191  *
192  * \param factor multiplication factor
193  * \return this parameter
194  */
195  JParameter_t& mul(const double factor)
196  {
197  set(get() * factor);
198 
199  return *this;
200  }
201 
202 
203  /**
204  * Scale parameter.
205  *
206  * \param factor division factor
207  * \return this parameter
208  */
209  JParameter_t& div(const double factor)
210  {
211  set(get() / factor);
212 
213  return *this;
214  }
215 
216 
217  /**
218  * Scale parameter.
219  *
220  * \param first first parameter
221  * \param second second parameter
222  * \return this parameter
223  */
225  {
226  set(first.get() * second.get());
227 
228  return *this;
229  }
230 
231 
232  /**
233  * Check if parameter is free.
234  *
235  * \return true if free; else false
236  */
237  bool isFree() const
238  {
239  return option == FREE_t;
240  }
241 
242 
243  /**
244  * Check if parameter is fixed.
245  *
246  * \return true if fixed; else false
247  */
248  bool isFixed() const
249  {
250  return option == FIXED_t;
251  }
252 
253 
254  /**
255  * Check if parameter is bound.
256  *
257  * \return true if bound; else false
258  */
259  bool isBound() const
260  {
261  return range.is_valid();
262  }
263 
264 
265  /**
266  * Set current value.
267  */
268  void set()
269  {
270  option = FREE_t;
271  }
272 
273 
274  /**
275  * Fix current value.
276  */
277  void fix()
278  {
279  option = FIXED_t;
280  }
281 
282 
283  /**
284  * Get value.
285  *
286  * \return value
287  */
288  double get() const
289  {
290  if (isBound())
291  return range.getLowerLimit() + 0.5 * range.getLength() * (sin(value) + 1.0);
292  else
293  return value;
294  }
295 
296 
297  /**
298  * Set value.
299  *
300  * \param value value
301  */
302  void set(const double value)
303  {
304  if (isBound())
305  this->value = asin(2.0 * (range.constrain(value) - range.getLowerLimit()) / range.getLength() - 1.0);
306  else
307  this->value = value;
308 
309  set();
310  }
311 
312 
313  /**
314  * Fix value.
315  *
316  * \param value value
317  */
318  void fix(const double value)
319  {
320  set(value);
321 
322  fix();
323  }
324 
325 
326  /**
327  * Get derivative of value.
328  *
329  * \return derivative of value
330  */
331  double getDerivative() const
332  {
333  if (isBound())
334  return 0.5 * range.getLength() * cos(value);
335  else
336  return 1.0;
337  }
338 
339 
340  /**
341  * Type conversion operator.
342  *
343  * \return value
344  */
345  double operator()() const
346  {
347  return get();
348  }
349 
350 
351  /**
352  * Type conversion operator.
353  *
354  * \return value
355  */
356  operator double() const
357  {
358  return get();
359  }
360 
361 
362  /**
363  * Assignment operator.
364  *
365  * \param value value
366  * \return this parameter
367  */
368  JParameter_t& operator=(double value)
369  {
370  set(value);
371 
372  return *this;
373  }
374 
375 
376  /**
377  * Read parameter from input stream.
378  *
379  * \param in input stream
380  * \param object parameter
381  * \return input stream
382  */
383  friend inline std::istream& operator>>(std::istream& in, JParameter_t& object)
384  {
385  return in >> object.value;
386  }
387 
388 
389  /**
390  * Write parameter to output stream.
391  *
392  * \param out output stream
393  * \param object parameter
394  * \return output stream
395  */
396  friend inline std::ostream& operator<<(std::ostream& out, const JParameter_t& object)
397  {
398  using namespace std;
399 
400  out << FIXED(12,6) << object.get() << ' '
401  << setw(5) << (object.isFixed() ? "fixed" : " ") << ' ';
402 
403  if (object.isBound()) {
404  out << FIXED(12,6) << object.value << ' ';
405  out << FIXED(12,6) << object.range.getLowerLimit() << ' '
406  << FIXED(12,6) << object.range.getUpperLimit();
407  }
408 
409  return out;
410  }
411 
412 
413  double value = 0.0;
416  };
417 
418 
419  /**
420  * Fit parameters for single PMT.
421  */
423 
424  static constexpr double QE_MIN = 0.0; //!< minimal QE
425  static constexpr double QE_MAX = 2.0; //!< maximal QE
426  static constexpr double TTS_NS = 2.0; //!< start value transition-time spread [ns]
427 
428  /**
429  * Default constructor.
430  */
432  {
433  reset();
434  }
435 
436 
437  /**
438  * Reset.
439  */
440  void reset()
441  {
442  status = true;
443  QE = 0.0;
444  TTS = 0.0;
445  t0 = 0.0;
446  }
447 
448 
449  /**
450  * Get default values.
451  *
452  * \return parameters
453  */
455  {
457 
458  parameters.QE.range = JParameter_t::range_type(QE_MIN, QE_MAX);
459 
460  parameters.status = true;
461  parameters.QE = 1.0;
462  parameters.TTS = TTS_NS;
463  parameters.t0 = 0.0;
464 
465  return parameters;
466  }
467 
468 
469  /**
470  * Get number of fit parameters.
471  *
472  * \return number of parameters
473  */
474  inline size_t getN() const
475  {
476  return ((QE. isFree() ? 1 : 0) +
477  (TTS.isFree() ? 1 : 0) +
478  (t0 .isFree() ? 1 : 0));
479  }
480 
481 
482  /**
483  * Get index of parameter.
484  *
485  * \param p pointer to data member
486  * \return index
487  */
489  {
490  if (!(this->*p).isFree()) {
491  return INVALID_INDEX;
492  }
493 
494  int N = 0;
495 
496  if (p == &JPMTParameters_t::QE ) { return N; }; if (QE .isFree()) { ++N; }
497  if (p == &JPMTParameters_t::TTS) { return N; }; if (TTS.isFree()) { ++N; }
498  if (p == &JPMTParameters_t::t0 ) { return N; }; if (t0 .isFree()) { ++N; }
499 
500  return INVALID_INDEX;
501  }
502 
503 
504  /**
505  * Disable PMT.
506  */
507  void disable()
508  {
509  status = false;
510 
511  QE .fix(0.0);
512  TTS.fix(TTS);
513  t0 .fix(0.0);
514  }
515 
516 
517  /**
518  * Enable PMT.
519  */
520  void enable()
521  {
522  status = true;
523 
524  QE .set();
525  TTS.set();
526  t0 .set();
527  }
528 
529 
530  /**
531  * Write PMT parameters to output stream.
532  *
533  * \param out output stream
534  * \param object PMT parameters
535  * \return output stream
536  */
537  friend inline std::ostream& operator<<(std::ostream& out, const JPMTParameters_t& object)
538  {
539  using namespace std;
540 
541  out << "QE " << object.QE << endl;
542  out << "TTS " << object.TTS << endl;
543  out << "t0 " << object.t0 << endl;
544 
545  return out;
546  }
547 
548 
549  bool status; //!< status
550  JParameter_t QE; //!< relative quantum efficiency [unit]
551  JParameter_t TTS; //!< transition-time spread [ns]
552  JParameter_t t0; //!< time offset [ns]
553  };
554 
555 
556  /**
557  * Fit parameters for two-fold coincidence rate due to K40.
558  */
560  /**
561  * Default constructor.
562  */
564  {
565  reset();
566  }
567 
568 
569  /**
570  * Reset.
571  */
572  void reset()
573  {
574  R = 0.0;
575  p1 = 0.0;
576  p2 = 0.0;
577  p3 = 0.0;
578  p4 = 0.0;
579  bg = 0.0;
580  cc = 0.0;
581  }
582 
583 
584  JParameter_t R; //!< maximal coincidence rate [Hz]
585  JParameter_t p1; //!< 1st order angle dependence coincidence rate
586  JParameter_t p2; //!< 2nd order angle dependence coincidence rate
587  JParameter_t p3; //!< 3rd order angle dependence coincidence rate
588  JParameter_t p4; //!< 4th order angle dependence coincidence rate
589  JParameter_t bg; //!< constant background [Hz]
590  JParameter_t cc; //!< fraction of signal correlated background
591  };
592 
593 
594  /**
595  * Fit parameters for two-fold coincidence rate due to K40.
596  */
597  struct JK40Parameters :
599  {
600  /**
601  * Default constructor.
602  */
604  {}
605 
606 
607  /**
608  * Get default values.
609  *
610  * The default parameter values are set to those obtained from a designated simulation
611  * of K40 decays (see http://wiki.km3net.de/index.php/OMGsim_simulations_for_K40_fit).\n
612  * If you change these values, you may also want to change the corresponding values in JK40DefaultSimulator.hh.
613  *
614  * \return parameters
615  */
616  static const JK40Parameters& getInstance()
617  {
618  static JK40Parameters parameters;
619 
620  parameters.R = 18.460546;
621  parameters.p1 = 3.0767;
622  parameters.p2 = -1.2078;
623  parameters.p3 = 0.9905;
624  parameters.p4 = 0.9379;
625  parameters.bg = 0.0;
626  parameters.cc = 0.0;
627 
628  return parameters;
629  }
630 
631 
632  /**
633  * Get K40 parameters.
634  *
635  * \return K40 parameters
636  */
638  {
639  return static_cast<const JK40Parameters&>(*this);
640  }
641 
642 
643  /**
644  * Set K40 parameters.
645  *
646  * \param parameters K40 parameters
647  */
649  {
650  static_cast<JK40Parameters_t&>(*this) = parameters;
651  }
652 
653 
654  /**
655  * Get number of fit parameters.
656  *
657  * \return number of parameters
658  */
659  inline size_t getN() const
660  {
661  return ((R .isFree() ? 1 : 0) +
662  (p1.isFree() ? 1 : 0) +
663  (p2.isFree() ? 1 : 0) +
664  (p3.isFree() ? 1 : 0) +
665  (p4.isFree() ? 1 : 0) +
666  (bg.isFree() ? 1 : 0) +
667  (cc.isFree() ? 1 : 0));
668  }
669 
670 
671  /**
672  * Get index of parameter.
673  *
674  * \param p pointer to data member
675  * \return index
676  */
678  {
679  if (!(this->*p).isFree()) {
680  return INVALID_INDEX;
681  }
682 
683  int N = 0;
684 
685  if (p == &JK40Parameters::R) { return N; } if (R .isFree()) { ++N; }
686  if (p == &JK40Parameters::p1) { return N; } if (p1.isFree()) { ++N; }
687  if (p == &JK40Parameters::p2) { return N; } if (p2.isFree()) { ++N; }
688  if (p == &JK40Parameters::p3) { return N; } if (p3.isFree()) { ++N; }
689  if (p == &JK40Parameters::p4) { return N; } if (p4.isFree()) { ++N; }
690  if (p == &JK40Parameters::bg) { return N; } if (bg.isFree()) { ++N; }
691  if (p == &JK40Parameters::cc) { return N; } if (cc.isFree()) { ++N; }
692 
693  return INVALID_INDEX;
694  }
695 
696 
697  /**
698  * Get K40 coincidence rate as a function of cosine angle between PMT axes.
699  *
700  * \param ct cosine angle between PMT axes
701  * \return rate [Hz]
702  */
703  double getValue(const double ct) const
704  {
705  return R * exp(ct*(p1+ct*(p2+ct*(p3+ct*p4))) - (p1+p2+p3+p4));
706  }
707 
708 
709  /**
710  * Get gradient.
711  *
712  * \param ct cosine angle between PMT axes
713  * \return gradient
714  */
715  const JK40Parameters_t& getGradient(const double ct) const
716  {
717  gradient.reset();
718 
719  const double rate = getValue(ct);
720  const double ct2 = ct * ct;
721 
722  if (R .isFree()) { gradient.R = rate / R; }
723  if (p1.isFree()) { gradient.p1 = rate * ct - rate; }
724  if (p2.isFree()) { gradient.p2 = rate * ct2 - rate; }
725  if (p3.isFree()) { gradient.p3 = rate * ct2 * ct - rate; }
726  if (p4.isFree()) { gradient.p4 = rate * ct2 * ct2 - rate; }
727  if (bg.isFree()) { gradient.bg = 1.0; }
728  if (cc.isFree()) { gradient.cc = rate; }
729 
730  return gradient;
731  }
732 
733  private:
735  };
736 
737 
738  /**
739  * Fit model.
740  *
741  * In the absence of TDC constraints, the average time offset is fixed to zero.
742  */
743  struct JModel :
744  public JK40Parameters,
745  public JModule,
746  public JCombinatorics_t
747  {
751 
752 
753  /**
754  * Auxiliary data structure for derived quantities of a given PMT pair.
755  */
756  struct real_type {
757  double ct; //!< cosine angle between PMT axes
758  double t0; //!< time offset [ns]
759  double sigma; //!< total width [ns]
760  double signal; //!< combined signal
761  };
762 
763 
764  /**
765  * Default constructor.
766  */
768  {}
769 
770 
771  /**
772  * Constructor.
773  *
774  * \param module detector module
775  * \param parameters K40 parameters
776  * \param TDC TDC constraints
777  * \param option option
778  */
779  JModel(const JModule& module,
780  const JK40Parameters& parameters,
781  const JTDC_t::range_type& TDC,
782  const int option) :
783  JModule (module),
784  JCombinatorics_t(module)
785  {
786  setK40Parameters(parameters);
787 
788  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
789  this->parameters[i] = JPMTParameters_t::getInstance();
790  }
791 
792  for (JTDC_t::const_iterator i = TDC.first; i != TDC.second; ++i) {
793  this->parameters[i->second].t0.fix();
794  }
795 
796  this->index = (TDC.first == TDC.second ? 0 : INVALID_INDEX);
797 
798  setOption(option);
799  }
800 
801 
802  /**
803  * Constructor.
804  *
805  * \param module detector module
806  * \param parameters K40 parameters
807  */
808  JModel(const JModule& module,
809  const JK40Parameters& parameters) :
810  JModule (module),
811  JCombinatorics_t(module)
812  {
813  setK40Parameters(parameters);
814 
815  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
816  this->parameters[i] = JPMTParameters_t::getInstance();
817  }
818  }
819 
820 
821  /**
822  * Get fit option.
823  *
824  * \return option
825  */
827  {
828  return option;
829  }
830 
831 
832  /**
833  * Set fit option.
834  *
835  * \param option option
836  */
837  inline void setOption(const int option)
838  {
839  if (option == FIT_PMTS_t) {
840 
841  R .fix();
842  p1.fix();
843  p2.fix();
844  p3.fix();
845  p4.fix();
846 
847  parameters[index].t0 .fix();
848 
849  } else if (option == FIT_MODEL_t) {
850 
851  bg.fix();
852  cc.fix();
853 
854  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
855  parameters[i].QE .fix();
856  parameters[i].t0 .fix();
857  }
858 
859  } else if (option == FIT_PMTS_AND_ANGULAR_DEPENDENCE_t) {
860 
861  R .fix();
862 
863  } else {
864 
865  THROW(JValueOutOfRange, "Invalid option " << option);
866  }
867 
868  this->option = static_cast<JOption_t>(option);
869  }
870 
871 
872  /**
873  * Check if time offset is fixed.
874  *
875  * \return true if time offset fixed; else false
876  */
877  bool hasFixedTimeOffset() const
878  {
879  return index != INVALID_INDEX;
880  }
881 
882 
883  /**
884  * Get time offset.
885  *
886  * \return time offset
887  */
888  double getFixedTimeOffset() const
889  {
890  double t0 = 0.0;
891  size_t N = 0;
892 
893  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
894  if (parameters[i].t0.isFree()) {
895  t0 += parameters[i].t0;
896  N += 1;
897  }
898  }
899 
900  return t0 /= N;
901  }
902 
903 
904  /**
905  * Get index of PMT used for fixed time offset
906  *
907  * \return index
908  */
909  int getIndex() const
910  {
911  return index;
912  }
913 
914 
915  /**
916  * Set index of PMT used for fixed time offset
917  */
918  void setIndex()
919  {
920  if (index != INVALID_INDEX) {
921 
922  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
923 
924  if (parameters[i].status) {
925 
926  index = i;
927 
928  parameters[index].t0.fix();
929 
930  return;
931  }
932  }
933 
934  THROW(JValueOutOfRange, "No valid index.");
935  }
936  }
937 
938 
939  /**
940  * Get number of fit parameters.
941  *
942  * \return number of parameters
943  */
944  inline size_t getN() const
945  {
946  size_t N = JK40Parameters::getN();
947 
948  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
949  N += parameters[i].getN();
950  }
951 
952  return N;
953  }
954 
955 
956  /**
957  * Get index of parameter.
958  *
959  * \param pmt PMT
960  * \return index
961  */
962  int getIndex(int pmt) const
963  {
964  int N = JK40Parameters::getN();
965 
966  for (int i = 0; i != pmt; ++i) {
967  N += parameters[i].getN();
968  }
969 
970  return N;
971  }
972 
973 
974  /**
975  * Get index of parameter.
976  *
977  * \param pmt PMT
978  * \param p pointer to data member
979  * \return index
980  */
981  int getIndex(int pmt, JParameter_t JPMTParameters_t::*p) const
982  {
983  return getIndex(pmt) + parameters[pmt].getIndex(p);
984  }
985 
986 
987  /**
988  * Get intrinsic K40 arrival time spread.
989  *
990  * \return sigma [ns]
991  */
992  double getSigmaK40() const
993  {
994  return this->sigmaK40_ns;
995  }
996 
997 
998  /**
999  * Set intrinsic K40 arrival time spread.
1000  *
1001  * \param sigma sigma [ns]
1002  */
1003  void setSigmaK40(const double sigma)
1004  {
1005  this->sigmaK40_ns = sigma;
1006  }
1007 
1008 
1009  /**
1010  * Get derived parameters.
1011  *
1012  * \param pair PMT pair
1013  * \return parameters
1014  */
1015  const real_type& getReal(const pair_type& pair) const
1016  {
1017  real.ct = JPP::getDot((*this)[pair.first].getDirection(), (*this)[pair.second].getDirection());
1018 
1019  real.t0 = (pair.first == this->index ? -this->parameters[pair.second].t0 :
1020  pair.second == this->index ? +this->parameters[pair.first ].t0 :
1021  this->parameters[pair.first].t0 - this->parameters[pair.second].t0);
1022 
1023  real.sigma = sqrt(this->parameters[pair.first ].TTS() * this->parameters[pair.first ].TTS() +
1024  this->parameters[pair.second].TTS() * this->parameters[pair.second].TTS() +
1025  this->getSigmaK40() * this->getSigmaK40());
1026 
1027  real.signal = this->parameters[pair.first].QE() * this->parameters[pair.second].QE();
1028 
1029  return real;
1030  }
1031 
1032 
1033  /**
1034  * Get K40 coincidence rate.
1035  *
1036  * \param pair PMT pair
1037  * \param dt_ns time difference [ns]
1038  * \return rate [Hz/ns]
1039  */
1040  double getValue(const pair_type& pair, const double dt_ns) const
1041  {
1042  using namespace std;
1043  using namespace JPP;
1044 
1045  const real_type& real = getReal(pair);
1046 
1047  const JGauss gauss(real.t0, real.sigma, real.signal);
1048 
1049  const double R1 = this->getValue(real.ct);
1050  const double R2 = gauss.getValue(dt_ns);
1051 
1052  return bg() + R1 * (cc() + R2);
1053  }
1054 
1055 
1056  /**
1057  * Get K40 coincidence rate.
1058  *
1059  * \param pair PMT pair
1060  * \return rate [Hz]
1061  */
1062  double getValue(const pair_type& pair) const
1063  {
1064  using namespace std;
1065  using namespace JPP;
1066 
1067  const real_type& real = getReal(pair);
1068 
1069  const double R1 = this->getValue(real.ct);
1070  const double R2 = real.signal;
1071 
1072  return bg() + R1 * (cc() + R2);
1073  }
1074 
1075 
1076  /**
1077  * Write model parameters to output stream.
1078  *
1079  * \param out output stream
1080  * \param object model parameters
1081  * \return output stream
1082  */
1083  friend inline std::ostream& operator<<(std::ostream& out, const JModel& object)
1084  {
1085  using namespace std;
1086 
1087  out << "Module " << setw(10) << object.getID() << endl;
1088  out << "option " << object.option << endl;
1089  out << "index " << object.index << endl;
1090  out << "Rate [Hz] " << FIXED(12,6) << object.R << endl;
1091  out << "p1 " << FIXED(12,6) << object.p1 << endl;
1092  out << "p2 " << FIXED(12,6) << object.p2 << endl;
1093  out << "p3 " << FIXED(12,6) << object.p3 << endl;
1094  out << "p4 " << FIXED(12,6) << object.p4 << endl;
1095  out << "bg " << FIXED(12,6) << object.bg << endl;
1096  out << "cc " << FIXED(12,6) << object.cc << endl;
1097 
1098  for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
1099  out << "PMT[" << FILL(2,'0') << i << FILL() << "]." << object.parameters[i].status << endl << object.parameters[i];
1100  }
1101 
1102  return out;
1103  }
1104 
1106 
1107  private:
1108  int index; //!< index of PMT used for fixed time offset
1109  double sigmaK40_ns = 0.54; //!< intrinsic K40 arrival time spread [ns]
1111  mutable real_type real;
1112  };
1113 
1114 
1115  /**
1116  * Fit.
1117  */
1118  class JFit
1119  {
1120  public:
1121  /**
1122  * Result type.
1123  */
1124  struct result_type {
1125  double chi2;
1126  int ndf;
1127  };
1128 
1129  typedef std::shared_ptr<JMEstimator> estimator_type;
1130 
1131 
1132  /**
1133  * Constructor
1134  *
1135  * \param option M-estimator
1136  * \param debug debug
1137  */
1138  JFit(const int option, const int debug) :
1139  debug(debug)
1140  {
1141  using namespace JPP;
1142 
1143  estimator.reset(getMEstimator(option));
1144  }
1145 
1146 
1147  /**
1148  * Fit.
1149  *
1150  * \param data data
1151  * \return chi2, NDF
1152  */
1154  {
1155  using namespace std;
1156  using namespace JPP;
1157 
1158 
1159  value.setIndex();
1160 
1161  const size_t N = value.getN();
1162 
1163  V.resize(N);
1164  Y.resize(N);
1165  h.resize(N);
1166 
1167  int ndf = 0;
1168 
1169  for (data_type::const_iterator ix = data.begin(); ix != data.end(); ++ix) {
1170 
1171  const pair_type& pair = ix->first;
1172 
1173  if (value.parameters[pair.first ].status &&
1174  value.parameters[pair.second].status) {
1175 
1176  ndf += ix->second.size();
1177  }
1178  }
1179 
1180  ndf -= value.getN();
1181 
1182 
1183  lambda = LAMBDA_MIN;
1184 
1185  double precessor = numeric_limits<double>::max();
1186 
1187  for (numberOfIterations = 0; numberOfIterations != MAXIMUM_ITERATIONS; ++numberOfIterations) {
1188 
1189  DEBUG("step: " << numberOfIterations << endl);
1190 
1191  evaluate(data);
1192 
1193  DEBUG("lambda: " << FIXED(12,5) << lambda << endl);
1194  DEBUG("chi2: " << FIXED(12,3) << successor << endl);
1195 
1196  if (successor < precessor) {
1197 
1198  if (numberOfIterations != 0) {
1199 
1200  if (fabs(precessor - successor) < EPSILON*fabs(precessor)) {
1201  return { successor / estimator->getRho(1.0), ndf };
1202  }
1203 
1204  if (lambda > LAMBDA_MIN) {
1205  lambda /= LAMBDA_DOWN;
1206  }
1207  }
1208 
1209  precessor = successor;
1210  previous = value;
1211 
1212  } else {
1213 
1214  value = previous;
1215  lambda *= LAMBDA_UP;
1216 
1217  if (lambda > LAMBDA_MAX) {
1218  return { precessor / estimator->getRho(1.0), ndf }; // no improvement found
1219  }
1220 
1221  evaluate(data);
1222  }
1223 
1224  if (debug >= debug_t) {
1225 
1226  size_t row = 0;
1227 
1228  if (value.R .isFree()) { cout << "R " << FIXED(12,5) << Y[row] << endl; ++row; }
1229  if (value.p1.isFree()) { cout << "p1 " << FIXED(12,5) << Y[row] << endl; ++row; }
1230  if (value.p2.isFree()) { cout << "p2 " << FIXED(12,5) << Y[row] << endl; ++row; }
1231  if (value.p3.isFree()) { cout << "p3 " << FIXED(12,5) << Y[row] << endl; ++row; }
1232  if (value.p4.isFree()) { cout << "p4 " << FIXED(12,5) << Y[row] << endl; ++row; }
1233  if (value.bg.isFree()) { cout << "bg " << FIXED(12,3) << Y[row] << endl; ++row; }
1234  if (value.cc.isFree()) { cout << "cc " << FIXED(12,3) << Y[row] << endl; ++row; }
1235 
1236  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
1237  if (value.parameters[pmt].QE .isFree()) { cout << "PMT[" << setw(2) << pmt << "].QE " << FIXED(12,5) << Y[row] << endl; ++row; }
1238  if (value.parameters[pmt].TTS.isFree()) { cout << "PMT[" << setw(2) << pmt << "].TTS " << FIXED(12,5) << Y[row] << endl; ++row; }
1239  if (value.parameters[pmt].t0 .isFree()) { cout << "PMT[" << setw(2) << pmt << "].t0 " << FIXED(12,5) << Y[row] << endl; ++row; }
1240  }
1241  }
1242 
1243  // force definite positiveness
1244 
1245  for (size_t i = 0; i != N; ++i) {
1246 
1247  if (V(i,i) < PIVOT) {
1248  V(i,i) = PIVOT;
1249  }
1250 
1251  h[i] = 1.0 / sqrt(V(i,i));
1252  }
1253 
1254  // normalisation
1255 
1256  for (size_t i = 0; i != N; ++i) {
1257  for (size_t j = 0; j != i; ++j) {
1258  V(j,i) *= h[i] * h[j];
1259  V(i,j) = V(j,i);
1260  }
1261  }
1262 
1263  for (size_t i = 0; i != N; ++i) {
1264  V(i,i) = 1.0 + lambda;
1265  }
1266 
1267  // solve A x = b
1268 
1269  for (size_t col = 0; col != N; ++col) {
1270  Y[col] *= h[col];
1271  }
1272 
1273  try {
1274  V.solve(Y);
1275  }
1276  catch (const exception& error) {
1277 
1278  ERROR("JGandalf: " << error.what() << endl << V << endl);
1279 
1280  break;
1281  }
1282 
1283  // update value
1284 
1285  const double factor = 2.0;
1286 
1287  size_t row = 0;
1288 
1289  if (value.R .isFree()) { value.R -= factor * h[row] * Y[row]; ++row; }
1290  if (value.p1.isFree()) { value.p1 -= factor * h[row] * Y[row]; ++row; }
1291  if (value.p2.isFree()) { value.p2 -= factor * h[row] * Y[row]; ++row; }
1292  if (value.p3.isFree()) { value.p3 -= factor * h[row] * Y[row]; ++row; }
1293  if (value.p4.isFree()) { value.p4 -= factor * h[row] * Y[row]; ++row; }
1294  if (value.bg.isFree()) { value.bg -= factor * h[row] * Y[row]; ++row; }
1295  if (value.cc.isFree()) { value.cc -= factor * h[row] * Y[row]; ++row; }
1296 
1297  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
1298  if (value.parameters[pmt].QE .isFree()) { value.parameters[pmt].QE -= factor * h[row] * Y[row]; ++row; }
1299  if (value.parameters[pmt].TTS.isFree()) { value.parameters[pmt].TTS -= factor * h[row] * Y[row]; ++row; }
1300  if (value.parameters[pmt].t0 .isFree()) { value.parameters[pmt].t0 -= factor * h[row] * Y[row]; ++row; }
1301  }
1302  }
1303 
1304  return { precessor / estimator->getRho(1.0), ndf };
1305  }
1306 
1307 
1308  static constexpr int MAXIMUM_ITERATIONS = 10000; //!< maximal number of iterations.
1309  static constexpr double EPSILON = 1.0e-4; //!< maximal distance to minimum.
1310  static constexpr double LAMBDA_MIN = 0.01; //!< minimal value control parameter
1311  static constexpr double LAMBDA_MAX = 100.0; //!< maximal value control parameter
1312  static constexpr double LAMBDA_UP = 10.0; //!< multiplication factor control parameter
1313  static constexpr double LAMBDA_DOWN = 10.0; //!< multiplication factor control parameter
1314  static constexpr double PIVOT = std::numeric_limits<double>::epsilon(); //!< minimal value diagonal element of matrix
1315 
1316  int debug;
1317  estimator_type estimator; //!< M-Estimator function
1318 
1319  double lambda;
1323 
1324  private:
1325  /**
1326  * Evaluation of fit.
1327  *
1328  * \param data data
1329  */
1330  void evaluate(const data_type& data)
1331  {
1332  using namespace std;
1333  using namespace JPP;
1334 
1335  typedef JModel::real_type real_type;
1336 
1337 
1338  successor = 0.0;
1339 
1340  V.reset();
1341  Y.reset();
1342 
1343 
1344  // model parameter indices
1345 
1346  const struct M_t {
1347  M_t(const JModel& model)
1348  {
1349  R = model.getIndex(&JK40Parameters_t::R);
1350  p1 = model.getIndex(&JK40Parameters_t::p1);
1351  p2 = model.getIndex(&JK40Parameters_t::p2);
1352  p3 = model.getIndex(&JK40Parameters_t::p3);
1353  p4 = model.getIndex(&JK40Parameters_t::p4);
1354  bg = model.getIndex(&JK40Parameters_t::bg);
1355  cc = model.getIndex(&JK40Parameters_t::cc);
1356  }
1357 
1358  int R;
1359  int p1;
1360  int p2;
1361  int p3;
1362  int p4;
1363  int bg;
1364  int cc;
1365 
1366  } M(value);
1367 
1368 
1369  // PMT parameter indices
1370 
1371  struct I_t {
1372  I_t(const JModel& model, const int pmt) :
1373  QE (INVALID_INDEX),
1374  TTS(INVALID_INDEX),
1375  t0 (INVALID_INDEX)
1376  {
1377  const int index = model.getIndex(pmt);
1378 
1379  int N = 0;
1380 
1381  if (model.parameters[pmt].QE .isFree()) { QE = index + N; ++N; }
1382  if (model.parameters[pmt].TTS.isFree()) { TTS = index + N; ++N; }
1383  if (model.parameters[pmt].t0 .isFree()) { t0 = index + N; ++N; }
1384  }
1385 
1386  int QE;
1387  int TTS;
1388  int t0;
1389  };
1390 
1391 
1392  typedef vector< pair<int, double> > buffer_type;
1393 
1394  buffer_type buffer;
1395 
1396  for (data_type::const_iterator ix = data.begin(); ix != data.end(); ++ix) {
1397 
1398  const pair_type& pair = ix->first;
1399 
1400  if (value.parameters[pair.first ].status &&
1401  value.parameters[pair.second].status) {
1402 
1403  const real_type& real = value.getReal(pair);
1404 
1405  const JGauss gauss(real.t0, real.sigma, real.signal);
1406 
1407  const double R1 = value.getValue (real.ct);
1408  const JK40Parameters_t& R1p = value.getGradient(real.ct);
1409 
1410  const std::pair<I_t, I_t> PMT(I_t(value, pair.first),
1411  I_t(value, pair.second));
1412 
1413  for (const rate_type& iy : ix->second) {
1414 
1415  const double R2 = gauss.getValue (iy.dt_ns);
1416  const JGauss& R2p = gauss.getGradient(iy.dt_ns);
1417 
1418  const double R = value.bg() + R1 * (value.cc() + R2);
1419  const double u = (iy.value - R) / iy.error;
1420  const double w = -estimator->getPsi(u) / iy.error;
1421 
1422  successor += estimator->getRho(u);
1423 
1424  buffer.clear();
1425 
1426  if (M.R != INVALID_INDEX) { buffer.push_back({M.R, w * (value.cc() + R2) * R1p.R () * value.R .getDerivative()}); }
1427  if (M.p1 != INVALID_INDEX) { buffer.push_back({M.p1, w * (value.cc() + R2) * R1p.p1() * value.p1.getDerivative()}); }
1428  if (M.p2 != INVALID_INDEX) { buffer.push_back({M.p2, w * (value.cc() + R2) * R1p.p2() * value.p2.getDerivative()}); }
1429  if (M.p3 != INVALID_INDEX) { buffer.push_back({M.p3, w * (value.cc() + R2) * R1p.p3() * value.p3.getDerivative()}); }
1430  if (M.p4 != INVALID_INDEX) { buffer.push_back({M.p4, w * (value.cc() + R2) * R1p.p4() * value.p4.getDerivative()}); }
1431  if (M.bg != INVALID_INDEX) { buffer.push_back({M.bg, w * value.bg.getDerivative()}); }
1432  if (M.cc != INVALID_INDEX) { buffer.push_back({M.cc, w * R1 * R1p.cc() * value.cc.getDerivative()}); }
1433 
1434  if (PMT.first .QE != INVALID_INDEX) { buffer.push_back({PMT.first .QE , w * R1 * R2p.signal * value.parameters[pair.second].QE () * value.parameters[pair.first ].QE .getDerivative()}); }
1435  if (PMT.second.QE != INVALID_INDEX) { buffer.push_back({PMT.second.QE , w * R1 * R2p.signal * value.parameters[pair.first ].QE () * value.parameters[pair.second].QE .getDerivative()}); }
1436  if (PMT.first .TTS != INVALID_INDEX) { buffer.push_back({PMT.first .TTS, w * R1 * R2p.sigma * value.parameters[pair.first ].TTS() * value.parameters[pair.first ].TTS.getDerivative() / real.sigma}); }
1437  if (PMT.second.TTS != INVALID_INDEX) { buffer.push_back({PMT.second.TTS, w * R1 * R2p.sigma * value.parameters[pair.second].TTS() * value.parameters[pair.second].TTS.getDerivative() / real.sigma}); }
1438  if (PMT.first .t0 != INVALID_INDEX) { buffer.push_back({PMT.first .t0, w * R1 * R2p.mean * value.parameters[pair.first ].t0 .getDerivative() * +1.0}); }
1439  if (PMT.second.t0 != INVALID_INDEX) { buffer.push_back({PMT.second.t0, w * R1 * R2p.mean * value.parameters[pair.second].t0 .getDerivative() * -1.0}); }
1440 
1441  for (buffer_type::const_iterator row = buffer.begin(); row != buffer.end(); ++row) {
1442 
1443  Y[row->first] += row->second;
1444 
1445  V[row->first][row->first] += row->second * row->second;
1446 
1447  for (buffer_type::const_iterator col = buffer.begin(); col != row; ++col) {
1448  V[row->first][col->first] += row->second * col->second;
1449  V[col->first][row->first] = V[row->first][col->first];
1450  }
1451  }
1452  }
1453  }
1454  }
1455  }
1456 
1457  JMATH::JVectorND Y; // gradient
1458  double successor;
1460  std::vector<double> h; // normalisation vector
1461  };
1462 }
1463 
1464 #endif
1465 
1466 
Data structure for measured coincidence rate of pair of PMTs.
Definition: JFitK40.hh:62
std::vector< double > h
Definition: JFitK40.hh:1460
result_type operator()(const data_type &data)
Fit.
Definition: JFitK40.hh:1153
JOption_t
Fit options.
Definition: JFitK40.hh:50
JTOOLS::JRange< double > range_type
Type definition for range of parameter values.
Definition: JFitK40.hh:122
size_t getN() const
Get number of fit parameters.
Definition: JFitK40.hh:474
data_type w[N+1][M+1]
Definition: JPolint.hh:778
Exceptions.
void set()
Set current value.
Definition: JFitK40.hh:268
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition: JScale.hh:47
int getIndex(JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
Definition: JFitK40.hh:488
const real_type & getReal(const pair_type &pair) const
Get derived parameters.
Definition: JFitK40.hh:1015
debug
Definition: JMessage.hh:29
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
int getIndex(JParameter_t JK40Parameters::*p) const
Get index of parameter.
Definition: JFitK40.hh:677
JParameter_t t0
time offset [ns]
Definition: JFitK40.hh:552
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:109
JK40Parameters()
Default constructor.
Definition: JFitK40.hh:603
TPaveText * p1
Auxiliary methods for geometrical methods.
Data structure for a composite optical module.
Definition: JModule.hh:68
void setSigmaK40(const double sigma)
Set intrinsic K40 arrival time spread.
Definition: JFitK40.hh:1003
JParameter_t R
maximal coincidence rate [Hz]
Definition: JFitK40.hh:584
bool hasFixedTimeOffset() const
Check if time offset is fixed.
Definition: JFitK40.hh:877
static const int INVALID_INDEX
invalid index
Definition: JFitK40.hh:56
size_t getN() const
Get number of fit parameters.
Definition: JFitK40.hh:659
Interface for maximum likelihood estimator (M-estimator).
Definition: JMEstimator.hh:20
JParameter_t & add(const JParameter_t &parameter)
Add parameter.
Definition: JFitK40.hh:167
JParameter_t & sub(const JParameter_t &parameter)
Subtract parameter.
Definition: JFitK40.hh:181
JK40Parameters_t()
Default constructor.
Definition: JFitK40.hh:563
JParameter_t & negate()
Negate parameter.
Definition: JFitK40.hh:153
double getDot(const JNeutrinoDirection &first, const JNeutrinoDirection &second)
Dot product.
Definition: JAstronomy.hh:409
const JK40Parameters_t & getGradient(const double ct) const
Get gradient.
Definition: JFitK40.hh:715
static const JPBS_t PMT(3, 4, 2, 3)
PBS of photo-multiplier tube (PMT)
void setIndex()
Set index of PMT used for fixed time offset.
Definition: JFitK40.hh:918
void setK40Parameters(const JK40Parameters_t &parameters)
Set K40 parameters.
Definition: JFitK40.hh:648
int index
index of PMT used for fixed time offset
Definition: JFitK40.hh:1108
void set(const double value)
Set value.
Definition: JFitK40.hh:302
JOption_t option
Definition: JFitK40.hh:1110
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
then set_variable singlesRate set_variable doublesRate set_variable numberOfSlices echo Generating random background echo Singles rate
double getDerivative() const
Get derivative of value.
Definition: JFitK40.hh:331
double getValue(const pair_type &pair) const
Get K40 coincidence rate.
Definition: JFitK40.hh:1062
Data structure for a pair of indices.
#define R1(x)
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
int getIndex() const
Get index of PMT used for fixed time offset.
Definition: JFitK40.hh:909
JK40Parameters_t gradient
Definition: JFitK40.hh:734
then fatal Wrong number of arguments fi set_variable STRING $argv[1] set_variable DETECTORXY_TXT $WORKDIR $DETECTORXY_TXT tail read X Y CHI2 RMS printf optimum n $X $Y $CHI2 $RMS awk v Y
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
JModel()
Default constructor.
Definition: JFitK40.hh:767
JPMTParameters_t()
Default constructor.
Definition: JFitK40.hh:431
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
double getValue(const double ct) const
Get K40 coincidence rate as a function of cosine angle between PMT axes.
Definition: JFitK40.hh:703
friend std::ostream & operator<<(std::ostream &out, const JModel &object)
Write model parameters to output stream.
Definition: JFitK40.hh:1083
const double sigma[]
Definition: JQuadrature.cc:74
real_type real
Definition: JFitK40.hh:1111
T getLength() const
Get length (difference between upper and lower limit).
Definition: JRange.hh:289
then usage set_variable ACOUSTICS_WORKDIR $WORKDIR set_variable FORMULA sin([0]+2 *$PI *([1]+[2]*x)*x)" set_variable DY 1.0e-8 mkdir $WORKDIR for DETECTOR in $DETECTORS[*]
JFit(const int option, const int debug)
Constructor.
Definition: JFitK40.hh:1138
void setOption(const int option)
Set fit option.
Definition: JFitK40.hh:837
fit parameters of PMTs
Definition: JFitK40.hh:51
JMATH::JMatrixNS V
Definition: JFitK40.hh:1322
void fix()
Fix current value.
Definition: JFitK40.hh:277
JParameter_t & operator=(double value)
Assignment operator.
Definition: JFitK40.hh:368
Fit parameters for two-fold coincidence rate due to K40.
Definition: JFitK40.hh:597
JParameter_t QE
relative quantum efficiency [unit]
Definition: JFitK40.hh:550
JParameter_t p3
3rd order angle dependence coincidence rate
Definition: JFitK40.hh:587
int numberOfIterations
Definition: JFitK40.hh:1321
int getIndex(const int first, const int second) const
Get index of pair of indices.
void evaluate(const data_type &data)
Evaluation of fit.
Definition: JFitK40.hh:1330
double ct
cosine angle between PMT axes
Definition: JFitK40.hh:757
estimator_type estimator
M-Estimator function.
Definition: JFitK40.hh:1317
JParameter_t()
Default constructor.
Definition: JFitK40.hh:128
rate_type(double dt_ns, double value, double error)
Constructor.
Definition: JFitK40.hh:80
fit parameters of PMTs and angular dependence of K40 rate
Definition: JFitK40.hh:53
#define ERROR(A)
Definition: JMessage.hh:66
double t0
time offset [ns]
Definition: JFitK40.hh:758
const JK40Parameters & getK40Parameters() const
Get K40 parameters.
Definition: JFitK40.hh:637
friend std::ostream & operator<<(std::ostream &out, const JParameter_t &object)
Write parameter to output stream.
Definition: JFitK40.hh:396
T constrain(argument_type x) const
Constrain value to range.
Definition: JRange.hh:350
int getIndex()
Get index for user I/O manipulation.
Definition: JManip.hh:26
void fix(const double value)
Fix value.
Definition: JFitK40.hh:318
double sigma
total width [ns]
Definition: JFitK40.hh:759
void enable()
Enable PMT.
Definition: JFitK40.hh:520
JParameter_t TTS
transition-time spread [ns]
Definition: JFitK40.hh:551
N x N symmetric matrix.
Definition: JMatrixNS.hh:28
static const JPMTParameters_t & getInstance()
Get default values.
Definition: JFitK40.hh:454
FIT_t
Fit options.
Definition: JFitK40.hh:113
Auxiliary data structure for sequence of same character.
Definition: JManip.hh:328
Fit parameters for single PMT.
Definition: JFitK40.hh:422
I/O manipulators.
JParameter_t p4
4th order angle dependence coincidence rate
Definition: JFitK40.hh:588
JParameter_t & mul(const JParameter_t &first, const JParameter_t &second)
Scale parameter.
Definition: JFitK40.hh:224
p2
Definition: module-Z:fit.sh:74
JOption_t getOption() const
Get fit option.
Definition: JFitK40.hh:826
JMATH::JVectorND Y
Definition: JFitK40.hh:1457
void reset(T &value)
Reset value.
then JCookie sh JDataQuality D $DETECTOR_ID R
Definition: JDataQuality.sh:41
bool is_valid() const
Check validity of range.
Definition: JRange.hh:311
size_t getN() const
Get number of fit parameters.
Definition: JFitK40.hh:944
friend std::istream & operator>>(std::istream &in, JParameter_t &object)
Read parameter from input stream.
Definition: JFitK40.hh:383
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
Definition: JMuonPostfit.sh:40
bool isFree() const
Check if parameter is free.
Definition: JFitK40.hh:237
Auxiliary class to define a range between two values.
JParameter_t p2
2nd order angle dependence coincidence rate
Definition: JFitK40.hh:586
Auxiliary data structure for derived quantities of a given PMT pair.
Definition: JFitK40.hh:756
fit parameters of K40 rate and TTSs of PMTs
Definition: JFitK40.hh:52
then set_variable NUMBER_OF_TESTS else set_variable NUMBER_OF_TESTS fi function gauss()
double getFixedTimeOffset() const
Get time offset.
Definition: JFitK40.hh:888
JParameter_t(const double value, const range_type &range=range_type::DEFAULT_RANGE())
Constructor.
Definition: JFitK40.hh:140
JParameter_t bg
constant background [Hz]
Definition: JFitK40.hh:589
double signal
combined signal
Definition: JFitK40.hh:760
PMT combinatorics for optical module.
JParameter_t & mul(const double factor)
Scale parameter.
Definition: JFitK40.hh:195
double getValue(const pair_type &pair, const double dt_ns) const
Get K40 coincidence rate.
Definition: JFitK40.hh:1040
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition: JFitK40.hh:98
static const JK40Parameters & getInstance()
Get default values.
Definition: JFitK40.hh:616
set_variable TDC
Definition: JPrintTDC.sh:20
JModel(const JModule &module, const JK40Parameters &parameters, const JTDC_t::range_type &TDC, const int option)
Constructor.
Definition: JFitK40.hh:779
JModel(const JModule &module, const JK40Parameters &parameters)
Constructor.
Definition: JFitK40.hh:808
Base class for data structures with artithmetic capabilities.
int getIndex(int pmt) const
Get index of parameter.
Definition: JFitK40.hh:962
double getSigmaK40() const
Get intrinsic K40 arrival time spread.
Definition: JFitK40.hh:992
int j
Definition: JPolint.hh:703
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:178
int getIndex(int pmt, JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
Definition: JFitK40.hh:981
Fit parameters for two-fold coincidence rate due to K40.
Definition: JFitK40.hh:559
JMEstimator * getMEstimator(const int type)
Get M-Estimator.
Definition: JMEstimator.hh:203
static JRange< double, std::less< double > > DEFAULT_RANGE()
Default range.
Definition: JRange.hh:555
KM3NeT DAQ constants, bit handling, etc.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition: JDAQ.hh:26
double u[N+1]
Definition: JPolint.hh:776
bool isBound() const
Check if parameter is bound.
Definition: JFitK40.hh:259
bool isFixed() const
Check if parameter is fixed.
Definition: JFitK40.hh:248
std::shared_ptr< JMEstimator > estimator_type
Definition: JFitK40.hh:1129
Fit model.
Definition: JFitK40.hh:743
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
rate_type()
Default constructor.
Definition: JFitK40.hh:66
double successor
Definition: JFitK40.hh:1458
void disable()
Disable PMT.
Definition: JFitK40.hh:507
JPMTParameters_t parameters[NUMBER_OF_PMTS]
Definition: JFitK40.hh:1105
JParameter_t & div(const double factor)
Scale parameter.
Definition: JFitK40.hh:209
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable STRING $argv[2] set_array QUANTILES set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable MODULE `getModule -a $DETECTOR -L "$STRING 0"` source JAcousticsToolkit.sh typeset -A TRIPODS get_tripods $WORKDIR/tripod.txt TRIPODS XMEAN
double get() const
Get value.
Definition: JFitK40.hh:288
friend std::ostream & operator<<(std::ostream &out, const JPMTParameters_t &object)
Write PMT parameters to output stream.
Definition: JFitK40.hh:537
p3
Definition: module-Z:fit.sh:74
Maximum likelihood estimator (M-estimators).
double operator()() const
Type conversion operator.
Definition: JFitK40.hh:345
const double epsilon
Definition: JQuadrature.cc:21
int debug
debug level
Nx1 matrix.
Definition: JVectorND.hh:21
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
JParameter_t p1
1st order angle dependence coincidence rate
Definition: JFitK40.hh:585
JParameter_t cc
fraction of signal correlated background
Definition: JFitK40.hh:590
Data structure for optical module.
Auxiliary class for fit parameter with optional limits.
Definition: JFitK40.hh:106