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.