1#ifndef __JACOUSTICS__JKATOOMBA_T__
2#define __JACOUSTICS__JKATOOMBA_T__
8#include "TMatrixTSym.h"
64 for (T i = __begin; i != __end; ++i) {
75 template<
template<
class T>
class JMinimiser_t =
JType>
109 return first.
getQ() > second.
getQ();
138 this->option = -option;
153 const JMODEL ::JString& parameters =
model.string[hit.
getString()];
157 const double Vi = velocity.getInverseVelocity(D, hit.
getZ(), position.
getZ());
173 const JMODEL ::JString& parameters =
model.string[hit.
getString()];
177 const double Vi = velocity.getInverseVelocity(D, hit.
getZ(), position.
getZ());
214 JMODEL::JEmission(emission),
301 const double toa_s = this->getToA(
model, hit);
304 return estimator->getRho(u) * hit.
getWeight();
318 this->value.setOption(this->option);
337 return (*
this)(__begin, __end);
365 ResizeTo(size, size);
384 unique_lock<mutex> lock(
mtx);
390 static_cast<TMatrixD&
>(*this) = svd.Invert(status);
398 template<
class JVectorND_t>
404 unique_lock<mutex> lock(
mtx);
408 TVectorD b(u.size());
410 for (
size_t i = 0; i != u.size(); ++i) {
416 for (
size_t i = 0; i != u.size(); ++i) {
466 switch (MATRIX_INVERSION) {
469 return this->evaluate(__begin, __end, svd);
472 return this->evaluate(__begin, __end, ldu);
497 template<
class T,
class JMatrixNS_t>
502 using namespace JGEOMETRY;
504 value =
JModel(__begin, __end);
514 const size_t N = value.getN();
522 for (T hit = __begin; hit != __end; ++hit) {
524 const JString&
string = geometry[hit->getString()];
526 const double Vi = velocity.getInverseVelocity(hit->getDistance(position), hit->getZ(), position.
getZ());
528 const double h1 =
string.getHeight(hit->getFloor());
530 const double ds = sqrt(
p1.getLengthSquared() + h1*h1 + 2.0*
p1.getZ()*h1);
531 const double y = hit->getValue() - Vi*ds;
532 const double W = sqrt(hit->getWeight());
535 H.tx = W * Vi *
p1.getX() * h1 / ds;
536 H.ty = W * Vi *
p1.getY() * h1 / ds;
538 i.t1 = value.getIndex(hit->getEKey(), &H_t::t1);
539 i.tx = value.getIndex(hit->getString(), &H_t::tx);
540 i.ty = value.getIndex(hit->getString(), &H_t::ty);
542 V(i.t1, i.t1) +=
H.t1 *
H.t1;
544 Y[i.t1] += W *
H.t1 * y;
546 if (hit->getFloor() != 0) {
550 V(i.t1, i.tx) +=
H.t1 *
H.tx; V(i.t1, i.ty) +=
H.t1 *
H.ty;
551 V(i.tx, i.t1) +=
H.tx *
H.t1; V(i.ty, i.t1) +=
H.ty *
H.t1;
553 V(i.tx, i.tx) +=
H.tx *
H.tx; V(i.tx, i.ty) +=
H.tx *
H.ty;
554 V(i.ty, i.tx) +=
H.ty *
H.tx; V(i.ty, i.ty) +=
H.ty *
H.ty;
556 Y[i.tx] += W *
H.tx * y;
557 Y[i.ty] += W *
H.ty * y;
566 for (
size_t row = 0; row != N; ++row) {
567 value[row] += Y[row];
612 const double toa_s = this->getToA(
model, hit);
615 return estimator->getRho(u);
635 switch (this->option) {
717 value.setOption(this->option);
719 const int N = value.getN();
727 for (T hit = __begin; hit != __end; ++hit) {
728 data[hit->getLocation()][hit->getEmitter()].push_back(*hit);
733 result_type precessor = numeric_limits<double>::max();
735 for (numberOfIterations = 0; numberOfIterations != MAXIMUM_ITERATIONS; ++numberOfIterations) {
737 DEBUG(
"step: " << numberOfIterations << endl);
741 DEBUG(
"lambda: " <<
FIXED(12,5) << lambda << endl);
742 DEBUG(
"chi2: " <<
FIXED(12,5) << successor << endl);
744 if (successor < precessor) {
746 if (numberOfIterations != 0) {
748 if (fabs(precessor - successor) < EPSILON*fabs(precessor)) {
752 if (lambda > LAMBDA_MIN) {
753 lambda /= LAMBDA_DOWN;
757 precessor = successor;
765 if (lambda > LAMBDA_MAX) {
774 for (
int i = 0; i != N; ++i) {
776 if (V(i,i) < PIVOT) {
780 h[i] = 1.0 / sqrt(V(i,i));
785 for (
int i = 0; i != N; ++i) {
786 for (
int j = 0;
j != i; ++
j) {
787 V(
j,i) *= h[i] * h[
j];
792 for (
int i = 0; i != N; ++i) {
793 V(i,i) = 1.0 + lambda;
799 for (
int col = 0; col != N; ++col) {
806 catch (
const exception& error) {
808 ERROR(
"JGandalf: " << error.what() << endl << V << endl);
815 for (
int row = 0; row != N; ++row) {
817 DEBUG(
"u[" << noshowpos << setw(3) << row <<
"] = " << showpos <<
FIXED(20,5) << value[row]);
819 value[row] -= h[row] * Y[row];
821 DEBUG(
" -> " <<
FIXED(20,10) << value[row] << noshowpos << endl);
858 for (data_type::const_iterator p = data.begin(); p != data.end(); ++p) {
861 const JMODEL ::JString& parameters = value.
string[p->first.getString()];
864 for (data_type::mapped_type::const_iterator emitter = p->second.begin(); emitter != p->second.end(); ++emitter) {
866 const double D = emitter->first.getDistance(position);
867 const double Vi = velocity.getInverseVelocity(D, emitter->first.getZ(), position.
getZ());
869 const H_t H0(1.0,
string.getGradient(parameters, emitter->first.getPosition(), p->first.getFloor()) * Vi);
871 for (data_type::mapped_type::mapped_type::const_iterator hit = emitter->second.begin(); hit != emitter->second.end(); ++hit) {
873 const double toa_s = value.
emission[hit->getEKey()].t1 + D * Vi;
875 const double u = (toa_s - hit->getValue()) / hit->getSigma();
876 const double W = sqrt(hit->getWeight());
878 successor += (W*W) * estimator->getRho(u);
880 const H_t
H = H0 * (W * estimator->getPsi(u) / hit->getSigma());
884 i.t1 = value.
getIndex(hit->getEKey(), &H_t::t1);
885 i.tx = value.
getIndex(hit->getString(), &H_t::tx);
886 i.ty = value.
getIndex(hit->getString(), &H_t::ty);
887 i.tx2 = value.
getIndex(hit->getString(), &H_t::tx2);
888 i.ty2 = value.
getIndex(hit->getString(), &H_t::ty2);
889 i.vs = value.
getIndex(hit->getString(), &H_t::vs);
891 V(i.t1, i.t1) +=
H.t1 *
H.t1;
895 if (hit->getFloor() != 0) {
897 switch (this->option) {
900 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;
902 V(i.vs, i.t1) = V(i.t1, i.vs);
903 V(i.vs, i.tx) = V(i.tx, i.vs);
904 V(i.vs, i.ty) = V(i.ty, i.vs);
905 V(i.vs, i.tx2) = V(i.tx2, i.vs);
906 V(i.vs, i.ty2) = V(i.ty2, i.vs);
908 V(i.vs, i.vs) +=
H.vs *
H.vs;
913 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;
915 V(i.tx2, i.t1) = V(i.t1, i.tx2);
916 V(i.tx2, i.tx) = V(i.tx, i.tx2);
917 V(i.tx2, i.ty) = V(i.ty, i.tx2);
919 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;
921 V(i.ty2, i.t1) = V(i.t1, i.ty2);
922 V(i.ty2, i.tx) = V(i.tx, i.ty2);
923 V(i.ty2, i.ty) = V(i.ty, i.ty2);
925 V(i.tx2, i.tx2) +=
H.tx2 *
H.tx2; V(i.tx2, i.ty2) +=
H.tx2 *
H.ty2;
926 V(i.ty2, i.tx2) = V(i.tx2, i.ty2); V(i.ty2, i.ty2) +=
H.ty2 *
H.ty2;
928 Y[i.tx2] += W *
H.tx2;
929 Y[i.ty2] += W *
H.ty2;
932 V(i.t1, i.tx) +=
H.t1 *
H.tx; V(i.t1, i.ty) +=
H.t1 *
H.ty;
933 V(i.tx, i.t1) = V(i.t1, i.tx); V(i.ty, i.t1) = V(i.t1, i.ty);
935 V(i.tx, i.tx) +=
H.tx *
H.tx; V(i.tx, i.ty) +=
H.tx *
H.ty;
936 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.
void model(JModel_t &value)
Auxiliary function to constrain model during fit.
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.
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...
JModel & evaluate(T __begin, T __end, JMatrixNS_t &V) const
Get start values of string parameters.
JModel & operator()(T __begin, T __end) const
Get start values of string parameters.
static JMatrix_t MATRIX_INVERSION
static double LAMBDA_DOWN
multiplication factor control parameter
static int debug
debug level
std::map< JLocation, std::map< JEmitter, std::vector< JHit > > > data_type
Type definition internal data structure.
static double PIVOT
minimal value diagonal element of matrix
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.
Indices of H-equation in global model.
I_t()
Default constructor.
Auxiliary data structure to sort transmissions.
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.