File indexing completed on 2024-04-06 11:57:22
0001
0002
0003
0004
0005
0006 #include <memory>
0007 #include <limits>
0008 #include <cmath>
0009 #include <cstdlib>
0010
0011 #include "Alignment/ReferenceTrajectories/interface/ReferenceTrajectory.h"
0012
0013 #include "DataFormats/GeometrySurface/interface/Surface.h"
0014 #include "DataFormats/GeometrySurface/interface/Plane.h"
0015
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017
0018 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
0019 #include "DataFormats/GeometrySurface/interface/LocalError.h"
0020 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0021 #include "Geometry/CommonDetUnit/interface/TrackerGeomDet.h"
0022
0023 #include "DataFormats/TrajectoryState/interface/LocalTrajectoryParameters.h"
0024 #include "DataFormats/TrackingRecHit/interface/KfComponentsHolder.h"
0025
0026 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
0027 #include "TrackingTools/AnalyticalJacobians/interface/JacobianLocalToCurvilinear.h"
0028 #include "TrackingTools/AnalyticalJacobians/interface/JacobianCurvilinearToLocal.h"
0029
0030 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
0031 #include "TrackPropagation/RungeKutta/interface/defaultRKPropagator.h"
0032
0033 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0034 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
0035
0036 #include "TrackingTools/MaterialEffects/interface/MultipleScatteringUpdator.h"
0037 #include "TrackingTools/MaterialEffects/interface/EnergyLossUpdator.h"
0038 #include "TrackingTools/MaterialEffects/interface/CombinedMaterialEffectsUpdator.h"
0039 #include <TrackingTools/PatternTools/interface/TSCPBuilderNoMaterial.h>
0040 #include <TrackingTools/PatternTools/interface/TSCBLBuilderNoMaterial.h>
0041 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToPoint.h"
0042 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToBeamLine.h"
0043
0044 #include "MagneticField/Engine/interface/MagneticField.h"
0045
0046 #include "Alignment/ReferenceTrajectories/interface/BeamSpotTransientTrackingRecHit.h"
0047 #include "Alignment/ReferenceTrajectories/interface/BeamSpotGeomDet.h"
0048
0049
0050 using namespace gbl;
0051
0052 ReferenceTrajectory::ReferenceTrajectory(const TrajectoryStateOnSurface &refTsos,
0053 const TransientTrackingRecHit::ConstRecHitContainer &recHits,
0054 const MagneticField *magField,
0055 const reco::BeamSpot &beamSpot,
0056 const ReferenceTrajectoryBase::Config &config)
0057 : ReferenceTrajectoryBase(
0058 (config.materialEffects >= brokenLinesCoarse) ? 1 : refTsos.localParameters().mixedFormatVector().kSize,
0059 (config.useBeamSpot) ? recHits.size() + 1 : recHits.size(),
0060 (config.materialEffects >= brokenLinesCoarse)
0061 ? 2 * ((config.useBeamSpot) ? recHits.size() + 1 : recHits.size())
0062 : ((config.materialEffects == breakPoints)
0063 ? 2 * ((config.useBeamSpot) ? recHits.size() + 1 : recHits.size()) - 2
0064 : 0),
0065 (config.materialEffects >= brokenLinesCoarse)
0066 ? 2 * ((config.useBeamSpot) ? recHits.size() + 1 : recHits.size()) - 4
0067 : ((config.materialEffects == breakPoints)
0068 ? 2 * ((config.useBeamSpot) ? recHits.size() + 1 : recHits.size()) - 2
0069 : 0)),
0070 mass_(config.mass),
0071 materialEffects_(config.materialEffects),
0072 propDir_(config.propDir),
0073 useBeamSpot_(config.useBeamSpot),
0074 includeAPEs_(config.includeAPEs),
0075 allowZeroMaterial_(config.allowZeroMaterial) {
0076
0077 theParameters = asHepVector<5>(refTsos.localParameters().mixedFormatVector());
0078
0079 if (config.hitsAreReverse) {
0080 TransientTrackingRecHit::ConstRecHitContainer fwdRecHits;
0081 fwdRecHits.reserve(recHits.size());
0082 for (TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator it = recHits.rbegin();
0083 it != recHits.rend();
0084 ++it) {
0085 fwdRecHits.push_back(*it);
0086 }
0087 theValidityFlag = this->construct(refTsos, fwdRecHits, magField, beamSpot);
0088 } else {
0089 theValidityFlag = this->construct(refTsos, recHits, magField, beamSpot);
0090 }
0091 }
0092
0093
0094
0095 ReferenceTrajectory::ReferenceTrajectory(unsigned int nPar,
0096 unsigned int nHits,
0097 const ReferenceTrajectoryBase::Config &config)
0098 : ReferenceTrajectoryBase((config.materialEffects >= brokenLinesCoarse) ? 1 : nPar,
0099 nHits,
0100 (config.materialEffects >= brokenLinesCoarse)
0101 ? 2 * nHits
0102 : ((config.materialEffects == breakPoints) ? 2 * nHits - 2 : 0),
0103 (config.materialEffects >= brokenLinesCoarse)
0104 ? 2 * nHits - 4
0105 : ((config.materialEffects == breakPoints) ? 2 * nHits - 2 : 0)),
0106 mass_(config.mass),
0107 materialEffects_(config.materialEffects),
0108 propDir_(config.propDir),
0109 useBeamSpot_(config.useBeamSpot),
0110 includeAPEs_(config.includeAPEs),
0111 allowZeroMaterial_(config.allowZeroMaterial) {}
0112
0113
0114
0115 bool ReferenceTrajectory::construct(const TrajectoryStateOnSurface &refTsos,
0116 const TransientTrackingRecHit::ConstRecHitContainer &recHits,
0117 const MagneticField *magField,
0118 const reco::BeamSpot &beamSpot) {
0119 TrajectoryStateOnSurface theRefTsos = refTsos;
0120
0121 const SurfaceSide surfaceSide = this->surfaceSide(propDir_);
0122
0123 std::unique_ptr<MaterialEffectsUpdator> aMaterialEffectsUpdator(this->createUpdator(materialEffects_, mass_));
0124 if (!aMaterialEffectsUpdator.get())
0125 return false;
0126
0127 AlgebraicMatrix fullJacobian(theParameters.num_row(), theParameters.num_row());
0128 std::vector<AlgebraicMatrix> allJacobians;
0129 allJacobians.reserve(theNumberOfHits);
0130
0131 TransientTrackingRecHit::ConstRecHitPointer previousHitPtr;
0132 TrajectoryStateOnSurface previousTsos;
0133 AlgebraicSymMatrix previousChangeInCurvature(theParameters.num_row(), 1);
0134 std::vector<AlgebraicSymMatrix> allCurvatureChanges;
0135 allCurvatureChanges.reserve(theNumberOfHits);
0136
0137 const LocalTrajectoryError zeroErrors(0., 0., 0., 0., 0.);
0138
0139 std::vector<AlgebraicMatrix> allProjections;
0140 allProjections.reserve(theNumberOfHits);
0141 std::vector<AlgebraicSymMatrix> allDeltaParameterCovs;
0142 allDeltaParameterCovs.reserve(theNumberOfHits);
0143
0144
0145 std::vector<AlgebraicMatrix> allLocalToCurv;
0146 allLocalToCurv.reserve(theNumberOfHits);
0147 std::vector<double> allSteps;
0148 allSteps.reserve(theNumberOfHits);
0149 std::vector<AlgebraicMatrix> allCurvlinJacobians;
0150 allCurvlinJacobians.reserve(theNumberOfHits);
0151
0152 AlgebraicMatrix firstCurvlinJacobian(5, 5, 1);
0153
0154 unsigned int iRow = 0;
0155
0156 theNomField = magField->nominalValue();
0157
0158 TransientTrackingRecHit::ConstRecHitContainer allRecHits;
0159
0160 if (useBeamSpot_ && propDir_ == alongMomentum) {
0161 GlobalPoint bs(beamSpot.x0(), beamSpot.y0(), beamSpot.z0());
0162
0163 TrajectoryStateClosestToBeamLine tsctbl(TSCBLBuilderNoMaterial()(*(refTsos.freeState()), beamSpot));
0164 if (!tsctbl.isValid()) {
0165 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct"
0166 << "TrajectoryStateClostestToBeamLine invalid. Skip track.";
0167 return false;
0168 }
0169
0170 FreeTrajectoryState pcaFts = tsctbl.trackStateAtPCA();
0171 GlobalVector bd(beamSpot.dxdz(), beamSpot.dydz(), 1.0);
0172
0173
0174 AnalyticalPropagator propagator(magField);
0175 std::pair<TrajectoryStateOnSurface, double> tsosWithPath = propagator.propagateWithPath(pcaFts, refTsos.surface());
0176
0177 if (!tsosWithPath.first.isValid())
0178 return false;
0179
0180 GlobalVector momDir(pcaFts.momentum());
0181 GlobalVector perpDir(bd.cross(momDir));
0182 Plane::RotationType rotation(perpDir, bd);
0183
0184 BeamSpotGeomDet *bsGeom = new BeamSpotGeomDet(Plane::build(bs, rotation));
0185
0186
0187 theRefTsos = TrajectoryStateOnSurface(pcaFts, bsGeom->surface());
0188
0189 TransientTrackingRecHit::ConstRecHitPointer bsRecHit(
0190 new BeamSpotTransientTrackingRecHit(beamSpot, bsGeom, theRefTsos.freeState()->momentum().phi()));
0191 allRecHits.push_back(bsRecHit);
0192 }
0193
0194
0195 TransientTrackingRecHit::ConstRecHitContainer::const_iterator itRecHit;
0196 for (itRecHit = recHits.begin(); itRecHit != recHits.end(); ++itRecHit) {
0197 const TransientTrackingRecHit::ConstRecHitPointer &hitPtr = *itRecHit;
0198 allRecHits.push_back(hitPtr);
0199 }
0200
0201 for (itRecHit = allRecHits.begin(); itRecHit != allRecHits.end(); ++itRecHit) {
0202 const TransientTrackingRecHit::ConstRecHitPointer &hitPtr = *itRecHit;
0203 theRecHits.push_back(hitPtr);
0204
0205 if (0 == iRow) {
0206
0207
0208 fullJacobian = AlgebraicMatrix(theParameters.num_row(), theParameters.num_row(), 1);
0209 allJacobians.push_back(fullJacobian);
0210 theTsosVec.push_back(theRefTsos);
0211 const JacobianLocalToCurvilinear startTrafo(hitPtr->det()->surface(), theRefTsos.localParameters(), *magField);
0212 const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
0213 if (materialEffects_ <= breakPoints) {
0214 theInnerTrajectoryToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
0215 theInnerLocalToTrajectory = AlgebraicMatrix(5, 5, 1);
0216 }
0217 allLocalToCurv.push_back(localToCurvilinear);
0218 allSteps.push_back(0.);
0219 allCurvlinJacobians.push_back(firstCurvlinJacobian);
0220
0221 } else {
0222 AlgebraicMatrix nextJacobian;
0223 AlgebraicMatrix nextCurvlinJacobian;
0224 double nextStep = 0.;
0225 TrajectoryStateOnSurface nextTsos;
0226
0227 if (!this->propagate(previousHitPtr->det()->surface(),
0228 previousTsos,
0229 hitPtr->det()->surface(),
0230 nextTsos,
0231 nextJacobian,
0232 nextCurvlinJacobian,
0233 nextStep,
0234 magField)) {
0235 return false;
0236 }
0237
0238 allJacobians.push_back(nextJacobian);
0239 fullJacobian = nextJacobian * previousChangeInCurvature * fullJacobian;
0240 theTsosVec.push_back(nextTsos);
0241
0242 const JacobianLocalToCurvilinear startTrafo(hitPtr->det()->surface(), nextTsos.localParameters(), *magField);
0243 const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
0244 allLocalToCurv.push_back(localToCurvilinear);
0245 if (nextStep == 0.) {
0246 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct"
0247 << "step 0. from id " << previousHitPtr->geographicalId() << " to "
0248 << hitPtr->det()->geographicalId() << ".";
0249
0250 if (materialEffects_ == brokenLinesFine) {
0251 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct"
0252 << "Skip track.";
0253 return false;
0254 }
0255 }
0256 allSteps.push_back(nextStep);
0257 allCurvlinJacobians.push_back(nextCurvlinJacobian);
0258 }
0259
0260
0261
0262 const TrajectoryStateOnSurface tmpTsos(
0263 theTsosVec.back().localParameters(), zeroErrors, theTsosVec.back().surface(), magField, surfaceSide);
0264 const TrajectoryStateOnSurface updatedTsos = aMaterialEffectsUpdator->updateState(tmpTsos, propDir_);
0265
0266 if (!updatedTsos.isValid())
0267 return false;
0268
0269 if (theTsosVec.back().localParameters().charge()) {
0270 previousChangeInCurvature[0][0] = updatedTsos.localParameters().signedInverseMomentum() /
0271 theTsosVec.back().localParameters().signedInverseMomentum();
0272 }
0273
0274
0275 allDeltaParameterCovs.push_back(asHepMatrix<5>(updatedTsos.localError().matrix()));
0276 allCurvatureChanges.push_back(previousChangeInCurvature);
0277
0278
0279 allProjections.push_back(this->getHitProjectionMatrix(hitPtr));
0280
0281
0282 previousHitPtr = hitPtr;
0283 previousTsos = TrajectoryStateOnSurface(updatedTsos.globalParameters(), updatedTsos.surface(), surfaceSide);
0284
0285 if (materialEffects_ < brokenLinesCoarse) {
0286 this->fillDerivatives(allProjections.back(), fullJacobian, iRow);
0287 }
0288
0289 AlgebraicVector mixedLocalParams = asHepVector<5>(theTsosVec.back().localParameters().mixedFormatVector());
0290 this->fillTrajectoryPositions(allProjections.back(), mixedLocalParams, iRow);
0291 if (useRecHit(hitPtr))
0292 this->fillMeasurementAndError(hitPtr, iRow, updatedTsos);
0293
0294 iRow += nMeasPerHit;
0295 }
0296
0297 bool msOK = true;
0298 switch (materialEffects_) {
0299 case none:
0300 break;
0301 case multipleScattering:
0302 case energyLoss:
0303 case combined:
0304 msOK = this->addMaterialEffectsCov(allJacobians, allProjections, allCurvatureChanges, allDeltaParameterCovs);
0305 break;
0306 case breakPoints:
0307 msOK = this->addMaterialEffectsBp(
0308 allJacobians, allProjections, allCurvatureChanges, allDeltaParameterCovs, allLocalToCurv);
0309 break;
0310 case brokenLinesCoarse:
0311 msOK = this->addMaterialEffectsBrl(
0312 allProjections, allDeltaParameterCovs, allLocalToCurv, allSteps, refTsos.globalParameters());
0313 break;
0314 case brokenLinesFine:
0315 msOK = this->addMaterialEffectsBrl(allCurvlinJacobians,
0316 allProjections,
0317 allCurvatureChanges,
0318 allDeltaParameterCovs,
0319 allLocalToCurv,
0320 refTsos.globalParameters());
0321 break;
0322 case localGBL:
0323 msOK = this->addMaterialEffectsLocalGbl(allJacobians, allProjections, allCurvatureChanges, allDeltaParameterCovs);
0324 break;
0325 case curvlinGBL:
0326 msOK = this->addMaterialEffectsCurvlinGbl(
0327 allCurvlinJacobians, allProjections, allCurvatureChanges, allDeltaParameterCovs, allLocalToCurv);
0328 }
0329 if (!msOK)
0330 return false;
0331
0332 if (refTsos.hasError()) {
0333 AlgebraicSymMatrix parameterCov = asHepMatrix<5>(refTsos.localError().matrix());
0334 AlgebraicMatrix parDeriv;
0335 if (theNumberOfVirtualPars > 0) {
0336 parDeriv = theDerivatives.sub(1, nMeasPerHit * allJacobians.size(), 1, theParameters.num_row());
0337 } else {
0338 parDeriv = theDerivatives;
0339 }
0340 theTrajectoryPositionCov = parameterCov.similarity(parDeriv);
0341 } else {
0342 theTrajectoryPositionCov = AlgebraicSymMatrix(theDerivatives.num_row(), 1);
0343 }
0344
0345 return true;
0346 }
0347
0348
0349
0350 MaterialEffectsUpdator *ReferenceTrajectory::createUpdator(MaterialEffects materialEffects, double mass) const {
0351 switch (materialEffects) {
0352
0353
0354 case none:
0355 case multipleScattering:
0356 return new MultipleScatteringUpdator(mass);
0357 case energyLoss:
0358 return new EnergyLossUpdator(mass);
0359 case combined:
0360 return new CombinedMaterialEffectsUpdator(mass);
0361 case breakPoints:
0362 return new CombinedMaterialEffectsUpdator(mass);
0363 case brokenLinesCoarse:
0364 case brokenLinesFine:
0365 case localGBL:
0366 case curvlinGBL:
0367 return new CombinedMaterialEffectsUpdator(mass);
0368 }
0369
0370 return nullptr;
0371 }
0372
0373
0374
0375 bool ReferenceTrajectory::propagate(const Plane &previousSurface,
0376 const TrajectoryStateOnSurface &previousTsos,
0377 const Plane &newSurface,
0378 TrajectoryStateOnSurface &newTsos,
0379 AlgebraicMatrix &newJacobian,
0380 AlgebraicMatrix &newCurvlinJacobian,
0381 double &nextStep,
0382 const MagneticField *magField) const {
0383
0384
0385
0386
0387
0388
0389
0390
0391 defaultRKPropagator::Product rkprod(magField, propDir_);
0392 Propagator &aPropagator = rkprod.propagator;
0393 const std::pair<TrajectoryStateOnSurface, double> tsosWithPath =
0394 aPropagator.propagateWithPath(previousTsos, newSurface);
0395
0396
0397 if (!tsosWithPath.first.isValid())
0398 return false;
0399
0400 nextStep = tsosWithPath.second;
0401
0402
0403 const AnalyticalCurvilinearJacobian aJacobian(previousTsos.globalParameters(),
0404 tsosWithPath.first.globalPosition(),
0405 tsosWithPath.first.globalMomentum(),
0406 tsosWithPath.second);
0407 const AlgebraicMatrix curvilinearJacobian = asHepMatrix<5, 5>(aJacobian.jacobian());
0408
0409
0410 const JacobianLocalToCurvilinear startTrafo(previousSurface, previousTsos.localParameters(), *magField);
0411 const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
0412
0413
0414 const JacobianCurvilinearToLocal endTrafo(newSurface, tsosWithPath.first.localParameters(), *magField);
0415 const AlgebraicMatrix curvilinearToLocal = asHepMatrix<5>(endTrafo.jacobian());
0416
0417
0418
0419 newCurvlinJacobian = curvilinearJacobian;
0420 newJacobian = curvilinearToLocal * curvilinearJacobian * localToCurvilinear;
0421 newTsos = tsosWithPath.first;
0422
0423 return true;
0424 }
0425
0426
0427
0428 void ReferenceTrajectory::fillMeasurementAndError(const TransientTrackingRecHit::ConstRecHitPointer &hitPtr,
0429 unsigned int iRow,
0430 const TrajectoryStateOnSurface &updatedTsos) {
0431
0432
0433
0434
0435
0436
0437
0438
0439 const auto &newHitPtr = hitPtr;
0440
0441
0442
0443 const LocalPoint localMeasurement = newHitPtr->localPosition();
0444 const LocalError localMeasurementCov = newHitPtr->localPositionError();
0445
0446 theMeasurements[iRow] = localMeasurement.x();
0447 theMeasurements[iRow + 1] = localMeasurement.y();
0448 theMeasurementsCov[iRow][iRow] = localMeasurementCov.xx();
0449 theMeasurementsCov[iRow][iRow + 1] = localMeasurementCov.xy();
0450 theMeasurementsCov[iRow + 1][iRow + 1] = localMeasurementCov.yy();
0451
0452 if (!includeAPEs_) {
0453
0454 auto det = static_cast<const TrackerGeomDet *>(newHitPtr->det());
0455 const auto localAPE = det->localAlignmentError();
0456 if (localAPE.valid()) {
0457 theMeasurementsCov[iRow][iRow] -= localAPE.xx();
0458 theMeasurementsCov[iRow][iRow + 1] -= localAPE.xy();
0459 theMeasurementsCov[iRow + 1][iRow + 1] -= localAPE.yy();
0460 }
0461 }
0462 }
0463
0464
0465
0466 void ReferenceTrajectory::fillDerivatives(const AlgebraicMatrix &projection,
0467 const AlgebraicMatrix &fullJacobian,
0468 unsigned int iRow) {
0469
0470 const AlgebraicMatrix projectedJacobian(projection * fullJacobian);
0471 for (int i = 0; i < parameters().num_row(); ++i) {
0472 for (int j = 0; j < projectedJacobian.num_row(); ++j) {
0473 theDerivatives[iRow + j][i] = projectedJacobian[j][i];
0474 }
0475 }
0476 }
0477
0478
0479
0480 void ReferenceTrajectory::fillTrajectoryPositions(const AlgebraicMatrix &projection,
0481 const AlgebraicVector &mixedLocalParams,
0482 unsigned int iRow) {
0483
0484 const AlgebraicVector localPosition(projection * mixedLocalParams);
0485 for (int i = 0; i < localPosition.num_row(); ++i) {
0486 theTrajectoryPositions[iRow + i] = localPosition[i];
0487 }
0488 }
0489
0490
0491
0492 bool ReferenceTrajectory::addMaterialEffectsCov(const std::vector<AlgebraicMatrix> &allJacobians,
0493 const std::vector<AlgebraicMatrix> &allProjections,
0494 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
0495 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs) {
0496
0497
0498
0499
0500 AlgebraicSymMatrix materialEffectsCov(nMeasPerHit * allJacobians.size(), 0);
0501
0502
0503 AlgebraicSymMatrix deltaMaterialEffectsCov;
0504
0505
0506 AlgebraicSymMatrix paramMaterialEffectsCov(allDeltaParameterCovs[0]);
0507
0508
0509
0510 AlgebraicMatrix tempParameterCov;
0511 AlgebraicMatrix tempMeasurementCov;
0512
0513 for (unsigned int k = 1; k < allJacobians.size(); ++k) {
0514
0515 paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allJacobians[k]);
0516
0517
0518 deltaMaterialEffectsCov = paramMaterialEffectsCov.similarity(allProjections[k]);
0519 materialEffectsCov[nMeasPerHit * k][nMeasPerHit * k] = deltaMaterialEffectsCov[0][0];
0520 materialEffectsCov[nMeasPerHit * k][nMeasPerHit * k + 1] = deltaMaterialEffectsCov[0][1];
0521 materialEffectsCov[nMeasPerHit * k + 1][nMeasPerHit * k] = deltaMaterialEffectsCov[1][0];
0522 materialEffectsCov[nMeasPerHit * k + 1][nMeasPerHit * k + 1] = deltaMaterialEffectsCov[1][1];
0523
0524
0525 paramMaterialEffectsCov += allDeltaParameterCovs[k];
0526
0527 tempParameterCov = paramMaterialEffectsCov;
0528
0529
0530 for (unsigned int l = k + 1; l < allJacobians.size(); ++l) {
0531 tempParameterCov = allJacobians[l] * allCurvatureChanges[l] * tempParameterCov;
0532 tempMeasurementCov = allProjections[l] * tempParameterCov * allProjections[k].T();
0533
0534 materialEffectsCov[nMeasPerHit * l][nMeasPerHit * k] = tempMeasurementCov[0][0];
0535 materialEffectsCov[nMeasPerHit * k][nMeasPerHit * l] = tempMeasurementCov[0][0];
0536
0537 materialEffectsCov[nMeasPerHit * l][nMeasPerHit * k + 1] = tempMeasurementCov[0][1];
0538 materialEffectsCov[nMeasPerHit * k + 1][nMeasPerHit * l] = tempMeasurementCov[0][1];
0539
0540 materialEffectsCov[nMeasPerHit * l + 1][nMeasPerHit * k] = tempMeasurementCov[1][0];
0541 materialEffectsCov[nMeasPerHit * k][nMeasPerHit * l + 1] = tempMeasurementCov[1][0];
0542
0543 materialEffectsCov[nMeasPerHit * l + 1][nMeasPerHit * k + 1] = tempMeasurementCov[1][1];
0544 materialEffectsCov[nMeasPerHit * k + 1][nMeasPerHit * l + 1] = tempMeasurementCov[1][1];
0545 }
0546
0547
0548
0549 paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allCurvatureChanges[k]);
0550 }
0551 theMeasurementsCov += materialEffectsCov;
0552
0553 return true;
0554 }
0555
0556
0557
0558 bool ReferenceTrajectory::addMaterialEffectsBp(const std::vector<AlgebraicMatrix> &allJacobians,
0559 const std::vector<AlgebraicMatrix> &allProjections,
0560 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
0561 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
0562 const std::vector<AlgebraicMatrix> &allLocalToCurv) {
0563
0564 int offsetPar = theNumberOfPars;
0565 int offsetMeas = nMeasPerHit * allJacobians.size();
0566 int ierr = 0;
0567
0568 AlgebraicMatrix tempJacobian;
0569 AlgebraicMatrix MSprojection(2, 5);
0570 MSprojection[0][1] = 1;
0571 MSprojection[1][2] = 1;
0572 AlgebraicSymMatrix tempMSCov;
0573 AlgebraicSymMatrix tempMSCovProj;
0574 AlgebraicMatrix tempMSJacProj;
0575
0576 for (unsigned int k = 1; k < allJacobians.size(); ++k) {
0577
0578 int kbp = k - 1;
0579 tempJacobian = allJacobians[k] * allCurvatureChanges[k];
0580 tempMSCov = allDeltaParameterCovs[k - 1].similarity(allLocalToCurv[k - 1]);
0581 tempMSCovProj = tempMSCov.similarity(MSprojection);
0582 theMeasurementsCov[offsetMeas + nMeasPerHit * kbp][offsetMeas + nMeasPerHit * kbp] = tempMSCovProj[0][0];
0583 theMeasurementsCov[offsetMeas + nMeasPerHit * kbp + 1][offsetMeas + nMeasPerHit * kbp + 1] = tempMSCovProj[1][1];
0584 theDerivatives[offsetMeas + nMeasPerHit * kbp][offsetPar + 2 * kbp] = 1.0;
0585 theDerivatives[offsetMeas + nMeasPerHit * kbp + 1][offsetPar + 2 * kbp + 1] = 1.0;
0586
0587 tempMSJacProj = (allProjections[k] * (tempJacobian * allLocalToCurv[k - 1].inverse(ierr))) * MSprojection.T();
0588 if (ierr) {
0589 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBp"
0590 << "Inversion 1 for break points failed: " << ierr;
0591 return false;
0592 }
0593 theDerivatives[nMeasPerHit * k][offsetPar + 2 * kbp] = tempMSJacProj[0][0];
0594 theDerivatives[nMeasPerHit * k][offsetPar + 2 * kbp + 1] = tempMSJacProj[0][1];
0595 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * kbp] = tempMSJacProj[1][0];
0596 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * kbp + 1] = tempMSJacProj[1][1];
0597
0598 for (unsigned int l = k + 1; l < allJacobians.size(); ++l) {
0599
0600 int kbp = k - 1;
0601 tempJacobian = allJacobians[l] * allCurvatureChanges[l] * tempJacobian;
0602 tempMSJacProj = (allProjections[l] * (tempJacobian * allLocalToCurv[k - 1].inverse(ierr))) * MSprojection.T();
0603 if (ierr) {
0604 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBp"
0605 << "Inversion 2 for break points failed: " << ierr;
0606 return false;
0607 }
0608 theDerivatives[nMeasPerHit * l][offsetPar + 2 * kbp] = tempMSJacProj[0][0];
0609 theDerivatives[nMeasPerHit * l][offsetPar + 2 * kbp + 1] = tempMSJacProj[0][1];
0610 theDerivatives[nMeasPerHit * l + 1][offsetPar + 2 * kbp] = tempMSJacProj[1][0];
0611 theDerivatives[nMeasPerHit * l + 1][offsetPar + 2 * kbp + 1] = tempMSJacProj[1][1];
0612 }
0613 }
0614
0615 return true;
0616 }
0617
0618
0619
0620 bool ReferenceTrajectory::addMaterialEffectsBrl(const std::vector<AlgebraicMatrix> &allCurvlinJacobians,
0621 const std::vector<AlgebraicMatrix> &allProjections,
0622 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
0623 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
0624 const std::vector<AlgebraicMatrix> &allLocalToCurv,
0625 const GlobalTrajectoryParameters >p) {
0626
0627
0628
0629
0630
0631
0632
0633
0634 int offsetPar = theNumberOfPars;
0635 int offsetMeas = nMeasPerHit * allCurvlinJacobians.size();
0636 int ierr = 0;
0637
0638 GlobalVector p = gtp.momentum();
0639 double cosLambda = sqrt((p.x() * p.x() + p.y() * p.y()) / (p.x() * p.x() + p.y() * p.y() + p.z() * p.z()));
0640
0641
0642 AlgebraicMatrix QbypToCurv(5, 1);
0643 QbypToCurv[0][0] = 1.;
0644 AlgebraicMatrix AngleToCurv(5, 2);
0645 AngleToCurv[1][1] = 1.;
0646 AngleToCurv[2][0] = 1. / cosLambda;
0647 AlgebraicMatrix CurvToAngle(2, 5);
0648 CurvToAngle[1][1] = 1.;
0649 CurvToAngle[0][2] = cosLambda;
0650 AlgebraicMatrix OffsetToCurv(5, 2);
0651 OffsetToCurv[3][0] = 1.;
0652 OffsetToCurv[4][1] = 1.;
0653 AlgebraicMatrix CurvToOffset(2, 5);
0654 CurvToOffset[0][3] = 1.;
0655 CurvToOffset[1][4] = 1.;
0656
0657
0658 AlgebraicMatrix TrajToQbyp(1, 5);
0659 TrajToQbyp[0][0] = 1.;
0660 AlgebraicMatrix TrajToOff1(2, 5);
0661 TrajToOff1[0][1] = 1.;
0662 TrajToOff1[1][2] = 1.;
0663 AlgebraicMatrix TrajToOff2(2, 5);
0664 TrajToOff2[0][3] = 1.;
0665 TrajToOff2[1][4] = 1.;
0666
0667 AlgebraicMatrix JacOffsetToAngleC, JacQbypToAngleC;
0668 AlgebraicMatrix JacCurvToOffsetL, JacOffsetToOffsetL, JacAngleToOffsetL, JacQbypToOffsetL, JacOffsetToAngleL;
0669 AlgebraicMatrix JacCurvToOffsetN, JacOffsetToOffsetN, JacAngleToOffsetN, JacQbypToOffsetN, JacOffsetToAngleN;
0670
0671
0672
0673 JacCurvToOffsetN = CurvToOffset * allCurvlinJacobians[1];
0674 JacOffsetToOffsetN = JacCurvToOffsetN * OffsetToCurv;
0675 JacAngleToOffsetN =
0676 JacCurvToOffsetN * AngleToCurv;
0677 JacQbypToOffsetN = JacCurvToOffsetN * QbypToCurv;
0678 JacOffsetToAngleN = JacAngleToOffsetN.inverse(ierr);
0679 if (ierr) {
0680 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0681 << "Inversion 1 for fine broken lines failed: " << ierr;
0682 return false;
0683 }
0684 JacOffsetToAngleC = -(JacOffsetToAngleN * JacOffsetToOffsetN);
0685 JacQbypToAngleC = -(JacOffsetToAngleN * JacQbypToOffsetN);
0686
0687 AlgebraicMatrix JacTrajToAngle =
0688 JacQbypToAngleC * TrajToQbyp + JacOffsetToAngleC * TrajToOff1 + JacOffsetToAngleN * TrajToOff2;
0689
0690 theInnerTrajectoryToCurvilinear = QbypToCurv * TrajToQbyp + AngleToCurv * JacTrajToAngle + OffsetToCurv * TrajToOff1;
0691 theInnerLocalToTrajectory = theInnerTrajectoryToCurvilinear.inverse(ierr) * allLocalToCurv[0];
0692 if (ierr) {
0693 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0694 << "Inversion 2 for fine broken lines failed: " << ierr;
0695 return false;
0696 }
0697
0698 AlgebraicMatrix tempJacobian(allCurvatureChanges[0]);
0699 AlgebraicSymMatrix tempMSCov;
0700 AlgebraicSymMatrix tempMSCovProj;
0701 AlgebraicMatrix tempJacL, tempJacN;
0702 AlgebraicMatrix JacOffsetToMeas;
0703
0704
0705 for (unsigned int k = 0; k < allCurvlinJacobians.size(); ++k) {
0706
0707 JacOffsetToMeas = (allProjections[k] * allLocalToCurv[k].inverse(ierr)) * OffsetToCurv;
0708 if (ierr) {
0709 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0710 << "Inversion 3 for fine broken lines failed: " << ierr;
0711 return false;
0712 }
0713 theDerivatives[nMeasPerHit * k][offsetPar + 2 * k] = JacOffsetToMeas[0][0];
0714 theDerivatives[nMeasPerHit * k][offsetPar + 2 * k + 1] = JacOffsetToMeas[0][1];
0715 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * k] = JacOffsetToMeas[1][0];
0716 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * k + 1] = JacOffsetToMeas[1][1];
0717 }
0718
0719
0720 for (unsigned int k = 1; k < allCurvlinJacobians.size() - 1; ++k) {
0721
0722 int iMsMeas = k - 1;
0723 int l = k - 1;
0724 int n = k + 1;
0725
0726
0727 tempMSCov = allDeltaParameterCovs[k].similarity(allLocalToCurv[k]);
0728 tempMSCovProj = tempMSCov.similarity(CurvToAngle);
0729 theMeasurementsCov[offsetMeas + nMeasPerHit * iMsMeas][offsetMeas + nMeasPerHit * iMsMeas] = tempMSCovProj[1][1];
0730 theMeasurementsCov[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetMeas + nMeasPerHit * iMsMeas + 1] =
0731 tempMSCovProj[0][0];
0732
0733
0734 tempJacL = allCurvlinJacobians[k] * tempJacobian;
0735 JacCurvToOffsetL = CurvToOffset * tempJacL.inverse(ierr);
0736
0737 if (ierr) {
0738 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0739 << "Inversion 4 for fine broken lines failed: " << ierr;
0740 return false;
0741 }
0742 JacOffsetToOffsetL =
0743 JacCurvToOffsetL * OffsetToCurv;
0744 JacAngleToOffsetL =
0745 JacCurvToOffsetL * AngleToCurv;
0746 JacQbypToOffsetL =
0747 JacCurvToOffsetL * QbypToCurv;
0748 JacOffsetToAngleL = -JacAngleToOffsetL.inverse(ierr);
0749 if (ierr) {
0750 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0751 << "Inversion 5 for fine broken lines failed: " << ierr;
0752 return false;
0753 }
0754 tempJacobian = tempJacobian * allCurvatureChanges[k];
0755 tempJacN = allCurvlinJacobians[n] * tempJacobian;
0756 JacCurvToOffsetN = CurvToOffset * tempJacN;
0757 JacOffsetToOffsetN =
0758 JacCurvToOffsetN * OffsetToCurv;
0759 JacAngleToOffsetN =
0760 JacCurvToOffsetN * AngleToCurv;
0761 JacQbypToOffsetN =
0762 JacCurvToOffsetN * QbypToCurv;
0763 JacOffsetToAngleN = JacAngleToOffsetN.inverse(ierr);
0764 if (ierr) {
0765 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0766 << "Inversion 6 for fine broken lines failed: " << ierr;
0767 return false;
0768 }
0769 JacOffsetToAngleC = -(JacOffsetToAngleL * JacOffsetToOffsetL + JacOffsetToAngleN * JacOffsetToOffsetN);
0770 JacQbypToAngleC = -(JacOffsetToAngleL * JacQbypToOffsetL + JacOffsetToAngleN * JacQbypToOffsetN);
0771
0772
0773 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][0] = JacQbypToAngleC[0][0];
0774 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][0] = JacQbypToAngleC[1][0];
0775
0776 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * l] = JacOffsetToAngleL[0][0];
0777 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * l + 1] = JacOffsetToAngleL[0][1];
0778 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * l] = JacOffsetToAngleL[1][0];
0779 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * l + 1] = JacOffsetToAngleL[1][1];
0780
0781 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * k] = JacOffsetToAngleC[0][0];
0782 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * k + 1] = JacOffsetToAngleC[0][1];
0783 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * k] = JacOffsetToAngleC[1][0];
0784 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * k + 1] = JacOffsetToAngleC[1][1];
0785
0786
0787 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * n] = JacOffsetToAngleN[0][0];
0788 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * n + 1] = JacOffsetToAngleN[0][1];
0789 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * n] = JacOffsetToAngleN[1][0];
0790 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * n + 1] = JacOffsetToAngleN[1][1];
0791 }
0792
0793 return true;
0794 }
0795
0796
0797
0798 bool ReferenceTrajectory::addMaterialEffectsBrl(const std::vector<AlgebraicMatrix> &allProjections,
0799 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
0800 const std::vector<AlgebraicMatrix> &allLocalToCurv,
0801 const std::vector<double> &allSteps,
0802 const GlobalTrajectoryParameters >p,
0803 const double minStep) {
0804
0805
0806
0807
0808
0809 int offsetPar = theNumberOfPars;
0810 int offsetMeas = nMeasPerHit * allSteps.size();
0811 int ierr = 0;
0812
0813 GlobalVector p = gtp.momentum();
0814 double cosLambda = sqrt((p.x() * p.x() + p.y() * p.y()) / (p.x() * p.x() + p.y() * p.y() + p.z() * p.z()));
0815 double bFac = -gtp.magneticFieldInInverseGeV(gtp.position()).mag();
0816
0817
0818 double delta(1.0 / allSteps[1]);
0819 theInnerTrajectoryToCurvilinear[0][0] = 1;
0820 theInnerTrajectoryToCurvilinear[1][2] = -delta;
0821 theInnerTrajectoryToCurvilinear[1][4] = delta;
0822 theInnerTrajectoryToCurvilinear[2][0] = -0.5 * bFac / delta;
0823 theInnerTrajectoryToCurvilinear[2][1] = -delta / cosLambda;
0824 theInnerTrajectoryToCurvilinear[2][3] = delta / cosLambda;
0825 theInnerTrajectoryToCurvilinear[3][1] = 1;
0826 theInnerTrajectoryToCurvilinear[4][2] = 1;
0827 theInnerLocalToTrajectory = theInnerTrajectoryToCurvilinear.inverse(ierr) * allLocalToCurv[0];
0828 if (ierr) {
0829 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0830 << "Inversion 1 for coarse broken lines failed: " << ierr;
0831 return false;
0832 }
0833
0834 AlgebraicMatrix CurvToAngle(2, 5);
0835 CurvToAngle[1][1] = 1.;
0836 CurvToAngle[0][2] = cosLambda;
0837 AlgebraicMatrix OffsetToCurv(5, 2);
0838 OffsetToCurv[3][0] = 1.;
0839 OffsetToCurv[4][1] = 1.;
0840
0841 AlgebraicSymMatrix tempMSCov;
0842 AlgebraicSymMatrix tempMSCovProj;
0843 AlgebraicMatrix JacOffsetToMeas;
0844
0845
0846 std::vector<unsigned int> first(allSteps.size());
0847 std::vector<unsigned int> last(allSteps.size());
0848 std::vector<unsigned int> plane(allSteps.size());
0849 std::vector<double> sPlane(allSteps.size());
0850 unsigned int nPlane = 0;
0851 double sTot = 0;
0852
0853 for (unsigned int k = 1; k < allSteps.size(); ++k) {
0854 sTot += allSteps[k];
0855 if (fabs(allSteps[k]) > minStep) {
0856 nPlane += 1;
0857 first[nPlane] = k;
0858 }
0859 last[nPlane] = k;
0860 plane[k] = nPlane;
0861 sPlane[nPlane] += sTot;
0862 }
0863 if (nPlane < 2)
0864 return false;
0865
0866 theNumberOfVirtualPars = 2 * (nPlane + 1);
0867 theNumberOfVirtualMeas = 2 * (nPlane - 1);
0868 for (unsigned int k = 0; k <= nPlane; ++k) {
0869 sPlane[k] /= (double)(last[k] - first[k] + 1);
0870 }
0871
0872
0873 sTot = 0;
0874 for (unsigned int k = 0; k < allSteps.size(); ++k) {
0875 sTot += allSteps[k];
0876
0877 JacOffsetToMeas = (allProjections[k] * allLocalToCurv[k].inverse(ierr)) * OffsetToCurv;
0878 if (ierr) {
0879 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
0880 << "Inversion 2 for coarse broken lines failed: " << ierr;
0881 return false;
0882 }
0883
0884 unsigned int iPlane = plane[k];
0885 if (last[iPlane] == first[iPlane]) {
0886 theDerivatives[nMeasPerHit * k][offsetPar + 2 * iPlane] = JacOffsetToMeas[0][0];
0887 theDerivatives[nMeasPerHit * k][offsetPar + 2 * iPlane + 1] = JacOffsetToMeas[0][1];
0888 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * iPlane] = JacOffsetToMeas[1][0];
0889 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * iPlane + 1] = JacOffsetToMeas[1][1];
0890 } else {
0891 unsigned int jPlane;
0892 if (fabs(sTot) < fabs(sPlane[iPlane])) {
0893 jPlane = (iPlane > 0) ? iPlane - 1 : 1;
0894 } else {
0895 jPlane = (iPlane < nPlane) ? iPlane + 1 : nPlane - 1;
0896 }
0897
0898 double sDiff = sPlane[iPlane] - sPlane[jPlane];
0899 double iFrac = (sTot - sPlane[jPlane]) / sDiff;
0900 double jFrac = 1.0 - iFrac;
0901 theDerivatives[nMeasPerHit * k][offsetPar + 2 * iPlane] = JacOffsetToMeas[0][0] * iFrac;
0902 theDerivatives[nMeasPerHit * k][offsetPar + 2 * iPlane + 1] = JacOffsetToMeas[0][1] * iFrac;
0903 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * iPlane] = JacOffsetToMeas[1][0] * iFrac;
0904 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * iPlane + 1] = JacOffsetToMeas[1][1] * iFrac;
0905 theDerivatives[nMeasPerHit * k][offsetPar + 2 * jPlane] = JacOffsetToMeas[0][0] * jFrac;
0906 theDerivatives[nMeasPerHit * k][offsetPar + 2 * jPlane + 1] = JacOffsetToMeas[0][1] * jFrac;
0907 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * jPlane] = JacOffsetToMeas[1][0] * jFrac;
0908 theDerivatives[nMeasPerHit * k + 1][offsetPar + 2 * jPlane + 1] = JacOffsetToMeas[1][1] * jFrac;
0909
0910
0911 }
0912 }
0913
0914
0915 for (unsigned int i = 1; i < nPlane; ++i) {
0916
0917 int iMsMeas = i - 1;
0918 int l = i - 1;
0919 int n = i + 1;
0920
0921
0922 for (unsigned int k = first[i]; k <= last[i]; ++k) {
0923 tempMSCov = allDeltaParameterCovs[k].similarity(allLocalToCurv[k]);
0924 tempMSCovProj = tempMSCov.similarity(CurvToAngle);
0925 theMeasurementsCov[offsetMeas + nMeasPerHit * iMsMeas][offsetMeas + nMeasPerHit * iMsMeas] += tempMSCovProj[0][0];
0926 theMeasurementsCov[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetMeas + nMeasPerHit * iMsMeas + 1] +=
0927 tempMSCovProj[1][1];
0928 }
0929
0930 double stepK = sPlane[i] - sPlane[l];
0931 double stepN = sPlane[n] - sPlane[i];
0932 double deltaK(1.0 / stepK);
0933 double deltaN(1.0 / stepN);
0934
0935 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][0] = -0.5 * bFac * (stepK + stepN) * cosLambda;
0936
0937 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * l] = deltaK;
0938 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * l + 1] = deltaK;
0939
0940 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * i] = -(deltaK + deltaN);
0941 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * i + 1] = -(deltaK + deltaN);
0942
0943 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas][offsetPar + 2 * n] = deltaN;
0944 theDerivatives[offsetMeas + nMeasPerHit * iMsMeas + 1][offsetPar + 2 * n + 1] = deltaN;
0945 }
0946
0947 return true;
0948 }
0949
0950
0951
0952 bool ReferenceTrajectory::addMaterialEffectsLocalGbl(const std::vector<AlgebraicMatrix> &allJacobians,
0953 const std::vector<AlgebraicMatrix> &allProjections,
0954 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
0955 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs) {
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966 const double minPrec = 0.3;
0967
0968 AlgebraicMatrix OffsetToLocal(5, 2);
0969 OffsetToLocal[3][0] = 1.;
0970 OffsetToLocal[4][1] = 1.;
0971 AlgebraicMatrix SlopeToLocal(5, 2);
0972 SlopeToLocal[1][0] = 1.;
0973 SlopeToLocal[2][1] = 1.;
0974
0975
0976 Eigen::Matrix2d covariance, scatPrecision, proLocalToMeas;
0977 Matrix5d jacPointToPoint;
0978 auto identity = Matrix5d::Identity();
0979 Eigen::Vector2d measurement, measPrecDiag;
0980 auto scatterer = Eigen::Vector2d::Zero();
0981
0982
0983
0984
0985 unsigned int numHits = allJacobians.size();
0986 std::vector<GblPoint> GblPointList;
0987 GblPointList.reserve(numHits);
0988 for (unsigned int k = 0; k < numHits; ++k) {
0989
0990 clhep2eigen(allJacobians[k] * allCurvatureChanges[k], jacPointToPoint);
0991
0992
0993 GblPoint aGblPoint(jacPointToPoint);
0994
0995
0996 clhep2eigen(allProjections[k] * OffsetToLocal, proLocalToMeas);
0997
0998
0999 clhep2eigen(theMeasurements.sub(2 * k + 1, 2 * k + 2) - theTrajectoryPositions.sub(2 * k + 1, 2 * k + 2),
1000 measurement);
1001
1002
1003 clhep2eigen(theMeasurementsCov.sub(2 * k + 1, 2 * k + 2), covariance);
1004
1005
1006 if (std::abs(covariance(0, 1)) < std::numeric_limits<double>::epsilon()) {
1007
1008 for (unsigned int row = 0; row < 2; ++row) {
1009 measPrecDiag(row) = (0. < covariance(row, row) ? 1.0 / covariance(row, row) : 0.);
1010 }
1011 aGblPoint.addMeasurement(proLocalToMeas, measurement, measPrecDiag, minPrec);
1012 } else {
1013
1014 aGblPoint.addMeasurement(proLocalToMeas, measurement, covariance.inverse(), minPrec);
1015 }
1016
1017
1018 clhep2eigen(allDeltaParameterCovs[k].similarityT(SlopeToLocal), scatPrecision);
1019 if (!(scatPrecision.colPivHouseholderQr().isInvertible())) {
1020 if (!allowZeroMaterial_) {
1021 throw cms::Exception("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsLocalGbl"
1022 << "\nEncountered singular scatter covariance-matrix without allowing "
1023 << "for zero material.";
1024 }
1025 } else {
1026
1027 aGblPoint.addScatterer(scatterer, Eigen::Matrix2d(scatPrecision.inverse()));
1028 }
1029
1030 GblPointList.push_back(aGblPoint);
1031 }
1032
1033 theGblInput.push_back(std::make_pair(GblPointList, identity));
1034
1035 return true;
1036 }
1037
1038
1039
1040 bool ReferenceTrajectory::addMaterialEffectsCurvlinGbl(const std::vector<AlgebraicMatrix> &allCurvlinJacobians,
1041 const std::vector<AlgebraicMatrix> &allProjections,
1042 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
1043 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
1044 const std::vector<AlgebraicMatrix> &allLocalToCurv) {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 const double minPrec = 0.3;
1056 int ierr = 0;
1057
1058 AlgebraicMatrix OffsetToCurv(5, 2);
1059 OffsetToCurv[3][0] = 1.;
1060 OffsetToCurv[4][1] = 1.;
1061
1062 AlgebraicMatrix JacOffsetToMeas, tempMSCov;
1063
1064
1065 Eigen::Matrix2d covariance, proLocalToMeas;
1066 Matrix5d jacPointToPoint, firstLocalToCurv;
1067 Eigen::Vector2d measurement, measPrecDiag, scatPrecDiag;
1068 auto scatterer = Eigen::Vector2d::Zero();
1069
1070
1071 unsigned int numHits = allCurvlinJacobians.size();
1072 std::vector<GblPoint> GblPointList;
1073 GblPointList.reserve(numHits);
1074 for (unsigned int k = 0; k < numHits; ++k) {
1075
1076 JacOffsetToMeas = (allProjections[k] * allLocalToCurv[k].inverse(ierr)) * OffsetToCurv;
1077 if (ierr) {
1078 edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsGbl"
1079 << "Inversion 1 for general broken lines failed: " << ierr;
1080 return false;
1081 }
1082
1083
1084 clhep2eigen(allCurvlinJacobians[k] * allCurvatureChanges[k], jacPointToPoint);
1085
1086
1087 GblPoint aGblPoint(jacPointToPoint);
1088
1089
1090 clhep2eigen(JacOffsetToMeas, proLocalToMeas);
1091
1092
1093 clhep2eigen(theMeasurements.sub(2 * k + 1, 2 * k + 2) - theTrajectoryPositions.sub(2 * k + 1, 2 * k + 2),
1094 measurement);
1095
1096
1097 clhep2eigen(theMeasurementsCov.sub(2 * k + 1, 2 * k + 2), covariance);
1098
1099
1100 if (std::abs(covariance(0, 1)) < std::numeric_limits<double>::epsilon()) {
1101
1102 for (unsigned int row = 0; row < 2; ++row) {
1103 measPrecDiag(row) = (0. < covariance(row, row) ? 1.0 / covariance(row, row) : 0.);
1104 }
1105 aGblPoint.addMeasurement(proLocalToMeas, measurement, measPrecDiag, minPrec);
1106 } else {
1107
1108 aGblPoint.addMeasurement(proLocalToMeas, measurement, covariance.inverse(), minPrec);
1109 }
1110
1111
1112 tempMSCov = allDeltaParameterCovs[k].similarity(allLocalToCurv[k]);
1113 for (unsigned int row = 0; row < 2; ++row) {
1114 scatPrecDiag(row) = 1.0 / tempMSCov[row + 1][row + 1];
1115 }
1116
1117
1118 bool singularCovariance{false};
1119 for (int row = 0; row < scatPrecDiag.rows(); ++row) {
1120 if (!(scatPrecDiag[row] < std::numeric_limits<double>::infinity())) {
1121 singularCovariance = true;
1122 break;
1123 }
1124 }
1125 if (singularCovariance && !allowZeroMaterial_) {
1126 throw cms::Exception("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsCurvlinGbl"
1127 << "\nEncountered singular scatter covariance-matrix without allowing "
1128 << "for zero material.";
1129 }
1130
1131
1132 aGblPoint.addScatterer(scatterer, Eigen::Vector2d(scatPrecDiag));
1133
1134
1135 GblPointList.push_back(aGblPoint);
1136 }
1137
1138 clhep2eigen(allLocalToCurv[0], firstLocalToCurv);
1139 theGblInput.push_back(std::make_pair(GblPointList, firstLocalToCurv));
1140
1141 return true;
1142 }
1143
1144
1145 template <typename Derived>
1146 void ReferenceTrajectory::clhep2eigen(const AlgebraicVector &in, Eigen::MatrixBase<Derived> &out) {
1147 static_assert(Derived::ColsAtCompileTime == 1, "clhep2eigen: 'out' must be of vector type");
1148 for (int row = 0; row < in.num_row(); ++row) {
1149 out(row) = in[row];
1150 }
1151 }
1152
1153 template <typename Derived>
1154 void ReferenceTrajectory::clhep2eigen(const AlgebraicMatrix &in, Eigen::MatrixBase<Derived> &out) {
1155 for (int row = 0; row < in.num_row(); ++row) {
1156 for (int col = 0; col < in.num_col(); ++col) {
1157 out(row, col) = in[row][col];
1158 }
1159 }
1160 }
1161
1162 template <typename Derived>
1163 void ReferenceTrajectory::clhep2eigen(const AlgebraicSymMatrix &in, Eigen::MatrixBase<Derived> &out) {
1164 for (int row = 0; row < in.num_row(); ++row) {
1165 for (int col = 0; col < in.num_col(); ++col) {
1166 out(row, col) = in[row][col];
1167 }
1168 }
1169 }
1170
1171
1172
1173 AlgebraicMatrix ReferenceTrajectory::getHitProjectionMatrix(
1174 const TransientTrackingRecHit::ConstRecHitPointer &hitPtr) const {
1175 if (this->useRecHit(hitPtr)) {
1176
1177 switch (hitPtr->dimension()) {
1178 case 1:
1179 return getHitProjectionMatrixT<1>(hitPtr);
1180 case 2:
1181 return getHitProjectionMatrixT<2>(hitPtr);
1182 case 3:
1183 return getHitProjectionMatrixT<3>(hitPtr);
1184 case 4:
1185 return getHitProjectionMatrixT<4>(hitPtr);
1186 case 5:
1187 return getHitProjectionMatrixT<5>(hitPtr);
1188 default:
1189 throw cms::Exception("ReferenceTrajectory::getHitProjectionMatrix")
1190 << "Unexpected hit dimension: " << hitPtr->dimension() << "\n";
1191 }
1192 }
1193
1194 return AlgebraicMatrix(2, 5, 0);
1195 }
1196
1197
1198
1199 template <unsigned int N>
1200 AlgebraicMatrix ReferenceTrajectory::getHitProjectionMatrixT(
1201 const TransientTrackingRecHit::ConstRecHitPointer &hitPtr) const {
1202
1203
1204
1205 ProjectMatrix<double, 5, N> pf;
1206 typename AlgebraicROOTObject<N>::Vector r, rMeas;
1207 typename AlgebraicROOTObject<N, N>::SymMatrix V, VMeas;
1208
1209 const AlgebraicVector5 dummyPars;
1210 const AlgebraicSymMatrix55 dummyErr;
1211
1212
1213 KfComponentsHolder holder;
1214 holder.setup<N>(&r, &V, &pf, &rMeas, &VMeas, dummyPars, dummyErr);
1215 hitPtr->getKfComponents(holder);
1216
1217 return asHepMatrix<N, 5>(holder.projection<N>());
1218 }