CMS 3D CMS Logo

Public Member Functions | Protected Member Functions

DualKalmanTrajectory Class Reference

#include <DualKalmanTrajectory.h>

Inheritance diagram for DualKalmanTrajectory:
ReferenceTrajectoryBase ReferenceCounted

List of all members.

Public Member Functions

virtual DualKalmanTrajectoryclone () const
 DualKalmanTrajectory (const Trajectory::DataContainer &trajMeasurements, const TrajectoryStateOnSurface &referenceTsos, const std::vector< unsigned int > &forwardRecHitNums, const std::vector< unsigned int > &backwardRecHitNums, const MagneticField *magField, MaterialEffects materialEffects, PropagationDirection propDir, double mass, bool useBeamSpot, const reco::BeamSpot &beamSpot, int residualMethod)
virtual ~DualKalmanTrajectory ()

Protected Member Functions

virtual bool construct (const Trajectory::DataContainer &trajMeasurements, const TrajectoryStateOnSurface &referenceTsos, const std::vector< unsigned int > &forwardRecHitNums, const std::vector< unsigned int > &backwardRecHitNums, double mass, MaterialEffects materialEffects, const PropagationDirection propDir, const MagneticField *magField, bool useBeamSpot, const reco::BeamSpot &beamSpot, int residualMethod)
 calculate members
virtual ReferenceTrajectoryconstruct (const Trajectory::DataContainer &trajMeasurements, const TrajectoryStateOnSurface &referenceTsos, const std::vector< unsigned int > &recHits, double mass, MaterialEffects materialEffects, const PropagationDirection propDir, const MagneticField *magField, bool useBeamSpot, const reco::BeamSpot &beamSpot) const
 Method to get a single ReferenceTrajectory for a half of the trajectory.
 DualKalmanTrajectory (unsigned int nPar=0, unsigned int nHits=0)
virtual AlgebraicVector extractParameters (const TrajectoryStateOnSurface &referenceTsos) const
bool fillKalmanPart (const Trajectory::DataContainer &trajMeasurements, const std::vector< unsigned int > &recHitNums, bool startFirst, unsigned int iNextHit, int residualMethod)
 Fill that part of data members that is different from DualReferenceTrajectory.
TrajectoryStateOnSurface fillMeasurementAndError1 (const TransientTrackingRecHit::ConstRecHitPointer &hitPtr, unsigned int iHit, const TrajectoryMeasurement &trajMeasurement)
 helper for 'unbiased residual' method (i.e. returns merged fwd/bwd states)
TrajectoryStateOnSurface fillMeasurementAndError2 (const TransientTrackingRecHit::ConstRecHitPointer &hitPtr, unsigned int iHit, const TrajectoryMeasurement &trajMeasurement, bool doPull)
void fillTrajectoryPositions (const AlgebraicMatrix &projection, const TrajectoryStateOnSurface &tsos, unsigned int iHit)
 fill trajectoryPositions
LocalError hitErrorWithAPE (const TransientTrackingRecHit::ConstRecHitPointer &hitPtr) const
 local error including APE if APE is on
const PropagationDirection oppositeDirection (const PropagationDirection propDir) const

Detailed Description

A trajectory that provides derivatives w.r.t. to the track parameters as the DualReferenceTrajectory, i.e. extrapolating a helix with five parameters from the hit in the middle. But measurements, trajectory positions and uncertainties are taken from the Kalman track fit. More precisely, the uncertainties are those of the residuals, i.e. of measurements() - trajectoryPositions().

Currently three methods to set residual and error can be choosen via cfg: 0: the hitError approach, i.e. residual w.r.t. updated state, but error from hit 1: the unbiased residal approach as in validation 2: the pull approach, i.e. residal w.r.t. to updated state withits error

Author:
: Gero Flucke date : October 2008
Revision:
1.5
Date:
2010/09/10 13:08:05

(last update by

Author:
mussgill

)

Author:
: Gero Flucke date : October 2008
Revision:
1.6
Date:
2010/09/10 13:09:00

(last update by

Author:
mussgill

)

