1 #ifndef __JCALIBRATE_JGANDALFK40__ 
    2 #define __JCALIBRATE_JGANDALFK40__ 
  102     public std::map<pair_type, std::vector<rate_type> >
 
  110     public JMath<JParameter_t>
 
  359     operator double()
 const 
  388       return in >> 
object.value;
 
  403       out << 
FIXED(12,6) <<  
object.get()                       << 
' ' 
  404           << setw(5)     << (
object.isFixed() ? 
"fixed" : 
" ")  << 
' ';
 
  407         out << 
FIXED(12,6) << 
object.value                 << 
' ';
 
  408         out << 
FIXED(12,6) << 
object.range.getLowerLimit() << 
' ' 
  409             << 
FIXED(12,6) << 
object.range.getUpperLimit();
 
  427     static constexpr 
double  QE_MIN  =  0.0;   
 
  428     static constexpr 
double  QE_MAX  =  2.0;   
 
  429     static constexpr 
double  TTS_NS  =  2.0;   
 
  467       parameters.
QE .
set(1.0);
 
  468       parameters.
TTS.
set(TTS_NS);
 
  469       parameters.
t0 .
set(0.0);
 
  470       parameters.
bg .
set(0.0);
 
  483       return ((QE. 
isFree() ? 1 : 0) +
 
  484               (TTS.isFree() ? 1 : 0) +
 
  485               (t0 .isFree() ? 1 : 0) +
 
  486               (bg .isFree() ? 1 : 0));
 
  498       if (!(this->*p).
isFree()) {
 
  552       out << 
"QE  " << 
FIXED(7,3) << 
object.QE  << endl;
 
  553       out << 
"TTS " << 
FIXED(7,3) << 
object.TTS << endl;
 
  554       out << 
"t0  " << 
FIXED(7,3) << 
object.t0  << endl;
 
  555       out << 
"bg  " << 
FIXED(7,3) << 
object.bg  << endl;
 
  631       parameters.
R .
set(18.460546);
 
  632       parameters.
p1.
set( 3.0767);
 
  633       parameters.
p2.
set(-1.2078);
 
  634       parameters.
p3.
set( 0.9905);
 
  635       parameters.
p4.
set( 0.9379);
 
  636       parameters.
cc.
set( 0.0);
 
  671       return ((R .
isFree() ? 1 : 0) +
 
  672               (
p1.isFree() ? 1 : 0) +
 
  673               (p2.isFree() ? 1 : 0) +
 
  674               (p3.isFree() ? 1 : 0) +
 
  675               (p4.isFree() ? 1 : 0) +
 
  676               (cc.isFree() ? 1 : 0));
 
  688       if (!(this->*p).
isFree()) {
 
  713       return R * exp(ct*(
p1+ct*(p2+ct*(p3+ct*p4))) - (
p1+p2+p3+p4));
 
  728       const double ct2   = ct * ct;
 
  730       if (R .
isFree()) { gradient.R  = rate / R; }
 
  731       if (
p1.isFree()) { gradient.p1 = rate * ct         -  rate; }
 
  732       if (p2.isFree()) { gradient.p2 = rate * ct2        -  rate; }
 
  733       if (p3.isFree()) { gradient.p3 = rate * ct2 * ct   -  rate; }
 
  734       if (p4.isFree()) { gradient.p4 = rate * ct2 * ct2  -  rate; }
 
  735       if (cc.isFree()) { gradient.cc = rate; }
 
  794       setK40Parameters(parameters);
 
  800       for (JTDC_t::const_iterator i = TDC.first; i != TDC.second; ++i) {
 
  804           this->parameters[i->second].t0.fix();
 
  809             this->parameters[i].t0.fix();
 
  831       setK40Parameters(parameters);
 
  868           parameters[i].bg.fix();
 
  878           parameters[i].bg.fix();
 
  902           parameters[i].QE.fix();
 
  903           parameters[i].bg.fix();
 
  913           parameters[i].QE.fix();
 
  914           parameters[i].t0.fix();
 
  915           parameters[i].bg.fix();
 
  951         if (parameters[i].t0.isFree()) {
 
  952           t0 += parameters[i].t0;
 
  981           if (parameters[i].status) {
 
  985             parameters[index].t0.fix();
 
 1006         N += parameters[i].getN();
 
 1023       for (
int i = 0; i != pmt; ++i) {
 
 1024         N += parameters[i].getN();
 
 1040       return getIndex(pmt) + parameters[pmt].getIndex(p);
 
 1051       return this->sigmaK40_ns;
 
 1062       this->sigmaK40_ns = 
sigma;
 
 1076       real.t0         = (
pair.first  == this->index  ?  -this->parameters[
pair.second].t0()  :
 
 1077                          pair.second == this->index  ?  +this->parameters[
pair.first ].t0()  :
 
 1078                          this->parameters[
pair.first].t0() - this->parameters[
pair.second].t0());
 
 1080       real.sigma      =  sqrt(this->parameters[
pair.first ].TTS() * this->parameters[
pair.first ].TTS()  +
 
 1081                               this->parameters[
pair.second].TTS() * this->parameters[
pair.second].TTS()  +
 
 1082                               this->getSigmaK40()                 * this->getSigmaK40());
 
 1084       real.signal     =  this->parameters[
pair.first].QE() * this->parameters[
pair.second].QE();
 
 1086       real.background =  this->parameters[
pair.first].bg() + this->parameters[
pair.second].bg();
 
 1101       using namespace std;
 
 1102       using namespace JPP;
 
 1109       const double R2  = 
gauss.getValue(dt_ns);
 
 1123       using namespace std;
 
 1124       using namespace JPP;
 
 1129       const double R2  = real.
signal;
 
 1144       using namespace std;
 
 1146       out << 
"Module    " << setw(10)  << 
object.getID() << endl;
 
 1147       out << 
"option    " << 
object.option << endl;
 
 1148       out << 
"index     " << 
object.index  << endl;
 
 1149       out << 
"Rate [Hz] " << 
FIXED(12,6) << 
object.R  << endl;
 
 1150       out << 
"p1        " << 
FIXED(12,6) << 
object.p1 << endl;
 
 1151       out << 
"p2        " << 
FIXED(12,6) << 
object.p2 << endl;
 
 1152       out << 
"p3        " << 
FIXED(12,6) << 
object.p3 << endl;
 
 1153       out << 
"p4        " << 
FIXED(12,6) << 
object.p4 << endl;
 
 1154       out << 
"cc        " << 
FIXED(12,6) << 
object.cc << endl;
 
 1157         out << 
"PMT[" << 
FILL(2,
'0') << i << 
FILL() << 
"]." << 
object.parameters[i].status << endl << 
object.parameters[i];
 
 1167     double            sigmaK40_ns  =  0.54;         
 
 1199       using namespace JPP;
 
 1213       using namespace std;
 
 1214       using namespace JPP;
 
 1219       const size_t N = 
value.getN();
 
 1227       for (data_type::const_iterator ix = 
data.begin(); ix != 
data.end(); ++ix) {
 
 1231         if (
value.parameters[
pair.first ].status &&
 
 1234           ndf += ix->second.size();
 
 1238       ndf -= 
value.getN();
 
 1241       lambda    = LAMBDA_MIN;
 
 1243       double precessor = numeric_limits<double>::max();
 
 1245       for (numberOfIterations = 0; numberOfIterations != MAXIMUM_ITERATIONS; ++numberOfIterations) {
 
 1247         DEBUG(
"step:     " << numberOfIterations << endl);
 
 1251         DEBUG(
"lambda:   " << 
FIXED(12,5) << lambda    << endl);
 
 1252         DEBUG(
"chi2:     " << 
FIXED(12,3) << successor << endl);
 
 1254         if (successor < precessor) {
 
 1256           if (numberOfIterations != 0) {
 
 1258             if (fabs(precessor - successor) < EPSILON*fabs(precessor)) {
 
 1259               return { successor / estimator->getRho(1.0), ndf };
 
 1262             if (lambda > LAMBDA_MIN) {
 
 1263               lambda /= LAMBDA_DOWN;
 
 1267           precessor = successor;
 
 1273           lambda *= LAMBDA_UP;
 
 1275           if (lambda > LAMBDA_MAX) {
 
 1276             return { precessor / estimator->getRho(1.0), ndf }; 
 
 1286           if (
value.R .isFree()) { cout << 
"R  " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1287           if (
value.p1.isFree()) { cout << 
"p1 " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1288           if (
value.p2.isFree()) { cout << 
"p2 " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1289           if (
value.p3.isFree()) { cout << 
"p3 " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1290           if (
value.p4.isFree()) { cout << 
"p4 " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1291           if (
value.cc.isFree()) { cout << 
"cc " << 
FIXED(12,3) << Y[row] << endl; ++row; }
 
 1294             if (
value.parameters[pmt].QE .isFree()) { cout << 
"PMT[" << setw(2) << pmt << 
"].QE  " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1295             if (
value.parameters[pmt].TTS.isFree()) { cout << 
"PMT[" << setw(2) << pmt << 
"].TTS " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1296             if (
value.parameters[pmt].t0 .isFree()) { cout << 
"PMT[" << setw(2) << pmt << 
"].t0  " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1297             if (
value.parameters[pmt].bg .isFree()) { cout << 
"PMT[" << setw(2) << pmt << 
"].bg  " << 
FIXED(12,5) << Y[row] << endl; ++row; }
 
 1303         for (
size_t i = 0; i != N; ++i) {
 
 1305           if (V(i,i) < PIVOT) {
 
 1309           h[i] = 1.0 / sqrt(V(i,i));
 
 1314         for (
size_t i = 0; i != N; ++i) {
 
 1315           for (
size_t j = 0; 
j != i; ++
j) {
 
 1316             V(
j,i) *= h[i] * h[
j];
 
 1321         for (
size_t i = 0; i != N; ++i) {
 
 1322           V(i,i) = 1.0 + lambda;
 
 1327         for (
size_t col = 0; col != N; ++col) {
 
 1334         catch (
const exception& error) {
 
 1336           ERROR(
"JGandalf: " << error.what() << endl << V << endl);
 
 1343         const double factor = 2.0;
 
 1347         if (
value.R .isFree()) { 
value.R  -= factor * h[row] * Y[row];  ++row; }
 
 1348         if (
value.p1.isFree()) { 
value.p1 -= factor * h[row] * Y[row];  ++row; }
 
 1349         if (
value.p2.isFree()) { 
value.p2 -= factor * h[row] * Y[row];  ++row; }
 
 1350         if (
value.p3.isFree()) { 
value.p3 -= factor * h[row] * Y[row];  ++row; }
 
 1351         if (
value.p4.isFree()) { 
value.p4 -= factor * h[row] * Y[row];  ++row; }
 
 1352         if (
value.cc.isFree()) { 
value.cc -= factor * h[row] * Y[row];  ++row; }
 
 1355           if (
value.parameters[pmt].QE .isFree()) { 
value.parameters[pmt].QE  -= factor * h[row] * Y[row];  ++row; }
 
 1356           if (
value.parameters[pmt].TTS.isFree()) { 
value.parameters[pmt].TTS -= factor * h[row] * Y[row];  ++row; }
 
 1357           if (
value.parameters[pmt].t0 .isFree()) { 
value.parameters[pmt].t0  -= factor * h[row] * Y[row];  ++row; }
 
 1358           if (
value.parameters[pmt].bg .isFree()) { 
value.parameters[pmt].bg  -= factor * h[row] * Y[row];  ++row; }
 
 1362       return { precessor / estimator->getRho(1.0), ndf };
 
 1366     static constexpr 
int    MAXIMUM_ITERATIONS =  10000;                                  
 
 1367     static constexpr 
double EPSILON            = 1.0e-5;                                  
 
 1368     static constexpr 
double LAMBDA_MIN         =   0.01;                                  
 
 1369     static constexpr 
double LAMBDA_MAX         = 100.0;                                   
 
 1370     static constexpr 
double LAMBDA_UP          =  10.0;                                   
 
 1371     static constexpr 
double LAMBDA_DOWN        =  10.0;                                   
 
 1390       using namespace std;
 
 1391       using namespace JPP;
 
 1434           const int index = 
model.getIndex(pmt);
 
 1438           if (
model.parameters[pmt].QE .isFree()) { QE  = index + N; ++N; }
 
 1439           if (
model.parameters[pmt].TTS.isFree()) { TTS = index + N; ++N; }
 
 1440           if (
model.parameters[pmt].t0 .isFree()) { t0  = index + N; ++N; }
 
 1441           if (
model.parameters[pmt].bg .isFree()) { bg  = index + N; ++N; }
 
 1455       for (data_type::const_iterator ix = 
data.begin(); ix != 
data.end(); ++ix) {
 
 1459         if (
value.parameters[
pair.first ].status &&
 
 1462           const real_type& real = 
value.getReal(
pair);
 
 1464           const JGauss gauss(real.t0, real.sigma, real.signal);
 
 1466           const double            R1  = 
value.getValue   (real.ct);
 
 1472           for (
const rate_type& iy : ix->second) {
 
 1477             const double  R   = real.background + 
R1 * (
value.cc() + R2);
 
 1479             const double  w   = -estimator->getPsi(
u) / iy.
error;
 
 1481             successor += estimator->getRho(
u);
 
 1501             for (buffer_type::const_iterator row = buffer.begin(); row != buffer.end(); ++row) {
 
 1503               Y[row->first] += row->second;
 
 1505               V[row->first][row->first] += row->second * row->second;
 
 1507               for (buffer_type::const_iterator col = buffer.begin(); col != row; ++col) {
 
 1508                 V[row->first][col->first] += row->second * col->second;
 
 1509                 V[col->first][row->first]  = V[row->first][col->first];
 
JDAQPMTIdentifier PMT
Command line options.
 
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.
 
result_type operator()(const data_type &data)
Fit.
 
JFit(const int option, const int debug)
Constructor.
 
std::shared_ptr< JMEstimator > estimator_type
 
void evaluate(const data_type &data)
Evaluation of fit.
 
estimator_type estimator
M-Estimator function.
 
Auxiliary class for fit parameter with optional limits.
 
JParameter_t & div(const double factor)
Scale parameter.
 
JParameter_t & operator=(double value)
Assignment operator.
 
void set(const double value)
Set value.
 
friend std::istream & operator>>(std::istream &in, JParameter_t &object)
Read parameter from input stream.
 
void fix()
Fix current value.
 
JParameter_t & negate()
Negate parameter.
 
bool isFree() const
Check if parameter is free.
 
friend std::ostream & operator<<(std::ostream &out, const JParameter_t &object)
Write parameter to output stream.
 
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 & mul(const double factor)
Scale parameter.
 
JParameter_t()
Default constructor.
 
JParameter_t & mul(const JParameter_t &first, const JParameter_t &second)
Scale parameter.
 
double getDerivative() const
Get derivative of value.
 
JParameter_t & sub(const JParameter_t ¶meter)
Subtract parameter.
 
JParameter_t & add(const JParameter_t ¶meter)
Add parameter.
 
void fix(const double value)
Fix value.
 
double get() const
Get value.
 
JTOOLS::JRange< double > range_type
Type definition for range of parameter values.
 
bool isBound() const
Check if parameter is bound.
 
bool isFixed() const
Check if parameter is fixed.
 
Data structure for a composite optical module.
 
Exception for accessing a value in a collection that is outside of its range.
 
double getDot(const JNeutrinoDirection &first, const JNeutrinoDirection &second)
Dot product.
 
Auxiliary classes and methods for PMT calibration.
 
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
 
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
 
JMEstimator * getMEstimator(const int type)
Get M-Estimator.
 
int getIndex()
Get index for user I/O manipulation.
 
double gauss(const double x, const double sigma)
Gauss function (normalised to 1 at x = 0).
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
std::vector< JHitW0 > buffer_type
hits
 
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
 
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 R
maximal coincidence rate [Hz]
 
JParameter_t p1
1st order angle dependence coincidence rate
 
JParameter_t p2
2nd order angle dependence coincidence rate
 
JParameter_t p3
3rd order angle dependence coincidence rate
 
JParameter_t p4
4th order angle dependence coincidence rate
 
JParameter_t cc
fraction of signal correlated background
 
JK40Parameters_t()
Default constructor.
 
Fit parameters for two-fold coincidence rate due to K40.
 
size_t getN() const
Get number of fit parameters.
 
const JK40Parameters & getK40Parameters() const
Get K40 parameters.
 
JK40Parameters_t gradient
 
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.
 
const JK40Parameters_t & getGradient(const double ct) const
Get gradient.
 
static const JK40Parameters & getInstance()
Get default values.
 
void setK40Parameters(const JK40Parameters_t ¶meters)
Set K40 parameters.
 
Auxiliary data structure for derived quantities of a given PMT pair.
 
double signal
combined signal
 
double sigma
total width [ns]
 
double background
combined background
 
double t0
time offset [ns]
 
double ct
cosine angle between PMT axes
 
JModel()
Default constructor.
 
int getIndex(int pmt, JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
 
int getIndex(int pmt) const
Get index of parameter.
 
size_t getN() const
Get number of fit parameters.
 
double getValue(const pair_type &pair) const
Get K40 coincidence rate.
 
JOption_t getOption() const
Get fit option.
 
double getFixedTimeOffset() const
Get time offset.
 
void setSigmaK40(const double sigma)
Set intrinsic K40 arrival time spread.
 
const real_type & getReal(const pair_type &pair) const
Get derived parameters.
 
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.
 
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.
 
JModel(const JModule &module, const JK40Parameters ¶meters, const JTDC_t::range_type &TDC, const int option)
Constructor.
 
friend std::ostream & operator<<(std::ostream &out, const JModel &object)
Write model parameters to output stream.
 
bool hasFixedTimeOffset() const
Check if time offset is fixed.
 
int index
index of PMT used for fixed time offset
 
Fit parameters for single PMT.
 
JParameter_t t0
time offset [ns]
 
JParameter_t TTS
transition-time spread [ns]
 
void disable()
Disable PMT.
 
size_t getN() const
Get number of fit parameters.
 
friend std::ostream & operator<<(std::ostream &out, const JPMTParameters_t &object)
Write PMT parameters to output stream.
 
JPMTParameters_t()
Default constructor.
 
JParameter_t bg
background [Hz/ns]
 
int getIndex(JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
 
JParameter_t QE
relative quantum efficiency [unit]
 
static const JPMTParameters_t & getInstance()
Get default values.
 
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]
 
Interface for maximum likelihood estimator (M-estimator).
 
Auxiliary base class for aritmetic operations of derived class types.
 
JMatrixND & reset()
Set matrix to the null matrix.