GeneralBrokenLines V03-01-01
using EIGEN
GblPoint.cpp
Go to the documentation of this file.
1/*
2 * GblPoint.cpp
3 *
4 * Created on: Aug 18, 2011
5 * Author: kleinwrt
6 */
7
30#include "GblPoint.h"
31using namespace Eigen;
32
34namespace gbl {
35
37
42GblPoint::GblPoint(const Matrix5d &aJacobian, unsigned int numMeasReserve) :
43 theLabel(0), theOffset(0), theType(0), p2pJacobian(aJacobian), scatDim(
44 0) {
45 theMeasurements.reserve(numMeasReserve);
46}
47
48#ifdef GBL_EIGEN_SUPPORT_ROOT
50
54GblPoint::GblPoint(const TMatrixD &aJacobian) :
55 theLabel(0), theOffset(0), theType(0), scatDim(0) {
56
57 for (unsigned int i = 0; i < 5; ++i) {
58 for (unsigned int j = 0; j < 5; ++j) {
59 p2pJacobian(i, j) = aJacobian(i, j);
60 }
61 }
62}
63#endif
64
66}
67
68#ifdef GBL_EIGEN_SUPPORT_ROOT
70
78void GblPoint::addMeasurement(const TMatrixD &aProjection,
79 const TVectorD &aResiduals, const TVectorD &aPrecision,
80 double minPrecision) {
81 theMeasurements.emplace_back(aProjection, aResiduals, aPrecision,
82 minPrecision);
83}
84
86
95void GblPoint::addMeasurement(const TMatrixD &aProjection,
96 const TVectorD &aResiduals, const TMatrixDSym &aPrecision,
97 double minPrecision) {
98 theMeasurements.emplace_back(aProjection, aResiduals, aPrecision,
99 minPrecision);
100}
101
103
110void GblPoint::addMeasurement(const TVectorD &aResiduals,
111 const TVectorD &aPrecision, double minPrecision) {
112 theMeasurements.emplace_back(aResiduals, aPrecision, minPrecision);
113}
114
116
124void GblPoint::addMeasurement(const TVectorD &aResiduals,
125 const TMatrixDSym &aPrecision, double minPrecision) {
126 theMeasurements.emplace_back(aResiduals, aPrecision, minPrecision);
127}
128#endif
129
131
135unsigned int GblPoint::numMeasurements() const {
136 return theMeasurements.size();
137}
138
140
159void GblPoint::addScatterer(const Eigen::Vector2d &aResiduals,
160 const Eigen::Matrix2d &aPrecision) {
161 scatDim = 2;
162 // arbitrary precision matrix
163 Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> scatEigen { aPrecision };
164 scatTransformation.topLeftCorner<2, 2>() = scatEigen.eigenvectors();
165 scatTransformation.topLeftCorner<2, 2>().transposeInPlace();
166 scatResiduals.head<2>() = scatTransformation.topLeftCorner<2, 2>()
167 * aResiduals;
168 scatPrecision.head<2>() = scatEigen.eigenvalues();
169}
170
172
194void GblPoint::addScatterer(const Eigen::Vector2d &aResiduals,
195 const Eigen::Vector2d &aPrecision) {
196 scatDim = 2;
197 scatResiduals.head<2>() = aResiduals;
198 scatPrecision.head<2>() = aPrecision;
199 scatTransformation.topLeftCorner<2, 2>().setIdentity();
200}
201
203
232void GblPoint::addThickScatterer(const Eigen::Vector4d &aResiduals,
233 const Eigen::Matrix4d &aPrecision) {
234 scatDim = 4;
235 // dense precision matrix
236 Eigen::SelfAdjointEigenSolver<Eigen::Matrix4d> scatEigen { aPrecision };
237 scatTransformation = scatEigen.eigenvectors();
238 scatTransformation.transposeInPlace();
239 scatResiduals = scatTransformation * aResiduals;
240 scatPrecision = scatEigen.eigenvalues();
241}
242
243#ifdef GBL_EIGEN_SUPPORT_ROOT
245
266void GblPoint::addScatterer(const TVectorD &aResiduals,
267 const TVectorD &aPrecision) {
268 scatDim = 2;
269 scatResiduals(0) = aResiduals[0];
270 scatResiduals(1) = aResiduals[1];
271 scatPrecision(0) = aPrecision[0];
272 scatPrecision(1) = aPrecision[1];
273 scatTransformation.setIdentity();
274}
275
277
295void GblPoint::addScatterer(const TVectorD &aResiduals,
296 const TMatrixDSym &aPrecision) {
297 scatDim = 2;
298 TMatrixDSymEigen scatEigen(aPrecision);
299 TMatrixD aTransformation = scatEigen.GetEigenVectors();
300 aTransformation.T();
301 TVectorD transResiduals = aTransformation * aResiduals;
302 TVectorD transPrecision = scatEigen.GetEigenValues();
303 for (unsigned int i = 0; i < 2; ++i) {
304 scatResiduals(i) = transResiduals[i];
305 scatPrecision(i) = transPrecision[i];
306 for (unsigned int j = 0; j < 2; ++j) {
307 scatTransformation(i, j) = aTransformation(i, j);
308 }
309 }
310}
311
313
342void GblPoint::addThickScatterer(const TVectorD &aResiduals,
343 const TMatrixDSym &aPrecision) {
344 scatDim = 4;
345 TMatrixDSymEigen scatEigen(aPrecision);
346 TMatrixD aTransformation = scatEigen.GetEigenVectors();
347 aTransformation.T();
348 TVectorD transResiduals = aTransformation * aResiduals;
349 TVectorD transPrecision = scatEigen.GetEigenValues();
350 for (unsigned int i = 0; i < 4; ++i) {
351 scatResiduals(i) = transResiduals[i];
352 scatPrecision(i) = transPrecision[i];
353 for (unsigned int j = 0; j < 4; ++j) {
354 scatTransformation(i, j) = aTransformation(i, j);
355 }
356 }
357}
358#endif
359
361
365unsigned int GblPoint::getScatDim() const {
366 return scatDim;
367}
368
370
375void GblPoint::getScatterer(Matrix4d &aTransformation, Vector4d &aResiduals,
376 Vector4d &aPrecision) const {
377 aTransformation.topLeftCorner(scatDim, scatDim) =
378 scatTransformation.topLeftCorner(scatDim, scatDim);
379 aResiduals.head(scatDim) = scatResiduals.head(scatDim);
380 aPrecision.head(scatDim) = scatPrecision.head(scatDim);
381}
382
384
391void GblPoint::getReducedScatterer(Matrix4d &aTransformation,
392 Vector4d &aResiduals, Vector4d &aPrecision) const {
393 // get scatterer input back from diagonalization
394 Matrix4d scatPrec = scatTransformation.transpose()
395 * scatPrecision.asDiagonal() * scatTransformation;
396 Vector4d scatRes = scatTransformation.transpose() * scatResiduals;
397 // block matrix algebra to get positional precision
398 Matrix2d posPrec = scatPrec.bottomRightCorner<2, 2>()
399 - scatPrec.bottomLeftCorner<2, 2>()
400 * scatPrec.topLeftCorner<2, 2>().inverse()
401 * scatPrec.topRightCorner<2, 2>();
402 // scatPrec with only positional precision
403 scatPrec.setZero();
404 scatPrec.bottomRightCorner<2, 2>() = posPrec;
405 // diagonalize again
406 Eigen::SelfAdjointEigenSolver<Eigen::Matrix4d> scatEigen { scatPrec };
407 //
408 aTransformation = scatEigen.eigenvectors().transpose();
409 aResiduals = aTransformation * scatRes;
410 aPrecision = scatEigen.eigenvalues();
411}
412
414
417void GblPoint::getScatTransformation(MatrixXd &aTransformation) const {
418 aTransformation.resize(scatDim, scatDim);
419 if (scatDim > 0) {
420 aTransformation = scatTransformation.topLeftCorner(scatDim, scatDim);
421 } else {
422 aTransformation.setIdentity();
423 }
424}
425
426#ifdef GBL_EIGEN_SUPPORT_ROOT
428
432void GblPoint::addLocals(const TMatrixD &aDerivatives) {
433 if (theMeasurements.size())
434 theMeasurements.back().addLocals(aDerivatives);
435}
436
438
443void GblPoint::addGlobals(const std::vector<int> &aLabels,
444 const TMatrixD &aDerivatives) {
445 if (theMeasurements.size())
446 theMeasurements.back().addGlobals(aLabels, aDerivatives);
447}
448#endif
449
451
454void GblPoint::setLabel(unsigned int aLabel) {
455 theLabel = aLabel;
456}
457
459unsigned int GblPoint::getLabel() const {
460 return theLabel;
461}
462
464
467void GblPoint::setOffset(int anOffset) {
468 theOffset = anOffset;
469}
470
473 return theOffset;
474}
475
477
480void GblPoint::setType(int aType) {
481 theType = aType;
482}
483
486 return p2pJacobian;
487}
488
490
494 // to optimize: need only two last rows of inverse
495 // prevJacobian = aJac.inverse();
496 // block matrix algebra
497 Matrix23d CA = aJac.block<2, 3>(3, 0) * aJac.block<3, 3>(0, 0).inverse(); // C*A^-1
498 Matrix2d DCAB = aJac.block<2, 2>(3, 3) - CA * aJac.block<3, 2>(0, 3); // D - C*A^-1 *B
499 Matrix2d DCABInv = DCAB.inverse();
500 prevJacobian.block<2, 2>(3, 3) = DCABInv;
501 prevJacobian.block<2, 3>(3, 0) = -DCABInv * CA;
502}
503
505
509 nextJacobian = aJac;
510}
511
513
522void GblPoint::getDerivatives(int aDirection, Matrix2d &matW, Matrix2d &matWJ,
523 Vector2d &vecWd) const {
524
525 Matrix2d matJ;
526 Vector2d vecd;
527 if (aDirection < 1) {
528 matJ = prevJacobian.block<2, 2>(3, 3);
529 matW = -prevJacobian.block<2, 2>(3, 1);
530 vecd = prevJacobian.block<2, 1>(3, 0);
531 } else {
532 matJ = nextJacobian.block<2, 2>(3, 3);
533 matW = nextJacobian.block<2, 2>(3, 1);
534 vecd = nextJacobian.block<2, 1>(3, 0);
535 }
536
537 if (!matW.determinant()) {
538 std::cout << " GblPoint::getDerivatives failed to invert matrix "
539 << std::endl;
540 std::cout
541 << " Possible reason for singular matrix: multiple GblPoints at same arc-length"
542 << std::endl;
543 throw std::overflow_error("Singular matrix inversion exception");
544 }
545 matW = matW.inverse().eval();
546 matWJ = matW * matJ;
547 vecWd = matW * vecd;
548}
549
551
554void GblPoint::printPoint(unsigned int level) const {
555 std::cout << " GblPoint";
556 if (theLabel) {
557 std::cout << ", label " << theLabel;
558 if (theOffset >= 0) {
559 std::cout << ", offset " << theOffset;
560 }
561 }
562 if (theMeasurements.size()) {
563 std::cout << ", " << theMeasurements.size() << " measurements";
564 }
565 std::vector<GblMeasurement>::const_iterator itMeas;
566 for (itMeas = theMeasurements.begin(); itMeas < theMeasurements.end();
567 ++itMeas) {
568 itMeas->printMeasurement(0);
569 }
570 if (scatDim == 2) {
571 std::cout << ", thin scatterer";
572 }
573 if (scatDim == 4) {
574 std::cout << ", thick scatterer";
575 }
576
577 std::cout << std::endl;
578 if (level > 0) {
579 for (itMeas = theMeasurements.begin(); itMeas < theMeasurements.end();
580 ++itMeas) {
581 itMeas->printMeasurement(level);
582 }
583 IOFormat CleanFmt(4, 0, ", ", "\n", "[", "]");
584 if (scatDim) {
585 std::cout << " Scatterer" << std::endl;
586 std::cout << " Residuals: "
587 << scatResiduals.head(scatDim).transpose().format(CleanFmt)
588 << std::endl;
589 std::cout << " Precision: "
590 << scatPrecision.head(scatDim).transpose().format(CleanFmt)
591 << std::endl;
592 }
593 std::cout << " Jacobian " << std::endl;
594 std::cout << " Point-to-point " << std::endl
595 << p2pJacobian.format(CleanFmt) << std::endl;
596 if (theLabel) {
597 if (!isFirst())
598 std::cout << " To previous offset (last 2 rows)" << std::endl
599 << prevJacobian.bottomRows<2>().format(CleanFmt)
600 << std::endl;
601 if (!isLast())
602 std::cout << " To next offset " << std::endl
603 << nextJacobian.format(CleanFmt) << std::endl;
604 }
605 }
606}
607
609std::vector<GblMeasurement>::iterator GblPoint::getMeasBegin() {
610 return theMeasurements.begin();
611}
612
614std::vector<GblMeasurement>::iterator GblPoint::getMeasEnd() {
615 return theMeasurements.end();
616}
617
619
626 unsigned int aRow, std::vector<int> &aLabels,
627 std::vector<double> &aDerivatives) const {
628 theMeasurements[aMeas].getGlobalLabelsAndDerivatives(aRow, aLabels,
629 aDerivatives);
630}
631
633bool GblPoint::isFirst() const {
634 return (theType < 0);
635}
636
638bool GblPoint::isLast() const {
639 return (theType > 0);
640}
641
642}
GblPoint definition.
Matrix5d nextJacobian
Jacobian to next scatterer (or last measurement)
Definition: GblPoint.h:226
void getScatterer(Eigen::Matrix4d &aTransformation, Eigen::Vector4d &aResiduals, Eigen::Vector4d &aPrecision) const
Retrieve scatterer of a point.
Definition: GblPoint.cpp:375
Eigen::Matrix4d scatTransformation
Transformation of diagonalization (of scat. precision matrix)
Definition: GblPoint.h:230
void addThickScatterer(const Eigen::Vector4d &aResiduals, const Eigen::Matrix4d &aPrecision)
Add a thick scatterer to a point.
Definition: GblPoint.cpp:232
void getScatTransformation(Eigen::MatrixXd &aTransformation) const
Get scatterer transformation (from diagonalization).
Definition: GblPoint.cpp:417
void getDerivatives(int aDirection, Eigen::Matrix2d &matW, Eigen::Matrix2d &matWJ, Eigen::Vector2d &vecWd) const
Retrieve derivatives of local track model.
Definition: GblPoint.cpp:522
void addMeasurement(const Eigen::MatrixBase< Projection > &aProjection, const Eigen::MatrixBase< Residuals > &aResiduals, const Eigen::MatrixBase< Precision > &aPrecision, double minPrecision=0.)
Add a measurement to a point.
Definition: GblPoint.h:238
void getGlobalLabelsAndDerivatives(unsigned int aMeas, unsigned int aRow, std::vector< int > &aLabels, std::vector< double > &aDerivatives) const
Retrieve global derivatives from a measurement at a point for a single row.
Definition: GblPoint.cpp:625
void setType(int aType)
Define type for point (by GBLTrajectory constructor)
Definition: GblPoint.cpp:480
void printPoint(unsigned int level=0) const
Print GblPoint.
Definition: GblPoint.cpp:554
void addPrevJacobian(const Matrix5d &aJac)
Define jacobian to previous scatterer (by GBLTrajectory constructor)
Definition: GblPoint.cpp:493
int theType
Type (-1: first, 0: inner, 1: last)
Definition: GblPoint.h:223
std::vector< GblMeasurement > theMeasurements
List of measurements at point.
Definition: GblPoint.h:233
Eigen::Vector4d scatPrecision
Scattering precision (diagonal of inverse covariance matrix)
Definition: GblPoint.h:232
unsigned int numMeasurements() const
Check for measurements at a point.
Definition: GblPoint.cpp:135
void getReducedScatterer(Eigen::Matrix4d &aTransformation, Eigen::Vector4d &aResiduals, Eigen::Vector4d &aPrecision) const
Retrieve (reduced) scatterer of a point.
Definition: GblPoint.cpp:391
unsigned int theLabel
Label identifying point.
Definition: GblPoint.h:221
std::vector< GblMeasurement >::iterator getMeasBegin()
Get GblMeasurement iterator for begin.
Definition: GblPoint.cpp:609
unsigned int scatDim
Dimension of scatterer (0: none, 2: thin, 4:thick)
Definition: GblPoint.h:227
int theOffset
Offset number at point if not negative (else interpolation needed)
Definition: GblPoint.h:222
bool isLast() const
Is last point on (sub)trajectory?
Definition: GblPoint.cpp:638
void setLabel(unsigned int aLabel)
Define label of point (by GBLTrajectory constructor)
Definition: GblPoint.cpp:454
void addLocals(const Eigen::MatrixBase< Derivative > &aDerivatives)
Add local derivatives to a point.
Definition: GblPoint.h:287
void addGlobals(const std::vector< int > &aLabels, const Eigen::MatrixBase< Derivative > &aDerivatives)
Add global derivatives to a point.
Definition: GblPoint.h:293
void addNextJacobian(const Matrix5d &aJac)
Define jacobian to next scatterer (by GBLTrajectory constructor)
Definition: GblPoint.cpp:508
unsigned int getScatDim() const
Get scatterer dimension.
Definition: GblPoint.cpp:365
unsigned int getLabel() const
Retrieve label of point.
Definition: GblPoint.cpp:459
GblPoint(const Matrix5d &aJacobian, unsigned int numMeasReserve=0)
Create a point.
Definition: GblPoint.cpp:42
Eigen::Vector4d scatResiduals
Scattering residuals (initial kinks if iterating)
Definition: GblPoint.h:231
virtual ~GblPoint()
Definition: GblPoint.cpp:65
Matrix5d prevJacobian
Jacobian to previous scatterer (or first measurement)
Definition: GblPoint.h:225
std::vector< GblMeasurement >::iterator getMeasEnd()
Get GblMeasurement iterator for end.
Definition: GblPoint.cpp:614
const Matrix5d & getP2pJacobian() const
Retrieve point-to-(previous)point jacobian.
Definition: GblPoint.cpp:485
void addScatterer(const Eigen::Vector2d &aResiduals, const Eigen::Matrix2d &aPrecision)
Add a thin scatterer to a point.
Definition: GblPoint.cpp:159
void setOffset(int anOffset)
Define offset for point (by GBLTrajectory constructor)
Definition: GblPoint.cpp:467
bool isFirst() const
Is first point on (sub)trajectory?
Definition: GblPoint.cpp:633
Matrix5d p2pJacobian
Point-to-point jacobian from previous point.
Definition: GblPoint.h:224
int getOffset() const
Retrieve offset for point.
Definition: GblPoint.cpp:472
Namespace for the general broken lines package.
Eigen::Matrix< double, 2, 3 > Matrix23d
Eigen::Matrix< double, 5, 5 > Matrix5d
Definition: GblData.h:46