Definition at line 34 of file DualKalmanTrajectory.h.


Constructor & Destructor Documentation

DualKalmanTrajectory::DualKalmanTrajectory ( const Trajectory::DataContainer trajMeasurements,
const TrajectoryStateOnSurface referenceTsos,
const std::vector< unsigned int > &  forwardRecHitNums,
const std::vector< unsigned int > &  backwardRecHitNums,
const MagneticField magField,
MaterialEffects  materialEffects,
PropagationDirection  propDir,
double  mass,
bool  useBeamSpot,
const reco::BeamSpot beamSpot,
int  residualMethod 
)

Definition at line 33 of file DualKalmanTrajectory.cc.

References construct(), and ReferenceTrajectoryBase::theValidityFlag.

Referenced by clone().

  : ReferenceTrajectoryBase(referenceTsos.localParameters().mixedFormatVector().kSize,
                            forwardRecHitNums.size() + backwardRecHitNums.size() - 1, 0, 0)
{
  theValidityFlag = this->construct(trajMeasurements, referenceTsos,
                                    forwardRecHitNums, backwardRecHitNums,
                                    mass, materialEffects, propDir, magField,
                                    useBeamSpot, beamSpot, residualMethod);
}
virtual DualKalmanTrajectory::~DualKalmanTrajectory ( ) [inline, virtual]

Definition at line 51 of file DualKalmanTrajectory.h.

{}
DualKalmanTrajectory::DualKalmanTrajectory ( unsigned int  nPar = 0,
unsigned int  nHits = 0 
) [protected]

Definition at line 55 of file DualKalmanTrajectory.cc.

  : ReferenceTrajectoryBase(nPar, nHits, 0, 0)
{}

Member Function Documentation

virtual DualKalmanTrajectory* DualKalmanTrajectory::clone ( void  ) const [inline, virtual]

Implements ReferenceTrajectoryBase.

Definition at line 53 of file DualKalmanTrajectory.h.

References DualKalmanTrajectory().

{ return new DualKalmanTrajectory(*this); }
bool DualKalmanTrajectory::construct ( const Trajectory::DataContainer trajMeasurements,
const TrajectoryStateOnSurface referenceTsos,
const std::vector< unsigned int > &  forwardRecHitNums,
const std::vector< unsigned int > &  backwardRecHitNums,
double  mass,
MaterialEffects  materialEffects,
const PropagationDirection  propDir,
const MagneticField magField,
bool  useBeamSpot,
const reco::BeamSpot beamSpot,
int  residualMethod 
) [protected, virtual]

calculate members

Definition at line 61 of file DualKalmanTrajectory.cc.

References extractParameters(), fillKalmanPart(), TrajectoryStateOnSurface::hasError(), TrajectoryStateOnSurface::localError(), LocalTrajectoryError::matrix(), ReferenceTrajectoryBase::nMeasPerHit, oppositeDirection(), ReferenceTrajectoryBase::theDerivatives, ReferenceTrajectoryBase::theParameters, ReferenceTrajectoryBase::theRecHits, and ReferenceTrajectoryBase::theTrajectoryPositionCov.

Referenced by DualKalmanTrajectory().

