1 #ifndef __JCALIBRATE_JGANDALFK40__
2 #define __JCALIBRATE_JGANDALFK40__
37 namespace JCALIBRATE {}
38 namespace JPP {
using namespace JCALIBRATE; }
40 namespace JCALIBRATE {
102 public std::map<pair_type, std::vector<rate_type> >
110 public JMath<JParameter_t>
172 set(
get() + parameter.
get());
186 set(
get() - parameter.
get());
305 void set(
const double value)
321 void fix(
const double value)
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) +
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()) {
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);
1023 for (
int i = 0;
i != pmt; ++
i) {
1051 return this->sigmaK40_ns;
1062 this->sigmaK40_ns =
sigma;
1074 real.
ct =
JPP::getDot((*
this)[pair.first].getDirection(), (*this)[pair.second].getDirection());
1076 real.t0 = (pair.first == this->index ? -this->
parameters[pair.second].t0() :
1077 pair.second == this->index ? +this->
parameters[pair.first ].t0() :
1082 this->getSigmaK40() * this->getSigmaK40());
1101 using namespace std;
1102 using namespace JPP;
1106 const JGauss
gauss(real.t0, real.sigma, real.signal);
1109 const double R2 = gauss.getValue(dt_ns);
1111 return real.background +
R1 * (cc() + R2);
1123 using namespace std;
1124 using namespace JPP;
1129 const double R2 = real.signal;
1131 return real.background +
R1 * (cc() + R2);
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 &&
1232 value.parameters[pair.second].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);
1455 for (data_type::const_iterator ix = data.begin(); ix != data.end(); ++ix) {
1459 if (
value.parameters[pair.first ].status &&
1460 value.parameters[pair.second].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);
1470 I_t(
value, pair.second));
1472 for (
const rate_type& iy : ix->second) {
1474 const double R2 = gauss.getValue (iy.
dt_ns);
1475 const JGauss& R2p = gauss.getGradient(iy.
dt_ns);
1477 const double R = real.background + R1 * (
value.cc() + R2);
1479 const double w = -estimator->getPsi(u) / iy.
error;
1481 successor += estimator->getRho(u);
1490 if (M.cc !=
INVALID_INDEX) { buffer.push_back({M.cc,
w * R1 * R1p.
cc() *
value.cc.getDerivative()}); }
1492 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()}); }
1493 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()}); }
1494 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}); }
1495 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}); }
1496 if (PMT.first .t0 !=
INVALID_INDEX) { buffer.push_back({PMT.first .t0,
w * R1 * R2p.mean *
value.parameters[pair.first ].t0 .getDerivative() * +1.0}); }
1497 if (PMT.second.t0 !=
INVALID_INDEX) { buffer.push_back({PMT.second.t0,
w * R1 * R2p.mean *
value.parameters[pair.second].t0 .getDerivative() * -1.0}); }
1498 if (PMT.first .bg !=
INVALID_INDEX) { buffer.push_back({PMT.first .bg,
w *
value.parameters[pair.first ].bg .getDerivative()}); }
1499 if (PMT.second.bg !=
INVALID_INDEX) { buffer.push_back({PMT.second.bg,
w *
value.parameters[pair.second].bg .getDerivative()}); }
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];
Data structure for measured coincidence rate of pair of PMTs.
result_type operator()(const data_type &data)
Fit.
JTOOLS::JRange< double > range_type
Type definition for range of parameter values.
size_t getN() const
Get number of fit parameters.
void set()
Set current value.
double getValue(const JScale_t scale)
Get numerical value corresponding to scale.
int getIndex(JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
const real_type & getReal(const pair_type &pair) const
Get derived parameters.
int getIndex(JParameter_t JK40Parameters::*p) const
Get index of parameter.
JParameter_t t0
time offset [ns]
Auxiliary base class for aritmetic operations of derived class types.
JK40Parameters()
Default constructor.
Data structure for a composite optical module.
void setSigmaK40(const double sigma)
Set intrinsic K40 arrival time spread.
JParameter_t R
maximal coincidence rate [Hz]
bool hasFixedTimeOffset() const
Check if time offset is fixed.
static const int INVALID_INDEX
invalid index
size_t getN() const
Get number of fit parameters.
Interface for maximum likelihood estimator (M-estimator).
JParameter_t & add(const JParameter_t ¶meter)
Add parameter.
JParameter_t & sub(const JParameter_t ¶meter)
Subtract parameter.
JK40Parameters_t()
Default constructor.
JParameter_t & negate()
Negate parameter.
double getDot(const JNeutrinoDirection &first, const JNeutrinoDirection &second)
Dot product.
const JK40Parameters_t & getGradient(const double ct) const
Get gradient.
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.
void setK40Parameters(const JK40Parameters_t ¶meters)
Set K40 parameters.
int index
index of PMT used for fixed time offset
void set(const double value)
Set value.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
then set_variable singlesRate set_variable doublesRate set_variable numberOfSlices echo Generating random background echo Singles rate
double getDerivative() const
Get derivative of value.
double getValue(const pair_type &pair) const
Get K40 coincidence rate.
*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
int getIndex() const
Get index of PMT used for fixed time offset.
JK40Parameters_t gradient
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.
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
JModel()
Default constructor.
double background
combined background
JPMTParameters_t()
Default constructor.
std::vector< JHitW0 > buffer_type
hits
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.
friend std::ostream & operator<<(std::ostream &out, const JModel &object)
Write model parameters to output stream.
double dt_ns
time difference [ns]
JFit(const int option, const int debug)
Constructor.
void setOption(const int option)
Set fit option.
JParameter_t bg
background [Hz/ns]
void fix()
Fix current value.
JParameter_t & operator=(double value)
Assignment operator.
Fit parameters for two-fold coincidence rate due to K40.
JParameter_t QE
relative quantum efficiency [unit]
JParameter_t p3
3rd order angle dependence coincidence rate
void evaluate(const data_type &data)
Evaluation of fit.
double ct
cosine angle between PMT axes
double error
error of rate [Hz/ns]
fit parameters of PMTs and background
estimator_type estimator
M-Estimator function.
JParameter_t()
Default constructor.
rate_type(double dt_ns, double value, double error)
Constructor.
fit parameters of PMTs and angular dependence of K40 rate
double t0
time offset [ns]
const JK40Parameters & getK40Parameters() const
Get K40 parameters.
friend std::ostream & operator<<(std::ostream &out, const JParameter_t &object)
Write parameter to output stream.
int getIndex()
Get index for user I/O manipulation.
void fix(const double value)
Fix value.
double sigma
total width [ns]
JParameter_t TTS
transition-time spread [ns]
static const JPMTParameters_t & getInstance()
Get default values.
General purpose messaging.
Auxiliary data structure for sequence of same character.
Fit parameters for single PMT.
JParameter_t p4
4th order angle dependence coincidence rate
JParameter_t & mul(const JParameter_t &first, const JParameter_t &second)
Scale parameter.
fit parameters of PMTs with QE fixed
JOption_t getOption() const
Get fit option.
then JCookie sh JDataQuality D $DETECTOR_ID R
size_t getN() const
Get number of fit parameters.
friend std::istream & operator>>(std::istream &in, JParameter_t &object)
Read parameter from input stream.
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
bool isFree() const
Check if parameter is free.
Auxiliary class to define a range between two values.
JParameter_t p2
2nd order angle dependence coincidence rate
then fatal The output file must have the wildcard in the e g root fi 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
Auxiliary data structure for derived quantities of a given PMT pair.
fit parameters of K40 rate and TTSs of PMTs
then set_variable NUMBER_OF_TESTS else set_variable NUMBER_OF_TESTS fi function gauss()
double getFixedTimeOffset() const
Get time offset.
JParameter_t(const double value, const range_type &range=range_type::DEFAULT_RANGE())
Constructor.
double signal
combined signal
PMT combinatorics for optical module.
JParameter_t & mul(const double factor)
Scale parameter.
double getValue(const pair_type &pair, const double dt_ns) const
Get K40 coincidence rate.
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
static const JK40Parameters & getInstance()
Get default values.
JModel(const JModule &module, const JK40Parameters ¶meters, const JTDC_t::range_type &TDC, const int option)
Constructor.
JModel(const JModule &module, const JK40Parameters ¶meters)
Constructor.
Base class for data structures with artithmetic capabilities.
int getIndex(int pmt) const
Get index of parameter.
double getSigmaK40() const
Get intrinsic K40 arrival time spread.
Exception for accessing a value in a collection that is outside of its range.
int getIndex(int pmt, JParameter_t JPMTParameters_t::*p) const
Get index of parameter.
Fit parameters for two-fold coincidence rate due to K40.
JMEstimator * getMEstimator(const int type)
Get M-Estimator.
KM3NeT DAQ constants, bit handling, etc.
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
bool isBound() const
Check if parameter is bound.
bool isFixed() const
Check if parameter is fixed.
std::shared_ptr< JMEstimator > estimator_type
rate_type()
Default constructor.
void disable()
Disable PMT.
JPMTParameters_t parameters[NUMBER_OF_PMTS]
JParameter_t & div(const double factor)
Scale parameter.
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.
friend std::ostream & operator<<(std::ostream &out, const JPMTParameters_t &object)
Write PMT parameters to output stream.
Maximum likelihood estimator (M-estimators).
double operator()() const
Type conversion operator.
double value
value of rate [Hz/ns]
#define DEBUG(A)
Message macros.
JParameter_t p1
1st order angle dependence coincidence rate
JParameter_t cc
fraction of signal correlated background
Data structure for optical module.
Auxiliary class for fit parameter with optional limits.