CMS 3D CMS Logo

TwoBodyDecayEstimator.cc
Go to the documentation of this file.
1 
4 
9 //#include "DataFormats/CLHEP/interface/Migration.h"
10 
12  const edm::ParameterSet &estimatorConfig = config.getParameter<edm::ParameterSet>("EstimatorParameters");
13 
14  theRobustificationConstant = estimatorConfig.getUntrackedParameter<double>("RobustificationConstant", 1.0);
15  theMaxIterDiff = estimatorConfig.getUntrackedParameter<double>("MaxIterationDifference", 1e-2);
16  theMaxIterations = estimatorConfig.getUntrackedParameter<int>("MaxIterations", 100);
17  theUseInvariantMass = estimatorConfig.getUntrackedParameter<bool>("UseInvariantMass", true);
18 }
19 
20 TwoBodyDecay TwoBodyDecayEstimator::estimate(const std::vector<RefCountedLinearizedTrackState> &linTracks,
21  const TwoBodyDecayParameters &linearizationPoint,
22  const TwoBodyDecayVirtualMeasurement &vm) const {
23  if (linTracks.size() != 2) {
24  edm::LogInfo("Alignment") << "@SUB=TwoBodyDecayEstimator::estimate"
25  << "Need 2 linearized tracks, got " << linTracks.size() << ".\n";
26  return TwoBodyDecay();
27  }
28 
29  AlgebraicVector vecM;
30  AlgebraicSymMatrix matG;
31  AlgebraicMatrix matA;
32 
33  bool check = constructMatrices(linTracks, linearizationPoint, vm, vecM, matG, matA);
34  if (!check)
35  return TwoBodyDecay();
36 
37  AlgebraicSymMatrix matGPrime;
38  AlgebraicSymMatrix invAtGPrimeA;
39  AlgebraicVector vecEstimate;
41 
42  int nIterations = 0;
43  bool stopIteration = false;
44 
45  // initialization - values are never used
46  int checkInversion = 0;
47  double chi2 = 0.;
48  double oldChi2 = 0.;
49  bool isValid = true;
50 
51  while (!stopIteration) {
52  matGPrime = matG;
53 
54  // compute weights
55  if (nIterations > 0) {
56  for (int i = 0; i < 10; i++) {
57  double sigma = 1. / sqrt(matG[i][i]);
58  double sigmaTimesR = sigma * theRobustificationConstant;
59  double absRes = fabs(res[i]);
60  if (absRes > sigmaTimesR)
61  matGPrime[i][i] *= sigmaTimesR / absRes;
62  }
63  }
64 
65  // make LS-fit
66  invAtGPrimeA = (matGPrime.similarityT(matA)).inverse(checkInversion);
67  if (checkInversion != 0) {
68  LogDebug("Alignment") << "@SUB=TwoBodyDecayEstimator::estimate"
69  << "Matrix At*G'*A not invertible (in iteration " << nIterations
70  << ", ifail = " << checkInversion << ").\n";
71  isValid = false;
72  break;
73  }
74  vecEstimate = invAtGPrimeA * matA.T() * matGPrime * vecM;
75  res = matA * vecEstimate - vecM;
76  chi2 = dot(res, matGPrime * res);
77 
78  if ((nIterations > 0) && (fabs(chi2 - oldChi2) < theMaxIterDiff))
79  stopIteration = true;
80  if (nIterations == theMaxIterations)
81  stopIteration = true;
82 
83  oldChi2 = chi2;
84  nIterations++;
85  }
86 
87  if (isValid) {
88  AlgebraicSymMatrix pullsCov = matGPrime.inverse(checkInversion) - invAtGPrimeA.similarity(matA);
89  thePulls = AlgebraicVector(matG.num_col(), 0);
90  for (int i = 0; i < pullsCov.num_col(); i++)
91  thePulls[i] = res[i] / sqrt(pullsCov[i][i]);
92  }
93 
94  theNdf = matA.num_row() - matA.num_col();
95 
96  return TwoBodyDecay(TwoBodyDecayParameters(vecEstimate, invAtGPrimeA), chi2, isValid, vm);
97 }
98 
99 bool TwoBodyDecayEstimator::constructMatrices(const std::vector<RefCountedLinearizedTrackState> &linTracks,
100  const TwoBodyDecayParameters &linearizationPoint,
102  AlgebraicVector &vecM,
103  AlgebraicSymMatrix &matG,
104  AlgebraicMatrix &matA) const {
105  PerigeeLinearizedTrackState *linTrack1 = dynamic_cast<PerigeeLinearizedTrackState *>(linTracks[0].get());
106  PerigeeLinearizedTrackState *linTrack2 = dynamic_cast<PerigeeLinearizedTrackState *>(linTracks[1].get());
107 
108  if (!linTrack1 || !linTrack2)
109  return false;
110 
111  AlgebraicVector trackParam1 = asHepVector(linTrack1->predictedStateParameters());
112  AlgebraicVector trackParam2 = asHepVector(linTrack2->predictedStateParameters());
113 
114  if (checkValues(trackParam1) || checkValues(trackParam2) || checkValues(linearizationPoint.parameters()))
115  return false;
116 
118 
119  double zMagField = linTrack1->track().field()->inInverseGeV(linTrack1->linearizationPoint()).z();
120 
121  int checkInversion = 0;
122 
123  TwoBodyDecayDerivatives tpeDerivatives(linearizationPoint[TwoBodyDecayParameters::mass], vm.secondaryMass());
124  std::pair<AlgebraicMatrix, AlgebraicMatrix> derivatives = tpeDerivatives.derivatives(linearizationPoint);
125 
126  TwoBodyDecayModel decayModel(linearizationPoint[TwoBodyDecayParameters::mass], vm.secondaryMass());
127  std::pair<AlgebraicVector, AlgebraicVector> linCartMomenta = decayModel.cartesianSecondaryMomenta(linearizationPoint);
128 
129  // first track
130  AlgebraicMatrix matA1 = asHepMatrix(linTrack1->positionJacobian());
131  AlgebraicMatrix matB1 = asHepMatrix(linTrack1->momentumJacobian());
132  AlgebraicVector vecC1 = asHepVector(linTrack1->constantTerm());
133 
134  AlgebraicVector curvMomentum1 = asHepVector(linTrack1->predictedStateMomentumParameters());
135  AlgebraicMatrix curv2cart1 = decayModel.curvilinearToCartesianJacobian(curvMomentum1, zMagField);
136 
137  AlgebraicVector cartMomentum1 = decayModel.convertCurvilinearToCartesian(curvMomentum1, zMagField);
138  vecC1 += matB1 * (curvMomentum1 - curv2cart1 * cartMomentum1);
139  matB1 = matB1 * curv2cart1;
140 
141  AlgebraicMatrix matF1 = derivatives.first;
142  AlgebraicVector vecD1 = linCartMomenta.first - matF1 * vecLinParam;
143  AlgebraicVector vecM1 = trackParam1 - vecC1 - matB1 * vecD1;
144  AlgebraicSymMatrix covM1 = asHepMatrix(linTrack1->predictedStateError());
145 
146  AlgebraicSymMatrix matG1 = covM1.inverse(checkInversion);
147  if (checkInversion != 0) {
148  LogDebug("Alignment") << "@SUB=TwoBodyDecayEstimator::constructMatrices"
149  << "Matrix covM1 not invertible.";
150  return false;
151  }
152 
153  // diagonalize for robustification
154  AlgebraicMatrix matU1 = diagonalize(&matG1).T();
155 
156  // second track
157  AlgebraicMatrix matA2 = asHepMatrix(linTrack2->positionJacobian());
158  AlgebraicMatrix matB2 = asHepMatrix(linTrack2->momentumJacobian());
159  AlgebraicVector vecC2 = asHepVector(linTrack2->constantTerm());
160 
161  AlgebraicVector curvMomentum2 = asHepVector(linTrack2->predictedStateMomentumParameters());
162  AlgebraicMatrix curv2cart2 = decayModel.curvilinearToCartesianJacobian(curvMomentum2, zMagField);
163 
164  AlgebraicVector cartMomentum2 = decayModel.convertCurvilinearToCartesian(curvMomentum2, zMagField);
165  vecC2 += matB2 * (curvMomentum2 - curv2cart2 * cartMomentum2);
166  matB2 = matB2 * curv2cart2;
167 
168  AlgebraicMatrix matF2 = derivatives.second;
169  AlgebraicVector vecD2 = linCartMomenta.second - matF2 * vecLinParam;
170  AlgebraicVector vecM2 = trackParam2 - vecC2 - matB2 * vecD2;
171  AlgebraicSymMatrix covM2 = asHepMatrix(linTrack2->predictedStateError());
172 
173  AlgebraicSymMatrix matG2 = covM2.inverse(checkInversion);
174  if (checkInversion != 0) {
175  LogDebug("Alignment") << "@SUB=TwoBodyDecayEstimator::constructMatrices"
176  << "Matrix covM2 not invertible.";
177  return false;
178  }
179 
180  // diagonalize for robustification
181  AlgebraicMatrix matU2 = diagonalize(&matG2).T();
182 
183  // combine first and second track
184  vecM = AlgebraicVector(14, 0);
185  vecM.sub(1, matU1 * vecM1);
186  vecM.sub(6, matU2 * vecM2);
187  // virtual measurement of the primary mass
188  vecM(11) = vm.primaryMass();
189  // virtual measurement of the beam spot
190  vecM.sub(12, vm.beamSpotPosition());
191 
192  // full weight matrix
193  matG = AlgebraicSymMatrix(14, 0);
194  matG.sub(1, matG1);
195  matG.sub(6, matG2);
196  // virtual measurement error of the primary mass
197  matG[10][10] = 1. / (vm.primaryWidth() * vm.primaryWidth());
198  // virtual measurement error of the beam spot
199  matG.sub(12, vm.beamSpotError().inverse(checkInversion));
200 
201  // full derivative matrix
202  matA = AlgebraicMatrix(14, 9, 0);
203  matA.sub(1, 1, matU1 * matA1);
204  matA.sub(6, 1, matU2 * matA2);
205  matA.sub(1, 4, matU1 * matB1 * matF1);
206  matA.sub(6, 4, matU2 * matB2 * matF2);
207  matA(11, 9) = 1.; // mass
208  matA(12, 1) = 1.; // vx
209  matA(13, 2) = 1.; // vy
210  matA(14, 3) = 1.; // vz
211 
212  return true;
213 }
214 
216  bool isNotFinite = false;
217 
218  for (int i = 0; i < vec.num_col(); ++i)
219  isNotFinite |= edm::isNotFinite(vec[i]);
220 
221  return isNotFinite;
222 }
CLHEP::HepMatrix asHepMatrix(const ROOT::Math::SMatrix< double, N1, N2, typename ROOT::Math::MatRepStd< double, N1, N2 > > &rm)
Definition: Migration.h:60
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
AlgebraicVector3 predictedStateMomentumParameters() const override
GlobalVector inInverseGeV(const GlobalPoint &gp) const
Field value ad specified global point, in 1/Gev.
Definition: MagneticField.h:36
Definition: config.py:1
const AlgebraicVector5 & constantTerm() const override
Definition: Electron.h:6
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
const AlgebraicVector & parameters(void) const
Get decay parameters.
const AlgebraicVector sub(ParameterName first, ParameterName last) const
Get specified range of decay parameters.
T getUntrackedParameter(std::string const &, T const &) const
TwoBodyDecayEstimator(const edm::ParameterSet &config)
CLHEP::HepMatrix AlgebraicMatrix
T sqrt(T t)
Definition: SSEVec.h:23
const MagneticField * field() const
const AlgebraicSymMatrix beamSpotError(void) const
virtual TwoBodyDecay estimate(const std::vector< RefCountedLinearizedTrackState > &linTracks, const TwoBodyDecayParameters &linearizationPoint, const TwoBodyDecayVirtualMeasurement &vm) const
Log< level::Info, false > LogInfo
const AlgebraicMatrix53 & positionJacobian() const override
CLHEP::HepVector AlgebraicVector
const AlgebraicMatrix53 & momentumJacobian() const override
const AlgebraicVector beamSpotPosition(void) const
virtual bool constructMatrices(const std::vector< RefCountedLinearizedTrackState > &linTracks, const TwoBodyDecayParameters &linearizationPoint, const TwoBodyDecayVirtualMeasurement &vm, AlgebraicVector &vecM, AlgebraicSymMatrix &matG, AlgebraicMatrix &matA) const
reco::TransientTrack track() const override
AlgebraicSymMatrix55 predictedStateError() const override
CLHEP::HepSymMatrix AlgebraicSymMatrix
AlgebraicVector5 predictedStateParameters() const override
bool checkValues(const AlgebraicVector &vec) const
CLHEP::HepVector asHepVector(const ROOT::Math::SVector< double, N > &v)
Definition: Migration.h:53
const GlobalPoint & linearizationPoint() const override
const std::pair< AlgebraicMatrix, AlgebraicMatrix > derivatives(const TwoBodyDecay &tbd) const
const std::pair< AlgebraicVector, AlgebraicVector > cartesianSecondaryMomenta(const AlgebraicVector &param)
#define LogDebug(id)