CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
KFParamsComb.cc
Go to the documentation of this file.
1 
7 
8 #include <array>
9 #include <sstream>
10 
11 using namespace std;
12 
13 namespace tmtt {
14 
15  /* Initialize */
16 
17  KFParamsComb::KFParamsComb(const Settings* settings, const uint nHelixPar, const std::string& fitterName)
18  : KFbase(settings, nHelixPar, fitterName),
19  // Initialize cuts applied to helix states vs KF layer number of last added stub.
20  kfLayerVsPtToler_(settings->kfLayerVsPtToler()),
21  kfLayerVsD0Cut5_(settings->kfLayerVsD0Cut5()),
22  kfLayerVsZ0Cut5_(settings->kfLayerVsZ0Cut5()),
23  kfLayerVsZ0Cut4_(settings->kfLayerVsZ0Cut4()),
24  kfLayerVsChiSq5_(settings->kfLayerVsChiSq5()),
25  kfLayerVsChiSq4_(settings->kfLayerVsChiSq4()) {}
26 
27  /* Helix state seed */
28 
29  TVectorD KFParamsComb::seedX(const L1track3D& l1track3D) const {
30  TVectorD vecX(nHelixPar_);
31  vecX[INV2R] = settings_->invPtToInvR() * l1track3D.qOverPt() / 2;
32  vecX[PHI0] = reco::deltaPhi(l1track3D.phi0() - sectorPhi(), 0.);
33  vecX[Z0] = l1track3D.z0();
34  vecX[T] = l1track3D.tanLambda();
35  if (nHelixPar_ == 5) { // fit without d0 constraint
36  vecX[D0] = l1track3D.d0();
37  }
38 
39  return vecX;
40  }
41 
42  /* Helix state seed covariance matrix */
43 
44  TMatrixD KFParamsComb::seedC(const L1track3D& l1track3D) const {
45  TMatrixD matC(nHelixPar_, nHelixPar_);
46 
47  double invPtToInv2R = settings_->invPtToInvR() / 2;
48 
49  // Assumed track seed (from HT) uncertainty in transverse impact parameter.
50 
51  // Constants optimised by hand for TMTT algo.
52  const float inv2Rsigma = 0.0314 * invPtToInv2R;
53  constexpr float phi0sigma = 0.0102;
54  constexpr float z0sigma = 5.0;
55  constexpr float tanLsigma = 0.5;
56  constexpr float d0Sigma = 1.0;
57  // (z0, tanL, d0) uncertainties could be smaller for Hybrid, if seeded in PS? -- To check!
58  // if (L1track3D.seedPS() > 0) z0sigma /= 4; ???
59  matC[INV2R][INV2R] = pow(inv2Rsigma, 2);
60  matC[PHI0][PHI0] = pow(phi0sigma, 2);
61  matC[Z0][Z0] = pow(z0sigma, 2);
62  matC[T][T] = pow(tanLsigma, 2);
63  if (nHelixPar_ == 5) { // fit without d0 constraint
64  matC[D0][D0] = pow(d0Sigma, 2);
65  }
66  return matC;
67  }
68 
69  /* Stub position measurements in (phi,z) */
70 
71  TVectorD KFParamsComb::vectorM(const Stub* stub) const {
72  TVectorD meas(2);
73  meas[PHI] = reco::deltaPhi(stub->phi(), sectorPhi());
74  meas[Z] = stub->z();
75  return meas;
76  }
77 
78  // Stub position resolution in (phi,z)
79 
80  TMatrixD KFParamsComb::matrixV(const Stub* stub, const KalmanState* state) const {
81  // Take Pt from input track candidate as more stable.
82  double inv2R = (settings_->invPtToInvR()) * 0.5 * state->candidate().qOverPt();
83  double inv2R2 = inv2R * inv2R;
84 
85  double tanl = state->vectorX()(T); // factor of 0.9 improves rejection
86  double tanl2 = tanl * tanl;
87 
88  double vphi(0);
89  double vz(0);
90  double vcorr(0);
91 
92  double a = stub->sigmaPerp() * stub->sigmaPerp();
93  double b = stub->sigmaPar() * stub->sigmaPar();
94  double r2 = stub->r() * stub->r();
95  double invr2 = 1. / r2;
96 
97  // Scattering term scaling as 1/Pt.
98  double sigmaScat = settings_->kalmanMultiScattTerm() / (state->candidate().pt());
99  double sigmaScat2 = sigmaScat * sigmaScat;
100 
101  if (stub->barrel()) {
102  vphi = (a * invr2) + sigmaScat2;
103 
104  if (stub->tiltedBarrel()) {
105  // Convert uncertainty in (r,phi) to (z,phi).
106  float scaleTilted = 1.;
107  if (settings_->kalmanHOtilted()) {
108  if (settings_->useApproxB()) { // Simple firmware approximation
109  scaleTilted = approxB(stub->z(), stub->r());
110  } else { // Exact C++ implementation.
111  float tilt = stub->tiltAngle();
112  scaleTilted = sin(tilt) + cos(tilt) * tanl;
113  }
114  }
115  float scaleTilted2 = scaleTilted * scaleTilted;
116  // This neglects the non-radial strip effect, assumed negligeable for PS.
117  vz = b * scaleTilted2;
118  } else {
119  vz = b;
120  }
121 
122  if (settings_->kalmanHOfw()) {
123  // Use approximation corresponding to current firmware.
124  vz = b;
125  }
126 
127  } else {
128  vphi = a * invr2 + sigmaScat2;
129  vz = (b * tanl2);
130 
131  if (not stub->psModule()) { // Neglect these terms in PS
132  double beta = 0.;
133  // Add correlation term related to conversion of stub residuals from (r,phi) to (z,phi).
134  if (settings_->kalmanHOprojZcorr() == 2)
135  beta += -inv2R;
136  // Add alpha correction for non-radial 2S endcap strips..
137  if (settings_->kalmanHOalpha() == 2)
138  beta += -stub->alpha(); // alpha is 0 except in endcap 2S disks
139 
140  double beta2 = beta * beta;
141  vphi += b * beta2;
142  vcorr = b * (beta * tanl);
143 
144  if (settings_->kalmanHOfw()) {
145  // Use approximation corresponding to current firmware.
146  vphi = (a * invr2) + (b * inv2R2) + sigmaScat2;
147  vcorr = 0.;
148  vz = (b * tanl2);
149  }
150  }
151  }
152 
153  TMatrixD matV(2, 2);
154  matV(PHI, PHI) = vphi;
155  matV(Z, Z) = vz;
156  matV(PHI, Z) = vcorr;
157  matV(Z, PHI) = vcorr;
158 
159  return matV;
160  }
161 
162  /* The Kalman measurement matrix = derivative of helix intercept w.r.t. helix params */
163  /* Here I always measure phi(r), and z(r) */
164 
165  TMatrixD KFParamsComb::matrixH(const Stub* stub) const {
166  TMatrixD matH(2, nHelixPar_);
167  double r = stub->r();
168  matH(PHI, INV2R) = -r;
169  matH(PHI, PHI0) = 1;
170  if (nHelixPar_ == 5) { // fit without d0 constraint
171  matH(PHI, D0) = -1. / r;
172  }
173  matH(Z, Z0) = 1;
174  matH(Z, T) = r;
175  return matH;
176  }
177 
178  /* Kalman helix ref point extrapolation matrix */
179 
180  TMatrixD KFParamsComb::matrixF(const Stub* stub, const KalmanState* state) const {
181  const TMatrixD unitMatrix(TMatrixD::kUnit, TMatrixD(nHelixPar_, nHelixPar_));
182  return unitMatrix;
183  }
184 
185  /* Get physical helix params */
186 
187  TVectorD KFParamsComb::trackParams(const KalmanState* state) const {
188  TVectorD vecX = state->vectorX();
189  TVectorD vecY(nHelixPar_);
190  vecY[QOVERPT] = 2. * vecX[INV2R] / settings_->invPtToInvR();
191  vecY[PHI0] = reco::deltaPhi(vecX[PHI0] + sectorPhi(), 0.);
192  vecY[Z0] = vecX[Z0];
193  vecY[T] = vecX[T];
194  if (nHelixPar_ == 5) { // fit without d0 constraint
195  vecY[D0] = vecX[D0];
196  }
197  return vecY;
198  }
199 
200  /* If using 5 param helix fit, get track params with beam-spot constraint & track fit chi2 from applying it. */
201  /* (N.B. chi2rz unchanged by constraint) */
202 
203  TVectorD KFParamsComb::trackParams_BeamConstr(const KalmanState* state, double& chi2rphi) const {
204  if (nHelixPar_ == 5) { // fit without d0 constraint
205  TVectorD vecX = state->vectorX();
206  TMatrixD matC = state->matrixC();
207  TVectorD vecY(nHelixPar_);
208  double delChi2rphi = (vecX[D0] * vecX[D0]) / matC[D0][D0];
209  chi2rphi = state->chi2rphi() + delChi2rphi;
210  // Apply beam-spot constraint to helix params in transverse plane only, as most sensitive to it.
211  vecX[INV2R] -= vecX[D0] * (matC[INV2R][D0] / matC[D0][D0]);
212  vecX[PHI0] -= vecX[D0] * (matC[PHI0][D0] / matC[D0][D0]);
213  vecX[D0] = 0.0;
214  vecY[QOVERPT] = 2. * vecX[INV2R] / settings_->invPtToInvR();
215  vecY[PHI0] = reco::deltaPhi(vecX[PHI0] + sectorPhi(), 0.);
216  vecY[Z0] = vecX[Z0];
217  vecY[T] = vecX[T];
218  vecY[D0] = vecX[D0];
219  return vecY;
220  } else {
221  return (this->trackParams(state));
222  }
223  }
224 
225  /* Check if helix state passes cuts */
226 
228  // Set cut values that are different for 4 & 5 param helix fits.
229  vector<double> kfLayerVsZ0Cut = (nHelixPar_ == 5) ? kfLayerVsZ0Cut5_ : kfLayerVsZ0Cut4_;
230  vector<double> kfLayerVsChiSqCut = (nHelixPar_ == 5) ? kfLayerVsChiSq5_ : kfLayerVsChiSq4_;
231 
232  unsigned nStubLayers = state.nStubLayers();
233  bool goodState(true);
234 
235  TVectorD vecY = trackParams(&state);
236  double qOverPt = vecY[QOVERPT];
237  double pt = std::abs(1 / qOverPt);
238  double z0 = std::abs(vecY[Z0]);
239 
240  // state parameter selections
241 
242  if (z0 > kfLayerVsZ0Cut[nStubLayers])
243  goodState = false;
244  if (pt < settings_->houghMinPt() - kfLayerVsPtToler_[nStubLayers])
245  goodState = false;
246  if (nHelixPar_ == 5) { // fit without d0 constraint
247  double d0 = std::abs(state.vectorX()[D0]);
248  if (d0 > kfLayerVsD0Cut5_[nStubLayers])
249  goodState = false;
250  }
251 
252  // chi2 selection
253 
254  double chi2scaled = state.chi2scaled(); // chi2(r-phi) scaled down to improve electron performance.
255 
256  if (chi2scaled > kfLayerVsChiSqCut[nStubLayers])
257  goodState = false; // No separate pT selection needed
258 
259  const bool countUpdateCalls = false; // Print statement to count calls to Updator.
260 
261  if (countUpdateCalls || (settings_->kalmanDebugLevel() >= 2 && tpa_ != nullptr) ||
262  (settings_->kalmanDebugLevel() >= 2 && settings_->hybrid())) {
263  std::stringstream text;
264  text << std::fixed << std::setprecision(4);
265  if (not goodState)
266  text << "State veto:";
267  if (goodState)
268  text << "State kept:";
269  text << " nlay=" << nStubLayers << " nskip=" << state.nSkippedLayers() << " chi2_scaled=" << chi2scaled;
270  if (tpa_ != nullptr)
271  text << " pt(mc)=" << tpa_->pt();
272  text << " pt=" << pt << " q/pt=" << qOverPt << " tanL=" << vecY[T] << " z0=" << vecY[Z0]
273  << " phi0=" << vecY[PHI0];
274  if (nHelixPar_ == 5) // fit without d0 constraint
275  text << " d0=" << vecY[D0];
276  text << " fake" << (tpa_ == nullptr);
277  if (tpa_ != nullptr)
278  text << " pt(mc)=" << tpa_->pt();
279  PrintL1trk() << text.str();
280  }
281 
282  return goodState;
283  }
284 
285 } // namespace tmtt
TVectorD trackParams(const KalmanState *state) const override
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
const L1track3D & candidate() const
Definition: KalmanState.h:59
float phi0() const override
Definition: L1track3D.h:158
kfLayerVsChiSq4_({999., 999., 10., 30., 80., 120., 160.})
bool kalmanHOtilted() const
Definition: Settings.h:329
TMatrixD matrixF(const Stub *stub, const KalmanState *state) const override
float alpha() const
Definition: Stub.h:119
const TMatrixD & matrixC() const
Definition: KalmanState.h:51
float z0() const
Definition: L1track3D.h:159
float sigmaPerp() const
Definition: Stub.h:189
float qOverPt() const override
Definition: L1track3D.h:149
kfLayerVsD0Cut5_({999., 999., 999., 10., 10., 10., 10.})
bool tiltedBarrel() const
Definition: Stub.h:203
bool hybrid() const
Definition: Settings.h:409
float sigmaPar() const
Definition: Stub.h:191
double sectorPhi() const
Definition: KFbase.h:124
double invPtToInvR() const
Definition: Settings.h:395
double chi2scaled() const
Definition: KalmanState.h:62
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
kfLayerVsPtToler_({999., 999., 0.1, 0.1, 0.05, 0.05, 0.05})
float tiltAngle() const
Definition: Stub.h:184
bool useApproxB() const
Definition: Settings.h:103
std::vector< double > kfLayerVsZ0Cut5_
Definition: KFParamsComb.h:47
TMatrixD matrixH(const Stub *stub) const override
kfLayerVsZ0Cut4_({999., 999., 15., 15., 15., 15., 15.})
unsigned kalmanDebugLevel() const
Definition: Settings.h:297
std::vector< double > kfLayerVsChiSq4_
Definition: KFParamsComb.h:50
bool barrel() const
Definition: Stub.h:201
TVectorD trackParams_BeamConstr(const KalmanState *state, double &chi2rphi) const override
unsigned nSkippedLayers() const
Definition: KalmanState.h:43
TVectorD vectorM(const Stub *stub) const override
Definition: KFParamsComb.cc:71
float phi() const
Definition: Stub.h:107
double chi2rphi() const
Definition: KalmanState.h:63
std::vector< double > kfLayerVsPtToler_
Definition: KFParamsComb.h:45
bool isGoodState(const KalmanState &state) const override
float d0() const
Definition: L1track3D.h:157
std::vector< double > kfLayerVsChiSq5_
Definition: KFParamsComb.h:49
const TP * tpa_
Definition: KFbase.h:165
std::vector< double > kfLayerVsZ0Cut4_
Definition: KFParamsComb.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float tanLambda() const
Definition: L1track3D.h:160
tuple text
Definition: runonSM.py:43
kfLayerVsChiSq5_({999., 999., 10., 30., 80., 120., 160.})
const Settings * settings_
float r() const
Definition: Stub.h:108
float pt() const
Definition: TP.h:48
unsigned int kalmanHOalpha() const
Definition: Settings.h:333
TMatrixD seedC(const L1track3D &l1track3D) const override
Definition: KFParamsComb.cc:44
static constexpr float d0
unsigned nStubLayers() const
Definition: KalmanState.h:65
float z() const
Definition: Stub.h:109
double b
Definition: hdecay.h:118
bool psModule() const
Definition: Stub.h:196
const TVectorD & vectorX() const
Definition: KalmanState.h:49
unsigned nHelixPar_
Definition: KFbase.h:153
double a
Definition: hdecay.h:119
double kalmanMultiScattTerm() const
Definition: Settings.h:324
unsigned int kalmanHOprojZcorr() const
Definition: Settings.h:335
float pt() const
Definition: L1track3D.h:153
long double T
kfLayerVsZ0Cut5_({999., 999., 25.5, 25.5, 25.5, 25.5, 25.5})
TVectorD seedX(const L1track3D &l1track3D) const override
Definition: KFParamsComb.cc:29
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
TMatrixD matrixV(const Stub *stub, const KalmanState *state) const override
Definition: KFParamsComb.cc:80
float approxB(float z, float r) const
Definition: KFbase.cc:899
bool kalmanHOfw() const
Definition: Settings.h:337
std::vector< double > kfLayerVsD0Cut5_
Definition: KFParamsComb.h:46