12 #include "cetlib_except/exception.h" 51 const std::shared_ptr<const Surface>& psurf,
59 std::optional<double> result{std::nullopt};
65 if (to == 0)
return result;
66 double x02 = to->
x0();
67 double y02 = to->
y0();
68 double z02 = to->
z0();
69 double phi2 = to->
phi();
86 TrackMatrix* plocal_prop_matrix = (prop_matrix == 0 ? 0 : &local_prop_matrix);
87 std::optional<double> result1 =
origin_vec_prop(trk, psurf, plocal_prop_matrix);
88 if (!result1)
return result1;
95 <<
"Track state vector has wrong size" << vec.size() <<
"\n";
98 double phid1 = vec(2);
100 double pinv = vec(4);
104 double sinphid1 = std::sin(phid1);
105 double cosphid1 = std::cos(phid1);
106 double sh1 = std::sinh(eta1);
107 double ch1 = std::cosh(eta1);
108 double sinphi2 = std::sin(phi2);
109 double cosphi2 = std::cos(phi2);
113 double u1 = -r1 * sinphid1;
114 double w1 = r1 * cosphid1;
118 double u2 = x01 - x02 + u1;
119 double v2 = (y01 - y02) * cosphi2 + (z01 - z02) * sinphi2 + v1;
120 double w2 = -(y01 - y02) * sinphi2 + (z01 - z02) * cosphi2 + w1;
124 double r2 = w2 * cosphid1 - u2 * sinphid1;
128 double d2 = -(w2 * sinphid1 + u2 * cosphid1);
133 double v2p = v2 + d2 * sh1;
157 auto pinv2 = std::make_optional(pinv);
159 double* pderiv = (prop_matrix != 0 ? &deriv : 0);
172 result = std::make_optional(s);
176 if (prop_matrix != 0) {
178 pm.resize(vec.size(), vec.size(),
false);
195 pm(1, 2) = -r2 * sh1;
215 *prop_matrix = prod(pm, *plocal_prop_matrix);
220 if (noise_matrix != 0) {
221 noise_matrix->resize(vec.size(), vec.size(),
false);
230 noise_matrix->clear();
266 const std::shared_ptr<const Surface>& porient,
271 std::optional<double> result{std::nullopt};
283 <<
"Track state vector has wrong size" << vec.size() <<
"\n";
298 if (orient == 0)
return result;
299 double phi2 = orient->
phi();
300 std::shared_ptr<const Surface> porigin(
new SurfYZLine(x02, y02, z02, phi2));
309 double phi1 = from->phi();
314 result = std::make_optional(0.);
315 if (!ok)
return std::nullopt;
322 double phi1 = from->phi();
327 result = std::make_optional(0.);
328 if (!ok)
return std::nullopt;
335 double theta1 = from->theta();
336 double phi1 = from->phi();
341 result = std::make_optional(0.);
342 if (!ok)
return std::nullopt;
355 result = std::nullopt;
373 double sindphi = std::sin(phi2 - phi1);
374 double cosdphi = std::cos(phi2 - phi1);
379 double phid1 = vec(2);
380 double eta1 = vec(3);
385 double rvv = cosdphi;
386 double rvw = sindphi;
388 double rwv = -sindphi;
389 double rww = cosdphi;
393 double sinphid1 = std::sin(phid1);
394 double cosphid1 = std::cos(phid1);
395 double sh1 = 1. / std::cosh(eta1);
396 double th1 = std::tanh(eta1);
400 double u1 = -r1 * sinphid1;
401 double w1 = r1 * cosphid1;
405 double du2 = sh1 * cosphid1;
406 double dv2 = th1 * cosdphi + sh1 * sinphid1 * sindphi;
407 double dw2 = -th1 * sindphi + sh1 * sinphid1 * cosdphi;
408 double duw2 = std::hypot(du2, dw2);
412 double phid2 = atan2(dw2, du2);
413 double eta2 = std::asinh(dv2 / duw2);
417 if (prop_matrix != 0) {
419 pm.resize(vec.size(), vec.size(),
false);
425 double du1dr1 = -sinphid1;
426 double du1dphi1 = -w1;
428 double dw1dr1 = cosphid1;
429 double dw1dphi1 = u1;
431 double ddu1dphi1 = -sinphid1 * sh1;
432 double ddu1deta1 = -cosphid1 * sh1 * th1;
434 double ddv1deta1 = sh1 * sh1;
436 double ddw1dphi1 = cosphid1 * sh1;
437 double ddw1deta1 = -sinphid1 * sh1 * th1;
441 double du2dr1 = du1dr1;
442 double dv2dr1 = rvw * dw1dr1;
443 double dw2dr1 = rww * dw1dr1;
448 double du2dphi1 = du1dphi1;
449 double dv2dphi1 = rvw * dw1dphi1;
450 double dw2dphi1 = rww * dw1dphi1;
452 double ddu2dphi1 = ddu1dphi1;
453 double ddv2dphi1 = rvw * ddw1dphi1;
454 double ddw2dphi1 = rww * ddw1dphi1;
456 double ddu2deta1 = ddu1deta1;
457 double ddv2deta1 = rvv * ddv1deta1 + rvw * ddw1deta1;
458 double ddw2deta1 = rwv * ddv1deta1 + rww * ddw1deta1;
462 double dr2du2 = -dw2 / duw2;
463 double dr2dw2 = du2 / duw2;
465 double dphi2ddu2 = -dw2 / (duw2 * duw2);
466 double dphi2ddw2 = du2 / (duw2 * duw2);
468 double deta2ddv2 = 1. / (duw2 * duw2);
472 double dr2dr1 = dr2du2 * du2dr1 + dr2dw2 * dw2dr1;
473 double dr2dv1 = dr2dw2 * dw2dv1;
474 double dr2dphi1 = dr2du2 * du2dphi1 + dr2dw2 * dw2dphi1;
476 double dphi2dphi1 = dphi2ddu2 * ddu2dphi1 + dphi2ddw2 * ddw2dphi1;
477 double dphi2deta1 = dphi2ddu2 * ddu2deta1 + dphi2ddw2 * ddw2deta1;
479 double deta2dphi1 = deta2ddv2 * ddv2dphi1;
480 double deta2deta1 = deta2ddv2 * ddv2deta1;
492 double dsdu2 = -du2 / (duw2 * duw2);
493 double dsdw2 = -dw2 / (duw2 * duw2);
497 double dsdr1 = dsdu2 * du2dr1 + dsdw2 * dw2dr1;
498 double dsdv1 = dsdw2 * dw2dv1;
499 double dsdphi1 = dsdu2 * du2dphi1 + dsdw2 * dw2dphi1;
503 dv2dr1 += dv2 * dsdr1;
504 dv2dv1 += dv2 * dsdv1;
505 dv2dphi1 += dv2 * dsdphi1;
523 pm(2, 2) = dphi2dphi1;
524 pm(3, 2) = deta2dphi1;
529 pm(2, 3) = dphi2deta1;
530 pm(3, 3) = deta2deta1;
562 double sindphi = std::sin(phi2 - phi1);
563 double cosdphi = std::cos(phi2 - phi1);
567 double dudw1 = vec(2);
568 double dvdw1 = vec(3);
581 double rvv = cosdphi;
582 double rvw = sindphi;
584 double rwv = -sindphi;
585 double rww = cosdphi;
589 double dw1 = dirf / std::sqrt(1. + dudw1 * dudw1 + dvdw1 * dvdw1);
590 double du1 = dudw1 * dw1;
591 double dv1 = dvdw1 * dw1;
596 double dv2 = rvv * dv1 + rvw * dw1;
597 double dw2 = rwv * dv1 + rww * dw1;
598 double duw2 = std::hypot(du2, dw2);
602 double phid2 = atan2(dw2, du2);
603 double eta2 = std::asinh(dv2 / duw2);
607 if (prop_matrix != 0) {
609 pm.resize(vec.size(), vec.size(),
false);
615 double ddu1ddudw1 = (1. + dvdw1 * dvdw1) * dw1 * dw1 * dw1;
616 double ddu1ddvdw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
618 double ddv1ddudw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
619 double ddv1ddvdw1 = (1. + dudw1 * dudw1) * dw1 * dw1 * dw1;
621 double ddw1ddudw1 = -dudw1 * dw1 * dw1 * dw1;
622 double ddw1ddvdw1 = -dvdw1 * dw1 * dw1 * dw1;
629 double ddu2ddudw1 = ddu1ddudw1;
630 double ddv2ddudw1 = rvv * ddv1ddudw1 + rvw * ddw1ddudw1;
631 double ddw2ddudw1 = rwv * ddv1ddudw1 + rww * ddw1ddudw1;
633 double ddu2ddvdw1 = ddu1ddvdw1;
634 double ddv2ddvdw1 = rvv * ddv1ddvdw1 + rvw * ddw1ddvdw1;
635 double ddw2ddvdw1 = rwv * ddv1ddvdw1 + rww * ddw1ddvdw1;
639 double dr2du2 = -dw2 / duw2;
640 double dr2dw2 = du2 / duw2;
642 double dphi2ddu2 = -dw2 / (duw2 * duw2);
643 double dphi2ddw2 = du2 / (duw2 * duw2);
645 double deta2ddv2 = 1. / (duw2 * duw2);
649 double dr2du1 = dr2du2;
650 double dr2dv1 = dr2dw2 * dw2dv1;
652 double dphi2ddudw1 = dphi2ddu2 * ddu2ddudw1 + dphi2ddw2 * ddw2ddudw1;
653 double dphi2ddvdw1 = dphi2ddu2 * ddu2ddvdw1 + dphi2ddw2 * ddw2ddvdw1;
655 double deta2ddudw1 = deta2ddv2 * ddv2ddudw1;
656 double deta2ddvdw1 = deta2ddv2 * ddv2ddvdw1;
668 double dsdu2 = -du2 / (duw2 * duw2);
669 double dsdw2 = -dw2 / (duw2 * duw2);
673 double dsdu1 = dsdu2;
674 double dsdv1 = dsdw2 * dw2dv1;
678 double dv2du1 = dv2 * dsdu1;
679 dv2dv1 += dv2 * dsdv1;
697 pm(2, 2) = dphi2ddudw1;
698 pm(3, 2) = deta2ddudw1;
703 pm(2, 3) = dphi2ddvdw1;
704 pm(3, 3) = deta2ddvdw1;
737 double sinth1 = std::sin(theta1);
738 double costh1 = std::cos(theta1);
740 double sindphi = std::sin(phi2 - phi1);
741 double cosdphi = std::cos(phi2 - phi1);
745 double dudw1 = vec(2);
746 double dvdw1 = vec(3);
762 double rvu = -sinth1 * sindphi;
763 double rvv = cosdphi;
764 double rvw = costh1 * sindphi;
766 double rwu = -sinth1 * cosdphi;
767 double rwv = -sindphi;
768 double rww = costh1 * cosdphi;
772 double dw1 = dirf / std::sqrt(1. + dudw1 * dudw1 + dvdw1 * dvdw1);
773 double du1 = dudw1 * dw1;
774 double dv1 = dvdw1 * dw1;
778 double du2 = ruu * du1 + ruw * dw1;
779 double dv2 = rvu * du1 + rvv * dv1 + rvw * dw1;
780 double dw2 = rwu * du1 + rwv * dv1 + rww * dw1;
781 double duw2 = std::hypot(du2, dw2);
785 double phid2 = atan2(dw2, du2);
786 double eta2 = std::asinh(dv2 / duw2);
790 if (prop_matrix != 0) {
792 pm.resize(vec.size(), vec.size(),
false);
798 double ddu1ddudw1 = (1. + dvdw1 * dvdw1) * dw1 * dw1 * dw1;
799 double ddu1ddvdw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
801 double ddv1ddudw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
802 double ddv1ddvdw1 = (1. + dudw1 * dudw1) * dw1 * dw1 * dw1;
804 double ddw1ddudw1 = -dudw1 * dw1 * dw1 * dw1;
805 double ddw1ddvdw1 = -dvdw1 * dw1 * dw1 * dw1;
816 double ddu2ddudw1 = ruu * ddu1ddudw1 + ruw * ddw1ddudw1;
817 double ddv2ddudw1 = rvu * ddu1ddudw1 + rvv * ddv1ddudw1 + rvw * ddw1ddudw1;
818 double ddw2ddudw1 = rwu * ddu1ddudw1 + rwv * ddv1ddudw1 + rww * ddw1ddudw1;
820 double ddu2ddvdw1 = ruu * ddu1ddvdw1 + ruw * ddw1ddvdw1;
821 double ddv2ddvdw1 = rvu * ddu1ddvdw1 + rvv * ddv1ddvdw1 + rvw * ddw1ddvdw1;
822 double ddw2ddvdw1 = rwu * ddu1ddvdw1 + rwv * ddv1ddvdw1 + rww * ddw1ddvdw1;
826 double dr2du2 = -dw2 / duw2;
827 double dr2dw2 = du2 / duw2;
829 double dphi2ddu2 = -dw2 / (duw2 * duw2);
830 double dphi2ddw2 = du2 / (duw2 * duw2);
832 double deta2ddv2 = 1. / (duw2 * duw2);
836 double dr2du1 = dr2du2 * du2du1 + dr2dw2 * dw2du1;
837 double dr2dv1 = dr2dw2 * dw2dv1;
839 double dphi2ddudw1 = dphi2ddu2 * ddu2ddudw1 + dphi2ddw2 * ddw2ddudw1;
840 double dphi2ddvdw1 = dphi2ddu2 * ddu2ddvdw1 + dphi2ddw2 * ddw2ddvdw1;
842 double deta2ddudw1 = deta2ddv2 * ddv2ddudw1;
843 double deta2ddvdw1 = deta2ddv2 * ddv2ddvdw1;
855 double dsdu2 = -du2 / (duw2 * duw2);
856 double dsdw2 = -dw2 / (duw2 * duw2);
860 double dsdu1 = dsdu2 * du2du1 + dsdw2 * dw2du1;
861 double dsdv1 = dsdw2 * dw2dv1;
865 dv2du1 += dv2 * dsdu1;
866 dv2dv1 += dv2 * dsdv1;
884 pm(2, 2) = dphi2ddudw1;
885 pm(3, 2) = deta2ddudw1;
890 pm(2, 3) = dphi2ddvdw1;
891 pm(3, 3) = deta2ddvdw1;
TrackDirection
Track direction enum.
bool transformXYZPlane(double theta1, double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform xyz plane -> yz line.
Interactor for planar surfaces.
double Mass() const
Based on pdg code.
const std::shared_ptr< const Surface > & getSurface() const
Surface.
std::optional< double > origin_vec_prop(KTrack &trk, const std::shared_ptr< const Surface > &porient, TrackMatrix *prop_matrix=0) const override
Propagate without error to surface whose origin parameters coincide with track position.
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
bool transformYZLine(double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform yz line -> yz line.
void setVector(const TrackVector &vec)
Set state vector.
void setDirection(Surface::TrackDirection dir)
Set direction.
Planar surface parallel to x-axis.
const std::shared_ptr< const Interactor > & getInteractor() const
void setSurface(const std::shared_ptr< const Surface > &psurf)
Set surface.
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
Propagate to SurfYZLine surface.
void getPosition(double xyz[3]) const
Get position of track.
std::optional< double > short_vec_prop(KTrack &trk, const std::shared_ptr< const Surface > &surf, Propagator::PropDirection dir, bool doDedx, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const override
Propagate without error.
bool transformYZPlane(double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform yz plane -> yz line.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
double z0() const
Z origin.
const TrackVector & getVector() const
Track state vector.
double x0() const
X origin.
std::optional< double > dedx_prop(double pinv, double mass, double s, double *deriv=0) const
Method to calculate updated momentum due to dE/dx.
PropYZLine(detinfo::DetectorPropertiesData const &detProp, double tcut, bool doDedx)
Surface::TrackDirection getDirection() const
Track direction.
double phi() const
Rotation angle about x-axis.
double y0() const
Y origin.
Line surface perpendicular to x-axis.
cet::coded_exception< error, detail::translate > exception
bool isValid() const
Test if track is valid.
PropDirection
Propagation direction enum.