1 #ifndef __JACOUSTICS__JKATOOMBA_T__
2 #define __JACOUSTICS__JKATOOMBA_T__
8 #include "TMatrixTSym.h"
9 #include "TDecompSVD.h"
65 for (T i = __begin; i != __end; ++i) {
76 template<
template<
class T>
class JMinimiser_t =
JType>
92 static const struct compare {
110 return first.
getQ() > second.
getQ();
139 this->option = -option;
154 const JMODEL ::JString& parameters =
model.string[hit.
getString()];
158 const double Vi = velocity.getInverseVelocity(D, hit.
getZ(), position.
getZ());
174 const JMODEL ::JString& parameters =
model.string[hit.
getString()];
178 const double Vi = velocity.getInverseVelocity(D, hit.
getZ(), position.
getZ());
215 JMODEL::JEmission(emission),
226 H_t&
mul(
const double factor)
302 const double toa_s = this->getToA(
model, hit);
305 return estimator->getRho(
u) * hit.
getWeight();
319 this->value.setOption(this->option);
338 return (*
this)(__begin, __end);
366 ResizeTo(size, size);
385 unique_lock<mutex> lock(
mtx);
391 static_cast<TMatrixD&
>(*this) = svd.Invert(status);
399 template<
class JVectorND_t>
405 unique_lock<mutex> lock(
mtx);
409 TVectorD b(
u.size());
411 for (
size_t i = 0; i !=
u.size(); ++i) {
417 for (
size_t i = 0; i !=
u.size(); ++i) {
467 switch (MATRIX_INVERSION) {
470 return this->evaluate(__begin, __end, svd);
473 return this->evaluate(__begin, __end, ldu);
498 template<
class T,
class JMatrixNS_t>
503 using namespace JGEOMETRY;
505 value =
JModel(__begin, __end);
515 const size_t N = value.getN();
523 for (T hit = __begin; hit != __end; ++hit) {
525 const JString&
string = geometry[hit->getString()];
527 const double Vi = velocity.getInverseVelocity(hit->getDistance(position), hit->getZ(), position.
getZ());
529 const double h1 =
string.getHeight(hit->getFloor());
530 const JPosition3D p1 =
string.getPosition() - hit->getPosition();
531 const double ds = sqrt(
p1.getLengthSquared() + h1*h1 + 2.0*
p1.getZ()*h1);
532 const double y = hit->getValue() - Vi*ds;
533 const double W = sqrt(hit->getWeight());
536 H.tx = W * Vi *
p1.getX() * h1 / ds;
537 H.ty = W * Vi *
p1.getY() * h1 / ds;
539 i.t1 = value.getIndex(hit->getEKey(), &H_t::t1);
540 i.tx = value.getIndex(hit->getString(), &H_t::tx);
541 i.ty = value.getIndex(hit->getString(), &H_t::ty);
543 V(i.t1, i.t1) +=
H.t1 *
H.t1;
545 Y[i.t1] += W *
H.t1 *
y;
547 if (hit->getFloor() != 0) {
551 V(i.t1, i.tx) +=
H.t1 *
H.tx; V(i.t1, i.ty) +=
H.t1 *
H.ty;
552 V(i.tx, i.t1) +=
H.tx *
H.t1; V(i.ty, i.t1) +=
H.ty *
H.t1;
554 V(i.tx, i.tx) +=
H.tx *
H.tx; V(i.tx, i.ty) +=
H.tx *
H.ty;
555 V(i.ty, i.tx) +=
H.ty *
H.tx; V(i.ty, i.ty) +=
H.ty *
H.ty;
557 Y[i.tx] += W *
H.tx *
y;
558 Y[i.ty] += W *
H.ty *
y;
567 for (
size_t row = 0; row != N; ++row) {
568 value[row] += Y[row];
613 const double toa_s = this->getToA(
model, hit);
616 return estimator->getRho(
u);
636 switch (this->option) {
718 value.setOption(this->option);
720 const int N = value.getN();
728 for (T hit = __begin; hit != __end; ++hit) {
729 data[hit->getLocation()][hit->getEmitter()].push_back(*hit);
734 result_type precessor = numeric_limits<double>::max();
736 for (numberOfIterations = 0; numberOfIterations != MAXIMUM_ITERATIONS; ++numberOfIterations) {
738 DEBUG(
"step: " << numberOfIterations << endl);
742 DEBUG(
"lambda: " <<
FIXED(12,5) << lambda << endl);
743 DEBUG(
"chi2: " <<
FIXED(12,5) << successor << endl);
745 if (successor < precessor) {
747 if (numberOfIterations != 0) {
749 if (fabs(precessor - successor) < EPSILON*fabs(precessor)) {
753 if (lambda > LAMBDA_MIN) {
754 lambda /= LAMBDA_DOWN;
758 precessor = successor;
766 if (lambda > LAMBDA_MAX) {
775 for (
int i = 0; i != N; ++i) {
777 if (V(i,i) < PIVOT) {
781 h[i] = 1.0 / sqrt(V(i,i));
786 for (
int i = 0; i != N; ++i) {
787 for (
int j = 0;
j != i; ++
j) {
788 V(
j,i) *= h[i] * h[
j];
793 for (
int i = 0; i != N; ++i) {
794 V(i,i) = 1.0 + lambda;
800 for (
int col = 0; col != N; ++col) {
807 catch (
const exception& error) {
809 ERROR(
"JGandalf: " << error.what() << endl << V << endl);
816 for (
int row = 0; row != N; ++row) {
818 DEBUG(
"u[" << noshowpos << setw(3) << row <<
"] = " << showpos <<
FIXED(20,5) << value[row]);
820 value[row] -= h[row] * Y[row];
822 DEBUG(
" -> " <<
FIXED(20,10) << value[row] << noshowpos << endl);
859 for (data_type::const_iterator p =
data.begin(); p !=
data.end(); ++p) {
862 const JMODEL ::JString& parameters = value.
string[p->first.getString()];
865 for (data_type::mapped_type::const_iterator emitter = p->second.begin(); emitter != p->second.end(); ++emitter) {
867 const double D = emitter->first.
getDistance(position);
868 const double Vi = velocity.getInverseVelocity(D, emitter->first.getZ(), position.
getZ());
870 const H_t H0(1.0,
string.getGradient(parameters, emitter->first.getPosition(), p->first.getFloor()) * Vi);
872 for (data_type::mapped_type::mapped_type::const_iterator hit = emitter->second.begin(); hit != emitter->second.end(); ++hit) {
874 const double toa_s = value.
emission[hit->getEKey()].t1 + D * Vi;
876 const double u = (toa_s - hit->getValue()) / hit->getSigma();
877 const double W = sqrt(hit->getWeight());
879 successor += (W*W) * estimator->getRho(
u);
881 const H_t
H = H0 * (W * estimator->getPsi(
u) / hit->getSigma());
885 i.t1 = value.
getIndex(hit->getEKey(), &H_t::t1);
886 i.tx = value.
getIndex(hit->getString(), &H_t::tx);
887 i.ty = value.
getIndex(hit->getString(), &H_t::ty);
888 i.tx2 = value.
getIndex(hit->getString(), &H_t::tx2);
889 i.ty2 = value.
getIndex(hit->getString(), &H_t::ty2);
892 V(i.t1, i.t1) +=
H.t1 *
H.t1;
896 if (hit->getFloor() != 0) {
898 switch (this->option) {
901 V(i.t1, i.vs) +=
H.t1 *
H.vs; V(i.tx, i.vs) +=
H.tx *
H.vs; V(i.ty, i.vs) +=
H.ty *
H.vs; V(i.tx2, i.vs) +=
H.tx2 *
H.vs; V(i.ty2, i.vs) +=
H.ty2 *
H.vs;
903 V(i.vs, i.t1) = V(i.t1, i.vs);
904 V(i.vs, i.tx) = V(i.tx, i.vs);
905 V(i.vs, i.ty) = V(i.ty, i.vs);
906 V(i.vs, i.tx2) = V(i.tx2, i.vs);
907 V(i.vs, i.ty2) = V(i.ty2, i.vs);
909 V(i.vs, i.vs) +=
H.vs *
H.vs;
914 V(i.t1, i.tx2) +=
H.t1 *
H.tx2; V(i.tx, i.tx2) +=
H.tx *
H.tx2; V(i.ty, i.tx2) +=
H.ty *
H.tx2;
916 V(i.tx2, i.t1) = V(i.t1, i.tx2);
917 V(i.tx2, i.tx) = V(i.tx, i.tx2);
918 V(i.tx2, i.ty) = V(i.ty, i.tx2);
920 V(i.t1, i.ty2) +=
H.t1 *
H.ty2; V(i.tx, i.ty2) +=
H.tx *
H.ty2; V(i.ty, i.ty2) +=
H.ty *
H.ty2;
922 V(i.ty2, i.t1) = V(i.t1, i.ty2);
923 V(i.ty2, i.tx) = V(i.tx, i.ty2);
924 V(i.ty2, i.ty) = V(i.ty, i.ty2);
926 V(i.tx2, i.tx2) +=
H.tx2 *
H.tx2; V(i.tx2, i.ty2) +=
H.tx2 *
H.ty2;
927 V(i.ty2, i.tx2) = V(i.tx2, i.ty2); V(i.ty2, i.ty2) +=
H.ty2 *
H.ty2;
929 Y[i.tx2] += W *
H.tx2;
930 Y[i.ty2] += W *
H.ty2;
933 V(i.t1, i.tx) +=
H.t1 *
H.tx; V(i.t1, i.ty) +=
H.t1 *
H.ty;
934 V(i.tx, i.t1) = V(i.t1, i.tx); V(i.ty, i.t1) = V(i.t1, i.ty);
936 V(i.tx, i.tx) +=
H.tx *
H.tx; V(i.tx, i.ty) +=
H.tx *
H.ty;
937 V(i.ty, i.tx) = V(i.tx, i.ty); V(i.ty, i.ty) +=
H.ty *
H.ty;
Model for fit to acoutsics data.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Maximum likelihood estimator (M-estimators).
General purpose messaging.
#define DEBUG(A)
Message macros.
General purpose data regression method.
Place holder for custom implementation.
int getFloor() const
Get floor number.
int getString() const
Get string number.
result_type operator()(const JFunction_t &fit, T __begin, T __end)
Get chi2.
Template definition of linear fit.
Simple fit method based on Powell's algorithm, see reference: Numerical Recipes in C++,...
double operator()(const JFunction_t &fit, T __begin, T __end)
Multi-dimensional fit.
Data structure for position in three dimensions.
const JPosition3D & getPosition() const
Get position.
double getDistance(const JVector3D &pos) const
Get distance to point.
double getZ() const
Get z position.
Exception for division by zero.
Wrapper class around STL string class.
Exception for accessing a value in a collection that is outside of its range.
@ FIT_EMITTERS_AND_STRINGS_1st_ORDER_t
fit times of emission of emitters and tilt angles of strings
@ FIT_EMITTERS_AND_STRINGS_2nd_ORDER_t
fit times of emission of emitters and tilt angles of strings with second order correction
@ FIT_EMITTERS_ONLY_t
fit only times of emission of emitters
@ FIT_EMITTERS_AND_STRINGS_2nd_ORDER_AND_STRETCHING_t
fit times of emission of emitters and tilt angles of strings with second order correction and stretch...
Auxiliary classes and methods for acoustic position calibration.
double getWeight(T __begin, T __end)
Get total weight of data points.
JMatrix_t
Algorithm for matrix inversion.
static const double H
Planck constant [eV s].
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
double getSigma() const
Get resolution of time-of-arrival.
double getValue() const
Get expectation value of time-of-arrival.
double getWeight() const
Get weight.
JEKey getEKey() const
Get emitter hash key of this hit.
result_type operator()(T __begin, T __end)
Fit.
JKatoomba(const JGeometry &geometry, const JSoundVelocity &velocity, const int option)
Constructor The option corresponds to the use of fit parameters in the model of the detector geometry...
result_type operator()(const JModel &model, T __begin, T __end)
Fit.
result_type operator()(const JModel &model, const JHit &hit) const
Fit function.
JModel & operator()(T __begin, T __end) const
Get start values of string parameters.
JKatoomba(const JGeometry &geometry, const JSoundVelocity &velocity, const int option)
Constructor The option corresponds to the use of fit parameters in the model of the detector geometry...
static JMatrix_t MATRIX_INVERSION
Matrix inversion.
JModel & evaluate(T __begin, T __end, JMatrixNS_t &V) const
Get start values of string parameters.
static double LAMBDA_DOWN
multiplication factor control parameter
static int debug
debug level
static double PIVOT
minimal value diagonal element of matrix
std::map< JLocation, std::map< JEmitter, std::vector< JHit > > > data_type
Type definition internal data structure.
JKatoomba(const JGeometry &geometry, const JSoundVelocity &velocity, const int option)
Constructor The option corresponds to the use of fit parameters in the model of the detector geometry...
result_type operator()(T __begin, T __end)
Fit.
static double LAMBDA_UP
multiplication factor control parameter
static int MAXIMUM_ITERATIONS
maximal number of iterations
static double LAMBDA_MAX
maximal value control parameter
static double EPSILON
maximal distance to minimum
void evaluate(const data_type &data)
Evaluation of fit.
static double LAMBDA_MIN
minimal value control parameter
JKatoomba(const JGeometry &geometry, const JSoundVelocity &velocity, const int option)
Constructor The option corresponds to the use of fit parameters in the model of the detector geometry...
double operator()(const JModel &model, const JHit &hit) const
Fit function.
double operator()(T __begin, T __end)
Fit.
H_t()
Default constructor.
H_t & mul(const double factor)
Scale H-equation.
H_t(const JMODEL::JEmission &emission, const JMODEL::JString &string)
Constructor.
I_t()
Default constructor.
bool operator()(const JTransmission &first, const JTransmission &second) const
Sort transmissions in following order.
const JGeometry & geometry
detector geometry
double getToA(const JModel &model, const JHit &hit) const
Get estimated time-of-arrival for given hit.
JKatoomba(const JGeometry &geometry, const JSoundVelocity &velocity, const int option)
Constructor.
std::shared_ptr< JMEstimator > estimator_type
estimator_type estimator
M-Estimator function.
double getToE(const JModel &model, const JHit &hit) const
Get estimated time-of-emission for given hit.
JSoundVelocity velocity
sound velocity
Template definition of fit function of acoustic model.
JEmission & mul(const double factor)
Scale emission.
JString & mul(const double factor)
Scale string.
static bool singularity
Option for common fit parameters.
Model for fit to acoustics data.
JACOUSTICS::JModel::emission_type emission
size_t getIndex(int id, double JString::*p) const
Get index of fit parameter for given string.
JACOUSTICS::JModel::string_type string
Implementation for depth dependend velocity of sound.
double getToA() const
Get calibrated time of arrival.
double getQ() const
Get quality.
int getID() const
Get identifier.
Auxiliary data structure for compatibility of symmetric matrix.
void resize(const size_t size)
Resize matrix.
static std::mutex mtx
TDecompSVD.
void reset()
Set matrix to the null matrix.
static constexpr double TOLERANCE
Tolerance for SVD.
void invert()
Invert matrix according SVD decomposition.
void solve(JVectorND_t &u)
Get solution of equation A x = b.
Interface for maximum likelihood estimator (M-estimator).
Auxiliary class for a type holder.
Auxiliary base class for aritmetic operations of derived class types.
JMatrixND & reset()
Set matrix to the null matrix.