{

  ReferenceTrajectoryPtr fwdTraj = this->construct(trajMeasurements, refTsos, forwardRecHitNums,
                                                   mass, materialEffects,
                                                   propDir, magField, useBeamSpot, beamSpot);
  
  ReferenceTrajectoryPtr bwdTraj = this->construct(trajMeasurements, refTsos, backwardRecHitNums,
                                                   mass, materialEffects,
                                                   this->oppositeDirection(propDir), magField,
                                                   useBeamSpot, beamSpot);

  //   edm::LogError("Alignment") << "@SUB=DualKalmanTrajectory::construct"
  //                         << "valid fwd/bwd " << fwdTraj->isValid() 
  //                         << "/" << bwdTraj->isValid();
  
  if (!fwdTraj->isValid() || !bwdTraj->isValid()) {
    return false;
  }

  //
  // Combine both reference trajactories to a dual reference trajectory
  //

//   const std::vector<TrajectoryStateOnSurface>& fwdTsosVec = fwdTraj->trajectoryStates();
//   const std::vector<TrajectoryStateOnSurface>& bwdTsosVec = bwdTraj->trajectoryStates();
//   theTsosVec.insert( theTsosVec.end(), fwdTsosVec.begin(), fwdTsosVec.end() );
//   theTsosVec.insert( theTsosVec.end(), ++bwdTsosVec.begin(), bwdTsosVec.end() );

  // Take hits as they come from the Kalman fit.
  const ConstRecHitContainer &fwdRecHits = fwdTraj->recHits(); 
  const ConstRecHitContainer &bwdRecHits = bwdTraj->recHits();
  theRecHits.insert(theRecHits.end(), fwdRecHits.begin(), fwdRecHits.end());
  theRecHits.insert(theRecHits.end(), ++bwdRecHits.begin(), bwdRecHits.end());

  theParameters = this->extractParameters(refTsos);

  unsigned int nParam   = theParameters.num_row();
  unsigned int nFwdMeas = nMeasPerHit * fwdTraj->numberOfHits();
  unsigned int nBwdMeas = nMeasPerHit * bwdTraj->numberOfHits();

//   theMeasurements.sub( 1, fwdTraj->measurements() );
//   theMeasurements.sub( nFwdMeas+1, bwdTraj->measurements().sub( nMeasPerHit+1, nBwdMeas ) );

//   theMeasurementsCov.sub( 1, fwdTraj->measurementErrors() );
//   theMeasurementsCov.sub( nFwdMeas+1, bwdTraj->measurementErrors().sub( nMeasPerHit+1, nBwdMeas ) );

//   theTrajectoryPositions.sub( 1, fwdTraj->trajectoryPositions() );
//   theTrajectoryPositions.sub( nFwdMeas+1, bwdTraj->trajectoryPositions().sub( nMeasPerHit+1, nBwdMeas ) );

//   theTrajectoryPositionCov.sub( 1, fwdTraj->trajectoryPositionErrors() );
//   theTrajectoryPositionCov.sub( nFwdMeas+1, bwdTraj->trajectoryPositionErrors().sub( nMeasPerHit+1, nBwdMeas ) );

  theDerivatives.sub(1, 1, fwdTraj->derivatives());
  theDerivatives.sub(nFwdMeas+1, 1,
                     bwdTraj->derivatives().sub(nMeasPerHit+1, nBwdMeas, 1, nParam));

  // FIXME: next lines stolen from ReferenceTrajectory, no idea whether OK or not...
  if (refTsos.hasError()) {
    AlgebraicSymMatrix parameterCov = asHepMatrix<5>(refTsos.localError().matrix());
    theTrajectoryPositionCov = parameterCov.similarity(theDerivatives);
  } else {
    theTrajectoryPositionCov = AlgebraicSymMatrix(theDerivatives.num_row(), 1);
  }

  // Fill Kalman part, first for forward, then for backward part.
  return this->fillKalmanPart(trajMeasurements, forwardRecHitNums, true, 0, residualMethod) 
    && this->fillKalmanPart(trajMeasurements, backwardRecHitNums, false,
                            forwardRecHitNums.size(), residualMethod);
}
ReferenceTrajectory * DualKalmanTrajectory::construct ( const Trajectory::DataContainer trajMeasurements,
const TrajectoryStateOnSurface referenceTsos,
const std::vector< unsigned int > &  recHits,
double  mass,
MaterialEffects  materialEffects,
const PropagationDirection  propDir,
const MagneticField magField,
bool  useBeamSpot,
const reco::BeamSpot beamSpot 
) const [protected, virtual]

Method to get a single ReferenceTrajectory for a half of the trajectory.

Definition at line 143 of file DualKalmanTrajectory.cc.

References i, and ReferenceTrajectoryBase::recHits().

