CMS 3D CMS Logo

TwoBodyDecayTrajectory.cc
Go to the documentation of this file.
2 
9 
11 
12 
14 
16  const ConstRecHitCollection& recHits,
17  const MagneticField* magField,
18  const reco::BeamSpot& beamSpot,
21  TwoBodyDecayParameters::dimension, recHits.first.size() + recHits.second.size(),
22  (config.materialEffects >= breakPoints) ? 2*(recHits.first.size() + recHits.second.size())-4 : 0,
23  (config.materialEffects >= breakPoints) ? 2*(recHits.first.size() + recHits.second.size())-3 : 1 ),
24  materialEffects_(config.materialEffects),
25  propDir_(config.propDir),
26  useRefittedState_(config.useRefittedState),
27  constructTsosWithErrors_(config.constructTsosWithErrors)
28 
29 {
30  if ( config.hitsAreReverse )
31  {
32  TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator itRecHits;
33  ConstRecHitCollection fwdRecHits;
34 
35  fwdRecHits.first.reserve( recHits.first.size() );
36  for ( itRecHits = recHits.first.rbegin(); itRecHits != recHits.first.rend(); ++itRecHits )
37  {
38  fwdRecHits.first.push_back( *itRecHits );
39  }
40 
41  fwdRecHits.second.reserve( recHits.second.size() );
42  for ( itRecHits = recHits.second.rbegin(); itRecHits != recHits.second.rend(); ++itRecHits )
43  {
44  fwdRecHits.second.push_back( *itRecHits );
45  }
46 
47  theValidityFlag = this->construct(tsos, fwdRecHits, magField, beamSpot);
48  }
49  else
50  {
51  theValidityFlag = this->construct(tsos, recHits, magField, beamSpot);
52  }
53 }
54 
55 
57  : ReferenceTrajectoryBase( 0, 0, 0, 0),
62 {}
63 
64 
67  const MagneticField* field,
68  const reco::BeamSpot& beamSpot)
69 {
72  double mass = state.particleMass();
73 
74  //
75  // first track
76  //
77 
78  // construct a trajectory (hits should be already in correct order)
80  config.useBeamSpot = false;
81  config.hitsAreReverse = false;
82 
83  ReferenceTrajectory trajectory1(tsos.first, recHits.first, field, beamSpot, config);
84 
85  // check if construction of trajectory was successful
86  if ( !trajectory1.isValid() ) return false;
87 
88  //
89  // second track
90  //
91 
92  ReferenceTrajectory trajectory2(tsos.second, recHits.second, field, beamSpot, config);
93 
94  if ( !trajectory2.isValid() ) return false;
95 
96  //
97  // combine both tracks
98  //
99  unsigned int nLocal = deriv.first.num_row();
100  unsigned int nTbd = deriv.first.num_col();
101 
102  if (materialEffects_ >= localGBL) {
103  // GBL trajectory inputs
104  // convert to Eigen::MatrixXd
105  Eigen::MatrixXd tbdToLocal1{nLocal, nTbd};
106  for (unsigned int row = 0; row < nLocal; ++row) {
107  for (unsigned int col = 0; col < nTbd; ++col) {
108  tbdToLocal1(row,col) = deriv.first[row][col];
109  }
110  }
111  // add first body
112  theGblInput.push_back(std::make_pair(trajectory1.gblInput().front().first,
113  trajectory1.gblInput().front().second*tbdToLocal1));
114  // convert to Eigen::MatrixXd
115  Eigen::MatrixXd tbdToLocal2{nLocal, nTbd};
116  for (unsigned int row = 0; row < nLocal; ++row) {
117  for (unsigned int col = 0; col < nTbd; ++col) {
118  tbdToLocal2(row,col) = deriv.second[row][col];
119  }
120  }
121  // add second body
122  theGblInput.push_back(std::make_pair(trajectory2.gblInput().front().first,
123  trajectory2.gblInput().front().second*tbdToLocal2));
124  // add virtual mass measurement
125  theGblExtDerivatives.resize(1,nTbd);
126  theGblExtDerivatives.setZero();
128  theGblExtMeasurements.resize(1);
130  theGblExtPrecisions.resize(1);
131  theGblExtPrecisions(0) = 1.0 / (state.primaryWidth() * state.primaryWidth());
132  // nominal field
133  theNomField = trajectory1.nominalField();
134  } else {
135  unsigned int nHitMeas1 = trajectory1.numberOfHitMeas();
136  unsigned int nVirtualMeas1 = trajectory1.numberOfVirtualMeas();
137  unsigned int nPar1 = trajectory1.numberOfPar();
138  unsigned int nVirtualPar1 = trajectory1.numberOfVirtualPar();
139 
140  // derivatives of the trajectory w.r.t. to the decay parameters
141  AlgebraicMatrix fullDeriv1 = trajectory1.derivatives().sub(1,nHitMeas1+nVirtualMeas1,1,nLocal) * trajectory1.localToTrajectory() * deriv.first;
142 
143  unsigned int nHitMeas2 = trajectory2.numberOfHitMeas();
144  unsigned int nVirtualMeas2 = trajectory2.numberOfVirtualMeas();
145  unsigned int nPar2 = trajectory2.numberOfPar();
146  unsigned int nVirtualPar2 = trajectory2.numberOfVirtualPar();
147 
148  AlgebraicMatrix fullDeriv2 = trajectory2.derivatives().sub(1,nHitMeas2+nVirtualMeas2,1,nLocal) * trajectory2.localToTrajectory() * deriv.second;
149 
150  theNumberOfRecHits.first = recHits.first.size();
151  theNumberOfRecHits.second = recHits.second.size();
152 
153  theNumberOfHits = trajectory1.numberOfHits() + trajectory2.numberOfHits();
154  theNumberOfPars = nPar1 + nPar2;
155  theNumberOfVirtualPars = nVirtualPar1 + nVirtualPar2;
156  theNumberOfVirtualMeas = nVirtualMeas1 + nVirtualMeas2 + 1; // add virtual mass measurement
157 
158  // hit measurements from trajectory 1
159  int rowOffset = 1;
160  int colOffset = 1;
161  theDerivatives.sub( rowOffset, colOffset, fullDeriv1.sub( 1, nHitMeas1, 1, nTbd ) );
162  colOffset += nTbd;
163  theDerivatives.sub( rowOffset, colOffset, trajectory1.derivatives().sub( 1, nHitMeas1, nLocal + 1, nPar1 + nVirtualPar1 ) );
164  // hit measurements from trajectory 2
165  rowOffset += nHitMeas1;
166  colOffset = 1;
167  theDerivatives.sub( rowOffset, colOffset, fullDeriv2.sub( 1, nHitMeas2, 1, nTbd ) );
168  colOffset += (nPar1 + nVirtualPar1 + nTbd - nLocal);
169  theDerivatives.sub( rowOffset, colOffset, trajectory2.derivatives().sub( 1, nHitMeas2, nLocal + 1, nPar2 + nVirtualPar2 ) );
170  // MS measurements from trajectory 1
171  rowOffset += nHitMeas2;
172  colOffset = 1;
173  theDerivatives.sub( rowOffset, colOffset, fullDeriv1.sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1, 1, nTbd ) );
174  colOffset += nTbd;
175  theDerivatives.sub( rowOffset, colOffset, trajectory1.derivatives().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1, nLocal + 1, nPar1 + nVirtualPar1 ) );
176  // MS measurements from trajectory 2
177  rowOffset += nVirtualMeas1;
178  colOffset = 1;
179  theDerivatives.sub( rowOffset, colOffset, fullDeriv2.sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2, 1, nTbd ) );
180  colOffset += (nPar1 + nVirtualPar1 + nTbd - nLocal);
181  theDerivatives.sub( rowOffset, colOffset, trajectory2.derivatives().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2, nLocal + 1, nPar2 + nVirtualPar2 ) );
182 
183  theMeasurements.sub( 1, trajectory1.measurements().sub( 1, nHitMeas1 ) );
184  theMeasurements.sub( nHitMeas1 + 1, trajectory2.measurements().sub( 1, nHitMeas2 ) );
185  theMeasurements.sub( nHitMeas1 + nHitMeas2 + 1, trajectory1.measurements().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1 ) );
186  theMeasurements.sub( nHitMeas1 + nHitMeas2 + nVirtualMeas1 + 1, trajectory2.measurements().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2 ) );
187 
188  theMeasurementsCov.sub( 1, trajectory1.measurementErrors().sub( 1, nHitMeas1 ) );
189  theMeasurementsCov.sub( nHitMeas1 + 1, trajectory2.measurementErrors().sub( 1, nHitMeas2 ) );
190  theMeasurementsCov.sub( nHitMeas1 + nHitMeas2 + 1, trajectory1.measurementErrors().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1 ) );
191  theMeasurementsCov.sub( nHitMeas1 + nHitMeas2 + nVirtualMeas1 + 1, trajectory2.measurementErrors().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2 ) );
192 
193  theTrajectoryPositions.sub( 1, trajectory1.trajectoryPositions() );
194  theTrajectoryPositions.sub( nHitMeas1 + 1, trajectory2.trajectoryPositions() );
195 
196  theTrajectoryPositionCov = state.decayParameters().covariance().similarity( theDerivatives.sub(1, nHitMeas1 + nHitMeas2, 1, 9) );
197 
199 
200  // add virtual mass measurement
201  rowOffset += nVirtualMeas2;
202  int indMass = rowOffset-1;
204  theMeasurementsCov[indMass][indMass] = state.primaryWidth() * state.primaryWidth();
206  }
207 
208  theRecHits.insert( theRecHits.end(), recHits.first.begin(), recHits.first.end() );
209  theRecHits.insert( theRecHits.end(), recHits.second.begin(), recHits.second.end() );
210 
212  {
213  constructTsosVecWithErrors( trajectory1, trajectory2, field );
214  }
215  else
216  {
217  theTsosVec.insert( theTsosVec.end(),
218  trajectory1.trajectoryStates().begin(),
219  trajectory1.trajectoryStates().end() );
220 
221  theTsosVec.insert( theTsosVec.end(),
222  trajectory2.trajectoryStates().begin(),
223  trajectory2.trajectoryStates().end() );
224  }
225 
226  return true;
227 }
228 
229 
231  const ReferenceTrajectory& traj2,
232  const MagneticField* field )
233 {
234  int iTsos = 0;
235 
236  std::vector< TrajectoryStateOnSurface >::const_iterator itTsos;
237 
238  for ( itTsos = traj1.trajectoryStates().begin(); itTsos != traj1.trajectoryStates().end(); itTsos++ )
239  {
240  constructSingleTsosWithErrors( *itTsos, iTsos, field );
241  iTsos++;
242  }
243 
244  for ( itTsos = traj2.trajectoryStates().begin(); itTsos != traj2.trajectoryStates().end(); itTsos++ )
245  {
246  constructSingleTsosWithErrors( *itTsos, iTsos, field );
247  iTsos++;
248  }
249 }
250 
251 
253  int iTsos,
254  const MagneticField* field )
255 {
256  AlgebraicSymMatrix55 localErrors;
257  const double coeff = 1e-2;
258 
259  double invP = tsos.localParameters().signedInverseMomentum();
261 
262  // rough estimate for the errors of q/p, dx/dz and dy/dz, assuming that
263  // sigma(px) = sigma(py) = sigma(pz) = coeff*p.
264  float dpinv = coeff*( fabs(p.x()) + fabs(p.y()) + fabs(p.z()) )*invP*invP;
265  float dxdir = coeff*( fabs(p.x()) + fabs(p.z()) )/p.z()/p.z();
266  float dydir = coeff*( fabs(p.y()) + fabs(p.z()) )/p.z()/p.z();
267  localErrors[0][0] = dpinv*dpinv;
268  localErrors[1][1] = dxdir*dxdir;
269  localErrors[2][2] = dydir*dydir;
270 
271  // exact values for the errors on local x and y
272  localErrors[3][3] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos];
273  localErrors[3][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos+1];
274  localErrors[4][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos+1][nMeasPerHit*iTsos+1];
275 
276  // construct tsos with local errors
278  LocalTrajectoryError( localErrors ),
279  tsos.surface(),
280  field,
281  tsos.surfaceSide() );
282 }
size
Write out results.
unsigned int numberOfHits() const
const LocalTrajectoryParameters & localParameters() const
bool construct(const TwoBodyDecayTrajectoryState &state, const ConstRecHitCollection &recHits, const MagneticField *field, const reco::BeamSpot &beamSpot)
const AlgebraicVector & parameters(void) const
Get decay parameters.
void constructSingleTsosWithErrors(const TrajectoryStateOnSurface &tsos, int iTsos, const MagneticField *field)
unsigned int numberOfHitMeas() const
const TransientTrackingRecHit::ConstRecHitContainer & recHits() const
T y() const
Definition: PV3DBase.h:63
unsigned int numberOfVirtualPar() const
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
Definition: config.py:1
const PropagationDirection propDir_
std::pair< ConstRecHitContainer, ConstRecHitContainer > ConstRecHitCollection
const TsosContainer & trajectoryStates(bool useRefittedState=true) const
const AlgebraicSymMatrix & measurementErrors() const
float signedInverseMomentum() const
Signed inverse momentum q/p (zero for neutrals).
U second(std::pair< T, U > const &p)
config
Definition: looper.py:287
AlgebraicSymMatrix theTrajectoryPositionCov
std::vector< std::pair< std::vector< gbl::GblPoint >, Eigen::MatrixXd > > theGblInput
const AlgebraicMatrix & derivatives() const
const SurfaceType & surface() const
const Derivatives & derivatives(void) const
CLHEP::HepMatrix AlgebraicMatrix
SurfaceSide surfaceSide() const
Position relative to material, defined relative to momentum vector.
T z() const
Definition: PV3DBase.h:64
std::pair< TrajectoryStateOnSurface, TrajectoryStateOnSurface > TsosContainer
const MaterialEffects materialEffects_
LocalVector momentum() const
Momentum vector in the local frame.
std::pair< int, int > theNumberOfRecHits
TransientTrackingRecHit::ConstRecHitContainer theRecHits
const AlgebraicMatrix & localToTrajectory() const
AlgebraicSymMatrix theMeasurementsCov
const TwoBodyDecayParameters & decayParameters(void) const
std::pair< AlgebraicMatrix, AlgebraicMatrix > Derivatives
unsigned int numberOfPar() const
std::vector< std::pair< std::vector< gbl::GblPoint >, Eigen::MatrixXd > > & gblInput()
void constructTsosVecWithErrors(const ReferenceTrajectory &traj1, const ReferenceTrajectory &traj2, const MagneticField *field)
const AlgebraicSymMatrix & covariance(void) const
Get error matrix.
unsigned int numberOfVirtualMeas() const
const AlgebraicVector & measurements() const
col
Definition: cuy.py:1008
std::vector< TrajectoryStateOnSurface > theTsosVec
const AlgebraicVector & trajectoryPositions() const
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
T x() const
Definition: PV3DBase.h:62
const std::vector< TrajectoryStateOnSurface > & trajectoryStates() const