File indexing completed on 2024-04-06 12:28:22
0001 #include "RecoTracker/MkFitCore/interface/cms_common_macros.h"
0002 #include "RecoTracker/MkFitCore/interface/Track.h"
0003 #include "Matrix.h"
0004
0005
0006 #include "Debug.h"
0007
0008 namespace mkfit {
0009
0010
0011
0012
0013
0014 void TrackState::convertFromCartesianToCCS() {
0015
0016 const float px = parameters.At(3);
0017 const float py = parameters.At(4);
0018 const float pz = parameters.At(5);
0019 const float pt = std::sqrt(px * px + py * py);
0020 const float phi = getPhi(px, py);
0021 const float theta = getTheta(pt, pz);
0022 parameters.At(3) = 1.f / pt;
0023 parameters.At(4) = phi;
0024 parameters.At(5) = theta;
0025 SMatrix66 jac = jacobianCartesianToCCS(px, py, pz);
0026 errors = ROOT::Math::Similarity(jac, errors);
0027 }
0028
0029 void TrackState::convertFromCCSToCartesian() {
0030
0031 const float invpt = parameters.At(3);
0032 const float phi = parameters.At(4);
0033 const float theta = parameters.At(5);
0034 const float pt = 1.f / invpt;
0035 float cosP = std::cos(phi);
0036 float sinP = std::sin(phi);
0037 float cosT = std::cos(theta);
0038 float sinT = std::sin(theta);
0039 parameters.At(3) = cosP * pt;
0040 parameters.At(4) = sinP * pt;
0041 parameters.At(5) = cosT * pt / sinT;
0042 SMatrix66 jac = jacobianCCSToCartesian(invpt, phi, theta);
0043 errors = ROOT::Math::Similarity(jac, errors);
0044 }
0045
0046 SMatrix66 TrackState::jacobianCCSToCartesian(float invpt, float phi, float theta) const {
0047
0048 SMatrix66 jac = ROOT::Math::SMatrixIdentity();
0049 float cosP = std::cos(phi);
0050 float sinP = std::sin(phi);
0051 float cosT = std::cos(theta);
0052 float sinT = std::sin(theta);
0053 const float pt = 1.f / invpt;
0054 jac(3, 3) = -cosP * pt * pt;
0055 jac(3, 4) = -sinP * pt;
0056 jac(4, 3) = -sinP * pt * pt;
0057 jac(4, 4) = cosP * pt;
0058 jac(5, 3) = -cosT * pt * pt / sinT;
0059 jac(5, 5) = -pt / (sinT * sinT);
0060 return jac;
0061 }
0062
0063 SMatrix66 TrackState::jacobianCartesianToCCS(float px, float py, float pz) const {
0064
0065 SMatrix66 jac = ROOT::Math::SMatrixIdentity();
0066 const float pt = std::sqrt(px * px + py * py);
0067 const float p2 = px * px + py * py + pz * pz;
0068 jac(3, 3) = -px / (pt * pt * pt);
0069 jac(3, 4) = -py / (pt * pt * pt);
0070 jac(4, 3) = -py / (pt * pt);
0071 jac(4, 4) = px / (pt * pt);
0072 jac(5, 3) = px * pz / (pt * p2);
0073 jac(5, 4) = py * pz / (pt * p2);
0074 jac(5, 5) = -pt / p2;
0075 return jac;
0076 }
0077
0078 void TrackState::convertFromGlbCurvilinearToCCS() {
0079
0080 const float px = parameters.At(3);
0081 const float py = parameters.At(4);
0082 const float pz = parameters.At(5);
0083 const float pt = std::sqrt(px * px + py * py);
0084 const float phi = getPhi(px, py);
0085 const float theta = getTheta(pt, pz);
0086 parameters.At(3) = 1.f / pt;
0087 parameters.At(4) = phi;
0088 parameters.At(5) = theta;
0089 SMatrix66 jac = jacobianCurvilinearToCCS(px, py, pz, charge);
0090 errors = ROOT::Math::Similarity(jac, errors);
0091 }
0092
0093 void TrackState::convertFromCCSToGlbCurvilinear() {
0094
0095 const float invpt = parameters.At(3);
0096 const float phi = parameters.At(4);
0097 const float theta = parameters.At(5);
0098 const float pt = 1.f / invpt;
0099 float cosP = std::cos(phi);
0100 float sinP = std::sin(phi);
0101 float cosT = std::cos(theta);
0102 float sinT = std::sin(theta);
0103 parameters.At(3) = cosP * pt;
0104 parameters.At(4) = sinP * pt;
0105 parameters.At(5) = cosT * pt / sinT;
0106 SMatrix66 jac = jacobianCCSToCurvilinear(invpt, cosP, sinP, cosT, sinT, charge);
0107 errors = ROOT::Math::Similarity(jac, errors);
0108 }
0109
0110 SMatrix66 TrackState::jacobianCCSToCurvilinear(
0111 float invpt, float cosP, float sinP, float cosT, float sinT, short charge) const {
0112 SMatrix66 jac;
0113 jac(3, 0) = -sinP;
0114 jac(4, 0) = -cosP * cosT;
0115 jac(3, 1) = cosP;
0116 jac(4, 1) = -sinP * cosT;
0117 jac(4, 2) = sinT;
0118 jac(0, 3) = charge * sinT;
0119 jac(0, 5) = charge * cosT * invpt;
0120 jac(1, 5) = -1.f;
0121 jac(2, 4) = 1.f;
0122
0123 return jac;
0124 }
0125
0126 SMatrix66 TrackState::jacobianCurvilinearToCCS(float px, float py, float pz, short charge) const {
0127 const float pt2 = px * px + py * py;
0128 const float pt = sqrt(pt2);
0129 const float invpt2 = 1.f / pt2;
0130 const float invpt = 1.f / pt;
0131 const float invp = 1.f / sqrt(pt2 + pz * pz);
0132 const float sinPhi = py * invpt;
0133 const float cosPhi = px * invpt;
0134 const float sinLam = pz * invp;
0135 const float cosLam = pt * invp;
0136
0137 SMatrix66 jac;
0138 jac(0, 3) = -sinPhi;
0139 jac(0, 4) = -sinLam * cosPhi;
0140 jac(1, 3) = cosPhi;
0141 jac(1, 4) = -sinLam * sinPhi;
0142 jac(2, 4) = cosLam;
0143 jac(3, 0) = charge / cosLam;
0144 jac(3, 1) = pz * invpt2;
0145 jac(4, 2) = 1.f;
0146 jac(5, 1) = -1.f;
0147
0148 return jac;
0149 }
0150
0151
0152
0153
0154
0155 bool TrackBase::hasSillyValues(bool dump, bool fix, const char* pref) {
0156 bool is_silly = false;
0157 for (int i = 0; i < LL; ++i) {
0158 for (int j = 0; j <= i; ++j) {
0159 if ((i == j && state_.errors.At(i, j) < 0) || !isFinite(state_.errors.At(i, j))) {
0160 if (!is_silly) {
0161 is_silly = true;
0162 if (dump)
0163 printf("%s (label=%d, pT=%f):", pref, label(), pT());
0164 }
0165 if (dump)
0166 printf(" (%d,%d)=%e", i, j, state_.errors.At(i, j));
0167 if (fix)
0168 state_.errors.At(i, j) = 0.00001;
0169 }
0170 }
0171 }
0172 if (is_silly && dump)
0173 printf("\n");
0174 return is_silly;
0175 }
0176
0177 bool TrackBase::hasNanNSillyValues() const {
0178 bool is_silly = false;
0179 for (int i = 0; i < LL; ++i) {
0180 for (int j = 0; j <= i; ++j) {
0181 if ((i == j && state_.errors.At(i, j) < 0) || !isFinite(state_.errors.At(i, j))) {
0182 is_silly = true;
0183 return is_silly;
0184 }
0185 }
0186 }
0187 return is_silly;
0188 }
0189
0190
0191 float TrackBase::d0BeamSpot(const float x_bs, const float y_bs, bool linearize) const {
0192 if (linearize) {
0193 return std::abs(std::cos(momPhi()) * (y() - y_bs) - std::sin(momPhi()) * (x() - x_bs));
0194 } else {
0195 const float k = ((charge() < 0) ? 100.0f : -100.0f) / (Const::sol * Config::Bfield);
0196 const float abs_ooc_half = std::abs(k * pT());
0197
0198 const float x_center = x() - k * py();
0199 const float y_center = y() + k * px();
0200 return std::hypot(x_center - x_bs, y_center - y_bs) - abs_ooc_half;
0201 }
0202 }
0203 float TrackBase::swimPhiToR(const float x0, const float y0) const {
0204 const float dR = getHypot(x() - x0, y() - y0);
0205
0206
0207 const float v = dR / 176.f / pT() * charge();
0208 const float dPhi = std::abs(v) <= 1.0f ? 2.f * std::asin(v) : Const::PI;
0209 ;
0210 return squashPhiGeneral(momPhi() - dPhi);
0211 }
0212
0213 bool TrackBase::canReachRadius(float R) const {
0214 const float k = ((charge() < 0) ? 100.0f : -100.0f) / (Const::sol * Config::Bfield);
0215 const float ooc = 2.0f * k * pT();
0216 return std::abs(ooc) > R - std::hypot(x(), y());
0217 }
0218
0219 float TrackBase::maxReachRadius() const {
0220 const float k = ((charge() < 0) ? 100.0f : -100.0f) / (Const::sol * Config::Bfield);
0221 const float abs_ooc_half = std::abs(k * pT());
0222
0223 const float x_center = x() - k * py();
0224 const float y_center = y() + k * px();
0225 return std::hypot(x_center, y_center) + abs_ooc_half;
0226 }
0227
0228 float TrackBase::zAtR(float R, float* r_reached) const {
0229 float xc = x();
0230 float yc = y();
0231 float pxc = px();
0232 float pyc = py();
0233
0234 const float ipt = invpT();
0235 const float kinv = ((charge() < 0) ? 0.01f : -0.01f) * Const::sol * Config::Bfield;
0236 const float k = 1.0f / kinv;
0237
0238 const float c = 0.5f * kinv * ipt;
0239 const float ooc = 1.0f / c;
0240 const float lambda = pz() * ipt;
0241
0242
0243
0244
0245 float D = 0;
0246
0247 for (int i = 0; i < Config::Niter; ++i) {
0248
0249
0250 float r0 = std::hypot(xc, yc);
0251 float td = (R - r0) * c;
0252 float id = ooc * td * (1.0f + 0.16666666f * td * td);
0253
0254
0255 D += id;
0256
0257
0258
0259
0260 float cosa = std::cos(id * ipt * kinv);
0261 float sina = std::sin(id * ipt * kinv);
0262
0263
0264 xc += k * (pxc * sina - pyc * (1.0f - cosa));
0265 yc += k * (pyc * sina + pxc * (1.0f - cosa));
0266
0267 const float pxo = pxc;
0268 pxc = pxc * cosa - pyc * sina;
0269 pyc = pyc * cosa + pxo * sina;
0270 }
0271
0272 if (r_reached)
0273 *r_reached = std::hypot(xc, yc);
0274
0275 return z() + lambda * D;
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 }
0304
0305 float TrackBase::rAtZ(float Z) const {
0306 float xc = x();
0307 float yc = y();
0308 float pxc = px();
0309 float pyc = py();
0310
0311 const float ipt = invpT();
0312 const float kinv = ((charge() < 0) ? 0.01f : -0.01f) * Const::sol * Config::Bfield;
0313 const float k = 1.0f / kinv;
0314
0315 const float dz = Z - z();
0316 const float alpha = dz * ipt * kinv * std::tan(theta());
0317
0318 const float cosa = std::cos(alpha);
0319 const float sina = std::sin(alpha);
0320
0321 xc += k * (pxc * sina - pyc * (1.0f - cosa));
0322 yc += k * (pyc * sina + pxc * (1.0f - cosa));
0323
0324
0325
0326
0327
0328 return std::hypot(xc, yc);
0329 }
0330
0331 const char* TrackBase::algoint_to_cstr(int algo) {
0332 static const char* const names[] = {"undefAlgorithm",
0333 "ctf",
0334 "duplicateMerge",
0335 "cosmics",
0336 "initialStep",
0337 "lowPtTripletStep",
0338 "pixelPairStep",
0339 "detachedTripletStep",
0340 "mixedTripletStep",
0341 "pixelLessStep",
0342 "tobTecStep",
0343 "jetCoreRegionalStep",
0344 "conversionStep",
0345 "muonSeededStepInOut",
0346 "muonSeededStepOutIn",
0347 "outInEcalSeededConv",
0348 "inOutEcalSeededConv",
0349 "nuclInter",
0350 "standAloneMuon",
0351 "globalMuon",
0352 "cosmicStandAloneMuon",
0353 "cosmicGlobalMuon",
0354 "highPtTripletStep",
0355 "lowPtQuadStep",
0356 "detachedQuadStep",
0357 "reservedForUpgrades1",
0358 "reservedForUpgrades2",
0359 "bTagGhostTracks",
0360 "beamhalo",
0361 "gsf",
0362 "hltPixel",
0363 "hltIter0",
0364 "hltIter1",
0365 "hltIter2",
0366 "hltIter3",
0367 "hltIter4",
0368 "hltIterX",
0369 "hiRegitMuInitialStep",
0370 "hiRegitMuLowPtTripletStep",
0371 "hiRegitMuPixelPairStep",
0372 "hiRegitMuDetachedTripletStep",
0373 "hiRegitMuMixedTripletStep",
0374 "hiRegitMuPixelLessStep",
0375 "hiRegitMuTobTecStep",
0376 "hiRegitMuMuonSeededStepInOut",
0377 "hiRegitMuMuonSeededStepOutIn",
0378 "algoSize"};
0379
0380 if (algo < 0 || algo >= (int)TrackAlgorithm::algoSize)
0381 return names[0];
0382 return names[algo];
0383 }
0384
0385
0386
0387
0388
0389 void Track::resizeHitsForInput() {
0390 bzero(&hitsOnTrk_, sizeof(hitsOnTrk_));
0391 hitsOnTrk_.resize(lastHitIdx_ + 1);
0392 }
0393
0394 void Track::sortHitsByLayer() {
0395 std::stable_sort(&hitsOnTrk_[0], &hitsOnTrk_[lastHitIdx_ + 1], [](const auto& h1, const auto& h2) {
0396 return h1.layer < h2.layer;
0397 });
0398 }
0399
0400
0401
0402 void print(const TrackState& s) {
0403 std::cout << " x: " << s.parameters[0] << " y: " << s.parameters[1] << " z: " << s.parameters[2] << std::endl
0404 << " px: " << s.parameters[3] << " py: " << s.parameters[4] << " pz: " << s.parameters[5] << std::endl
0405 << "valid: " << s.valid << " errors: " << std::endl;
0406 dumpMatrix(s.errors);
0407 std::cout << std::endl;
0408 }
0409
0410 void print(std::string pfx, int itrack, const Track& trk, bool print_hits) {
0411 std::cout << std::endl
0412 << pfx << ": " << itrack << " hits: " << trk.nFoundHits() << " label: " << trk.label() << " State"
0413 << std::endl;
0414 print(trk.state());
0415 if (print_hits) {
0416 for (int i = 0; i < trk.nTotalHits(); ++i)
0417 printf(" %2d: lyr %2d idx %d\n", i, trk.getHitLyr(i), trk.getHitIdx(i));
0418 }
0419 }
0420
0421 void print(std::string pfx, const TrackState& s) {
0422 std::cout << pfx << std::endl;
0423 print(s);
0424 }
0425
0426 }