{

  ConstRecHitContainer recHits;
  recHits.reserve(recHitNums.size());
  for (unsigned int i = 0; i < recHitNums.size(); ++i) {
    recHits.push_back(trajMeasurements[recHitNums[i]].recHit());
  }

  return new ReferenceTrajectory(referenceTsos, recHits, false, // hits are already ordered
                                 magField, materialEffects, propDir, mass,
                                 useBeamSpot, beamSpot);
}
AlgebraicVector DualKalmanTrajectory::extractParameters ( const TrajectoryStateOnSurface referenceTsos) const [protected, virtual]

Definition at line 329 of file DualKalmanTrajectory.cc.

References TrajectoryStateOnSurface::localParameters(), and LocalTrajectoryParameters::mixedFormatVector().

Referenced by construct().

{
  return asHepVector<5>( referenceTsos.localParameters().mixedFormatVector() );
}
bool DualKalmanTrajectory::fillKalmanPart ( const Trajectory::DataContainer trajMeasurements,
const std::vector< unsigned int > &  recHitNums,
bool  startFirst,
unsigned int  iNextHit,
int  residualMethod 
) [protected]

Fill that part of data members that is different from DualReferenceTrajectory.

Definition at line 164 of file DualKalmanTrajectory.cc.

References Exception, fillMeasurementAndError1(), fillMeasurementAndError2(), fillTrajectoryPositions(), TrajectoryStateOnSurface::isValid(), TrajectoryMeasurement::recHit(), and ReferenceTrajectoryBase::theTsosVec.

Referenced by construct().

{
  // startFirst==false: skip first hit of recHitNums
  // iNextHit: first hit number to fill data members with
  //
  // Three approaches, choosen by 'residualMethod':
  // 0: Just take hit error and the updated state as millepede needs it to redo the last fit step.
  // 1: Use the unbiased residuals as for residual monitoring.
  // 2: Use the _updated_ state and calculate the sigma that is part of
  //    the pull as sqrt(sigma_hit^2 - sigma_tsos^2).
  //    This should lead to the pull as defined on p. 236 of Blobel's book.
  //    Not sure whether this is 100% applicable/correct here, at least it might lead to 
  //    numerical instabilities, cf.:
  //    https://hypernews.cern.ch/HyperNews/CMS/get/recoTracking/517/1/1/1/1/1.html

  for (unsigned int iMeas = (startFirst ? 0 : 1); iMeas < recHitNums.size(); ++iMeas, ++iNextHit) {
    const TrajectoryMeasurement &trajMeasurement = trajMeasurements[recHitNums[iMeas]];

    TrajectoryStateOnSurface tsos; // depends on method
    switch (residualMethod) {
    case 0:
      tsos = this->fillMeasurementAndError2(trajMeasurement.recHit(), iNextHit, trajMeasurement,
                                            false); // plain hit error, not pull
      break;
    case 1:
      tsos = this->fillMeasurementAndError1(trajMeasurement.recHit(), iNextHit, trajMeasurement);
      break;
    case 2:
      tsos = this->fillMeasurementAndError2(trajMeasurement.recHit(), iNextHit, trajMeasurement,
                                            true); // error of pull
      break;
    default:
      throw cms::Exception("BadConfig")
        << "[DualKalmanTrajectory::fillKalmanPart] expect residualMethod == 0, 1 or 2, not "
        << residualMethod << ".";
    }

    if (!tsos.isValid()) return false;
    theTsosVec.push_back(tsos);
    
    this->fillTrajectoryPositions(trajMeasurement.recHit()->projectionMatrix(),
                                  tsos, iNextHit);
  }

  return true;
} 
TrajectoryStateOnSurface DualKalmanTrajectory::fillMeasurementAndError1 ( const TransientTrackingRecHit::ConstRecHitPointer hitPtr,
unsigned int  iHit,
const TrajectoryMeasurement trajMeasurement 
) [protected]

helper for 'unbiased residual' method (i.e. returns merged fwd/bwd states)

Definition at line 216 of file DualKalmanTrajectory.cc.

