12 #include "cetlib_except/exception.h" 52 const std::shared_ptr<const Surface>& psurf,
60 std::optional<double>
result{std::nullopt};
66 if (to == 0)
return result;
67 double x02 = to->
x0();
68 double y02 = to->
y0();
69 double z02 = to->
z0();
70 double phi2 = to->
phi();
87 TrackMatrix* plocal_prop_matrix = (prop_matrix == 0 ? 0 : &local_prop_matrix);
88 std::optional<double> result1 =
origin_vec_prop(trk, psurf, plocal_prop_matrix);
89 if (!result1)
return result1;
96 <<
"Track state vector has wrong size" << vec.size() <<
"\n";
99 double phid1 = vec(2);
100 double eta1 = vec(3);
101 double pinv = vec(4);
105 double sinphid1 = std::sin(phid1);
106 double cosphid1 = std::cos(phid1);
107 double sh1 = std::sinh(eta1);
108 double ch1 = std::cosh(eta1);
109 double sinphi2 = std::sin(phi2);
110 double cosphi2 = std::cos(phi2);
114 double u1 = -r1 * sinphid1;
115 double w1 = r1 * cosphid1;
119 double u2 = x01 - x02 + u1;
120 double v2 = (y01 - y02) * cosphi2 + (z01 - z02) * sinphi2 + v1;
121 double w2 = -(y01 - y02) * sinphi2 + (z01 - z02) * cosphi2 + w1;
125 double r2 = w2 * cosphid1 - u2 * sinphid1;
129 double d2 = -(w2 * sinphid1 + u2 * cosphid1);
134 double v2p = v2 + d2 * sh1;
158 auto pinv2 = std::make_optional(pinv);
160 double* pderiv = (prop_matrix != 0 ? &deriv : 0);
173 result = std::make_optional(s);
177 if (prop_matrix != 0) {
179 pm.resize(vec.size(), vec.size(),
false);
196 pm(1, 2) = -r2 * sh1;
216 *prop_matrix = prod(pm, *plocal_prop_matrix);
221 if (noise_matrix != 0) {
222 noise_matrix->resize(vec.size(), vec.size(),
false);
231 noise_matrix->clear();
266 std::optional<double>
268 const std::shared_ptr<const Surface>& porient,
273 std::optional<double>
result{std::nullopt};
285 <<
"Track state vector has wrong size" << vec.size() <<
"\n";
300 if (orient == 0)
return result;
301 double phi2 = orient->
phi();
302 std::shared_ptr<const Surface> porigin(
new SurfYZLine(x02, y02, z02, phi2));
311 double phi1 = from->phi();
316 result = std::make_optional(0.);
317 if (!ok)
return std::nullopt;
324 double phi1 = from->phi();
329 result = std::make_optional(0.);
330 if (!ok)
return std::nullopt;
337 double theta1 = from->theta();
338 double phi1 = from->phi();
343 result = std::make_optional(0.);
344 if (!ok)
return std::nullopt;
376 double sindphi = std::sin(phi2 - phi1);
377 double cosdphi = std::cos(phi2 - phi1);
382 double phid1 = vec(2);
383 double eta1 = vec(3);
388 double rvv = cosdphi;
389 double rvw = sindphi;
391 double rwv = -sindphi;
392 double rww = cosdphi;
396 double sinphid1 = std::sin(phid1);
397 double cosphid1 = std::cos(phid1);
398 double sh1 = 1. / std::cosh(eta1);
399 double th1 = std::tanh(eta1);
403 double u1 = -r1 * sinphid1;
404 double w1 = r1 * cosphid1;
408 double du2 = sh1 * cosphid1;
409 double dv2 = th1 * cosdphi + sh1 * sinphid1 * sindphi;
410 double dw2 = -th1 * sindphi + sh1 * sinphid1 * cosdphi;
415 double phid2 = atan2(dw2, du2);
416 double eta2 = std::asinh(dv2 / duw2);
420 if (prop_matrix != 0) {
422 pm.resize(vec.size(), vec.size(),
false);
428 double du1dr1 = -sinphid1;
429 double du1dphi1 = -w1;
431 double dw1dr1 = cosphid1;
432 double dw1dphi1 = u1;
434 double ddu1dphi1 = -sinphid1 * sh1;
435 double ddu1deta1 = -cosphid1 * sh1 * th1;
437 double ddv1deta1 = sh1 * sh1;
439 double ddw1dphi1 = cosphid1 * sh1;
440 double ddw1deta1 = -sinphid1 * sh1 * th1;
444 double du2dr1 = du1dr1;
445 double dv2dr1 = rvw * dw1dr1;
446 double dw2dr1 = rww * dw1dr1;
451 double du2dphi1 = du1dphi1;
452 double dv2dphi1 = rvw * dw1dphi1;
453 double dw2dphi1 = rww * dw1dphi1;
455 double ddu2dphi1 = ddu1dphi1;
456 double ddv2dphi1 = rvw * ddw1dphi1;
457 double ddw2dphi1 = rww * ddw1dphi1;
459 double ddu2deta1 = ddu1deta1;
460 double ddv2deta1 = rvv * ddv1deta1 + rvw * ddw1deta1;
461 double ddw2deta1 = rwv * ddv1deta1 + rww * ddw1deta1;
465 double dr2du2 = -dw2 / duw2;
466 double dr2dw2 = du2 / duw2;
468 double dphi2ddu2 = -dw2 / (duw2 * duw2);
469 double dphi2ddw2 = du2 / (duw2 * duw2);
471 double deta2ddv2 = 1. / (duw2 * duw2);
475 double dr2dr1 = dr2du2 * du2dr1 + dr2dw2 * dw2dr1;
476 double dr2dv1 = dr2dw2 * dw2dv1;
477 double dr2dphi1 = dr2du2 * du2dphi1 + dr2dw2 * dw2dphi1;
479 double dphi2dphi1 = dphi2ddu2 * ddu2dphi1 + dphi2ddw2 * ddw2dphi1;
480 double dphi2deta1 = dphi2ddu2 * ddu2deta1 + dphi2ddw2 * ddw2deta1;
482 double deta2dphi1 = deta2ddv2 * ddv2dphi1;
483 double deta2deta1 = deta2ddv2 * ddv2deta1;
495 double dsdu2 = -du2 / (duw2 * duw2);
496 double dsdw2 = -dw2 / (duw2 * duw2);
500 double dsdr1 = dsdu2 * du2dr1 + dsdw2 * dw2dr1;
501 double dsdv1 = dsdw2 * dw2dv1;
502 double dsdphi1 = dsdu2 * du2dphi1 + dsdw2 * dw2dphi1;
506 dv2dr1 += dv2 * dsdr1;
507 dv2dv1 += dv2 * dsdv1;
508 dv2dphi1 += dv2 * dsdphi1;
526 pm(2, 2) = dphi2dphi1;
527 pm(3, 2) = deta2dphi1;
532 pm(2, 3) = dphi2deta1;
533 pm(3, 3) = deta2deta1;
566 double sindphi = std::sin(phi2 - phi1);
567 double cosdphi = std::cos(phi2 - phi1);
571 double dudw1 = vec(2);
572 double dvdw1 = vec(3);
585 double rvv = cosdphi;
586 double rvw = sindphi;
588 double rwv = -sindphi;
589 double rww = cosdphi;
593 double dw1 = dirf / std::sqrt(1. + dudw1 * dudw1 + dvdw1 * dvdw1);
594 double du1 = dudw1 * dw1;
595 double dv1 = dvdw1 * dw1;
600 double dv2 = rvv * dv1 + rvw * dw1;
601 double dw2 = rwv * dv1 + rww * dw1;
606 double phid2 = atan2(dw2, du2);
607 double eta2 = std::asinh(dv2 / duw2);
611 if (prop_matrix != 0) {
613 pm.resize(vec.size(), vec.size(),
false);
619 double ddu1ddudw1 = (1. + dvdw1 * dvdw1) * dw1 * dw1 * dw1;
620 double ddu1ddvdw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
622 double ddv1ddudw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
623 double ddv1ddvdw1 = (1. + dudw1 * dudw1) * dw1 * dw1 * dw1;
625 double ddw1ddudw1 = -dudw1 * dw1 * dw1 * dw1;
626 double ddw1ddvdw1 = -dvdw1 * dw1 * dw1 * dw1;
633 double ddu2ddudw1 = ddu1ddudw1;
634 double ddv2ddudw1 = rvv * ddv1ddudw1 + rvw * ddw1ddudw1;
635 double ddw2ddudw1 = rwv * ddv1ddudw1 + rww * ddw1ddudw1;
637 double ddu2ddvdw1 = ddu1ddvdw1;
638 double ddv2ddvdw1 = rvv * ddv1ddvdw1 + rvw * ddw1ddvdw1;
639 double ddw2ddvdw1 = rwv * ddv1ddvdw1 + rww * ddw1ddvdw1;
643 double dr2du2 = -dw2 / duw2;
644 double dr2dw2 = du2 / duw2;
646 double dphi2ddu2 = -dw2 / (duw2 * duw2);
647 double dphi2ddw2 = du2 / (duw2 * duw2);
649 double deta2ddv2 = 1. / (duw2 * duw2);
653 double dr2du1 = dr2du2;
654 double dr2dv1 = dr2dw2 * dw2dv1;
656 double dphi2ddudw1 = dphi2ddu2 * ddu2ddudw1 + dphi2ddw2 * ddw2ddudw1;
657 double dphi2ddvdw1 = dphi2ddu2 * ddu2ddvdw1 + dphi2ddw2 * ddw2ddvdw1;
659 double deta2ddudw1 = deta2ddv2 * ddv2ddudw1;
660 double deta2ddvdw1 = deta2ddv2 * ddv2ddvdw1;
672 double dsdu2 = -du2 / (duw2 * duw2);
673 double dsdw2 = -dw2 / (duw2 * duw2);
677 double dsdu1 = dsdu2;
678 double dsdv1 = dsdw2 * dw2dv1;
682 double dv2du1 = dv2 * dsdu1;
683 dv2dv1 += dv2 * dsdv1;
701 pm(2, 2) = dphi2ddudw1;
702 pm(3, 2) = deta2ddudw1;
707 pm(2, 3) = dphi2ddvdw1;
708 pm(3, 3) = deta2ddvdw1;
742 double sinth1 = std::sin(theta1);
743 double costh1 = std::cos(theta1);
745 double sindphi = std::sin(phi2 - phi1);
746 double cosdphi = std::cos(phi2 - phi1);
750 double dudw1 = vec(2);
751 double dvdw1 = vec(3);
767 double rvu = -sinth1 * sindphi;
768 double rvv = cosdphi;
769 double rvw = costh1 * sindphi;
771 double rwu = -sinth1 * cosdphi;
772 double rwv = -sindphi;
773 double rww = costh1 * cosdphi;
777 double dw1 = dirf / std::sqrt(1. + dudw1 * dudw1 + dvdw1 * dvdw1);
778 double du1 = dudw1 * dw1;
779 double dv1 = dvdw1 * dw1;
783 double du2 = ruu * du1 + ruw * dw1;
784 double dv2 = rvu * du1 + rvv * dv1 + rvw * dw1;
785 double dw2 = rwu * du1 + rwv * dv1 + rww * dw1;
790 double phid2 = atan2(dw2, du2);
791 double eta2 = std::asinh(dv2 / duw2);
795 if (prop_matrix != 0) {
797 pm.resize(vec.size(), vec.size(),
false);
803 double ddu1ddudw1 = (1. + dvdw1 * dvdw1) * dw1 * dw1 * dw1;
804 double ddu1ddvdw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
806 double ddv1ddudw1 = -dudw1 * dvdw1 * dw1 * dw1 * dw1;
807 double ddv1ddvdw1 = (1. + dudw1 * dudw1) * dw1 * dw1 * dw1;
809 double ddw1ddudw1 = -dudw1 * dw1 * dw1 * dw1;
810 double ddw1ddvdw1 = -dvdw1 * dw1 * dw1 * dw1;
821 double ddu2ddudw1 = ruu * ddu1ddudw1 + ruw * ddw1ddudw1;
822 double ddv2ddudw1 = rvu * ddu1ddudw1 + rvv * ddv1ddudw1 + rvw * ddw1ddudw1;
823 double ddw2ddudw1 = rwu * ddu1ddudw1 + rwv * ddv1ddudw1 + rww * ddw1ddudw1;
825 double ddu2ddvdw1 = ruu * ddu1ddvdw1 + ruw * ddw1ddvdw1;
826 double ddv2ddvdw1 = rvu * ddu1ddvdw1 + rvv * ddv1ddvdw1 + rvw * ddw1ddvdw1;
827 double ddw2ddvdw1 = rwu * ddu1ddvdw1 + rwv * ddv1ddvdw1 + rww * ddw1ddvdw1;
831 double dr2du2 = -dw2 / duw2;
832 double dr2dw2 = du2 / duw2;
834 double dphi2ddu2 = -dw2 / (duw2 * duw2);
835 double dphi2ddw2 = du2 / (duw2 * duw2);
837 double deta2ddv2 = 1. / (duw2 * duw2);
841 double dr2du1 = dr2du2 * du2du1 + dr2dw2 * dw2du1;
842 double dr2dv1 = dr2dw2 * dw2dv1;
844 double dphi2ddudw1 = dphi2ddu2 * ddu2ddudw1 + dphi2ddw2 * ddw2ddudw1;
845 double dphi2ddvdw1 = dphi2ddu2 * ddu2ddvdw1 + dphi2ddw2 * ddw2ddvdw1;
847 double deta2ddudw1 = deta2ddv2 * ddv2ddudw1;
848 double deta2ddvdw1 = deta2ddv2 * ddv2ddvdw1;
860 double dsdu2 = -du2 / (duw2 * duw2);
861 double dsdw2 = -dw2 / (duw2 * duw2);
865 double dsdu1 = dsdu2 * du2du1 + dsdw2 * dw2du1;
866 double dsdv1 = dsdw2 * dw2dv1;
870 dv2du1 += dv2 * dsdu1;
871 dv2dv1 += dv2 * dsdv1;
889 pm(2, 2) = dphi2ddudw1;
890 pm(3, 2) = deta2ddudw1;
895 pm(2, 3) = dphi2ddvdw1;
896 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
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
void setSurface(const std::shared_ptr< const Surface > &psurf)
Set surface.
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.
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
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.