Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:18:25

0001 /*
0002  * GblPoint.cpp
0003  *
0004  *  Created on: Aug 18, 2011
0005  *      Author: kleinwrt
0006  */
0007 
0008 /** \file
0009  *  GblPoint methods.
0010  *
0011  *  \author Claus Kleinwort, DESY, 2011 (Claus.Kleinwort@desy.de)
0012  *
0013  *  \copyright
0014  *  Copyright (c) 2011 - 2016 Deutsches Elektronen-Synchroton,
0015  *  Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY \n\n
0016  *  This library is free software; you can redistribute it and/or modify
0017  *  it under the terms of the GNU Library General Public License as
0018  *  published by the Free Software Foundation; either version 2 of the
0019  *  License, or (at your option) any later version. \n\n
0020  *  This library is distributed in the hope that it will be useful,
0021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0023  *  GNU Library General Public License for more details. \n\n
0024  *  You should have received a copy of the GNU Library General Public
0025  *  License along with this program (see the file COPYING.LIB for more
0026  *  details); if not, write to the Free Software Foundation, Inc.,
0027  *  675 Mass Ave, Cambridge, MA 02139, USA.
0028  */
0029 
0030 #include "GblPoint.h"
0031 
0032 //! Namespace for the general broken lines package
0033 namespace gbl {
0034 
0035 /// Create a point.
0036 /**
0037  * Create point on (initial) trajectory. Needs transformation jacobian from previous point.
0038  * \param [in] aJacobian Transformation jacobian from previous point
0039  */
0040 GblPoint::GblPoint(const TMatrixD &aJacobian) :
0041         theLabel(0), theOffset(0), measDim(0), transFlag(false), measTransformation(), scatFlag(
0042                 false), localDerivatives(), globalLabels(), globalDerivatives() {
0043 
0044     for (unsigned int i = 0; i < 5; ++i) {
0045         for (unsigned int j = 0; j < 5; ++j) {
0046             p2pJacobian(i, j) = aJacobian(i, j);
0047         }
0048     }
0049 }
0050 
0051 GblPoint::GblPoint(const SMatrix55 &aJacobian) :
0052         theLabel(0), theOffset(0), p2pJacobian(aJacobian), measDim(0), transFlag(
0053                 false), measTransformation(), scatFlag(false), localDerivatives(), globalLabels(), globalDerivatives() {
0054 
0055 }
0056 
0057 GblPoint::~GblPoint() {
0058 }
0059 
0060 /// Add a measurement to a point.
0061 /**
0062  * Add measurement (in meas. system) with diagonal precision (inverse covariance) matrix.
0063  * ((up to) 2D: position, 4D: slope+position, 5D: curvature+slope+position)
0064  * \param [in] aProjection Projection from local to measurement system
0065  * \param [in] aResiduals Measurement residuals
0066  * \param [in] aPrecision Measurement precision (diagonal)
0067  * \param [in] minPrecision Minimal precision to accept measurement
0068  */
0069 void GblPoint::addMeasurement(const TMatrixD &aProjection,
0070         const TVectorD &aResiduals, const TVectorD &aPrecision,
0071         double minPrecision) {
0072     measDim = aResiduals.GetNrows();
0073     unsigned int iOff = 5 - measDim;
0074     for (unsigned int i = 0; i < measDim; ++i) {
0075         measResiduals(iOff + i) = aResiduals[i];
0076         measPrecision(iOff + i) = (
0077                 aPrecision[i] >= minPrecision ? aPrecision[i] : 0.);
0078         for (unsigned int j = 0; j < measDim; ++j) {
0079             measProjection(iOff + i, iOff + j) = aProjection(i, j);
0080         }
0081     }
0082 }
0083 
0084 /// Add a measurement to a point.
0085 /**
0086  * Add measurement (in meas. system) with arbitrary precision (inverse covariance) matrix.
0087  * Will be diagonalized.
0088  * ((up to) 2D: position, 4D: slope+position, 5D: curvature+slope+position)
0089  * \param [in] aProjection Projection from local to measurement system
0090  * \param [in] aResiduals Measurement residuals
0091  * \param [in] aPrecision Measurement precision (matrix)
0092  * \param [in] minPrecision Minimal precision to accept measurement
0093  */
0094 void GblPoint::addMeasurement(const TMatrixD &aProjection,
0095         const TVectorD &aResiduals, const TMatrixDSym &aPrecision,
0096         double minPrecision) {
0097     measDim = aResiduals.GetNrows();
0098     TMatrixDSymEigen measEigen(aPrecision);
0099     measTransformation.ResizeTo(measDim, measDim);
0100     measTransformation = measEigen.GetEigenVectors();
0101     measTransformation.T();
0102     transFlag = true;
0103     TVectorD transResiduals = measTransformation * aResiduals;
0104     TVectorD transPrecision = measEigen.GetEigenValues();
0105     TMatrixD transProjection = measTransformation * aProjection;
0106     unsigned int iOff = 5 - measDim;
0107     for (unsigned int i = 0; i < measDim; ++i) {
0108         measResiduals(iOff + i) = transResiduals[i];
0109         measPrecision(iOff + i) = (
0110                 transPrecision[i] >= minPrecision ? transPrecision[i] : 0.);
0111         for (unsigned int j = 0; j < measDim; ++j) {
0112             measProjection(iOff + i, iOff + j) = transProjection(i, j);
0113         }
0114     }
0115 }
0116 
0117 /// Add a measurement to a point.
0118 /**
0119  * Add measurement in local system with diagonal precision (inverse covariance) matrix.
0120  * ((up to) 2D: position, 4D: slope+position, 5D: curvature+slope+position)
0121  * \param [in] aResiduals Measurement residuals
0122  * \param [in] aPrecision Measurement precision (diagonal)
0123  * \param [in] minPrecision Minimal precision to accept measurement
0124  */
0125 void GblPoint::addMeasurement(const TVectorD &aResiduals,
0126         const TVectorD &aPrecision, double minPrecision) {
0127     measDim = aResiduals.GetNrows();
0128     unsigned int iOff = 5 - measDim;
0129     for (unsigned int i = 0; i < measDim; ++i) {
0130         measResiduals(iOff + i) = aResiduals[i];
0131         measPrecision(iOff + i) = (
0132                 aPrecision[i] >= minPrecision ? aPrecision[i] : 0.);
0133     }
0134     measProjection = ROOT::Math::SMatrixIdentity();
0135 }
0136 
0137 /// Add a measurement to a point.
0138 /**
0139  * Add measurement in local system with arbitrary precision (inverse covariance) matrix.
0140  * Will be diagonalized.
0141  * ((up to) 2D: position, 4D: slope+position, 5D: curvature+slope+position)
0142  * \param [in] aResiduals Measurement residuals
0143  * \param [in] aPrecision Measurement precision (matrix)
0144  * \param [in] minPrecision Minimal precision to accept measurement
0145  */
0146 void GblPoint::addMeasurement(const TVectorD &aResiduals,
0147         const TMatrixDSym &aPrecision, double minPrecision) {
0148     measDim = aResiduals.GetNrows();
0149     TMatrixDSymEigen measEigen(aPrecision);
0150     measTransformation.ResizeTo(measDim, measDim);
0151     measTransformation = measEigen.GetEigenVectors();
0152     measTransformation.T();
0153     transFlag = true;
0154     TVectorD transResiduals = measTransformation * aResiduals;
0155     TVectorD transPrecision = measEigen.GetEigenValues();
0156     unsigned int iOff = 5 - measDim;
0157     for (unsigned int i = 0; i < measDim; ++i) {
0158         measResiduals(iOff + i) = transResiduals[i];
0159         measPrecision(iOff + i) = (
0160                 transPrecision[i] >= minPrecision ? transPrecision[i] : 0.);
0161         for (unsigned int j = 0; j < measDim; ++j) {
0162             measProjection(iOff + i, iOff + j) = measTransformation(i, j);
0163         }
0164     }
0165 }
0166 
0167 /// Check for measurement at a point.
0168 /**
0169  * Get dimension of measurement (0 = none).
0170  * \return measurement dimension
0171  */
0172 unsigned int GblPoint::hasMeasurement() const {
0173     return measDim;
0174 }
0175 
0176 /// Retrieve measurement of a point.
0177 /**
0178  * \param [out] aProjection Projection from (diagonalized) measurement to local system
0179  * \param [out] aResiduals Measurement residuals
0180  * \param [out] aPrecision Measurement precision (diagonal)
0181  */
0182 void GblPoint::getMeasurement(SMatrix55 &aProjection, SVector5 &aResiduals,
0183         SVector5 &aPrecision) const {
0184     aProjection = measProjection;
0185     aResiduals = measResiduals;
0186     aPrecision = measPrecision;
0187 }
0188 
0189 /// Get measurement transformation (from diagonalization).
0190 /**
0191  * \param [out] aTransformation Transformation matrix
0192  */
0193 void GblPoint::getMeasTransformation(TMatrixD &aTransformation) const {
0194     aTransformation.ResizeTo(measDim, measDim);
0195     if (transFlag) {
0196         aTransformation = measTransformation;
0197     } else {
0198         aTransformation.UnitMatrix();
0199     }
0200 }
0201 
0202 /// Add a (thin) scatterer to a point.
0203 /**
0204  * Add scatterer with diagonal precision (inverse covariance) matrix.
0205  * Changes local track direction.
0206  *
0207  * \param [in] aResiduals Scatterer residuals
0208  * \param [in] aPrecision Scatterer precision (diagonal of inverse covariance matrix)
0209  */
0210 void GblPoint::addScatterer(const TVectorD &aResiduals,
0211         const TVectorD &aPrecision) {
0212     scatFlag = true;
0213     scatResiduals(0) = aResiduals[0];
0214     scatResiduals(1) = aResiduals[1];
0215     scatPrecision(0) = aPrecision[0];
0216     scatPrecision(1) = aPrecision[1];
0217     scatTransformation = ROOT::Math::SMatrixIdentity();
0218 }
0219 
0220 /// Add a (thin) scatterer to a point.
0221 /**
0222  * Add scatterer with arbitrary precision (inverse covariance) matrix.
0223  * Will be diagonalized. Changes local track direction.
0224  *
0225  * The precision matrix for the local slopes is defined by the
0226  * angular scattering error theta_0 and the scalar products c_1, c_2 of the
0227  * offset directions in the local frame with the track direction:
0228  *
0229  *            (1 - c_1*c_1 - c_2*c_2)   |  1 - c_1*c_1     - c_1*c_2  |
0230  *       P =  ----------------------- * |                             |
0231  *                theta_0*theta_0       |    - c_1*c_2   1 - c_2*c_2  |
0232  *
0233  * \param [in] aResiduals Scatterer residuals
0234  * \param [in] aPrecision Scatterer precision (matrix)
0235  */
0236 void GblPoint::addScatterer(const TVectorD &aResiduals,
0237         const TMatrixDSym &aPrecision) {
0238     scatFlag = true;
0239     TMatrixDSymEigen scatEigen(aPrecision);
0240     TMatrixD aTransformation = scatEigen.GetEigenVectors();
0241     aTransformation.T();
0242     TVectorD transResiduals = aTransformation * aResiduals;
0243     TVectorD transPrecision = scatEigen.GetEigenValues();
0244     for (unsigned int i = 0; i < 2; ++i) {
0245         scatResiduals(i) = transResiduals[i];
0246         scatPrecision(i) = transPrecision[i];
0247         for (unsigned int j = 0; j < 2; ++j) {
0248             scatTransformation(i, j) = aTransformation(i, j);
0249         }
0250     }
0251 }
0252 
0253 /// Check for scatterer at a point.
0254 bool GblPoint::hasScatterer() const {
0255     return scatFlag;
0256 }
0257 
0258 /// Retrieve scatterer of a point.
0259 /**
0260  * \param [out] aTransformation Scatterer transformation from diagonalization
0261  * \param [out] aResiduals Scatterer residuals
0262  * \param [out] aPrecision Scatterer precision (diagonal)
0263  */
0264 void GblPoint::getScatterer(SMatrix22 &aTransformation, SVector2 &aResiduals,
0265         SVector2 &aPrecision) const {
0266     aTransformation = scatTransformation;
0267     aResiduals = scatResiduals;
0268     aPrecision = scatPrecision;
0269 }
0270 
0271 /// Get scatterer transformation (from diagonalization).
0272 /**
0273  * \param [out] aTransformation Transformation matrix
0274  */
0275 void GblPoint::getScatTransformation(TMatrixD &aTransformation) const {
0276     aTransformation.ResizeTo(2, 2);
0277     if (scatFlag) {
0278         for (unsigned int i = 0; i < 2; ++i) {
0279             for (unsigned int j = 0; j < 2; ++j) {
0280                 aTransformation(i, j) = scatTransformation(i, j);
0281             }
0282         }
0283     } else {
0284         aTransformation.UnitMatrix();
0285     }
0286 }
0287 
0288 /// Add local derivatives to a point.
0289 /**
0290  * Point needs to have a measurement.
0291  * \param [in] aDerivatives Local derivatives (matrix)
0292  */
0293 void GblPoint::addLocals(const TMatrixD &aDerivatives) {
0294     if (measDim) {
0295         localDerivatives.ResizeTo(aDerivatives);
0296         if (transFlag) {
0297             localDerivatives = measTransformation * aDerivatives;
0298         } else {
0299             localDerivatives = aDerivatives;
0300         }
0301     }
0302 }
0303 
0304 /// Retrieve number of local derivatives from a point.
0305 unsigned int GblPoint::getNumLocals() const {
0306     return localDerivatives.GetNcols();
0307 }
0308 
0309 /// Retrieve local derivatives from a point.
0310 const TMatrixD& GblPoint::getLocalDerivatives() const {
0311     return localDerivatives;
0312 }
0313 
0314 /// Add global derivatives to a point.
0315 /**
0316  * Point needs to have a measurement.
0317  * \param [in] aLabels Global derivatives labels
0318  * \param [in] aDerivatives Global derivatives (matrix)
0319  */
0320 void GblPoint::addGlobals(const std::vector<int> &aLabels,
0321         const TMatrixD &aDerivatives) {
0322     if (measDim) {
0323         globalLabels = aLabels;
0324         globalDerivatives.ResizeTo(aDerivatives);
0325         if (transFlag) {
0326             globalDerivatives = measTransformation * aDerivatives;
0327         } else {
0328             globalDerivatives = aDerivatives;
0329         }
0330 
0331     }
0332 }
0333 
0334 /// Retrieve number of global derivatives from a point.
0335 unsigned int GblPoint::getNumGlobals() const {
0336     return globalDerivatives.GetNcols();
0337 }
0338 
0339 /// Retrieve global derivatives labels from a point.
0340 std::vector<int> GblPoint::getGlobalLabels() const {
0341     return globalLabels;
0342 }
0343 
0344 /// Retrieve global derivatives from a point.
0345 const TMatrixD& GblPoint::getGlobalDerivatives() const {
0346     return globalDerivatives;
0347 }
0348 
0349 /// Define label of point (by GBLTrajectory constructor)
0350 /**
0351  * \param [in] aLabel Label identifying point
0352  */
0353 void GblPoint::setLabel(unsigned int aLabel) {
0354     theLabel = aLabel;
0355 }
0356 
0357 /// Retrieve label of point
0358 unsigned int GblPoint::getLabel() const {
0359     return theLabel;
0360 }
0361 
0362 /// Define offset for point (by GBLTrajectory constructor)
0363 /**
0364  * \param [in] anOffset Offset number
0365  */
0366 void GblPoint::setOffset(int anOffset) {
0367     theOffset = anOffset;
0368 }
0369 
0370 /// Retrieve offset for point
0371 int GblPoint::getOffset() const {
0372     return theOffset;
0373 }
0374 
0375 /// Retrieve point-to-(previous)point jacobian
0376 const SMatrix55& GblPoint::getP2pJacobian() const {
0377     return p2pJacobian;
0378 }
0379 
0380 /// Define jacobian to previous scatterer (by GBLTrajectory constructor)
0381 /**
0382  * \param [in] aJac Jacobian
0383  */
0384 void GblPoint::addPrevJacobian(const SMatrix55 &aJac) {
0385     int ifail = 0;
0386 // to optimize: need only two last rows of inverse
0387 //  prevJacobian = aJac.InverseFast(ifail);
0388 //  block matrix algebra
0389     SMatrix23 CA = aJac.Sub<SMatrix23>(3, 0)
0390             * aJac.Sub<SMatrix33>(0, 0).InverseFast(ifail); // C*A^-1
0391     SMatrix22 DCAB = aJac.Sub<SMatrix22>(3, 3) - CA * aJac.Sub<SMatrix32>(0, 3); // D - C*A^-1 *B
0392     DCAB.InvertFast();
0393     prevJacobian.Place_at(DCAB, 3, 3);
0394     prevJacobian.Place_at(-DCAB * CA, 3, 0);
0395 }
0396 
0397 /// Define jacobian to next scatterer (by GBLTrajectory constructor)
0398 /**
0399  * \param [in] aJac Jacobian
0400  */
0401 void GblPoint::addNextJacobian(const SMatrix55 &aJac) {
0402     nextJacobian = aJac;
0403 }
0404 
0405 /// Retrieve derivatives of local track model
0406 /**
0407  * Linearized track model: F_u(q/p,u',u) = J*u + S*u' + d*q/p,
0408  * W is inverse of S, negated for backward propagation.
0409  * \param [in] aDirection Propagation direction (>0 forward, else backward)
0410  * \param [out] matW W
0411  * \param [out] matWJ W*J
0412  * \param [out] vecWd W*d
0413  * \exception std::overflow_error : matrix S is singular.
0414  */
0415 void GblPoint::getDerivatives(int aDirection, SMatrix22 &matW, SMatrix22 &matWJ,
0416         SVector2 &vecWd) const {
0417 
0418     SMatrix22 matJ;
0419     SVector2 vecd;
0420     if (aDirection < 1) {
0421         matJ = prevJacobian.Sub<SMatrix22>(3, 3);
0422         matW = -prevJacobian.Sub<SMatrix22>(3, 1);
0423         vecd = prevJacobian.SubCol<SVector2>(0, 3);
0424     } else {
0425         matJ = nextJacobian.Sub<SMatrix22>(3, 3);
0426         matW = nextJacobian.Sub<SMatrix22>(3, 1);
0427         vecd = nextJacobian.SubCol<SVector2>(0, 3);
0428     }
0429 
0430     if (!matW.InvertFast()) {
0431         std::cout << " GblPoint::getDerivatives failed to invert matrix: "
0432                 << matW << std::endl;
0433         std::cout
0434                 << " Possible reason for singular matrix: multiple GblPoints at same arc-length"
0435                 << std::endl;
0436         throw std::overflow_error("Singular matrix inversion exception");
0437     }
0438     matWJ = matW * matJ;
0439     vecWd = matW * vecd;
0440 
0441 }
0442 
0443 /// Print GblPoint
0444 /**
0445  * \param [in] level print level (0: minimum, >0: more)
0446  */
0447 void GblPoint::printPoint(unsigned int level) const {
0448     std::cout << " GblPoint";
0449     if (theLabel) {
0450         std::cout << ", label " << theLabel;
0451         if (theOffset >= 0) {
0452             std::cout << ", offset " << theOffset;
0453         }
0454     }
0455     if (measDim) {
0456         std::cout << ", " << measDim << " measurements";
0457     }
0458     if (scatFlag) {
0459         std::cout << ", scatterer";
0460     }
0461     if (transFlag) {
0462         std::cout << ", diagonalized";
0463     }
0464     if (localDerivatives.GetNcols()) {
0465         std::cout << ", " << localDerivatives.GetNcols()
0466                 << " local derivatives";
0467     }
0468     if (globalDerivatives.GetNcols()) {
0469         std::cout << ", " << globalDerivatives.GetNcols()
0470                 << " global derivatives";
0471     }
0472     std::cout << std::endl;
0473     if (level > 0) {
0474         if (measDim) {
0475             std::cout << "  Measurement" << std::endl;
0476             std::cout << "   Projection: " << std::endl << measProjection
0477                     << std::endl;
0478             std::cout << "   Residuals: " << measResiduals << std::endl;
0479             std::cout << "   Precision: " << measPrecision << std::endl;
0480         }
0481         if (scatFlag) {
0482             std::cout << "  Scatterer" << std::endl;
0483             std::cout << "   Residuals: " << scatResiduals << std::endl;
0484             std::cout << "   Precision: " << scatPrecision << std::endl;
0485         }
0486         if (localDerivatives.GetNcols()) {
0487             std::cout << "  Local Derivatives:" << std::endl;
0488             localDerivatives.Print();
0489         }
0490         if (globalDerivatives.GetNcols()) {
0491             std::cout << "  Global Labels:";
0492             for (unsigned int i = 0; i < globalLabels.size(); ++i) {
0493                 std::cout << " " << globalLabels[i];
0494             }
0495             std::cout << std::endl;
0496             std::cout << "  Global Derivatives:" << std::endl;
0497             globalDerivatives.Print();
0498         }
0499         std::cout << "  Jacobian " << std::endl;
0500         std::cout << "   Point-to-point " << std::endl << p2pJacobian
0501                 << std::endl;
0502         if (theLabel) {
0503             std::cout << "   To previous offset " << std::endl << prevJacobian
0504                     << std::endl;
0505             std::cout << "   To next offset " << std::endl << nextJacobian
0506                     << std::endl;
0507         }
0508     }
0509 }
0510 
0511 }