References TrajectoryMeasurement::backwardPredictedState(), TrajectoryMeasurement::forwardPredictedState(), hitErrorWithAPE(), TrajectoryStateOnSurface::isValid(), TrajectoryStateOnSurface::localError(), ReferenceTrajectoryBase::nMeasPerHit, LocalTrajectoryError::positionError(), ReferenceTrajectoryBase::theMeasurements, and ReferenceTrajectoryBase::theMeasurementsCov.

Referenced by fillKalmanPart().

{
  // Get the measurements and their errors.
  // We have to add error from hit and that tsos that is combination of fwd and bwd state.

  TrajectoryStateCombiner tsosComb;
  const TrajectoryStateOnSurface tsos = tsosComb(trajMeasurement.forwardPredictedState(),
                                                 trajMeasurement.backwardPredictedState());
  if (tsos.isValid()) {
    // No update of hit with tsos: it comes already from fwd+bwd tsos combination.
    // See also https://hypernews.cern.ch/HyperNews/CMS/get/recoTracking/517/1.html .
    // ConstRecHitPointer newHitPtr(hitPtr->canImproveWithTrack() ? hitPtr->clone(tsos) : hitPtr);
    
    const LocalPoint localMeasurement(hitPtr->localPosition());
    const LocalError hitErr(this->hitErrorWithAPE(hitPtr));
    // tsos prediction includes APE of other hits:
    const LocalError tsosErr(tsos.localError().positionError());
    const LocalError localMeasurementCov(hitErr.xx() + tsosErr.xx(),
                                         hitErr.xy() + tsosErr.xy(),
                                         hitErr.yy() + tsosErr.yy());
    
    theMeasurements[nMeasPerHit*iHit]   = localMeasurement.x();
    theMeasurements[nMeasPerHit*iHit+1] = localMeasurement.y();
    theMeasurementsCov[nMeasPerHit*iHit]  [nMeasPerHit*iHit]   = localMeasurementCov.xx();
    theMeasurementsCov[nMeasPerHit*iHit]  [nMeasPerHit*iHit+1] = localMeasurementCov.xy();
    theMeasurementsCov[nMeasPerHit*iHit+1][nMeasPerHit*iHit+1] = localMeasurementCov.yy();
  }

  return tsos;
}
TrajectoryStateOnSurface DualKalmanTrajectory::fillMeasurementAndError2 ( const TransientTrackingRecHit::ConstRecHitPointer hitPtr,
unsigned int  iHit,
const TrajectoryMeasurement trajMeasurement,
bool  doPull 
) [protected]

helper for 'pull' (doPull=true) or 'hitError' method (doPull=false), returns updated tsos in both cases

Definition at line 251 of file DualKalmanTrajectory.cc.

References hitErrorWithAPE(), TrajectoryStateOnSurface::isValid(), TrajectoryStateOnSurface::localError(), ReferenceTrajectoryBase::nMeasPerHit, LocalTrajectoryError::positionError(), mathSSE::sqrt(), ReferenceTrajectoryBase::theMeasurements, ReferenceTrajectoryBase::theMeasurementsCov, and TrajectoryMeasurement::updatedState().

Referenced by fillKalmanPart().

