Changeset 0b8551f in git for external/TrackCovariance/TrkUtil.cc
- Timestamp:
- Nov 29, 2021, 4:04:38 PM (3 years ago)
- Branches:
- master
- Children:
- 0c0c9af
- Parents:
- 9a7ea36 (diff), bd376e3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Michele Selvaggi <michele.selvaggi@…> (11/29/21 16:04:38)
- git-committer:
- GitHub <noreply@…> (11/29/21 16:04:38)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
external/TrackCovariance/TrkUtil.cc
r9a7ea36 r0b8551f 3 3 #include <algorithm> 4 4 #include <TSpline.h> 5 #include <TDecompChol.h> 5 6 6 7 // Constructor … … 33 34 fZmin = 0.0; // Lower DCH z 34 35 fZmax = 0.0; // Higher DCH z 36 } 37 // 38 // Distance between two lines 39 // 40 void TrkUtil::LineDistance(TVector3 x0, TVector3 y0, TVector3 dirx, TVector3 diry, Double_t &sx, Double_t &sy, Double_t &distance) 41 { 42 TMatrixDSym M(2); 43 M(0,0) = dirx.Mag2(); 44 M(1,1) = diry.Mag2(); 45 M(0,1) = -dirx.Dot(diry); 46 M(1,0) = M(0,1); 47 M.Invert(); 48 TVectorD c(2); 49 c(0) = dirx.Dot(y0-x0); 50 c(1) = diry.Dot(x0-y0); 51 TVectorD st = M*c; 52 // 53 // Fill output 54 sx = st(0); 55 sy = st(1); 56 // 57 TVector3 x = x0+sx*dirx; 58 TVector3 y = y0+sy*diry; 59 TVector3 d = x-y; 60 distance = d.Mag(); 61 } 62 // 63 // Covariance smearing 64 // 65 TVectorD TrkUtil::CovSmear(TVectorD x, TMatrixDSym C) 66 { 67 // 68 // Check arrays 69 // 70 // Consistency of dimensions 71 Int_t Nvec = x.GetNrows(); 72 Int_t Nmat = C.GetNrows(); 73 if (Nvec != Nmat || Nvec == 0) 74 { 75 std::cout << "TrkUtil::CovSmear: vector/matrix mismatch. Aborting." << std::endl; 76 exit(EXIT_FAILURE); 77 } 78 // Positive diagonal elements 79 for (Int_t i = 0; i < Nvec; i++) 80 { 81 if (C(i, i) <= 0.0) 82 { 83 std::cout << "TrkUtil::CovSmear: covariance matrix has negative diagonal elements. Aborting." << std::endl; 84 exit(EXIT_FAILURE); 85 } 86 } 87 // 88 // Do a Choleski decomposition and random number extraction, with appropriate stabilization 89 // 90 TMatrixDSym CvN = C; 91 TMatrixDSym DCv(Nvec); DCv.Zero(); 92 TMatrixDSym DCvInv(Nvec); DCvInv.Zero(); 93 for (Int_t id = 0; id < Nvec; id++) 94 { 95 Double_t dVal = TMath::Sqrt(C(id, id)); 96 DCv(id, id) = dVal; 97 DCvInv(id, id) = 1.0 / dVal; 98 } 99 CvN.Similarity(DCvInv); // Normalize diagonal to 1 100 TDecompChol Chl(CvN); 101 Bool_t OK = Chl.Decompose(); // Choleski decomposition of normalized matrix 102 if (!OK) 103 { 104 std::cout << "TrkUtil::CovSmear: covariance matrix is not positive definite. Aborting." << std::endl; 105 exit(EXIT_FAILURE); 106 } 107 TMatrixD U = Chl.GetU(); // Get Upper triangular matrix 108 TMatrixD Ut(TMatrixD::kTransposed, U); // Transposed of U (lower triangular) 109 TVectorD r(Nvec); 110 for (Int_t i = 0; i < Nvec; i++)r(i) = gRandom->Gaus(0.0, 1.0); // Array of normal random numbers 111 TVectorD xOut = x + DCv * (Ut * r); // Observed parameter vector 112 // 113 return xOut; 35 114 } 36 115 // … … 48 127 Double_t r2 = x(0) * x(0) + x(1) * x(1); 49 128 Double_t cross = x(0) * p(1) - x(1) * p(0); 50 Double_t T = sqrt(pt * pt - 2 * a * cross + a * a * r2);51 Double_t phi0 = atan2((p(1) - a * x(0)) / T, (p(0) + a * x(1)) / T); // Phi0129 Double_t T = TMath::Sqrt(pt * pt - 2 * a * cross + a * a * r2); 130 Double_t phi0 = TMath::ATan2((p(1) - a * x(0)) / T, (p(0) + a * x(1)) / T); // Phi0 52 131 Double_t D; // Impact parameter D 53 132 if (pt < 10.0) D = (T - pt) / a; … … 58 137 Par(2) = C; // Store C 59 138 //Longitudinal parameters 60 Double_t B = C * sqrt(TMath::Max(r2 - D * D, 0.0) / (1 + 2 * C * D));61 Double_t st = asin(B) / C;139 Double_t B = C * TMath::Sqrt(TMath::Max(r2 - D * D, 0.0) / (1 + 2 * C * D)); 140 Double_t st = TMath::ASin(B) / C; 62 141 Double_t ct = p(2) / pt; 63 142 Double_t z0; … … 235 314 // 236 315 return Cmm; 316 }// 317 // Regularized symmetric matrix inversion 318 // 319 TMatrixDSym TrkUtil::RegInv(TMatrixDSym& Min) 320 { 321 TMatrixDSym M = Min; // Decouple from input 322 Int_t N = M.GetNrows(); // Matrix size 323 TMatrixDSym D(N); D.Zero(); // Normaliztion matrix 324 TMatrixDSym R(N); // Normarized matrix 325 TMatrixDSym Rinv(N); // Inverse of R 326 TMatrixDSym Minv(N); // Inverse of M 327 // 328 // Check for 0's and normalize 329 for (Int_t i = 0; i < N; i++) 330 { 331 if (M(i, i) != 0.0) D(i, i) = 1. / TMath::Sqrt(TMath::Abs(M(i, i))); 332 else D(i, i) = 1.0; 333 } 334 R = M.Similarity(D); 335 // 336 // Recursive algorithms stops when N = 2 337 // 338 //**************** 339 // case N = 2 *** 340 //**************** 341 if (N == 2) 342 { 343 Double_t det = R(0, 0) * R(1, 1) - R(0, 1) * R(1, 0); 344 if (det == 0) 345 { 346 std::cout << "VertexFit::RegInv: null determinant for N = 2" << std::endl; 347 Rinv.Zero(); // Return null matrix 348 } 349 else 350 { 351 // invert matrix 352 Rinv(0, 0) = R(1, 1); 353 Rinv(0, 1) = -R(0, 1); 354 Rinv(1, 0) = Rinv(0, 1); 355 Rinv(1, 1) = R(0, 0); 356 Rinv *= 1. / det; 357 } 358 } 359 //**************** 360 // case N > 2 *** 361 //**************** 362 else 363 { 364 // Break up matrix 365 TMatrixDSym Q = R.GetSub(0, N - 2, 0, N - 2); // Upper left 366 TVectorD p(N - 1); 367 for (Int_t i = 0; i < N - 1; i++)p(i) = R(N - 1, i); 368 Double_t q = R(N - 1, N - 1); 369 //Invert pieces and re-assemble 370 TMatrixDSym Ainv(N - 1); 371 TMatrixDSym A(N - 1); 372 if (TMath::Abs(q) > 1.0e-15) 373 { 374 // Case |q| > 0 375 Ainv.Rank1Update(p, -1.0 / q); 376 Ainv += Q; 377 A = RegInv(Ainv); // Recursive call 378 TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A; 379 // 380 TVectorD b = (-1.0 / q) * (A * p); 381 for (Int_t i = 0; i < N - 1; i++) 382 { 383 Rinv(N - 1, i) = b(i); 384 Rinv(i, N - 1) = b(i); 385 } 386 // 387 Double_t pdotb = 0.; 388 for (Int_t i = 0; i < N - 1; i++)pdotb += p(i) * b(i); 389 Double_t c = (1.0 - pdotb) / q; 390 Rinv(N - 1, N - 1) = c; 391 } 392 else 393 { 394 // case q = 0 395 TMatrixDSym Qinv = RegInv(Q); // Recursive call 396 Double_t a = Qinv.Similarity(p); 397 Double_t c = -1.0 / a; 398 Rinv(N - 1, N - 1) = c; 399 // 400 TVectorD b = (1.0 / a) * (Qinv * p); 401 for (Int_t i = 0; i < N - 1; i++) 402 { 403 Rinv(N - 1, i) = b(i); 404 Rinv(i, N - 1) = b(i); 405 } 406 // 407 A.Rank1Update(p, -1 / a); 408 A += Q; 409 A.Similarity(Qinv); 410 TMatrixDSub(Rinv, 0, N - 2, 0, N - 2) = A; 411 } 412 } 413 Minv = Rinv.Similarity(D); 414 return Minv; 415 } 416 // 417 // Track tracjectory 418 // 419 TVector3 TrkUtil::Xtrack(TVectorD par, Double_t s) 420 { 421 // 422 // unpack parameters 423 Double_t D = par(0); 424 Double_t p0 = par(1); 425 Double_t C = par(2); 426 Double_t z0 = par(3); 427 Double_t ct = par(4); 428 // 429 Double_t x = -D * TMath::Sin(p0) + (TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C); 430 Double_t y = D * TMath::Cos(p0) - (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C); 431 Double_t z = z0 + ct * s / (2 * C); 432 // 433 TVector3 Xt(x, y, z); 434 return Xt; 435 } 436 // 437 // Track derivatives 438 // 439 // Constant radius 440 // R-Phi 441 TVectorD TrkUtil::derRphi_R(TVectorD par, Double_t R) 442 { 443 TVectorD dRphi(5); // return vector 444 // 445 // unpack parameters 446 Double_t D = par(0); 447 Double_t C = par(2); 448 // 449 Double_t s = 2 * TMath::ASin(C * TMath::Sqrt((R * R - D * D)/(1 + 2 * C * D))); 450 TVector3 X = Xtrack(par, s); // Intersection point 451 TVector3 v(-X.y()/R, X.x()/R, 0.); // measurement direction 452 TMatrixD derX = derXdPar(par, s); // dX/dp 453 TVectorD derXs = derXds(par, s); // dX/ds 454 TVectorD ders = dsdPar_R(par, R); // ds/dp 455 // 456 for (Int_t i = 0; i < 5; i++) 457 { 458 dRphi(i) = 0.; 459 for (Int_t j = 0; j < 3; j++) 460 { 461 dRphi(i) += v(j) * (derX(j, i) + derXs(j) * ders(i)); 462 } 463 } 464 // 465 return dRphi; 466 } 467 // z 468 TVectorD TrkUtil::derZ_R(TVectorD par, Double_t R) 469 { 470 471 TVectorD dZ(5); // return vector 472 // 473 // unpack parameters 474 Double_t D = par(0); 475 Double_t C = par(2); 476 // 477 Double_t s = 2 * TMath::ASin(C * TMath::Sqrt((R * R - D * D)/(1 + 2 * C * D))); // phase 478 TVector3 v(0., 0., 1.); // measurement direction 479 TMatrixD derX = derXdPar(par, s); // dX/dp 480 TVectorD derXs = derXds(par, s); // dX/ds 481 TVectorD ders = dsdPar_R(par, R); // ds/dp 482 // 483 for (Int_t i = 0; i < 5; i++) 484 { 485 dZ(i) = 0.; 486 for (Int_t j = 0; j < 3; j++) 487 { 488 dZ(i) += v(j) * (derX(j, i) + derXs(j) * ders(i)); 489 } 490 } 491 // 492 return dZ; 493 } 494 // 495 // constant z 496 // R-Phi 497 TVectorD TrkUtil::derRphi_Z(TVectorD par, Double_t z) 498 { 499 TVectorD dRphi(5); // return vector 500 // 501 // unpack parameters 502 Double_t C = par(2); 503 Double_t z0 = par(3); 504 Double_t ct = par(4); 505 // 506 Double_t s = 2 * C * (z - z0) / ct; 507 TVector3 X = Xtrack(par, s); // Intersection point 508 TVector3 v(-X.y() / X.Pt(), X.x() / X.Pt(), 0.); // measurement direction 509 TMatrixD derX = derXdPar(par, s); // dX/dp 510 TVectorD derXs = derXds(par, s); // dX/ds 511 TVectorD ders = dsdPar_z(par, z); // ds/dp 512 // 513 for (Int_t i = 0; i < 5; i++) 514 { 515 dRphi(i) = 0.; 516 for (Int_t j = 0; j < 3; j++) 517 { 518 dRphi(i) += v(j) * (derX(j, i) + derXs(j) * ders(i)); 519 } 520 } 521 // 522 return dRphi; 523 524 } 525 // R 526 TVectorD TrkUtil::derR_Z(TVectorD par, Double_t z) 527 { 528 TVectorD dR(5); // return vector 529 // 530 // unpack parameters 531 Double_t C = par(2); 532 Double_t z0 = par(3); 533 Double_t ct = par(4); 534 // 535 Double_t s = 2 * C * (z - z0) / ct; 536 TVector3 X = Xtrack(par, s); // Intersection point 537 TVector3 v(X.x() / X.Pt(), X.y() / X.Pt(), 0.); // measurement direction 538 TMatrixD derX = derXdPar(par, s); // dX/dp 539 TVectorD derXs = derXds(par, s); // dX/ds 540 TVectorD ders = dsdPar_z(par, z); // ds/dp 541 // 542 for (Int_t i = 0; i < 5; i++) 543 { 544 dR(i) = 0.; 545 for (Int_t j = 0; j < 3; j++) 546 { 547 dR(i) += v(j) * (derX(j, i) + derXs(j) * ders(i)); 548 } 549 } 550 // 551 return dR; 552 553 } 554 // 555 // derivatives of track trajectory 556 // 557 // dX/dPar 558 TMatrixD TrkUtil::derXdPar(TVectorD par, Double_t s) 559 { 560 TMatrixD dxdp(3, 5); // return matrix 561 // 562 // unpack parameters 563 Double_t D = par(0); 564 Double_t p0 = par(1); 565 Double_t C = par(2); 566 Double_t z0 = par(3); 567 Double_t ct = par(4); 568 // 569 // derivatives 570 // dx/dD 571 dxdp(0, 0) = -TMath::Sin(p0); 572 dxdp(1, 0) = TMath::Cos(p0); 573 dxdp(2, 0) = 0.; 574 // dx/dphi0 575 dxdp(0, 1) = -D * TMath::Cos(p0) + (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C); 576 dxdp(1, 1) = -D * TMath::Sin(p0) + (TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C); 577 dxdp(2, 1) = 0; 578 // dx/dC 579 dxdp(0, 2) = -(TMath::Sin(s + p0) - TMath::Sin(p0)) / (2 * C * C); 580 dxdp(1, 2) = (TMath::Cos(s + p0) - TMath::Cos(p0)) / (2 * C * C); 581 dxdp(2, 2) = -ct * s / (2 * C * C); 582 // dx/dz0 583 dxdp(0, 3) = 0; 584 dxdp(1, 3) = 0; 585 dxdp(2, 3) = 1.; 586 // dx/dCtg 587 dxdp(0, 4) = 0; 588 dxdp(1, 4) = 0; 589 dxdp(2, 4) = s / (2 * C); 590 // 591 return dxdp; 592 } 593 // 594 // dX/ds 595 // 596 TVectorD TrkUtil::derXds(TVectorD par, Double_t s) 597 { 598 TVectorD dxds(3); // return vector 599 // 600 // unpack parameters 601 Double_t p0 = par(1); 602 Double_t C = par(2); 603 Double_t ct = par(4); 604 // 605 // dX/ds 606 dxds(0) = TMath::Cos(s + p0) / (2 * C); 607 dxds(1) = TMath::Sin(s + p0) / (2 * C); 608 dxds(2) = ct / (2 * C); 609 // 610 return dxds; 611 } 612 // 613 // derivative of trajectory phase s 614 //Constant R 615 TVectorD TrkUtil::dsdPar_R(TVectorD par, Double_t R) 616 { 617 TVectorD dsdp(5); // return vector 618 // 619 // unpack parameters 620 Double_t D = par(0); 621 Double_t p0 = par(1); 622 Double_t C = par(2); 623 // 624 // derivatives 625 Double_t opCD = 1. + 2 * C * D; 626 Double_t A = C*TMath::Sqrt((R*R-D*D)/opCD); 627 Double_t sqA0 = TMath::Sqrt(1. - A * A); 628 Double_t dMin = 0.01; 629 Double_t sqA = TMath::Max(dMin, sqA0); // Protect against divergence 630 // 631 dsdp(0) = -2 * C * C * (D * (1. + C * D) + C * R * R) / (A * sqA * opCD * opCD); 632 dsdp(1) = 0; 633 dsdp(2) = 2 * A * (1 + C * D) / (C * sqA * opCD); 634 dsdp(3) = 0; 635 dsdp(4) = 0; 636 // 637 return dsdp; 638 } 639 // Constant z 640 TVectorD TrkUtil::dsdPar_z(TVectorD par, Double_t z) 641 { 642 TVectorD dsdp(5); // return vector 643 // 644 // unpack parameters 645 Double_t C = par(2); 646 Double_t z0 = par(3); 647 Double_t ct = par(4); 648 // 649 // derivatives 650 // 651 dsdp(0) = 0; 652 dsdp(1) = 0; 653 dsdp(2) = 2*(z-z0)/ct; 654 dsdp(3) = -2*C/ct; 655 dsdp(4) = -2*C*(z-z0)/(ct*ct); 656 // 657 return dsdp; 237 658 } 238 659 //
Note:
See TracChangeset
for help on using the changeset viewer.