CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ReferenceTrajectory.cc
Go to the documentation of this file.
1 // Author : Gero Flucke (based on code by Edmund Widl replacing ORCA's TkReferenceTrack)
2 // date : 2006/09/17
3 // last update: $Date: 2012/06/20 12:07:28 $
4 // by : $Author: flucke $
5 
6 #include <memory>
7 
9 
13 
15 
20 
23 
27 
30 
33 
41 
43 
46 
47 //__________________________________________________________________________________
48 
51  &recHits, bool hitsAreReverse,
52  const MagneticField *magField,
53  MaterialEffects materialEffects,
54  PropagationDirection propDir,
55  double mass,
56  bool useBeamSpot, const reco::BeamSpot &beamSpot)
58  (materialEffects >= brokenLinesCoarse) ? 1 : refTsos.localParameters().mixedFormatVector().kSize,
59  (useBeamSpot == true) ? recHits.size()+1 : recHits.size(),
60  (materialEffects >= brokenLinesCoarse) ?
61  2*((useBeamSpot == true) ? recHits.size()+1 : recHits.size()) :
62  ( (materialEffects == breakPoints) ? 2*((useBeamSpot == true) ? recHits.size()+1 : recHits.size())-2 : 0) ,
63  (materialEffects >= brokenLinesCoarse) ?
64  2*((useBeamSpot == true) ? recHits.size()+1 : recHits.size())-4 :
65  ( (materialEffects == breakPoints) ? 2*((useBeamSpot == true) ? recHits.size()+1 : recHits.size())-2 : 0) )
66 {
67  // no check against magField == 0
68  theParameters = asHepVector<5>( refTsos.localParameters().mixedFormatVector() );
69 
70  if (hitsAreReverse) {
72  fwdRecHits.reserve(recHits.size());
73  for (TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator it=recHits.rbegin();
74  it != recHits.rend(); ++it) {
75  fwdRecHits.push_back(*it);
76  }
77  theValidityFlag = this->construct(refTsos, fwdRecHits, mass, materialEffects,
78  propDir, magField,
79  useBeamSpot, beamSpot);
80  } else {
81  theValidityFlag = this->construct(refTsos, recHits, mass, materialEffects,
82  propDir, magField,
83  useBeamSpot, beamSpot);
84  }
85 }
86 
87 
88 //__________________________________________________________________________________
89 
90 ReferenceTrajectory::ReferenceTrajectory( unsigned int nPar, unsigned int nHits,
91  MaterialEffects materialEffects)
93  (materialEffects >= brokenLinesCoarse) ? 1 : nPar,
94  nHits,
95  (materialEffects >= brokenLinesCoarse) ? 2*nHits : ( (materialEffects == breakPoints) ? 2*nHits-2 : 0 ),
96  (materialEffects >= brokenLinesCoarse) ? 2*nHits-4 : ( (materialEffects == breakPoints) ? 2*nHits-2 : 0 ) )
97 {}
98 
99 
100 //__________________________________________________________________________________
101 
104  double mass, MaterialEffects materialEffects,
105  const PropagationDirection propDir,
106  const MagneticField *magField,
107  bool useBeamSpot,
108  const reco::BeamSpot &beamSpot)
109 {
110  TrajectoryStateOnSurface theRefTsos = refTsos;
111 
112  const SurfaceSide surfaceSide = this->surfaceSide(propDir);
113  // auto_ptr to avoid memory leaks in case of not reaching delete at end of method:
114  std::auto_ptr<MaterialEffectsUpdator> aMaterialEffectsUpdator
115  (this->createUpdator(materialEffects, mass));
116  if (!aMaterialEffectsUpdator.get()) return false; // empty auto_ptr
117 
118  AlgebraicMatrix fullJacobian(theParameters.num_row(), theParameters.num_row());
119  std::vector<AlgebraicMatrix> allJacobians;
120  allJacobians.reserve(theNumberOfHits);
121 
123  TrajectoryStateOnSurface previousTsos;
124  AlgebraicSymMatrix previousChangeInCurvature(theParameters.num_row(), 1);
125  std::vector<AlgebraicSymMatrix> allCurvatureChanges;
126  allCurvatureChanges.reserve(theNumberOfHits);
127 
128  const LocalTrajectoryError zeroErrors(0., 0., 0., 0., 0.);
129 
130  std::vector<AlgebraicMatrix> allProjections;
131  allProjections.reserve(theNumberOfHits);
132  std::vector<AlgebraicSymMatrix> allDeltaParameterCovs;
133  allDeltaParameterCovs.reserve(theNumberOfHits);
134 
135  // CHK
136  std::vector<AlgebraicMatrix> allLocalToCurv;
137  allLocalToCurv.reserve(theNumberOfHits);
138  std::vector<double> allSteps;
139  allSteps.reserve(theNumberOfHits);
140  std::vector<AlgebraicMatrix> allCurvlinJacobians;
141  allCurvlinJacobians.reserve(theNumberOfHits);
142 
143  AlgebraicMatrix firstCurvlinJacobian(5, 5, 1);
144 
145  unsigned int iRow = 0;
146 
147  // local storage vector of all rechits (including rechit for beam spot in case it is used)
149 
150  if (useBeamSpot && propDir==alongMomentum) {
151 
152  GlobalPoint bs(beamSpot.x0(), beamSpot.y0(), beamSpot.z0());
153 
154  TrajectoryStateClosestToBeamLine tsctbl(TSCBLBuilderNoMaterial()(*(refTsos.freeState()), beamSpot));
155  if (!tsctbl.isValid()) {
156  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct"
157  << "TrajectoryStateClostestToBeamLine invalid. Skip track.";
158  return false;
159  }
160 
161  FreeTrajectoryState pcaFts = tsctbl.trackStateAtPCA();
162  GlobalVector bd(beamSpot.dxdz(), beamSpot.dydz(), 1.0);
163 
164  //propagation FIXME: Should use same propagator everywhere...
166  std::pair< TrajectoryStateOnSurface, double > tsosWithPath =
167  propagator.propagateWithPath(pcaFts, refTsos.surface());
168 
169  if (!tsosWithPath.first.isValid()) return false;
170 
171  GlobalVector momDir(pcaFts.momentum());
172  GlobalVector perpDir(bd.cross(momDir));
173  BoundPlane::RotationType rotation(perpDir, bd);
174 
175  BeamSpotGeomDet * bsGeom = new BeamSpotGeomDet(BoundPlane::build(bs, rotation, OpenBounds()));
176 
177  // There is also a constructor taking the magentic field. Use this one instead?
178  theRefTsos = TrajectoryStateOnSurface(pcaFts, bsGeom->surface());
179 
181  new BeamSpotTransientTrackingRecHit(beamSpot,
182  bsGeom,
183  theRefTsos.freeState()->momentum().phi());
184  allRecHits.push_back(bsRecHit);
185 
186  }
187 
188  // copy all rechits to the local storage vector
189  TransientTrackingRecHit::ConstRecHitContainer::const_iterator itRecHit;
190  for ( itRecHit = recHits.begin(); itRecHit != recHits.end(); ++itRecHit ) {
191  const TransientTrackingRecHit::ConstRecHitPointer &hitPtr = *itRecHit;
192  allRecHits.push_back(hitPtr);
193  }
194 
195  for ( itRecHit = allRecHits.begin(); itRecHit != allRecHits.end(); ++itRecHit ) {
196 
197  const TransientTrackingRecHit::ConstRecHitPointer &hitPtr = *itRecHit;
198  theRecHits.push_back(hitPtr);
199 
200  if (0 == iRow) {
201 
202  // compute the derivatives of the reference-track's parameters w.r.t. the initial ones
203  // derivative of the initial reference-track parameters w.r.t. themselves is of course the identity
204  fullJacobian = AlgebraicMatrix(theParameters.num_row(), theParameters.num_row(), 1);
205  allJacobians.push_back(fullJacobian);
206  theTsosVec.push_back(theRefTsos);
207  const JacobianLocalToCurvilinear startTrafo(hitPtr->det()->surface(), theRefTsos.localParameters(), *magField);
208  const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
209  if (materialEffects <= breakPoints) {
210  theInnerTrajectoryToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
212  }
213  allLocalToCurv.push_back(localToCurvilinear);
214  allSteps.push_back(0.);
215  allCurvlinJacobians.push_back(firstCurvlinJacobian);
216 
217  } else {
218 
219  AlgebraicMatrix nextJacobian;
220  AlgebraicMatrix nextCurvlinJacobian;
221  double nextStep = 0.;
222  TrajectoryStateOnSurface nextTsos;
223 
224  if (!this->propagate(previousHitPtr->det()->surface(), previousTsos,
225  hitPtr->det()->surface(), nextTsos,
226  nextJacobian, nextCurvlinJacobian, nextStep, propDir, magField)) {
227  return false; // stop if problem...// no delete aMaterialEffectsUpdator needed
228  }
229 
230  allJacobians.push_back(nextJacobian);
231  fullJacobian = nextJacobian * previousChangeInCurvature * fullJacobian;
232  theTsosVec.push_back(nextTsos);
233 
234  const JacobianLocalToCurvilinear startTrafo(hitPtr->det()->surface(), nextTsos.localParameters(), *magField);
235  const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
236  allLocalToCurv.push_back(localToCurvilinear);
237  if (nextStep == 0.) {
238  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct"
239  << "step 0. from id " << previousHitPtr->geographicalId()
240  << " to " << hitPtr->det()->geographicalId() << ".";
241  // brokenLinesFine will not work, brokenLinesCoarse combines close by layers
242  if (materialEffects == brokenLinesFine) {
243  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::construct" << "Skip track.";
244  return false;
245  }
246  }
247  allSteps.push_back(nextStep);
248  allCurvlinJacobians.push_back(nextCurvlinJacobian);
249 
250  }
251 
252  // take material effects into account. since trajectory-state is constructed with errors equal zero,
253  // the updated state contains only the uncertainties due to interactions in the current layer.
254  const TrajectoryStateOnSurface tmpTsos(theTsosVec.back().localParameters(), zeroErrors,
255  theTsosVec.back().surface(), magField, surfaceSide);
256  const TrajectoryStateOnSurface updatedTsos = aMaterialEffectsUpdator->updateState(tmpTsos, propDir);
257 
258  if ( !updatedTsos.isValid() ) return false;// no delete aMaterialEffectsUpdator needed
259 
260  if ( theTsosVec.back().localParameters().charge() )
261  {
262  previousChangeInCurvature[0][0] = updatedTsos.localParameters().signedInverseMomentum()
263  / theTsosVec.back().localParameters().signedInverseMomentum();
264  }
265 
266  // get multiple-scattering covariance-matrix
267  allDeltaParameterCovs.push_back( asHepMatrix<5>(updatedTsos.localError().matrix()) );
268  allCurvatureChanges.push_back(previousChangeInCurvature);
269 
270  // projection-matrix tsos-parameters -> measurement-coordinates
271  allProjections.push_back(this->getHitProjectionMatrix(hitPtr));
272  // set start-parameters for next propagation. trajectory-state without error
273  // - no error propagation needed here.
274  previousHitPtr = hitPtr;
275  previousTsos = TrajectoryStateOnSurface(updatedTsos.globalParameters(),
276  updatedTsos.surface(), surfaceSide);
277 
278  if (materialEffects < brokenLinesCoarse) {
279  this->fillDerivatives(allProjections.back(), fullJacobian, iRow);
280  }
281 
282  AlgebraicVector mixedLocalParams = asHepVector<5>(theTsosVec.back().localParameters().mixedFormatVector());
283  this->fillTrajectoryPositions(allProjections.back(), mixedLocalParams, iRow);
284  if ( useRecHit( hitPtr ) ) this->fillMeasurementAndError(hitPtr, iRow, updatedTsos);
285 
286  iRow += nMeasPerHit;
287  } // end of loop on hits
288 
289  bool msOK = true;
290  switch (materialEffects) {
291  case none:
292  break;
293  case multipleScattering:
294  case energyLoss:
295  case combined:
296  msOK = this->addMaterialEffectsCov(allJacobians, allProjections, allCurvatureChanges,
297  allDeltaParameterCovs);
298  break;
299  case breakPoints:
300  msOK = this->addMaterialEffectsBp(allJacobians, allProjections, allCurvatureChanges,
301  allDeltaParameterCovs, allLocalToCurv);
302  break;
303  case brokenLinesCoarse:
304  msOK = this->addMaterialEffectsBrl(allProjections, allDeltaParameterCovs, allLocalToCurv,
305  allSteps, refTsos.globalParameters());
306  break;
307  case brokenLinesFine:
308  msOK = this->addMaterialEffectsBrl(allCurvlinJacobians, allProjections, allCurvatureChanges,
309  allDeltaParameterCovs, allLocalToCurv, refTsos.globalParameters());
310  }
311  if (!msOK) return false;
312 
313  if (refTsos.hasError()) {
314  AlgebraicSymMatrix parameterCov = asHepMatrix<5>(refTsos.localError().matrix());
315  AlgebraicMatrix parDeriv;
316  if (theNumberOfVirtualPars>0) {
317  parDeriv = theDerivatives.sub( 1, nMeasPerHit*allJacobians.size(), 1, theParameters.num_row() );
318  } else {
319  parDeriv = theDerivatives;
320  }
321  theTrajectoryPositionCov = parameterCov.similarity(parDeriv);
322  } else {
324  }
325 
326  return true;
327 }
328 
329 //__________________________________________________________________________________
330 
333 {
334  switch (materialEffects) {
335  // MultipleScatteringUpdator doesn't change the trajectory-state
336  // during update and can therefore be used if material effects should be ignored:
337  case none:
338  case multipleScattering:
339  return new MultipleScatteringUpdator(mass);
340  case energyLoss:
341  return new EnergyLossUpdator(mass);
342  case combined:
343  return new CombinedMaterialEffectsUpdator(mass);
344  case breakPoints:
345  return new CombinedMaterialEffectsUpdator(mass);
346  case brokenLinesCoarse:
347  case brokenLinesFine:
348  return new CombinedMaterialEffectsUpdator(mass);
349 }
350 
351  return 0;
352 }
353 
354 //__________________________________________________________________________________
355 
356 bool ReferenceTrajectory::propagate(const BoundPlane &previousSurface, const TrajectoryStateOnSurface &previousTsos,
357  const BoundPlane &newSurface, TrajectoryStateOnSurface &newTsos, AlgebraicMatrix &newJacobian,
358  AlgebraicMatrix &newCurvlinJacobian, double &nextStep,
359  const PropagationDirection propDir, const MagneticField *magField) const
360 {
361  // propagate to next layer
365  //AnalyticalPropagator aPropagator(magField, propDir);
366  // Hard coded RungeKutta instead Analytical (avoid bias in TEC), but
367  // work around TrackPropagation/RungeKutta/interface/RKTestPropagator.h and
368  // http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
369  RKTestPropagator bPropagator(magField, propDir); //double tolerance = 5.e-5)
370  Propagator &aPropagator = bPropagator;
371  const std::pair<TrajectoryStateOnSurface, double> tsosWithPath =
372  aPropagator.propagateWithPath(previousTsos, newSurface);
373 
374  // stop if propagation wasn't successful
375  if (!tsosWithPath.first.isValid()) return false;
376 
377  nextStep = tsosWithPath.second;
378  // calculate derivative of reference-track parameters on the actual layer w.r.t. the ones
379  // on the previous layer (both in global coordinates)
380  const AnalyticalCurvilinearJacobian aJacobian(previousTsos.globalParameters(),
381  tsosWithPath.first.globalPosition(),
382  tsosWithPath.first.globalMomentum(),
383  tsosWithPath.second);
384  const AlgebraicMatrix curvilinearJacobian = asHepMatrix<5,5>(aJacobian.jacobian());
385 
386  // jacobian of the track parameters on the previous layer for local->global transformation
387  const JacobianLocalToCurvilinear startTrafo(previousSurface, previousTsos.localParameters(), *magField);
388  const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
389 
390  // jacobian of the track parameters on the actual layer for global->local transformation
391  const JacobianCurvilinearToLocal endTrafo(newSurface, tsosWithPath.first.localParameters(), *magField);
392  const AlgebraicMatrix curvilinearToLocal = asHepMatrix<5>(endTrafo.jacobian());
393 
394  // compute derivative of reference-track parameters on the actual layer w.r.t. the ones on
395  // the previous layer (both in their local representation)
396  newCurvlinJacobian = curvilinearJacobian;
397  newJacobian = curvilinearToLocal * curvilinearJacobian * localToCurvilinear;
398  newTsos = tsosWithPath.first;
399 
400  return true;
401 }
402 
403 //__________________________________________________________________________________
404 
406  unsigned int iRow,
407  const TrajectoryStateOnSurface &updatedTsos)
408 {
409  // get the measurements and their errors, use information updated with tsos if improving
410  // (GF: Also for measurements or only for errors or do the former not change?)
411  // GF 10/2008: I doubt that it makes sense to update the hit with the tsos here:
412  // That is an analytical extrapolation and not the best guess of the real
413  // track state on the module, but the latter should be better to get the best
414  // hit uncertainty estimate!
415  TransientTrackingRecHit::ConstRecHitPointer newHitPtr(hitPtr->canImproveWithTrack() ?
416  hitPtr->clone(updatedTsos) : hitPtr);
417 
418  const LocalPoint localMeasurement = newHitPtr->localPosition();
419  const LocalError localMeasurementCov = newHitPtr->localPositionError();
420 
421  theMeasurements[iRow] = localMeasurement.x();
422  theMeasurements[iRow+1] = localMeasurement.y();
423  theMeasurementsCov[iRow][iRow] = localMeasurementCov.xx();
424  theMeasurementsCov[iRow][iRow+1] = localMeasurementCov.xy();
425  theMeasurementsCov[iRow+1][iRow+1] = localMeasurementCov.yy();
426  // GF: Should be a loop once the hit dimension is not hardcoded as nMeasPerHit (to be checked):
427  // for (int i = 0; i < hitPtr->dimension(); ++i) {
428  // theMeasurements[iRow+i] = hitPtr->parameters()[i]; // fixme: parameters() is by value!
429  // for (int j = i; j < hitPtr->dimension(); ++j) {
430  // theMeasurementsCov[iRow+i][iRow+j] = hitPtr->parametersError()[i][j];
431  // }
432  // }
433 }
434 
435 //__________________________________________________________________________________
436 
438  const AlgebraicMatrix &fullJacobian,
439  unsigned int iRow)
440 {
441  // derivatives of the local coordinates of the reference track w.r.t. to the inital track-parameters
442  const AlgebraicMatrix projectedJacobian(projection * fullJacobian);
443  for (int i = 0; i < parameters().num_row(); ++i) {
444  theDerivatives[iRow ][i] = projectedJacobian[0][i];
445  theDerivatives[iRow+1][i] = projectedJacobian[1][i];
446  // GF: Should be a loop once the hit dimension is not hardcoded as nMeasPerHit (to be checked):
447  // for (int j = 0; j < projection.num_col(); ++j) {
448  // theDerivatives[iRow+j][i] = projectedJacobian[j][i];
449  // }
450  }
451 }
452 
453 //__________________________________________________________________________________
454 
456  const AlgebraicVector &mixedLocalParams,
457  unsigned int iRow)
458 {
459  // get the local coordinates of the reference trajectory
460  const AlgebraicVector localPosition(projection * mixedLocalParams);
461  theTrajectoryPositions[iRow] = localPosition[0];
462  theTrajectoryPositions[iRow+1] = localPosition[1];
463  // GF: Should be a loop once the hit dimension is not hardcoded as nMeasPerHit (to be checked):
464  // for (int j = 0; j < projection.num_col(); ++j) {
465  // theTrajectoryPositions[iRow+j] = localPosition[j];
466  // }
467 }
468 
469 //__________________________________________________________________________________
470 
471 bool ReferenceTrajectory::addMaterialEffectsCov(const std::vector<AlgebraicMatrix> &allJacobians,
472  const std::vector<AlgebraicMatrix> &allProjections,
473  const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
474  const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs)
475 {
476  // the uncertainty due to multiple scattering is 'transferred' to the error matrix of the hits
477 
478  // GF: Needs update once hit dimension is not hardcoded as nMeasPerHit!
479 
480  AlgebraicSymMatrix materialEffectsCov(nMeasPerHit * allJacobians.size(), 0);
481 
482  // additional covariance-matrix of the measurements due to material-effects (single measurement)
483  AlgebraicSymMatrix deltaMaterialEffectsCov;
484 
485  // additional covariance-matrix of the parameters due to material-effects
486  AlgebraicSymMatrix paramMaterialEffectsCov(allDeltaParameterCovs[0]); //initialization
487  // error-propagation to state after energy loss
488  //GFback paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allCurvatureChanges[0]);
489 
490  AlgebraicMatrix tempParameterCov;
491  AlgebraicMatrix tempMeasurementCov;
492 
493  for (unsigned int k = 1; k < allJacobians.size(); ++k) {
494  // error-propagation to next layer
495  paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allJacobians[k]);
496 
497  // get dependences for the measurements
498  deltaMaterialEffectsCov = paramMaterialEffectsCov.similarity(allProjections[k]);
499  materialEffectsCov[nMeasPerHit*k ][nMeasPerHit*k ] = deltaMaterialEffectsCov[0][0];
500  materialEffectsCov[nMeasPerHit*k ][nMeasPerHit*k+1] = deltaMaterialEffectsCov[0][1];
501  materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*k ] = deltaMaterialEffectsCov[1][0];
502  materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*k+1] = deltaMaterialEffectsCov[1][1];
503 
504  // GFback add uncertainties for the following layers due to scattering at this layer
505  paramMaterialEffectsCov += allDeltaParameterCovs[k];
506  // end GFback
507  tempParameterCov = paramMaterialEffectsCov;
508 
509  // compute "inter-layer-dependencies"
510  for (unsigned int l = k+1; l < allJacobians.size(); ++l) {
511  tempParameterCov = allJacobians[l] * allCurvatureChanges[l] * tempParameterCov;
512  tempMeasurementCov = allProjections[l] * tempParameterCov * allProjections[k].T();
513 
514  materialEffectsCov[nMeasPerHit*l][nMeasPerHit*k] = tempMeasurementCov[0][0];
515  materialEffectsCov[nMeasPerHit*k][nMeasPerHit*l] = tempMeasurementCov[0][0];
516 
517  materialEffectsCov[nMeasPerHit*l][nMeasPerHit*k+1] = tempMeasurementCov[0][1];
518  materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*l] = tempMeasurementCov[0][1];
519 
520  materialEffectsCov[nMeasPerHit*l+1][nMeasPerHit*k] = tempMeasurementCov[1][0];
521  materialEffectsCov[nMeasPerHit*k][nMeasPerHit*l+1] = tempMeasurementCov[1][0];
522 
523  materialEffectsCov[nMeasPerHit*l+1][nMeasPerHit*k+1] = tempMeasurementCov[1][1];
524  materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*l+1] = tempMeasurementCov[1][1];
525  }
526  // add uncertainties for the following layers due to scattering at this layer
527  // GFback paramMaterialEffectsCov += allDeltaParameterCovs[k];
528  // error-propagation to state after energy loss
529  paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allCurvatureChanges[k]);
530 
531  }
532  theMeasurementsCov += materialEffectsCov;
533 
534  return true; // cannot fail
535 }
536 
537 //__________________________________________________________________________________
538 
539 bool ReferenceTrajectory::addMaterialEffectsBp(const std::vector<AlgebraicMatrix> &allJacobians,
540  const std::vector<AlgebraicMatrix> &allProjections,
541  const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
542  const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
543  const std::vector<AlgebraicMatrix> &allLocalToCurv)
544 {
545 //CHK: add material effects using break points
546  int offsetPar = theNumberOfPars;
547  int offsetMeas = nMeasPerHit * allJacobians.size();
548  int ierr = 0;
549 
550  AlgebraicMatrix tempJacobian;
551  AlgebraicMatrix MSprojection(2,5);
552  MSprojection[0][1] = 1;
553  MSprojection[1][2] = 1;
554  AlgebraicSymMatrix tempMSCov;
555  AlgebraicSymMatrix tempMSCovProj;
556  AlgebraicMatrix tempMSJacProj;
557 
558  for (unsigned int k = 1; k < allJacobians.size(); ++k) {
559 // CHK
560  int kbp = k-1;
561  tempJacobian = allJacobians[k] * allCurvatureChanges[k];
562  tempMSCov = allDeltaParameterCovs[k-1].similarity(allLocalToCurv[k-1]);
563  tempMSCovProj = tempMSCov.similarity(MSprojection);
564  theMeasurementsCov[offsetMeas+nMeasPerHit*kbp ][offsetMeas+nMeasPerHit*kbp ] = tempMSCovProj[0][0];
565  theMeasurementsCov[offsetMeas+nMeasPerHit*kbp+1][offsetMeas+nMeasPerHit*kbp+1]= tempMSCovProj[1][1];
566  theDerivatives[offsetMeas+nMeasPerHit*kbp ][offsetPar+2*kbp ] = 1.0;
567  theDerivatives[offsetMeas+nMeasPerHit*kbp+1][offsetPar+2*kbp+1] = 1.0 ;
568 
569  tempMSJacProj = (allProjections[k] * ( tempJacobian * allLocalToCurv[k-1].inverse(ierr) )) * MSprojection.T();
570  if (ierr) {
571  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBp"
572  << "Inversion 1 for break points failed: " << ierr;
573  return false;
574  }
575  theDerivatives[nMeasPerHit*k ][offsetPar+2*kbp ] = tempMSJacProj[0][0];
576  theDerivatives[nMeasPerHit*k ][offsetPar+2*kbp+1] = tempMSJacProj[0][1];
577  theDerivatives[nMeasPerHit*k+1][offsetPar+2*kbp ] = tempMSJacProj[1][0];
578  theDerivatives[nMeasPerHit*k+1][offsetPar+2*kbp+1] = tempMSJacProj[1][1];
579 
580  for (unsigned int l = k+1; l < allJacobians.size(); ++l) {
581 // CHK
582  int kbp = k-1;
583  tempJacobian = allJacobians[l] * allCurvatureChanges[l] * tempJacobian;
584  tempMSJacProj = (allProjections[l] * ( tempJacobian * allLocalToCurv[k-1].inverse(ierr) )) * MSprojection.T();
585  if (ierr) {
586  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBp"
587  << "Inversion 2 for break points failed: " << ierr;
588  return false;
589  }
590  theDerivatives[nMeasPerHit*l ][offsetPar+2*kbp ] = tempMSJacProj[0][0];
591  theDerivatives[nMeasPerHit*l ][offsetPar+2*kbp+1] = tempMSJacProj[0][1];
592  theDerivatives[nMeasPerHit*l+1][offsetPar+2*kbp ] = tempMSJacProj[1][0];
593  theDerivatives[nMeasPerHit*l+1][offsetPar+2*kbp+1] = tempMSJacProj[1][1];
594 
595  }
596 
597  }
598 
599  return true;
600 }
601 
602 //__________________________________________________________________________________
603 
604 bool ReferenceTrajectory::addMaterialEffectsBrl(const std::vector<AlgebraicMatrix> &allCurvlinJacobians,
605  const std::vector<AlgebraicMatrix> &allProjections,
606  const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
607  const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
608  const std::vector<AlgebraicMatrix> &allLocalToCurv,
609  const GlobalTrajectoryParameters &gtp)
610 {
611 //CHK: add material effects using broken lines
612 //fine: use exact Jacobians, all detectors
613 //broken lines: pair of offsets (u1,u2) = (xt,yt) (in curvilinear frame (q/p,lambda,phi,xt,yt)) at each layer
614 // scattering angles (alpha1,alpha2) = (cosLambda*dPhi, dLambda) (cosLambda cancels in Chi2)
615 // DU' = (dU'/dU)*DU + (dU'/dAlpha)*DAlpha + (dU'/dQbyp)*DQbyp (propagation of U)
616 // = J*DU + S*DAlpha + d*DQbyp
617 // => DAlpha = S^-1 (DU' - J*DU - d*DQbyp)
618 
619  int offsetPar = theNumberOfPars;
620  int offsetMeas = nMeasPerHit*allCurvlinJacobians.size();
621  int ierr = 0;
622 
623  GlobalVector p = gtp.momentum();
624  double cosLambda = sqrt((p.x()*p.x()+p.y()*p.y())/(p.x()*p.x()+p.y()*p.y()+p.z()*p.z()));
625 
626 // transformations Curvilinear <-> BrokenLines
627  AlgebraicMatrix QbypToCurv(5,1); // dCurv/dQbyp
628  QbypToCurv[0][0] = 1.; // dQbyp/dQbyp
629  AlgebraicMatrix AngleToCurv(5,2); // dCurv/dAlpha
630  AngleToCurv[1][1] = 1.; // dlambda/dalpha2
631  AngleToCurv[2][0] = 1./cosLambda; // dphi/dalpha1
632  AlgebraicMatrix CurvToAngle(2,5); // dAlpha/dCurv
633  CurvToAngle[1][1] = 1.; // dalpha2/dlambda
634  CurvToAngle[0][2] = cosLambda; // dalpha1/dphi
635  AlgebraicMatrix OffsetToCurv(5,2); // dCurv/dU
636  OffsetToCurv[3][0] = 1.; // dxt/du1
637  OffsetToCurv[4][1] = 1.; // dyt/du2
638  AlgebraicMatrix CurvToOffset(2,5); // dU/dCurv
639  CurvToOffset[0][3] = 1.; // du1/dxt
640  CurvToOffset[1][4] = 1.; // du2/dyt
641 
642 // transformations trajectory to components (Qbyp, U1, U2)
643  AlgebraicMatrix TrajToQbyp(1,5);
644  TrajToQbyp[0][0] = 1.;
645  AlgebraicMatrix TrajToOff1(2,5);
646  TrajToOff1[0][1] = 1.;
647  TrajToOff1[1][2] = 1.;
648  AlgebraicMatrix TrajToOff2(2,5);
649  TrajToOff2[0][3] = 1.;
650  TrajToOff2[1][4] = 1.;
651 
652  AlgebraicMatrix JacOffsetToAngleC, JacQbypToAngleC;
653  AlgebraicMatrix JacCurvToOffsetL, JacOffsetToOffsetL, JacAngleToOffsetL, JacQbypToOffsetL, JacOffsetToAngleL;
654  AlgebraicMatrix JacCurvToOffsetN, JacOffsetToOffsetN, JacAngleToOffsetN, JacQbypToOffsetN, JacOffsetToAngleN;
655 
656 // transformation from trajectory to curvilinear parameters
657 
658  JacCurvToOffsetN = CurvToOffset * allCurvlinJacobians[1]; // (dU'/dCurv') * (dCurv'/dCurv) @ 2nd point
659  JacOffsetToOffsetN = JacCurvToOffsetN * OffsetToCurv; // J: (dU'/dU) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dU)
660  JacAngleToOffsetN = JacCurvToOffsetN * AngleToCurv; // S: (dU'/dAlpha) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dAlpha)
661  JacQbypToOffsetN = JacCurvToOffsetN * QbypToCurv; // d: (dU'/dQbyp) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dQbyp)
662  JacOffsetToAngleN = JacAngleToOffsetN.inverse(ierr); // W
663  if (ierr) {
664  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
665  << "Inversion 1 for fine broken lines failed: " << ierr;
666  return false;
667  }
668  JacOffsetToAngleC = -(JacOffsetToAngleN * JacOffsetToOffsetN); // (dAlpha/dU)
669  JacQbypToAngleC = -(JacOffsetToAngleN * JacQbypToOffsetN); // (dAlpha/dQbyp)
670  // (dAlpha/dTraj) = (dAlpha/dQbyp) * (dQbyp/dTraj) + (dAlpha/dU1) * (dU1/dTraj) + (dAlpha/dU2) * (dU2/dTraj)
671  AlgebraicMatrix JacTrajToAngle = JacQbypToAngleC * TrajToQbyp + JacOffsetToAngleC * TrajToOff1 + JacOffsetToAngleN * TrajToOff2;
672  // (dCurv/dTraj) = (dCurv/dQbyp) * (dQbyp/dTraj) + (dCurv/dAlpha) * (dAlpha/dTraj) + (dCurv/dU) * (dU/dTraj)
673  theInnerTrajectoryToCurvilinear = QbypToCurv * TrajToQbyp + AngleToCurv * JacTrajToAngle + OffsetToCurv * TrajToOff1;
674  theInnerLocalToTrajectory = theInnerTrajectoryToCurvilinear.inverse(ierr) * allLocalToCurv[0];
675  if (ierr) {
676  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
677  << "Inversion 2 for fine broken lines failed: " << ierr;
678  return false;
679  }
680 
681  AlgebraicMatrix tempJacobian(allCurvatureChanges[0]);
682  AlgebraicSymMatrix tempMSCov;
683  AlgebraicSymMatrix tempMSCovProj;
684  AlgebraicMatrix tempJacL, tempJacN;
685  AlgebraicMatrix JacOffsetToMeas;
686 
687 // measurements from hits
688  for (unsigned int k = 0; k < allCurvlinJacobians.size(); ++k) {
689 // (dMeas/dU) = (dMeas/dLoc) * (dLoc/dCurv) * (dCurv/dU)
690  JacOffsetToMeas = (allProjections[k] * allLocalToCurv[k].inverse(ierr) ) * OffsetToCurv;
691  if (ierr) {
692  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
693  << "Inversion 3 for fine broken lines failed: " << ierr;
694  return false;
695  }
696  theDerivatives[nMeasPerHit*k ][offsetPar+2*k ] = JacOffsetToMeas[0][0];
697  theDerivatives[nMeasPerHit*k ][offsetPar+2*k+1] = JacOffsetToMeas[0][1];
698  theDerivatives[nMeasPerHit*k+1][offsetPar+2*k ] = JacOffsetToMeas[1][0];
699  theDerivatives[nMeasPerHit*k+1][offsetPar+2*k+1] = JacOffsetToMeas[1][1];
700  }
701 
702 // measurement of MS kink
703  for (unsigned int k = 1; k < allCurvlinJacobians.size()-1; ++k) {
704 // CHK
705  int iMsMeas = k-1;
706  int l = k-1; // last hit
707  int n = k+1; // next hit
708 
709 // amount of multiple scattering in layer k (angular error perp to direction)
710  tempMSCov = allDeltaParameterCovs[k].similarity(allLocalToCurv[k]);
711  tempMSCovProj = tempMSCov.similarity(CurvToAngle);
712  theMeasurementsCov[offsetMeas+nMeasPerHit*iMsMeas ][offsetMeas+nMeasPerHit*iMsMeas ] = tempMSCovProj[1][1];
713  theMeasurementsCov[offsetMeas+nMeasPerHit*iMsMeas+1][offsetMeas+nMeasPerHit*iMsMeas+1] = tempMSCovProj[0][0];
714 
715 // transformation matices for offsets ( l <- k -> n )
716  tempJacL = allCurvlinJacobians[k] * tempJacobian;
717  JacCurvToOffsetL = CurvToOffset * tempJacL.inverse(ierr); // (dU'/dCurv') * (dCurv'/dCurv) @ last point
718 
719  if (ierr) {
720  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
721  << "Inversion 4 for fine broken lines failed: " << ierr;
722  return false;
723  }
724  JacOffsetToOffsetL = JacCurvToOffsetL * OffsetToCurv; // J-: (dU'/dU) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dU)
725  JacAngleToOffsetL = JacCurvToOffsetL * AngleToCurv; // S-: (dU'/dAlpha) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dAlpha)
726  JacQbypToOffsetL = JacCurvToOffsetL * QbypToCurv; // d-: (dU'/dQbyp) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dQbyp)
727  JacOffsetToAngleL =-JacAngleToOffsetL.inverse(ierr); // W-
728  if (ierr) {
729  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
730  << "Inversion 5 for fine broken lines failed: " << ierr;
731  return false;
732  }
733  tempJacobian = tempJacobian * allCurvatureChanges[k];
734  tempJacN = allCurvlinJacobians[n] * tempJacobian;
735  JacCurvToOffsetN = CurvToOffset * tempJacN; // (dU'/dCurv') * (dCurv'/dCurv) @ next point
736  JacOffsetToOffsetN = JacCurvToOffsetN * OffsetToCurv; // J+: (dU'/dU) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dU)
737  JacAngleToOffsetN = JacCurvToOffsetN * AngleToCurv; // S+: (dU'/dAlpha) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dAlpha)
738  JacQbypToOffsetN = JacCurvToOffsetN * QbypToCurv; // d+: (dU'/dQbyp) = (dU'/dCurv') * (dCurv'/dCurv) * (dCurv/dQbyp)
739  JacOffsetToAngleN = JacAngleToOffsetN.inverse(ierr); // W+
740  if (ierr) {
741  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
742  << "Inversion 6 for fine broken lines failed: " << ierr;
743  return false;
744  }
745  JacOffsetToAngleC = -(JacOffsetToAngleL * JacOffsetToOffsetL + JacOffsetToAngleN * JacOffsetToOffsetN);
746  JacQbypToAngleC = -(JacOffsetToAngleL * JacQbypToOffsetL + JacOffsetToAngleN * JacQbypToOffsetN);
747 
748  // bending
749  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][ 0] = JacQbypToAngleC[0][0];
750  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][ 0] = JacQbypToAngleC[1][0];
751  // last layer
752  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*l ] = JacOffsetToAngleL[0][0];
753  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*l+1] = JacOffsetToAngleL[0][1];
754  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*l ] = JacOffsetToAngleL[1][0];
755  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*l+1] = JacOffsetToAngleL[1][1];
756  // current layer
757  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*k ] = JacOffsetToAngleC[0][0];
758  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*k+1] = JacOffsetToAngleC[0][1];
759  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*k ] = JacOffsetToAngleC[1][0];
760  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*k+1] = JacOffsetToAngleC[1][1];
761 
762  // next layer
763  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*n ] = JacOffsetToAngleN[0][0];
764  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*n+1] = JacOffsetToAngleN[0][1];
765  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*n ] = JacOffsetToAngleN[1][0];
766  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*n+1] = JacOffsetToAngleN[1][1];
767 
768  }
769 
770  return true;
771 }
772 
773 //__________________________________________________________________________________
774 
775 bool ReferenceTrajectory::addMaterialEffectsBrl(const std::vector<AlgebraicMatrix> &allProjections,
776  const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs,
777  const std::vector<AlgebraicMatrix> &allLocalToCurv,
778  const std::vector<double> &allSteps,
779  const GlobalTrajectoryParameters &gtp,
780  const double minStep)
781 {
782 //CHK: add material effects using broken lines
783 //BrokenLinesCoarse: combine close by detectors,
784 // use approximate Jacobians from Steps (limit Qbyp -> 0),
785 // bending only in RPhi (B=(0,0,Bz)), no energy loss correction
786 
787  int offsetPar = theNumberOfPars;
788  int offsetMeas = nMeasPerHit*allSteps.size();
789  int ierr = 0;
790 
791  GlobalVector p = gtp.momentum();
792  double cosLambda = sqrt((p.x()*p.x()+p.y()*p.y())/(p.x()*p.x()+p.y()*p.y()+p.z()*p.z()));
793  double bFac = -gtp.magneticFieldInInverseGeV(gtp.position()).mag();
794 
795  // transformation from trajectory to curvilinear parameters at refTsos
796  double delta (1.0/allSteps[1]);
800  theInnerTrajectoryToCurvilinear[2][0] = -0.5*bFac/delta;
801  theInnerTrajectoryToCurvilinear[2][1] = -delta/cosLambda;
802  theInnerTrajectoryToCurvilinear[2][3] = delta/cosLambda;
805  theInnerLocalToTrajectory = theInnerTrajectoryToCurvilinear.inverse(ierr) * allLocalToCurv[0];
806  if (ierr) {
807  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
808  << "Inversion 1 for coarse broken lines failed: " << ierr;
809  return false;
810  }
811 
812  AlgebraicMatrix CurvToAngle(2,5); // dAlpha/dCurv
813  CurvToAngle[1][1] = 1.; // dalpha2/dlambda
814  CurvToAngle[0][2] = cosLambda; // dalpha1/dphi
815  AlgebraicMatrix OffsetToCurv(5,2); // dCurv/dU
816  OffsetToCurv[3][0] = 1.; // dxt/du1
817  OffsetToCurv[4][1] = 1.; // dyt/du2
818 
819  AlgebraicSymMatrix tempMSCov;
820  AlgebraicSymMatrix tempMSCovProj;
821  AlgebraicMatrix JacOffsetToMeas;
822 
823  // combine closeby detectors into single plane
824  std::vector<unsigned int> first(allSteps.size());
825  std::vector<unsigned int> last (allSteps.size());
826  std::vector<unsigned int> plane(allSteps.size());
827  std::vector<double> sPlane(allSteps.size());
828  unsigned int nPlane = 0;
829  double sTot = 0;
830 
831  for (unsigned int k = 1; k < allSteps.size(); ++k) {
832  sTot += allSteps[k];
833  if (fabs(allSteps[k])>minStep) { nPlane += 1; first[nPlane] = k; }
834  last[nPlane] = k;
835  plane[k] = nPlane;
836  sPlane[nPlane] += sTot;
837  }
838  if (nPlane < 2) return false; // pathological cases: need at least 2 planes
839 
840  theNumberOfVirtualPars = 2*(nPlane+1);
841  theNumberOfVirtualMeas = 2*(nPlane-1);// unsigned underflow for nPlane == 0...
842  for (unsigned int k = 0; k <= nPlane; ++k) { sPlane[k] /= (double) (last[k]-first[k]+1); }
843 
844  // measurements from hits
845  sTot = 0;
846  for (unsigned int k = 0; k < allSteps.size(); ++k) {
847  sTot += allSteps[k];
848 // (dMeas/dU) = (dMeas/dLoc) * (dLoc/dCurv) * (dCurv/dU)
849  JacOffsetToMeas = (allProjections[k] * allLocalToCurv[k].inverse(ierr) ) * OffsetToCurv;
850  if (ierr) {
851  edm::LogError("Alignment") << "@SUB=ReferenceTrajectory::addMaterialEffectsBrl"
852  << "Inversion 2 for coarse broken lines failed: " << ierr;
853  return false;
854  }
855 
856  unsigned int iPlane = plane[k];
857  if (last[iPlane] == first[iPlane])
858  { // single plane
859  theDerivatives[nMeasPerHit*k ][offsetPar+2*iPlane ] = JacOffsetToMeas[0][0];
860  theDerivatives[nMeasPerHit*k ][offsetPar+2*iPlane+1] = JacOffsetToMeas[0][1];
861  theDerivatives[nMeasPerHit*k+1][offsetPar+2*iPlane ] = JacOffsetToMeas[1][0];
862  theDerivatives[nMeasPerHit*k+1][offsetPar+2*iPlane+1] = JacOffsetToMeas[1][1];
863  } else
864  { // combined plane: (linear) interpolation
865  unsigned int jPlane; // neighbor plane for interpolation
866  if (fabs(sTot) < fabs(sPlane[iPlane])) { jPlane = (iPlane>0) ? iPlane - 1 : 1; }
867  else { jPlane = (iPlane<nPlane) ? iPlane + 1 : nPlane -1 ;}
868  // interpolation weights
869  double sDiff = sPlane[iPlane] - sPlane[jPlane];
870  double iFrac = (sTot - sPlane[jPlane]) / sDiff;
871  double jFrac = 1.0 - iFrac;
872  theDerivatives[nMeasPerHit*k ][offsetPar+2*iPlane ] = JacOffsetToMeas[0][0]*iFrac;
873  theDerivatives[nMeasPerHit*k ][offsetPar+2*iPlane+1] = JacOffsetToMeas[0][1]*iFrac;
874  theDerivatives[nMeasPerHit*k+1][offsetPar+2*iPlane ] = JacOffsetToMeas[1][0]*iFrac;
875  theDerivatives[nMeasPerHit*k+1][offsetPar+2*iPlane+1] = JacOffsetToMeas[1][1]*iFrac;
876  theDerivatives[nMeasPerHit*k ][offsetPar+2*jPlane ] = JacOffsetToMeas[0][0]*jFrac;
877  theDerivatives[nMeasPerHit*k ][offsetPar+2*jPlane+1] = JacOffsetToMeas[0][1]*jFrac;
878  theDerivatives[nMeasPerHit*k+1][offsetPar+2*jPlane ] = JacOffsetToMeas[1][0]*jFrac;
879  theDerivatives[nMeasPerHit*k+1][offsetPar+2*jPlane+1] = JacOffsetToMeas[1][1]*jFrac;
880  // 2nd order neglected
881  // theDerivatives[nMeasPerHit*k ][ 0] = -0.5*bFac*sDiff*iFrac*sDiff*jFrac*cosLambda;
882  }
883  }
884 
885 // measurement of MS kink
886  for (unsigned int i = 1; i < nPlane; ++i) {
887 // CHK
888  int iMsMeas = i-1;
889  int l = i-1; // last hit
890  int n = i+1; // next hit
891 
892 // amount of multiple scattering in plane k
893  for (unsigned int k = first[i]; k <= last[i]; ++k) {
894  tempMSCov = allDeltaParameterCovs[k].similarity(allLocalToCurv[k]);
895  tempMSCovProj = tempMSCov.similarity(CurvToAngle);
896  theMeasurementsCov[offsetMeas+nMeasPerHit*iMsMeas ][offsetMeas+nMeasPerHit*iMsMeas ] += tempMSCovProj[0][0];
897  theMeasurementsCov[offsetMeas+nMeasPerHit*iMsMeas+1][offsetMeas+nMeasPerHit*iMsMeas+1] += tempMSCovProj[1][1];
898  }
899 // broken line measurements for layer k, correlations between both planes neglected
900  double stepK = sPlane[i] - sPlane[l];
901  double stepN = sPlane[n] - sPlane[i];
902  double deltaK (1.0/stepK);
903  double deltaN (1.0/stepN);
904  // bending (only in RPhi)
905  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][ 0] = -0.5*bFac*(stepK+stepN)*cosLambda;
906  // last layer
907  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*l ] = deltaK;
908  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*l+1] = deltaK;
909  // current layer
910  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*i ] = -(deltaK + deltaN);
911  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*i+1] = -(deltaK + deltaN);
912  // next layer
913  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas ][offsetPar+2*n ] = deltaN;
914  theDerivatives[offsetMeas+nMeasPerHit*iMsMeas+1][offsetPar+2*n+1] = deltaN;
915  }
916 
917  return true;
918 }
919 
920 //__________________________________________________________________________________
921 
925 {
926  if (this->useRecHit(hitPtr)) {
927  // check which templated non-member function to call:
928  switch (hitPtr->dimension()) {
929  case 1:
930  return getHitProjectionMatrixT<1>(hitPtr);
931  case 2:
932  return getHitProjectionMatrixT<2>(hitPtr);
933  case 3:
934  return getHitProjectionMatrixT<3>(hitPtr);
935  case 4:
936  return getHitProjectionMatrixT<4>(hitPtr);
937  case 5:
938  return getHitProjectionMatrixT<5>(hitPtr);
939  default:
940  throw cms::Exception("ReferenceTrajectory::getHitProjectionMatrix")
941  << "Unexpected hit dimension: " << hitPtr->dimension() << "\n";
942  }
943  }
944  // invalid or (to please compiler) unknown dimension
945  return AlgebraicMatrix(2, 5, 0); // get size from ???
946 }
947 
948 //__________________________________________________________________________________
949 
950 template<unsigned int N>
954 {
955  // define variables that will be used to setup the KfComponentsHolder
956  // (their allocated memory is needed by 'hitPtr->getKfComponents(..)'
957  // ProjectMatrix<double,5,N> pf; // not needed
959  typename AlgebraicROOTObject<N>::Vector r, rMeas;
960  typename AlgebraicROOTObject<N,N>::SymMatrix V, VMeas;
961  // input for the holder - but dummy is OK here to just get the projection matrix:
962  const AlgebraicVector5 dummyPars;
963  const AlgebraicSymMatrix55 dummyErr;
964 
965  // setup the holder with the correct dimensions and get the values
966  KfComponentsHolder holder;
967  holder.setup<N>(&r, &V, &H, /*&pf,*/ &rMeas, &VMeas, dummyPars, dummyErr);
968  hitPtr->getKfComponents(holder);
969 
970  return asHepMatrix<N,5>(holder.projection<N>());
971 }
972 
dbl * delta
Definition: mlp_gen.cc:36
AlgebraicMatrix theInnerTrajectoryToCurvilinear
double z0() const
z coordinate
Definition: BeamSpot.h:69
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
AlgebraicMatrix getHitProjectionMatrix(const TransientTrackingRecHit::ConstRecHitPointer &recHit) const
ROOT::Math::SMatrix< double, D1, D1, ROOT::Math::MatRepSym< double, D1 > > SymMatrix
virtual bool addMaterialEffectsBrl(const std::vector< AlgebraicMatrix > &allJacobians, const std::vector< AlgebraicMatrix > &allProjections, const std::vector< AlgebraicSymMatrix > &allCurvChanges, const std::vector< AlgebraicSymMatrix > &allDeltaParaCovs, const std::vector< AlgebraicMatrix > &allLocalToCurv, const GlobalTrajectoryParameters &gtp)
const LocalTrajectoryParameters & localParameters() const
virtual bool construct(const TrajectoryStateOnSurface &referenceTsos, const TransientTrackingRecHit::ConstRecHitContainer &recHits, double mass, MaterialEffects materialEffects, const PropagationDirection propDir, const MagneticField *magField, bool useBeamSpot, const reco::BeamSpot &beamSpot)
AlgebraicMatrix theInnerLocalToTrajectory
virtual void fillMeasurementAndError(const TransientTrackingRecHit::ConstRecHitPointer &hitPtr, unsigned int iRow, const TrajectoryStateOnSurface &updatedTsos)
static const unsigned int nMeasPerHit
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
T y() const
Definition: PV3DBase.h:62
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
PropagationDirection
SurfaceSide surfaceSide(const PropagationDirection dir) const
static BoundPlanePointer build(const PositionType &pos, const RotationType &rot, const Bounds *bounds, MediumProperties *mp=0)
Definition: BoundPlane.h:26
virtual bool addMaterialEffectsBp(const std::vector< AlgebraicMatrix > &allJacobians, const std::vector< AlgebraicMatrix > &allProjections, const std::vector< AlgebraicSymMatrix > &allCurvChanges, const std::vector< AlgebraicSymMatrix > &allDeltaParaCovs, const std::vector< AlgebraicMatrix > &allLocalToCurv)
GlobalVector magneticFieldInInverseGeV(const GlobalPoint &x) const
virtual bool propagate(const BoundPlane &previousSurface, const TrajectoryStateOnSurface &previousTsos, const BoundPlane &newSurface, TrajectoryStateOnSurface &newTsos, AlgebraicMatrix &newJacobian, AlgebraicMatrix &newCurvlinJacobian, double &nextStep, const PropagationDirection propDir, const MagneticField *magField) const
AlgebraicSymMatrix theTrajectoryPositionCov
double dydz() const
dydz slope
Definition: BeamSpot.h:85
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const
Definition: Propagator.cc:77
ROOT::Math::SMatrix< double, D1, D2, ROOT::Math::MatRepStd< double, D1, D2 > > Matrix
float xy() const
Definition: LocalError.h:25
CLHEP::HepMatrix AlgebraicMatrix
FreeTrajectoryState * freeState(bool withErrors=true) const
float yy() const
Definition: LocalError.h:26
T sqrt(T t)
Definition: SSEVec.h:46
ReferenceTrajectory(const TrajectoryStateOnSurface &referenceTsos, const TransientTrackingRecHit::ConstRecHitContainer &recHits, bool hitsAreReverse, const MagneticField *magField, MaterialEffects materialEffects, PropagationDirection propDir, double mass, bool useBeamSpot, const reco::BeamSpot &beamSpot)
Vector3DBase< typename PreciseFloatType< T, U >::Type, FrameTag > cross(const Vector3DBase< U, FrameTag > &v) const
Definition: Vector3DBase.h:119
std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &fts, const Plane &plane) const
propagation to plane with path length
T z() const
Definition: PV3DBase.h:63
MaterialEffectsUpdator * createUpdator(MaterialEffects materialEffects, double mass) const
void setup(typename AlgebraicROOTObject< D >::Vector *params, typename AlgebraicROOTObject< D, D >::SymMatrix *errors, typename AlgebraicROOTObject< D, 5 >::Matrix *projection, ProjectMatrix< double, 5, D > *projFunc, typename AlgebraicROOTObject< D >::Vector *measuredParams, typename AlgebraicROOTObject< D, D >::SymMatrix *measuredErrors, const AlgebraicVector5 &tsosLocalParameters, const AlgebraicSymMatrix55 &tsosLocalErrors)
const AlgebraicSymMatrix55 & matrix() const
virtual void fillDerivatives(const AlgebraicMatrix &projection, const AlgebraicMatrix &fullJacobian, unsigned int iRow)
const LocalTrajectoryError & localError() const
bool first
Definition: L1TdeRCT.cc:94
GlobalVector momentum() const
double dxdz() const
dxdz slope
Definition: BeamSpot.h:83
TransientTrackingRecHit::ConstRecHitContainer theRecHits
int k[5][pyjets_maxn]
AlgebraicSymMatrix theMeasurementsCov
AlgebraicMatrix getHitProjectionMatrixT(const TransientTrackingRecHit::ConstRecHitPointer &recHit) const
std::vector< ConstRecHitPointer > ConstRecHitContainer
const AlgebraicVector & parameters() const
CLHEP::HepVector AlgebraicVector
ROOT::Math::SVector< double, D1 > Vector
#define N
Definition: blowfish.cc:9
ROOT::Math::SVector< double, 5 > AlgebraicVector5
const GlobalTrajectoryParameters & globalParameters() const
AlgebraicVector5 mixedFormatVector() const
const BoundPlane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
Unlimited (trivial) bounds.
Definition: OpenBounds.h:10
tuple mass
Definition: scaleCards.py:27
const Surface & surface() const
CLHEP::HepSymMatrix AlgebraicSymMatrix
std::vector< TrajectoryStateOnSurface > theTsosVec
double y0() const
y coordinate
Definition: BeamSpot.h:67
virtual bool addMaterialEffectsCov(const std::vector< AlgebraicMatrix > &allJacobians, const std::vector< AlgebraicMatrix > &allProjections, const std::vector< AlgebraicSymMatrix > &allCurvChanges, const std::vector< AlgebraicSymMatrix > &allDeltaParaCovs)
virtual void fillTrajectoryPositions(const AlgebraicMatrix &projection, const AlgebraicVector &mixedLocalParams, unsigned int iRow)
bool useRecHit(const TransientTrackingRecHit::ConstRecHitPointer &hitPtr) const
AlgebraicROOTObject< D, 5 >::Matrix & projection()
T x() const
Definition: PV3DBase.h:61
double signedInverseMomentum() const
Signed inverse momentum q/p (zero for neutrals).
tuple size
Write out results.
double x0() const
x coordinate
Definition: BeamSpot.h:65