1#ifndef __JCALIBRATE_JFITK40__
2#define __JCALIBRATE_JFITK40__
43 using KM3NETDAQ::NUMBER_OF_PMTS;
109 public std::map<pair_type, std::vector<rate_type> >
117 public JMath<JParameter_t>
331 const double x =
get();
344 const double x =
get();
411 operator double()
const
440 return in >>
object.value;
455 out <<
FIXED(12,6) <<
object.get() <<
' '
456 << setw(5) << (
object.isFixed() ?
"fixed" :
" ") <<
' ';
459 out <<
"[" <<
FIXED(12,6) <<
object.range.getLowerLimit() <<
"," <<
FIXED(12,6) <<
object.range.getUpperLimit() <<
"]";
503 parameters.
QE .
set(1.0);
505 parameters.
t0 .
set(0.0);
506 parameters.
bg .
set(0.0);
533 if (
QE .isFree()) {
QE .
set(parameters.
QE); }
535 if (
t0 .isFree()) {
t0 .
set(parameters.
t0); }
536 if (
bg .isFree()) {
bg .
set(parameters.
bg); }
547 return ((
QE. isFree() ? 1 : 0) +
593 out <<
"QE " <<
FIXED(7,3) <<
object.QE << endl;
594 out <<
"TTS " <<
FIXED(7,3) <<
object.TTS << endl;
595 out <<
"t0 " <<
FIXED(7,3) <<
object.t0 << endl;
596 out <<
"bg " <<
FIXED(7,3) <<
object.bg << endl;
669 out <<
"JFitK40.hh" << endl;
670 out <<
"parameters.R .set(" <<
FIXED(9,6) << this->
R () <<
");" << endl;
671 out <<
"parameters.p1.set(" <<
FIXED(9,6) << this->
p1() <<
");" << endl;
672 out <<
"parameters.p2.set(" <<
FIXED(9,6) << this->
p2() <<
");" << endl;
673 out <<
"parameters.p3.set(" <<
FIXED(9,6) << this->
p3() <<
");" << endl;
674 out <<
"parameters.p4.set(" <<
FIXED(9,6) << this->
p4() <<
");" << endl;
675 out <<
"cc " <<
FIXED(9,6) << this->
cc() << endl;
676 out <<
"bc " <<
FIXED(9,6) << this->
bc() << endl;
679 out <<
"JK40DefaultSimulator.hh" << endl;
680 out <<
"static constexpr double p1 = " <<
FIXED(9,6) << this->
p1() <<
";" << endl;
681 out <<
"static constexpr double p2 = " <<
FIXED(9,6) << this->
p2() <<
";" << endl;
682 out <<
"static constexpr double p3 = " <<
FIXED(9,6) << this->
p3() <<
";" << endl;
683 out <<
"static constexpr double p4 = " <<
FIXED(9,6) << this->
p4() <<
";" << endl;
699 out <<
"Rate [Hz] " <<
FIXED(12,6) <<
object.R << endl;
700 out <<
"p1 " <<
FIXED(12,6) <<
object.p1 << endl;
701 out <<
"p2 " <<
FIXED(12,6) <<
object.p2 << endl;
702 out <<
"p3 " <<
FIXED(12,6) <<
object.p3 << endl;
703 out <<
"p4 " <<
FIXED(12,6) <<
object.p4 << endl;
704 out <<
"cc " <<
FIXED(12,6) <<
object.cc << endl;
705 out <<
"bc " <<
FIXED(12,6) <<
object.bc << endl;
745 parameters.
R .
set(18.430675);
746 parameters.
p1.
set( 2.919895);
747 parameters.
p2.
set(-0.831970);
748 parameters.
p3.
set( 1.407887);
749 parameters.
p4.
set( 0.170510);
750 parameters.
cc.
set( 0.0);
751 parameters.
bc.
set( 0.0);
764 return ((
R .isFree() ? 1 : 0) +
782 if (!(this->*p).isFree()) {
823 const double ct2 = ct * ct;
853 this->
R .
set( 0.595927);
854 this->
p1.
set(-0.032784);
855 this->
p2.
set( 0.075297);
856 this->
p3.
set(-0.076032);
857 this->
p4.
set(-0.453102);
943 return { (char) (
'A' + index) };
969 return out << ring.
c;
990 const double rz[] = {
999 const int N =
sizeof(rz) /
sizeof(rz[0]);
1001 for (
int i = 1; i != N; ++i) {
1002 if (dz <= 0.5 * (rz[i-1] + rz[i])) {
1032 (*this)[i].set(0.0);
1045 if ((*
this)[i].isFree()) { (*this)[i].set(parameters[i].get()); }
1074 transmittance[i].
set(1.0);
1077 return transmittance;
1091 if ((*
this)[i].isFree()) {
1111 return w * (*this)[
pair.first].get() * (*this)[
pair.second].get() + (1.0 - w);
1144 using namespace std;
1176 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1191 using namespace std;
1193 out <<
object.model;
1194 out <<
object.transmittance;
1196 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1197 out <<
"PMT[" <<
FILL(2,
'0') << i <<
FILL() <<
"]." <<
object.parameters[i].status << endl <<
object.parameters[i];
1257 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1261 for (JTDC_t::const_iterator i = TDC.first; i != TDC.second; ++i) {
1265 this->parameters[i->second].t0.fix();
1269 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1270 this->parameters[i].t0.fix();
1295 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1333 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1347 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1379 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1397 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1435 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1464 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1493 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1537 pair.second == this->index ? +this->parameters[
pair.first ].t0() :
1538 this->parameters[
pair.first].t0() - this->parameters[
pair.second].t0());
1541 this->parameters[
pair.second].TTS() * this->parameters[
pair.second].TTS() +
1542 this->getSigmaK40() * this->getSigmaK40());
1551 const double z1 = (*this)[
pair.first ].getDirection().getDZ();
1552 const double z2 = (*this)[
pair.second].getDirection().getDZ();
1556 signbit(z1) != signbit(z2)) {
1586 using namespace std;
1587 using namespace JPP;
1594 const double R2 = bell .
getValue(dt_ns);
1609 using namespace std;
1611 out <<
"Module " << setw(10) <<
object.getID() << endl;
1612 out <<
"option " <<
object.option << endl;
1613 out <<
"index " <<
object.index << endl;
1615 out << static_cast<const JModel_t&>(
object);
1654 using namespace JPP;
1668 using namespace std;
1669 using namespace JPP;
1680 double xmax = numeric_limits<double>::lowest();
1681 double xmin = numeric_limits<double>::max();
1685 for (data_type::const_iterator ix = data.begin(); ix != data.end(); ++ix) {
1692 ndf += ix->second.size();
1694 for (
const rate_type& iy : ix->second) {
1704 return { 0.0, ndf };
1707 for (
int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
1716 double precessor = numeric_limits<double>::max();
1758 if (
debug >= debug_t) {
1773 for (
int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
1783 for (
size_t i = 0; i != N; ++i) {
1789 h[i] = 1.0 / sqrt(
V(i,i));
1794 for (
size_t i = 0; i != N; ++i) {
1795 for (
size_t j = 0; j != i; ++j) {
1796 V(j,i) *=
h[i] *
h[j];
1801 for (
size_t i = 0; i != N; ++i) {
1807 for (
size_t col = 0; col != N; ++col) {
1814 catch (
const exception&
error) {
1816 ERROR(
"JGandalf: " <<
error.what() << endl <<
V << endl);
1823 const double factor = 2.0;
1839 for (
int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
1849 return { precessor /
estimator->getRho(1.0), ndf };
1859 static constexpr double PIVOT = std::numeric_limits<double>::epsilon();
1880 using namespace std;
1881 using namespace JPP;
1919 const struct T_t :
public std::array<int, NUMBER_OF_RINGS> {
1929 if (value.
transmittance[i].isFree()) { (*this)[i] = N; ++N; }
1951 const struct I_t :
public std::array<i_t, NUMBER_OF_PMTS> {
1956 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
1968 double operator[](
const int index)
const
1970 for (const_iterator i = this->begin(); i != this->end(); ++i) {
1971 if (i->first == index) {
1982#define PUSH_BACK(i,v) if (i != INVALID_INDEX) { buffer.push_back({i, v}); }
1985 size_t number_of_errors = 0;
1987 for (data_type::const_iterator ix = data.begin(); ix != data.end(); ++ix) {
2003 for (
const rate_type& iy : ix->second) {
2008 const double R = real.bc + real.
background + T1 *
R1 * (real.cc + R2);
2039 DEBUG(
"PMT pair(" << setw(2) <<
pair.first <<
"," << setw(2) <<
pair.second <<
") " <<
FIXED(7,3) << iy.
dt_ns <<
" [ns]" << endl);
2041 const double PRECISION = 1.0e-5;
2043#define MAKE_TEST(i,v) if (i != INVALID_INDEX) { \
2045 const bool status = fabs(buffer[i] - v) <= PRECISION; \
2047 DEBUG((status ? GREEN : RED) \
2048 << setw(20) << left << #i << right << ' ' \
2049 << setw(3) << i << ' ' \
2050 << FIXED(12,5) << buffer[i] << ' ' \
2051 << FIXED(12,5) << v << ' ' \
2052 << (!status ? "***" : "") \
2053 << RESET << endl); \
2056 number_of_errors += 1; \
2064 static_cast<JModel&
>(*this) = model;
2066 this->model.R .relax();
2067 this->model.p1.relax();
2068 this->model.p2.relax();
2069 this->model.p3.relax();
2070 this->model.p4.relax();
2071 this->model.cc.relax();
2072 this->model.bc.relax();
2074 for (
int i = 0; i != NUMBER_OF_PMTS; ++i) {
2075 parameters[i].QE .relax();
2076 parameters[i].TTS.relax();
2077 parameters[i].t0 .relax();
2078 parameters[i].bg .relax();
2090 const double DX = 1.0e-8;
2124 for (buffer_type::const_iterator row = buffer.begin(); row != buffer.end(); ++row) {
2126 Y[row->first] += row->second;
2128 V[row->first][row->first] += row->second * row->second;
2130 for (buffer_type::const_iterator col = buffer.begin(); col != row; ++col) {
2131 V[row->first][col->first] += row->second * col->second;
2132 V[col->first][row->first] =
V[row->first][col->first];
2143 STATUS(
"Test finished with " << number_of_errors <<
" errors." << endl);
2145 exit(number_of_errors == 0 ? 0 : 1);
2157 using namespace std;
2166 catch (
const exception&
error) {}
2168#define SQRT(X) (X >= 0.0 ? sqrt(X) : std::numeric_limits<double>::max())
2184 for (
int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
KM3NeT DAQ constants, bit handling, etc.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Maximum likelihood estimator (M-estimators).
Base class for data structures with artithmetic capabilities.
General purpose messaging.
#define DEBUG(A)
Message macros.
Data structure for optical module.
Auxiliary class to define a range between two values.
std::shared_ptr< JMEstimator > estimator_type
static constexpr double LAMBDA_MIN
minimal value control parameter
static constexpr double LAMBDA_DOWN
multiplication factor control parameter
result_type operator()(const data_type &data)
Fit.
void seterr(const data_type &data)
Set errors.
static constexpr double LAMBDA_MAX
maximal value control parameter
static constexpr double LAMBDA_UP
multiplication factor control parameter
static constexpr double EPSILON
maximal distance to minimum.
JFit(const int option, const int debug)
Constructor.
void evaluate(const data_type &data)
Evaluation of fit.
static constexpr int MAXIMUM_ITERATIONS
maximal number of iterations.
static constexpr double PIVOT
minimal value diagonal element of matrix
estimator_type estimator
M-Estimator function.
Auxiliary class for fit parameter with optional limits.
JParameter_t & mul(const double factor)
Scale parameter.
void set(const double value)
Set value.
void fix()
Fix current value.
JParameter_t & sub(const JParameter_t ¶meter)
Subtract parameter.
JParameter_t & operator=(double value)
Assignment operator.
bool isFree() const
Check if parameter is free.
friend std::ostream & operator<<(std::ostream &out, const JParameter_t &object)
Write parameter to output stream.
friend std::istream & operator>>(std::istream &in, JParameter_t &object)
Read parameter from input stream.
JParameter_t & div(const double factor)
Scale parameter.
void relax()
Relax limits.
JParameter_t & mul(const JParameter_t &first, const JParameter_t &second)
Scale parameter.
double operator()() const
Type conversion operator.
void set()
Set current value.
JParameter_t(const double value, const range_type &range=range_type::DEFAULT_RANGE())
Constructor.
JParameter_t & negate()
Negate parameter.
JParameter_t()
Default constructor.
bool atLimit(const double precision) const
Check if parameter is at limit.
JTOOLS::JRange< double > range_type
Type definition for range of parameter values.
double getDerivative() const
Get derivative of value.
void setLimits(const double xmin, const double xmax)
Set limits.
JParameter_t & add(const JParameter_t ¶meter)
Add parameter.
void fix(const double value)
Fix value.
double get() const
Get value.
bool isBound() const
Check if parameter is bound.
bool isFixed() const
Check if parameter is fixed.
Interface to read input and write output for TObject tests.
Data structure for a composite optical module.
Exception for accessing a value in a collection that is outside of its range.
Auxiliary classes and methods for PMT calibration.
static double TEROSTAT_R1
scaling factor
const JWater getWater
Function object for fraction of water to total.
static const int INVALID_INDEX
invalid index
@ FIT_PMTS_QE_FIXED_t
fit parameters of PMTs with QE fixed
@ FIT_PMTS_AND_ANGULAR_DEPENDENCE_t
fit parameters of PMTs and angular dependence of K40 rate
@ FIT_MODEL_t
fit parameters of K40 rate and TTSs of PMTs
@ FIT_PMTS_AND_BACKGROUND_t
fit parameters of PMTs and background
@ FIT_PMTS_t
fit parameters of PMTs
static const int NUMBER_OF_RINGS
number of rings in optical module.
static double TEROSTAT_DZ
maximal PMT inclination
std::pair< int, int > ring_pair
Type definition of indices of pair of rings.
ring_type getRing(const double dz)
Get ring.
static double BELL_SHAPE
Bell shape.
double getDot(const JFirst_t &first, const JSecond_t &second)
Get dot product of objects.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for sequence of same character.
Auxiliary data structure for floating point format specification.
PMT combinatorics for optical module.
Fit parameters for two-fold coincidence rate due to K40.
JParameter_t bc
constant background
JParameter_t R
maximal coincidence rate [Hz]
JParameter_t p1
1st order angle dependence coincidence rate
JParameter_t p2
2nd order angle dependence coincidence rate
friend std::ostream & operator<<(std::ostream &out, const JK40Parameters_t &object)
Write model parameters to output stream.
JParameter_t p3
3rd order angle dependence coincidence rate
const JK40Parameters_t & getK40Parameters() const
Get K40 parameters.
JParameter_t p4
4th order angle dependence coincidence rate
JParameter_t cc
fraction of signal correlated background
JK40Parameters_t()
Default constructor.
void setK40Parameters(const JK40Parameters_t ¶meters)
Set K40 parameters.
void print(std::ostream &out) const
Print model parameters to output stream conform include files.
Fit parameters for two-fold coincidence rate due to K40.
size_t getN() const
Get number of fit parameters.
const JK40Parameters_t & getGradient(const double ct) const
Get gradient.
JK40Parameters_t gradient
static const JK40Parameters & getInstance()
Get default values.
int getIndex(JParameter_t JK40Parameters::*p) const
Get index of parameter.
double getValue(const double ct) const
Get K40 coincidence rate as a function of cosine angle between PMT axes.
JK40Parameters()
Default constructor.
Auxiliary data structure for derived quantities of a given PMT pair.
double signal
combined signal
double sigma
total width [ns]
double cc
correlated background
double background
combined background
double t0
time offset [ns]
ring_pair pair
PMT ring pair.
double bc
uncorrelated background
double ct
cosine angle between PMT axes
JTransmittance transmittance
friend std::ostream & operator<<(std::ostream &out, const JModel_t &object)
Write model parameters to output stream.
JPMTParameters_t parameters[NUMBER_OF_PMTS]
JModel()
Default constructor.
friend std::ostream & operator<<(std::ostream &out, const JModel &object)
Write model parameters to output stream.
size_t getN() const
Get number of fit parameters.
double getValue(const double ct) const
Get K40 coincidence rate as a function of cosine angle between PMT axes.
double sigmaK40_ns
intrinsic K40 arrival time spread [ns]
JOption_t getOption() const
Get fit option.
double getFixedTimeOffset() const
Get time offset.
void setSigmaK40(const double sigma)
Set intrinsic K40 arrival time spread.
int getIndex() const
Get index of PMT used for fixed time offset.
double getSigmaK40() const
Get intrinsic K40 arrival time spread.
void setOption(const int option)
Set fit option.
const real_type & getReal(const pair_type &pair) const
Get derived quantities.
JModel(const JModule &module, const JK40Parameters ¶meters)
Constructor.
double getValue(const pair_type &pair, const double dt_ns) const
Get K40 coincidence rate.
void setIndex()
Set index of PMT used for fixed time offset.
JOption_t option
fit option (see JCALIBRATE::JOption_t)
JModel(const JModule &module, const JK40Parameters ¶meters, const JTDC_t::range_type &TDC, const int option)
Constructor.
bool hasFixedTimeOffset() const
Check if time offset is fixed.
int index
index of PMT used for fixed time offset
Fit parameters for single PMT.
static constexpr double QE_MIN
minimal QE
friend std::ostream & operator<<(std::ostream &out, const JPMTParameters_t &object)
Write PMT parameters to output stream.
JParameter_t t0
time offset [ns]
static constexpr double TTS_NS
start value transition-time spread [ns]
JParameter_t TTS
transition-time spread [ns]
void disable()
Disable PMT.
size_t getN() const
Get number of fit parameters.
JPMTParameters_t()
Default constructor.
void set(const JPMTParameters_t ¶meters)
Set parameters that are free to given values.
JParameter_t bg
background [Hz/ns]
static constexpr double QE_MAX
maximal QE
static const JPMTParameters_t & getInstance()
Get default values.
JParameter_t QE
relative quantum efficiency [unit]
Auxiliary data structure to handle transmittance of glass sphere due to sedimentation.
void set(const JTransmittance_t ¶meters)
Set parameters that are free to given values.
JTransmittance_t()
Default constructor.
Auxiliary data structure to handle transmittance of glass sphere due to sedimentation.
JTransmittance()
Default constructor.
JTransmittance_t gradient
size_t getN() const
Get number of fit parameters.
double getValue(const double ct, const ring_pair pair) const
Get weighed contribution of water and glass.
friend std::ostream & operator<<(std::ostream &out, const JTransmittance &object)
Write transmittances to output stream.
const JTransmittance_t & getGradient(const double ct, const ring_pair pair) const
Get gradient.
static const JTransmittance & getInstance()
Get default values.
Auxiliary data structure for fraction of water to total.
double operator()(const double ct) const
Get fraction of water as a function of cosine angle between PMT axes.
JWater()
Default constructor.
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Data structure for measured coincidence rate of pair of PMTs.
rate_type(double dt_ns, double value, double error)
Constructor.
double error
error of rate [Hz/ns]
double value
value of rate [Hz/ns]
rate_type()
Default constructor.
double dt_ns
time difference [ns]
Auxiliary data structure to define ring.
int getIndex() const
Get index.
friend std::ostream & operator<<(std::ostream &out, const ring_type &ring)
Write ring to output stream.
friend std::istream & operator>>(std::istream &in, ring_type &ring)
Read ring from input stream.
ring_type(const char c)
Constructor.
static ring_type getRing(const int index)
Get ring.
Interface for maximum likelihood estimator (M-estimator).
const JBell_t & getGradient(const double x) const
Get gradient.
double getValue(const double x) const
Function value.
Auxiliary base class for aritmetic operations of derived class types.
void resize(const size_t size)
Resize matrix.
JMatrixND & reset()
Set matrix to the null matrix.
void solve(JVectorND_t &u)
Get solution of equation A x = b.
void invert()
Invert matrix according LDU decomposition.