Jpp 21.0.0-rc.1-88-g0130508c4
the software that should make you happy
Loading...
Searching...
No Matches
JWifi.cc
Go to the documentation of this file.
1
2#include <string>
3#include <iostream>
4#include <iomanip>
5#include <chrono>
6#include <map>
7#include <sstream>
8#include <cmath>
9#include <vector>
10
11#include <mutex>
12#include <thread>
13#include <condition_variable>
14#include <vector>
15#include <queue>
16
17#include "TROOT.h"
18#include "TFile.h"
19#include "TH2D.h"
20
22
23#include "JPhysics/JPDF.hh"
26#include "JPhysics/KM3NeT.hh"
27
28#include "JMath/JConstants.hh"
29
30#include "JTools/JRange.hh"
31
34
35#include "JFit/JGradient.hh"
36
38
39#include "Jeep/JProperties.hh"
40#include "Jeep/JParser.hh"
41#include "Jeep/JMessage.hh"
42
43
44namespace {
45
46 using JPHYSICS::JPDF_C;
49 using JPHYSICS::JQE;
51
52
53 /**
54 * PDF fixed parameters.
55 */
56 struct PDF {
57 static constexpr int numberOfPoints = 25;
58 static constexpr double epsilon = 1.0e-10;
59 };
60
61
62 /**
63 * Fit fixed parameters.
64 */
65 struct FIT {
66 static constexpr int number_of_iterations = 10000;
67 static constexpr int number_of_extra_steps = 1;
68 static constexpr double epsilon = 1.0e-4;
69 };
70
71
72 static const double PMIN = 1.0e-6; //!< minimal average probability
73 static const double TMIN_NS = -2.0; //!< minimal arrival time [ns]
74
75
76 /**
77 * Auxiliary data structure for experiment.
78 */
79 struct experiment_type {
80
81 JGIZMO::JRootObjectID Ha; //!< scattered light
82 JGIZMO::JRootObjectID Hb; //!< direct light
83
84 /**
85 * Read experiment from input stream.
86 *
87 * \param in input stream
88 * \param experiment experiment
89 * \return input stream
90 */
91 friend inline std::istream& operator>>(std::istream& in, experiment_type& experiment)
92 {
93 return in >> experiment.Ha
94 >> experiment.Hb;
95 }
96
97
98 /**
99 * Write experiment to output stream.
100 *
101 * \param out output stream
102 * \param experiment experiment
103 * \return output stream
104 */
105 friend inline std::ostream& operator<<(std::ostream& out, const experiment_type& experiment)
106 {
107 return out << experiment.Ha << ' '
108 << experiment.Hb;
109 }
110 };
111
112
113 typedef std::pair<double, double> pair_type; //!< bin edges
114
115 /**
116 * Auxiliary data structure for measurement.
117 */
118 struct bin_type {
119
120 /**
121 * Get chi2.
122 *
123 * \param ps average hit probability
124 * \return chi2
125 */
126 double getChi2(const double ps) const
127 {
128 const double u = (ratio - ps/value) / error;
129
130 return u*u;
131 }
132
133 pair_type R_m; //!< distance [m]
134 pair_type t_ns; //!< time residual [ns]
135 double ratio; //!< measured ratio
136 double error; //!< measured error
137 double value; //!< computed value
138 };
139
140
143
145
146
147 /**
148 * Auxiliary class for editing value of fit parameter.
149 */
150 struct JEditor :
151 public JParameter_t,
152 public range_type
153 {
154 /**
155 * Constructor.
156 *
157 * \param ps parameter
158 * \param range allowed range
159 */
160 JEditor(double& ps, const range_type& range = range_type()) :
161 ps(ps)
162 {}
163
164
165 /**
166 * Apply step.
167 *
168 * \param step step
169 */
170 virtual void apply(const double step) override
171 {
172 this->ps += step;
173
174 this->ps = constrain(this->ps);
175 }
176
177
178 /**
179 * Get value.
180 *
181 * \return value
182 */
183 double getValue() const
184 {
185 return ps;
186 }
187
188 private:
189 double& ps; //!< pointer to parameter
190 };
191
192
193 /**
194 * Auxiliary data structure for correlated fit parameters.
195 */
196 struct JMixed {
197
198 /**
199 * Get factor of absorption length.
200 *
201 * \return factor
202 */
203 static inline double getFactorAbsorptionLength()
204 {
205 return get_factor_a() * get_factor_b();
206 }
207
208
209 /**
210 * Get offset of absorption length.
211 *
212 * \return factor
213 */
214 static inline double getOffsetAbsorptionLength()
215 {
216 const double y = 1.0 / get_offset_a() + 1.0 / get_offset_b();
217
218 return 1.0 / y;
219 }
220
221 /**
222 * Get absorption length.
223 *
224 * \param lambda wavelength of light [nm]
225 * \return absorption length [m]
226 */
227 static inline double getAbsorptionLength(const double lambda)
228 {
229 const double y = 1.0 / (JAbsorptionLength::getAbsorptionLength(lambda) * getFactorAbsorptionLength()) + 1.0 / getOffsetAbsorptionLength();
230
231 return 1.0 / y;
232 }
233
234
235 /**
236 * Get scattering length.
237 *
238 * \param lambda wavelength of light [nm]
239 * \return scattering length [m]
240 */
241 static inline double getScatteringLength(const double lambda)
242 {
243 return JScatteringLength::getScatteringLength(lambda);
244 }
245
246
247 /**
248 * Get factor of quantum efficiency.
249 *
250 * \return factor
251 */
252 static inline double getFactorQE()
253 {
254 return (get_factor_a() / get_factor_b()) * ((ABSORPTION_LENGTH_M + get_offset_a()) / get_offset_a()) * (get_offset_b() / (ABSORPTION_LENGTH_M + get_offset_b()));
255 }
256
257
258 /**
259 * Get quantum efficiency.
260 *
261 * \param lambda wavelength of light [nm]
262 * \return quantum efficiency [m]
263 */
264 static inline double getQE(const double lambda)
265 {
266 return JQE::getQE(lambda) * getFactorQE();
267 }
268
269
270 /**
271 * Get reference to common factor.
272 *
273 * \return factor
274 */
275 static double& get_factor_a()
276 {
277 static double a = 1.0;
278
279 return a;
280 }
281
282
283 /**
284 * Get reference to common factor.
285 *
286 * \return factor
287 */
288 static double& get_factor_b()
289 {
290 static double b = 1.0;
291
292 return b;
293 }
294
295
296 /**
297 * Get reference to common offset.
298 *
299 * \return offset
300 */
301 static double& get_offset_a()
302 {
303 static double a = 1.0e6;
304
305 return a;
306 }
307
308
309 /**
310 * Get reference to common offset.
311 *
312 * \return offset
313 */
314 static double& get_offset_b()
315 {
316 static double b = 1.0e6;
317
318 return b;
319 }
320
321 static constexpr double ABSORPTION_LENGTH_M = 50.0; //!< absorption length [m]
322 };
323
324
325 typedef JGEOMETRY3D::JAngle3D pmt_type;
326 typedef std::vector<pmt_type> module_type;
327
328
329 /**
330 * Auxiliary data structure for chi2 function object.
331 */
332 struct JWifi {
333
334 static const int ND = 2; //!< number of histograms
335
336 /**
337 * Check bin contents.
338 *
339 * \param value value
340 * \param error error
341 * \return true if bin contents are valid; else false
342 */
343 static bool check(const double value, const double error)
344 {
345 return (value > 0.0 &&
346 error > 0.0);
347 }
348
349
350 /**
351 * Auxiliary data structure for sampling of bins.
352 */
353 static struct bins_type {
354
355 static const char SEPARATOR = 'x';
356
357 /**
358 * Read bins from input stream.
359 *
360 * \param in input stream
361 * \param bins bins
362 * \return input stream
363 */
364 friend inline std::istream& operator>>(std::istream& in, bins_type& bins)
365 {
366 using namespace std;
367
368 string buffer;
369
370 getline(in,buffer);
371
372 const size_t pos = buffer.find(SEPARATOR);
373
374 if (pos != string::npos) {
375
376 if (!(istringstream(buffer.substr(0,pos)) >> bins.R_m)) { in.setstate(ios::badbit); }
377 if (!(istringstream(buffer.substr(pos+1)) >> bins.t_ns)) { in.setstate(ios::badbit); }
378
379 } else {
380
381 in.setstate(ios::badbit);
382 }
383
384 return in;
385 }
386
387
388 /**
389 * Write bins to output stream.
390 *
391 * \param out output stream
392 * \param bins bins
393 * \return output stream
394 */
395 friend inline std::ostream& operator<<(std::ostream& out, const bins_type& bins)
396 {
397 return out << bins.R_m << SEPARATOR << bins.t_ns;
398 }
399
400 size_t R_m;
401 size_t t_ns;
402
403 } bins;
404
405
406 /**
407 * Get average hit probability at given time for optical module at given distance.
408 *
409 * \param pdf PDF
410 * \param E_GeV muon energy [GeV]
411 * \param R_m distance [m]
412 * \param t_ns time residual [ns]
413 * \param module module
414 * \return probability
415 */
416 static double getPs(const JPDF_C& pdf,
417 const double E_GeV,
418 const pair_type& R_m,
419 const pair_type& t_ns,
420 const module_type& module)
421 {
422 // integrate time and average PMTs and distances
423
424 const double dr = (R_m .second - R_m .first) / JWifi::bins.R_m;
425 const double dt = (t_ns.second - t_ns.first) / JWifi::bins.t_ns;
426
427 double ps = 0.0;
428
429 for (const pmt_type& pmt : module) {
430
431 for (double r1 = R_m.first + 0.5*dr; r1 < R_m.second; r1 += dr) {
432
433 double npe = 0.0;
434
435 for (double t1 = t_ns.first + 0.5*dt; t1 < t_ns.second; t1 += dt) {
436 npe += pdf.getLightFromMuon(E_GeV, r1, pmt.getTheta(), pmt.getPhi(), t1) * dt;
437 }
438
439 ps += 1.0 - exp(-npe);
440 }
441 }
442
443 return ps / (module.size() * JWifi::bins.R_m);
444 }
445
446
447 /**
448 * Constructor.
449 *
450 * \param E_GeV muon energy [GeV]
451 * \param ha histogram scattered light
452 * \param hb histogram direct light
453 * \param angle_Deg grid angle [deg]
454 * \param ns number of threads
455 */
456 JWifi(const double E_GeV,
457 const TH2* ha,
458 const TH2* hb,
459 const double angle_Deg,
460 const size_t ns) :
461
463 JMixed::getQE,
465 JMixed::getAbsorptionLength,
466 JMixed::getScatteringLength,
471 PDF::numberOfPoints,
472 PDF::epsilon),
473
474 E_GeV(E_GeV),
475 ns(ns)
476 {
477 using namespace JPP;
478
479 // sets of PMTs conform 'stopping muon' definition of scattered (0) and direct (1) light
480
481 const JOmega3D omega(angle_Deg * PI / 180.0);
482
483 for (JOmega3D::const_iterator i = omega.begin(); i != omega.end(); ++i) {
484
485 if (i->getTheta() <= 0.5*PI && i->getPhi() <= 0.5*PI)
486 module[0].push_back(*i);
487 else if (i->getTheta() >= 0.5*PI && i->getPhi() >= 0.5*PI)
488 module[1].push_back(*i);
489 }
490
491 // import data
492
493 const TH2* h2[ND] = { ha, hb };
494
495 for (int i = 0; i != ND; ++i) {
496
497 for (Int_t ix = 1; ix <= h2[i]->GetXaxis()->GetNbins(); ++ix) {
498 for (Int_t iy = 1; iy <= h2[i]->GetYaxis()->GetNbins(); ++iy) {
499
500 pair_type R_m = { h2[i]->GetXaxis()->GetBinLowEdge(ix), h2[i]->GetXaxis()->GetBinUpEdge(ix) };
501 pair_type t_ns = { h2[i]->GetYaxis()->GetBinLowEdge(iy), h2[i]->GetYaxis()->GetBinUpEdge(iy) };
502
503 if (t_ns.first < TMIN_NS) {
504 t_ns.first = TMIN_NS;
505 }
506
507 double value = h2[i]->GetBinContent(ix,iy);
508 double error = h2[i]->GetBinError (ix,iy);
509
510 if (check(value, error)) {
511
512 const double ps = getPs(pdf, E_GeV, R_m, t_ns, module[i]);
513
514 if (ps >= PMIN) {
515 buffer[i].push_back({R_m, t_ns, value, error, ps});
516 }
517 }
518 }
519 }
520 }
521 }
522
523
524 /**
525 * Get number of points.
526 *
527 * \return number of points
528 */
529 size_t getN() const
530 {
531 return buffer[0].size() + buffer[1].size();
532 }
533
534
535 /**
536 * Get chi2.
537 *
538 * \param option option
539 * \return chi2
540 */
541 double operator()(const int option) const
542 {
543 using namespace std;
544
545 double chi2 = 0.0;
546
547 for (int i = 0; i != ND; ++i) {
548
549 if (ns == 0) {
550
551 for (const auto& bin : buffer[i]) {
552
553 const double ps = getPs(pdf, E_GeV, bin.R_m, bin.t_ns, module[i]);
554
555 chi2 += bin.getChi2(ps);
556 }
557
558 } else {
559
560 {
561 JPerth perth(pdf, E_GeV, buffer[i], module[i], ns);
562 }
563
564 chi2 += JPerth::chi2;
565 }
566 }
567
568 return chi2;
569 }
570
571
572 const JPDF_C pdf; //!< PDF
573 const double E_GeV; //!< muon energy
574
575 const size_t ns; //!< number of threads
576
577 data_type buffer[ND];
578 module_type module[ND];
579
580
581 /**
582 * Thread pool for fits to data.
583 */
584 struct JPerth {
585 /**
586 * Constructor.
587 *
588 * \param pdf PDF
589 * \param E_GeV energy [GeV]
590 * \param data data
591 * \param module optical module
592 * \param ns number of threads
593 */
594 JPerth(const JPDF_C& pdf,
595 const double E_GeV,
596 const data_type& data,
597 const module_type& module,
598 const size_t ns) :
599 input(data),
600 stop(false)
601 {
602 using namespace std;
603 using namespace JPP;
604
605 chi2 = 0.0;
606
607 for (size_t i = 0; i < ns; ++i) {
608
609 thread worker([this, pdf, E_GeV, module]() {
610
611 for ( ; ; ) {
612
613 bin_type bin;
614
615 {
616 unique_lock<mutex> lock(in);
617
618 cv.wait(lock, [this]() { return stop || this->input.hasNext(); });
619
620 if (stop && !this->input.hasNext()) {
621 return;
622 }
623
624 bin = *(this->input.next());
625 }
626
627 const double ps = getPs(pdf, E_GeV, bin.R_m, bin.t_ns, module);
628
629 {
630 unique_lock<mutex> lock(out);
631
632 chi2 += bin.getChi2(ps);
633 }
634 }
635 });
636
637 workers.emplace_back(std::move(worker));
638 }
639 }
640
641
642 /**
643 * Destructor.
644 */
645 ~JPerth()
646 {
647 using namespace std;
648
649 {
650 unique_lock<mutex> lock(in);
651
652 stop = true;
653 }
654
655 cv.notify_all();
656
657 for (auto& worker : workers) {
658 worker.join();
659 }
660 }
661
662
663 static double chi2; //!< final result
664
665 private:
666 input_type input;
668 std::mutex in;
669 std::mutex out;
670 std::condition_variable cv;
671 bool stop;
672 };
673 };
674
675 /**
676 * Storage of bins.
677 */
678 JWifi::bins_type JWifi::bins = { 1, 1};
679
680 /**
681 * Storage of result of multi-threading.
682 */
683 double JWifi::JPerth::chi2 = 0.0;
684
685
686 /**
687 * Fit options.
688 */
689 const char* const absorption_factor_t = "absorption_factor";
690 const char* const absorption_offset_t = "absorption_offset";
691 const char* const scattering_factor_t = "scattering_factor";
692 const char* const qe_factor_t = "qe_factor";
693 const char* const mixed_factor_a_t = "mixed_factor_a";
694 const char* const mixed_factor_b_t = "mixed_factor_b";
695 const char* const mixed_offset_a_t = "mixed_offset_a";
696 const char* const mixed_offset_b_t = "mixed_offset_b";
697}
698
699
700/**
701 * Application to fit parameters to stopping muon data.
702 *
703 * \author mdejong
704 */
705int main(int argc, char **argv)
706{
707 using namespace std;
708 using namespace JPP;
709
710 typedef std::pair<double, double> parameter_type;
711 typedef map<string, parameter_type> option_type;
712
713 experiment_type setup;
714 JAbsorptionLength absorptionLength;
715 JScatteringLength scatteringLength;
716 double E_GeV;
717 double angle_Deg;
718 size_t threads;
719 option_type option;
720 bool normalise;
722 int debug;
723
724 try {
725
726 JProperties properties;
727
728 properties.insert(gmake_property(absorptionLength));
729 properties.insert(gmake_property(scatteringLength));
730
731 JParser<> zap;
732
733 zap['@'] = make_field(properties, endl
734 << "possible options absorptionLength: " << get_keys(absorptionLength) << endl
735 << "possible options scatteringLength: " << get_keys(scatteringLength) << endl) = JPARSER::initialised();
736 zap['f'] = make_field(setup,
737 "douplet of histograms corresponding to scattered and direct light, "
738 << "each of which defined by <file name>:<histogram name>");
739 zap['E'] = make_field(E_GeV, "muon energy [GeV]") = 10.0;
740 zap['G'] = make_field(angle_Deg, "grid angle for PMT directions [deg]") = 25.0;
741 zap['M'] = make_field(JWifi::bins, "number of points in distance and time bin") = JPARSER::initialised();
742 zap['N'] = make_field(threads, "number threads") = 0;
743 zap['O'] = make_field(option, "fit options: \"parameter <start value> <step size>\"" << endl
744 << "possible parameters: "
745 << absorption_factor_t << ", "
746 << absorption_offset_t << ", "
747 << scattering_factor_t << ", "
748 << qe_factor_t << ", "
749 << mixed_factor_a_t << ", "
750 << mixed_factor_b_t << ", "
751 << mixed_offset_a_t << ", "
752 << mixed_offset_b_t);
753 zap['n'] = make_field(normalise, "normalise gradient");
754 zap['x'] = make_field(xs, "scan step sizes") = JPARSER::initialised();
755 zap['d'] = make_field(debug) = 2;
756
757 zap(argc, argv);
758 }
759 catch(const exception& error) {
760 FATAL(error.what() << endl);
761 }
762
763
764 const TH2* ha = dynamic_cast<const TH2*>(getObject(setup.Ha));
765 const TH2* hb = dynamic_cast<const TH2*>(getObject(setup.Hb));
766
767 if (ha == NULL) { FATAL("Missing histogram: " << setup.Ha << endl); }
768 if (hb == NULL) { FATAL("Missing histogram: " << setup.Hb << endl); }
769
770 const JWifi wifi(E_GeV, ha, hb, angle_Deg, threads);
771
772 // fit
773
774 JGradient fit(FIT::number_of_iterations, FIT::number_of_extra_steps, FIT::epsilon, 3);
775
776 fit.normalise = normalise;
777
778 auto fp = [&option, &fit](const string& key, double& value, const range_type& range) {
779 if (option.count(key)) {
780 fit.push_back(JModifier_t(key, new JEditor(value = option[key].first, range), option[key].second));
781 }
782 };
783
784 fp(absorption_factor_t, JAbsorptionLength::get_factor(), range_type(0.1, 1.0e1));
785 fp(absorption_offset_t, JAbsorptionLength::get_offset(), range_type(1.0, 1.0e6));
786 fp(scattering_factor_t, JScatteringLength::get_factor(), range_type(0.1, 1.0e1));
787 fp(qe_factor_t, JQE ::get_factor(), range_type(0.1, 1.0e1));
788 fp(mixed_factor_a_t, JMixed ::get_factor_a(), range_type(0.1, 1.0e1));
789 fp(mixed_factor_b_t, JMixed ::get_factor_b(), range_type(0.1, 1.0e1));
790 fp(mixed_offset_a_t, JMixed ::get_offset_a(), range_type(1.0, 1.0e6));
791 fp(mixed_offset_b_t, JMixed ::get_offset_b(), range_type(1.0, 1.0e6));
792
793 const chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
794
795 const double chi2 = fit(wifi);
796
797 const chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
798
799 cout << "chi2/NDF " << FIXED(9,5) << chi2 << "/" << setw(4) << (wifi.getN() - fit.size()) << endl;
800
801 cout << "Elapsed time: " << setw(6) << (t1 - t0) / chrono::seconds(1) << " [s]" << endl;
802
803 for (const auto& i : fit) {
804 cout << left << setw(36) << i.name << ' ' << right << FIXED(13,3) << dynamic_cast<const JEditor*>(i.get())->getValue() << endl;
805 }
806
807 auto get_offset = [](const double x1, const double x2) { const double y = 1.0/x1 + 1.0/x2; return 1.0/y; };
808 auto get_factor = [](const double x1, const double x2) { return x1 * x2; };
809
810 cout << "Additional absorption length: " << FIXED(13,5) << get_offset(JAbsorptionLength::get_offset(), JMixed::getOffsetAbsorptionLength()) << " [m]" << endl;
811 cout << "Scaling of absorption length: " << FIXED(13,5) << get_factor(JAbsorptionLength::get_factor(), JMixed::getFactorAbsorptionLength()) << endl;
812 cout << "Scaling of scattering length: " << FIXED(13,5) << JScatteringLength::get_factor() << endl;
813 cout << "Scaling of QE: " << FIXED(13,5) << get_factor(JQE ::get_factor(), JMixed::getFactorQE()) << endl;
814
815 if (!xs.empty()) {
816 fit(cout, wifi, xs);
817 }
818}
double getAngularAcceptance(const double x)
Angular acceptence of PMT.
Definition JDrawLED.cc:68
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition JHead.hh:1850
Mathematical constants.
General purpose messaging.
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:74
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2140
Utility class to parse parameter values.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
Auxiliary class to define a range between two values.
int numberOfPoints
Definition JResultPDF.cc:22
Properties of KM3NeT PMT and deep-sea water.
Utility class to parse parameter values.
Data structure for angles in three dimensions.
Definition JAngle3D.hh:35
Direction set covering (part of) solid angle.
Definition JOmega3D.hh:68
Auxiliary class to handle file name, ROOT directory and object name.
Utility class to parse command line options.
Definition JParser.hh:1697
Probability Density Functions of the time response of a PMT with an implementation of the JAbstractPM...
Definition JPDF.hh:2188
Range of values.
Definition JRange.hh:42
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
int main()
double getAmbientPressure()
Get ambient pressure.
Definition Antares.hh:40
double getScatteringLength(const double lambda)
Get scattering length.
Definition Antares.hh:148
double getScatteringProbability(const double x)
Function to describe light scattering in water.
Definition Antares.hh:210
double getPhotocathodeArea()
Get photo-cathode area of PMT.
Definition Antares.hh:51
double getAbsorptionLength(const double lambda)
Get absorption length.
Definition Antares.hh:63
JCombinatorics::pair_type pair_type
double getQE(const double R, const double mu)
Get QE for given ratio of hit probabilities and expectation value of the number of photo-electrons.
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
Definition JScale.hh:47
double getChi2(const double P)
Get chi2 corresponding to given probability.
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition JString.hh:478
Auxiliary methods for light properties of deep-sea water.
double getMinimalWavelength()
Get minimal wavelength for PDF evaluations.
double getMaximalWavelength()
Get maximal wavelength for PDF evaluations.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
JLANG::JSTDObjectReader< const event_type > input_type
Definition JPerth.cc:106
std::vector< event_type > data_type
Definition JPerth.cc:105
double getN(const JRange< T > &range, const double R)
Get expected number of occurrences due to given rate within specified interval.
Definition JRange.hh:704
JRange< int > range_type
Name space for KM3NeT.
Definition Jpp.hh:16
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition JFitK40.hh:110
Conjugate gradient fit.
Definition JGradient.hh:76
bool normalise
normalise gradient
Definition JGradient.hh:301
Auxiliary data structure for editable parameter.
Definition JGradient.hh:50
Auxiliary data structure for fit parameter.
Definition JGradient.hh:29
Implementation of object iteration from STD container.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:67
Auxiliary data structure to customize absorption length.
Auxiliary data structure to customize quantum efficiency.
Auxiliary data structure to customize scattering length.
Thread pool for fits to data.
Definition JPerth.cc:162
Data structure for a pair of indices.