{
  // Get the measurements and their errors.
  // We have to subtract error of updated tsos from hit.

  const TrajectoryStateOnSurface tsos = trajMeasurement.updatedState();
  if (tsos.isValid()) {
    // No further update of hit: 
    // - The Kalman fit used hitPtr as it comes here (besides APE, see below).
    // - If the hit errors improve, we might get (rare) problems of negative diagonal elements, see below.
    // ConstRecHitPointer newHitPtr(hitPtr->canImproveWithTrack() ? hitPtr->clone(tsos) : hitPtr);

    const LocalPoint localMeasurement(hitPtr->localPosition());
    // Add APE manually to avoid that the hit error might be smaller than tsos error:
    // - hit local errors are always without APE,
    // - the tsos errors include APE since they come from track fit.
    const LocalError hitErr(this->hitErrorWithAPE(hitPtr));

    LocalError localMeasurementCov(hitErr.xx(), hitErr.xy(), hitErr.yy());
    if (doPull) {
      const LocalError tsosErr(tsos.localError().positionError());
      // Should not be possible to become negative if all is correct - see above.
      if (hitErr.xx() < tsosErr.xx() || hitErr.yy() < tsosErr.yy()) {
        edm::LogError("Alignment") << "@SUB=DualKalmanTrajectory::fillMeasurementAndError2"
                                   << "not OK in subdet " << hitPtr->geographicalId().subdetId()
                                   << "\ns_x " << sqrt(hitErr.xx()) << " " << sqrt(tsosErr.xx())
                                   << "\ns_xy " << hitErr.xy() << " " << tsosErr.xy()
                                   << "\ns_y " << sqrt(hitErr.yy()) << " " << sqrt(tsosErr.yy());
        return TrajectoryStateOnSurface(); // is invalid state
      }
      // cf. Blobel/Lohrmann, p. 236:
      // But numerical stability? Should we return false if difference very small compared to values?
      localMeasurementCov = LocalError(hitErr.xx() - tsosErr.xx(), // tsos puts correlation in,   
                                       hitErr.xy() - tsosErr.xy(), // even for 1D strip!            
                                       hitErr.yy() - tsosErr.yy());
    }

    theMeasurements[nMeasPerHit*iHit]   = localMeasurement.x();
    theMeasurements[nMeasPerHit*iHit+1] = localMeasurement.y();
    theMeasurementsCov[nMeasPerHit*iHit]  [nMeasPerHit*iHit]   = localMeasurementCov.xx();
    theMeasurementsCov[nMeasPerHit*iHit]  [nMeasPerHit*iHit+1] = localMeasurementCov.xy();
    theMeasurementsCov[nMeasPerHit*iHit+1][nMeasPerHit*iHit+1] = localMeasurementCov.yy();
  }

  return tsos;
}
void DualKalmanTrajectory::fillTrajectoryPositions ( const AlgebraicMatrix projection,
const TrajectoryStateOnSurface tsos,
unsigned int  iHit 
) [protected]

fill trajectoryPositions

Definition at line 302 of file DualKalmanTrajectory.cc.

References TrajectoryStateOnSurface::localParameters(), LocalTrajectoryParameters::mixedFormatVector(), ReferenceTrajectoryBase::nMeasPerHit, and ReferenceTrajectoryBase::theTrajectoryPositions.

Referenced by fillKalmanPart().

{
  // get the local coordinates of the reference trajectory
  // (~copied from ReferenceTrajectory::fillTrajectoryPositions)
  AlgebraicVector mixedLocalParams = asHepVector<5>(tsos.localParameters().mixedFormatVector());
  const AlgebraicVector localPosition(projection * mixedLocalParams);

  theTrajectoryPositions[nMeasPerHit*iHit]   = localPosition[0];
  theTrajectoryPositions[nMeasPerHit*iHit+1] = localPosition[1];
}
LocalError DualKalmanTrajectory::hitErrorWithAPE ( const TransientTrackingRecHit::ConstRecHitPointer hitPtr) const [protected]

local error including APE if APE is on

Definition at line 316 of file DualKalmanTrajectory.cc.

References alignmentValidation::help, and HelpertRecHit2DLocalPos::parError().

Referenced by fillMeasurementAndError1(), and fillMeasurementAndError2().

{
  if (hitPtr->det() && hitPtr->det()->alignmentPositionError()) {
    HelpertRecHit2DLocalPos help;
    const AlgebraicSymMatrix errMat(help.parError(hitPtr->localPositionError(), *(hitPtr->det())));
    return LocalError(errMat[0][0], errMat[0][1], errMat[1][1]);
  } else {
    return hitPtr->localPositionError();
  }
}
const PropagationDirection DualKalmanTrajectory::oppositeDirection ( const PropagationDirection  propDir) const [inline, protected]

Definition at line 102 of file DualKalmanTrajectory.h.

References alongMomentum, anyDirection, and oppositeToMomentum.

Referenced by construct().

  { return ((propDir == anyDirection) ? anyDirection 
            : ((propDir == alongMomentum) ? oppositeToMomentum : alongMomentum));
  }