LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PropYZPlane.cxx
Go to the documentation of this file.
1 
12 #include "cetlib_except/exception.h"
17 #include <cmath>
18 
19 namespace trkf {
20 
28  PropYZPlane::PropYZPlane(detinfo::DetectorPropertiesData const& detProp, double tcut, bool doDedx)
29  : Propagator{detProp,
30  tcut,
31  doDedx,
32  (tcut >= 0. ? std::make_shared<InteractPlane const>(detProp, tcut) :
33  std::shared_ptr<Interactor const>{})}
34  {}
35 
50  std::optional<double> PropYZPlane::short_vec_prop(KTrack& trk,
51  const std::shared_ptr<const Surface>& psurf,
53  bool doDedx,
54  TrackMatrix* prop_matrix,
55  TrackError* noise_matrix) const
56  {
57  // Set the default return value to be unitialized with value 0.
58 
59  std::optional<double> result{std::nullopt};
60 
61  // Get destination surface and surface parameters.
62  // Return failure if wrong surface type.
63 
64  const SurfYZPlane* to = dynamic_cast<const SurfYZPlane*>(&*psurf);
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();
70 
71  // Remember starting track.
72 
73  KTrack trk0(trk);
74 
75  // Get track position.
76 
77  double xyz[3];
78  trk.getPosition(xyz);
79  double x01 = xyz[0];
80  double y01 = xyz[1];
81  double z01 = xyz[2];
82 
83  // Propagate to origin surface.
84 
85  TrackMatrix local_prop_matrix;
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;
89 
90  // Get the intermediate track state vector and track parameters.
91 
92  const TrackVector& vec = trk.getVector();
93  if (vec.size() != 5)
94  throw cet::exception("PropYZPlane")
95  << "Track state vector has wrong size" << vec.size() << "\n";
96  double u1 = vec(0);
97  double v1 = vec(1);
98  double dudw1 = vec(2);
99  double dvdw1 = vec(3);
100  double pinv = vec(4);
102 
103  // Make sure intermediate track has a valid direction.
104 
105  if (dir1 == Surface::UNKNOWN) {
106  trk = trk0;
107  return result;
108  }
109 
110  // Calculate transcendental functions.
111 
112  double sinphi2 = std::sin(phi2);
113  double cosphi2 = std::cos(phi2);
114 
115  // Calculate initial position in the destination coordinate
116  // system.
117 
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;
121 
122  // Calculate position at destination surface (propagate distance -w2).
123 
124  double u2p = u2 - w2 * dudw1;
125  double v2p = v2 - w2 * dvdw1;
126 
127  // Calculate the signed propagation distance.
128 
129  double s = -w2 * std::sqrt(1. + dudw1 * dudw1 + dvdw1 * dvdw1);
130  if (dir1 == Surface::BACKWARD) s = -s;
131 
132  // Check if propagation was in the right direction.
133  // (Compare sign of s with requested direction).
134 
135  bool sok = (dir == Propagator::UNKNOWN || (dir == Propagator::FORWARD && s >= 0.) ||
136  (dir == Propagator::BACKWARD && s <= 0.));
137 
138  // If wrong direction, return failure without updating the track
139  // or propagation matrix.
140 
141  if (!sok) {
142  trk = trk0;
143  return result;
144  }
145 
146  // Find final momentum.
147 
148  double deriv = 1.;
149  auto pinv2 = std::make_optional(pinv);
150  if (getDoDedx() && doDedx && s != 0.) {
151  double* pderiv = (prop_matrix != 0 ? &deriv : 0);
152  pinv2 = dedx_prop(pinv, trk.Mass(), s, pderiv);
153  }
154 
155  // Return failure in case of range out.
156 
157  if (!pinv2) {
158  trk = trk0;
159  return result;
160  }
161 
162  // Update default result to success and store propagation distance.
163 
164  result = std::make_optional(s);
165 
166  // Update propagation matrix (if requested).
167 
168  if (prop_matrix != 0) {
169  TrackMatrix pm;
170  pm.resize(vec.size(), vec.size(), false);
171 
172  // Calculate partial derivatives.
173 
174  pm(0, 0) = 1.; // du2/du1
175  pm(1, 0) = 0.; // dv2/du1
176  pm(2, 0) = 0.; // d(dudw2)/du1
177  pm(3, 0) = 0.; // d(dvdw2)/du1
178  pm(4, 0) = 0.; // d(pinv2)/du1
179 
180  pm(0, 1) = 0.; // du2/dv1
181  pm(1, 1) = 1.; // dv2/dv1
182  pm(2, 1) = 0.; // d(dudw2)/dv1
183  pm(3, 1) = 0.; // d(dvdw2)/dv1
184  pm(4, 1) = 0.; // d(pinv2)/dv1
185 
186  pm(0, 2) = -w2; // du2/d(dudw1);
187  pm(1, 2) = 0.; // dv2/d(dudw1);
188  pm(2, 2) = 1.; // d(dudw2)/d(dudw1);
189  pm(3, 2) = 0.; // d(dvdw2)/d(dudw1);
190  pm(4, 2) = 0.; // d(pinv2)/d(dudw1);
191 
192  pm(0, 3) = 0.; // du2/d(dvdw1);
193  pm(1, 3) = -w2; // dv2/d(dvdw1);
194  pm(2, 3) = 0.; // d(dudw2)/d(dvdw1);
195  pm(3, 3) = 1.; // d(dvdw2)/d(dvdw1);
196  pm(4, 3) = 0.; // d(pinv2)/d(dvdw1);
197 
198  pm(0, 4) = 0.; // du2/d(pinv1);
199  pm(1, 4) = 0.; // dv2/d(pinv1);
200  pm(2, 4) = 0.; // d(dudw2)/d(pinv1);
201  pm(3, 4) = 0.; // d(dvdw2)/d(pinv1);
202  pm(4, 4) = deriv; // d(pinv2)/d(pinv1);
203 
204  // Compose the final propagation matrix from zero-distance propagation and
205  // parallel surface propagation.
206 
207  *prop_matrix = prod(pm, *plocal_prop_matrix);
208  }
209 
210  // Update noise matrix (if requested).
211 
212  if (noise_matrix != 0) {
213  noise_matrix->resize(vec.size(), vec.size(), false);
214  if (getInteractor().get() != 0) {
215  bool ok = getInteractor()->noise(trk, s, *noise_matrix);
216  if (!ok) {
217  trk = trk0;
218  return std::nullopt;
219  }
220  }
221  else
222  noise_matrix->clear();
223  }
224 
225  // Construct track vector at destination surface.
226 
227  TrackVector vec2(vec.size());
228  vec2(0) = u2p;
229  vec2(1) = v2p;
230  vec2(2) = dudw1;
231  vec2(3) = dvdw1;
232  vec2(4) = *pinv2;
233 
234  // Update track.
235 
236  trk.setSurface(psurf);
237  trk.setVector(vec2);
238 
239  // Done.
240 
241  return result;
242  }
243 
257  std::optional<double> PropYZPlane::origin_vec_prop(KTrack& trk,
258  const std::shared_ptr<const Surface>& porient,
259  TrackMatrix* prop_matrix) const
260  {
261  // Set the default return value to be unitialized with value 0.
262 
263  std::optional<double> result{std::nullopt};
264 
265  // Remember starting track.
266 
267  KTrack trk0(trk);
268 
269  // Get initial track parameters and direction.
270  // Note the initial track can be on any type of surface.
271 
272  TrackVector vec = trk.getVector(); // Modifiable copy.
273  if (vec.size() != 5)
274  throw cet::exception("PropYZPlane")
275  << "Track state vector has wrong size" << vec.size() << "\n";
277 
278  // Get track position.
279 
280  double xyz[3];
281  trk.getPosition(xyz);
282  double x02 = xyz[0];
283  double y02 = xyz[1];
284  double z02 = xyz[2];
285 
286  // Generate the origin surface, which will be the destination surface.
287  // Return failure if orientation surface is the wrong type.
288 
289  const SurfYZPlane* orient = dynamic_cast<const SurfYZPlane*>(&*porient);
290  if (orient == 0) return result;
291  double phi2 = orient->phi();
292  std::shared_ptr<const Surface> porigin(new SurfYZPlane(x02, y02, z02, phi2));
293 
294  // Test initial surface types.
295 
296  if (const SurfYZLine* from = dynamic_cast<const SurfYZLine*>(&*trk.getSurface())) {
297 
298  // Initial surface is SurfYZLine.
299  // Get surface paramters.
300 
301  double phi1 = from->phi();
302 
303  // Transform track to origin surface.
304 
305  bool ok = transformYZLine(phi1, phi2, vec, dir, prop_matrix);
306  result = std::make_optional(0.);
307  if (!ok) return std::nullopt;
308  }
309  else if (const SurfYZPlane* from = dynamic_cast<const SurfYZPlane*>(&*trk.getSurface())) {
310 
311  // Initial surface is SurfYZPlane.
312  // Get surface paramters.
313 
314  double phi1 = from->phi();
315 
316  // Transform track to origin surface.
317 
318  bool ok = transformYZPlane(phi1, phi2, vec, dir, prop_matrix);
319  result = std::make_optional(0.);
320  if (!ok) return std::nullopt;
321  }
322  else if (const SurfXYZPlane* from = dynamic_cast<const SurfXYZPlane*>(&*trk.getSurface())) {
323 
324  // Initial surface is SurfXYZPlane.
325  // Get surface paramters.
326 
327  double theta1 = from->theta();
328  double phi1 = from->phi();
329 
330  // Transform track to origin surface.
331 
332  bool ok = transformXYZPlane(theta1, phi1, phi2, vec, dir, prop_matrix);
333  result = std::make_optional(0.);
334  if (!ok) return std::nullopt;
335  }
336 
337  // Update track.
338 
339  trk.setSurface(porigin);
340  trk.setVector(vec);
341  trk.setDirection(dir);
342 
343  // Final validity check.
344 
345  if (!trk.isValid()) {
346  trk = trk0;
347  result = std::nullopt;
348  }
349 
350  // Done.
351 
352  return result;
353  }
354 
355  // Transform track parameters from SurfYZLine to SurfYZPlane.
356 
358  double phi2,
359  TrackVector& vec,
361  TrackMatrix* prop_matrix) const
362  {
363  // Calculate surface transcendental functions.
364 
365  double sindphi = std::sin(phi2 - phi1);
366  double cosdphi = std::cos(phi2 - phi1);
367 
368  // Get the initial track parameters.
369 
370  double r1 = vec(0);
371  double phid1 = vec(2);
372  double eta1 = vec(3);
373 
374  // Calculate elements of rotation matrix from initial coordinate
375  // system to destination coordinte system.
376 
377  double rvv = cosdphi;
378  double rvw = sindphi;
379 
380  double rwv = -sindphi;
381  double rww = cosdphi;
382 
383  // Calculate track transcendental functions.
384 
385  double sinphid1 = std::sin(phid1);
386  double cosphid1 = std::cos(phid1);
387  double sh1 = 1. / std::cosh(eta1); // sech(eta1)
388  double th1 = std::tanh(eta1);
389 
390  // Calculate initial position in Cartesian coordinates.
391 
392  double u1 = -r1 * sinphid1;
393  double w1 = r1 * cosphid1;
394 
395  // Calculate direction in destination coordinate system.
396 
397  double du2 = sh1 * cosphid1;
398  double dv2 = th1 * cosdphi + sh1 * sinphid1 * sindphi;
399  double dw2 = -th1 * sindphi + sh1 * sinphid1 * cosdphi;
400  //double duw2 = std::hypot(du2, dw2);
401 
402  // Calculate the track direction relative to the destination surface.
403  // The track direction comes from the sign of dw2 (=dw/ds).
404  // If dw2 is zero, the destionation surface is unreachable, return failure.
405 
406  if (dw2 > 0.)
407  dir = Surface::TrackDirection::FORWARD;
408  else if (dw2 < 0.)
409  dir = Surface::TrackDirection::BACKWARD;
410  else
411  return false;
412 
413  // Calculate final track slope track parameters.
414 
415  double dudw2 = du2 / dw2;
416  double dvdw2 = dv2 / dw2;
417 
418  // Update propagation matrix (if requested).
419 
420  if (prop_matrix != 0) {
421  TrackMatrix& pm = *prop_matrix;
422  pm.resize(vec.size(), vec.size(), false);
423 
424  // Calculate partial derivatives.
425 
426  // Partials of initial positions and directions wrt initial t.p.'s.
427 
428  double du1dr1 = -sinphid1;
429  double du1dphi1 = -w1;
430 
431  double dw1dr1 = cosphid1;
432  double dw1dphi1 = u1;
433 
434  double ddu1dphi1 = -sinphid1 * sh1;
435  double ddu1deta1 = -cosphid1 * sh1 * th1;
436 
437  double ddv1deta1 = sh1 * sh1;
438 
439  double ddw1dphi1 = cosphid1 * sh1;
440  double ddw1deta1 = -sinphid1 * sh1 * th1;
441 
442  // Rotate partials to destination coordinate system.
443 
444  double du2dr1 = du1dr1;
445  double dv2dr1 = rvw * dw1dr1;
446  double dw2dr1 = rww * dw1dr1;
447 
448  double dv2dv1 = rvv;
449  double dw2dv1 = rwv;
450 
451  double du2dphi1 = du1dphi1;
452  double dv2dphi1 = rvw * dw1dphi1;
453  double dw2dphi1 = rww * dw1dphi1;
454 
455  double ddu2dphi1 = ddu1dphi1;
456  double ddv2dphi1 = rvw * ddw1dphi1;
457  double ddw2dphi1 = rww * ddw1dphi1;
458 
459  double ddu2deta1 = ddu1deta1;
460  double ddv2deta1 = rvv * ddv1deta1 + rvw * ddw1deta1;
461  double ddw2deta1 = rwv * ddv1deta1 + rww * ddw1deta1;
462 
463  // Partials of final slope t.p. wrt final position and direction.
464 
465  double ddudw2ddu2 = 1. / dw2;
466  double ddudw2ddw2 = -dudw2 / dw2;
467 
468  double ddvdw2ddv2 = 1. / dw2;
469  double ddvdw2ddw2 = -dvdw2 / dw2;
470 
471  // Partials of final slope t.p. wrt initial t.p.
472 
473  double ddudw2dphi1 = ddudw2ddu2 * ddu2dphi1 + ddudw2ddw2 * ddw2dphi1;
474  double ddudw2deta1 = ddudw2ddu2 * ddu2deta1 + ddudw2ddw2 * ddw2deta1;
475 
476  double ddvdw2dphi1 = ddvdw2ddv2 * ddv2dphi1 + ddvdw2ddw2 * ddw2dphi1;
477  double ddvdw2deta1 = ddvdw2ddv2 * ddv2deta1 + ddvdw2ddw2 * ddw2deta1;
478 
479  // We still need to calculate the corretion due to the dependence of the
480  // propagation distance on the initial track parameters. This correction is
481  // needed even though the actual propagation distance is zero.
482 
483  // This correction effects the u and v track parameters.
484 
485  // Partials of perpendicular propagation distance wrt initial t.p.
486 
487  double dstdr1 = -dw2dr1;
488  double dstdv1 = -dw2dv1;
489  double dstdphi1 = -dw2dphi1;
490 
491  // Calculate correction to u and v parameter partials wrt initial t.p. due to path length.
492 
493  du2dr1 += dstdr1 * dudw2;
494  double du2dv1 = dstdv1 * dudw2;
495  du2dphi1 += dstdphi1 * dudw2;
496 
497  dv2dr1 += dstdr1 * dvdw2;
498  dv2dv1 += dstdv1 * dvdw2;
499  dv2dphi1 += dstdphi1 * dvdw2;
500 
501  // Fill derivative matrix.
502 
503  pm(0, 0) = du2dr1; // du2/dr1
504  pm(1, 0) = dv2dr1; // dv2/dr1
505  pm(2, 0) = 0.; // d(dudw2)/dr1
506  pm(3, 0) = 0.; // d(dvdw2)/dr1
507  pm(4, 0) = 0.; // d(pinv2)/dr1
508 
509  pm(0, 1) = du2dv1; // du2/dv1
510  pm(1, 1) = dv2dv1; // dv2/dv1
511  pm(2, 1) = 0.; // d(dudw2)/dv1
512  pm(3, 1) = 0.; // d(dvdw2)/dv1
513  pm(4, 1) = 0.; // d(pinv2)/dv1
514 
515  pm(0, 2) = du2dphi1; // du2/d(phi1);
516  pm(1, 2) = dv2dphi1; // dv2/d(phi1);
517  pm(2, 2) = ddudw2dphi1; // d(dudw2)/d(phi1);
518  pm(3, 2) = ddvdw2dphi1; // d(dvdw2)/d(phi1);
519  pm(4, 2) = 0.; // d(pinv2)/d(phi1);
520 
521  pm(0, 3) = 0.; // du2/d(eta1);
522  pm(1, 3) = 0.; // dv2/d(eta1);
523  pm(2, 3) = ddudw2deta1; // d(dudw2)/d(eta1);
524  pm(3, 3) = ddvdw2deta1; // d(dvdw2)/d(eta1);
525  pm(4, 3) = 0.; // d(pinv2)/d(eta1);
526 
527  pm(0, 4) = 0.; // du2/d(pinv1);
528  pm(1, 4) = 0.; // dv2/d(pinv1);
529  pm(2, 4) = 0.; // d(dudw2)/d(pinv1);
530  pm(3, 4) = 0.; // d(dvdw2)/d(pinv1);
531  pm(4, 4) = 1.; // d(pinv2)/d(pinv1);
532  }
533 
534  // Update track vector.
535 
536  vec(0) = 0.;
537  vec(1) = 0.;
538  vec(2) = dudw2;
539  vec(3) = dvdw2;
540 
541  // Done (success).
542 
543  return true;
544  }
545 
546  // Transform track parameters from SurfYZPlane to SurfYZPlane.
547 
549  double phi2,
550  TrackVector& vec,
552  TrackMatrix* prop_matrix) const
553  {
554  // Calculate transcendental functions.
555 
556  double sindphi = std::sin(phi2 - phi1);
557  double cosdphi = std::cos(phi2 - phi1);
558 
559  // Get the initial track parameters.
560 
561  double dudw1 = vec(2);
562  double dvdw1 = vec(3);
563 
564  // Make sure initial track has a valid direction.
565 
566  if (dir == Surface::UNKNOWN) return false;
567 
568  // Calculate derivative dw2/dw1.
569  // If dw2/dw1 == 0., that means the track is moving parallel
570  // to destination plane.
571  // In this case return propagation failure.
572 
573  double dw2dw1 = cosdphi - dvdw1 * sindphi;
574  if (dw2dw1 == 0.) return false;
575 
576  // Calculate slope in destrination coordiante system.
577 
578  double dudw2 = dudw1 / dw2dw1;
579  double dvdw2 = (sindphi + dvdw1 * cosdphi) / dw2dw1;
580 
581  // Calculate direction parameter at destination surface.
582  // Direction will flip if dw2dw1 < 0.;
583 
584  switch (dir) {
585  case Surface::FORWARD: dir = (dw2dw1 > 0.) ? Surface::FORWARD : Surface::BACKWARD; break;
586  case Surface::BACKWARD: dir = (dw2dw1 > 0.) ? Surface::BACKWARD : Surface::FORWARD; break;
587  default: throw cet::exception("PropYZPlane") << "unexpected direction #" << ((int)dir) << "\n";
588  } // switch
589 
590  // Update propagation matrix (if requested).
591 
592  if (prop_matrix != 0) {
593  TrackMatrix& pm = *prop_matrix;
594  pm.resize(vec.size(), vec.size(), false);
595 
596  // Calculate partial derivatives.
597 
598  pm(0, 0) = 1.; // du2/du1
599  pm(1, 0) = 0.; // dv2/du1
600  pm(2, 0) = 0.; // d(dudw2)/du1
601  pm(3, 0) = 0.; // d(dvdw2)/du1
602  pm(4, 0) = 0.; // d(pinv2)/du1
603 
604  pm(0, 1) = dudw2 * sindphi; // du2/dv1
605  pm(1, 1) = cosdphi + dvdw2 * sindphi; // dv2/dv1
606  pm(2, 1) = 0.; // d(dudw2)/dv1
607  pm(3, 1) = 0.; // d(dvdw2)/dv1
608  pm(4, 1) = 0.; // d(pinv2)/dv1
609 
610  pm(0, 2) = 0.; // du2/d(dudw1);
611  pm(1, 2) = 0.; // dv2/d(dudw1);
612  pm(2, 2) = 1. / dw2dw1; // d(dudw2)/d(dudw1);
613  pm(3, 2) = 0.; // d(dvdw2)/d(dudw1);
614  pm(4, 2) = 0.; // d(pinv2)/d(dudw1);
615 
616  pm(0, 3) = 0.; // du2/d(dvdw1);
617  pm(1, 3) = 0.; // dv2/d(dvdw1);
618  pm(2, 3) = dudw1 * sindphi / (dw2dw1 * dw2dw1); // d(dudw2)/d(dvdw1);
619  pm(3, 3) = 1. / (dw2dw1 * dw2dw1); // d(dvdw2)/d(dvdw1);
620  pm(4, 3) = 0.; // d(pinv2)/d(dvdw1);
621 
622  pm(0, 4) = 0.; // du2/d(pinv1);
623  pm(1, 4) = 0.; // dv2/d(pinv1);
624  pm(2, 4) = 0.; // d(dudw2)/d(pinv1);
625  pm(3, 4) = 0.; // d(dvdw2)/d(pinv1);
626  pm(4, 4) = 1.; // d(pinv2)/d(pinv1);
627  }
628 
629  // Update track vector.
630 
631  vec(0) = 0.;
632  vec(1) = 0.;
633  vec(2) = dudw2;
634  vec(3) = dvdw2;
635 
636  // Done (success).
637 
638  return true;
639  }
640 
641  // Transform track parameters from SurfXYZPlane to SurfYZPlane.
642 
643  bool PropYZPlane::transformXYZPlane(double theta1,
644  double phi1,
645  double phi2,
646  TrackVector& vec,
648  TrackMatrix* prop_matrix) const
649  {
650  // Calculate transcendental functions.
651 
652  double sinth1 = std::sin(theta1);
653  double costh1 = std::cos(theta1);
654 
655  double sindphi = std::sin(phi2 - phi1);
656  double cosdphi = std::cos(phi2 - phi1);
657 
658  // Get the initial track state vector and track parameters.
659 
660  double dudw1 = vec(2);
661  double dvdw1 = vec(3);
662 
663  // Make sure initial track has a valid direction.
664 
665  if (dir == Surface::UNKNOWN) return false;
666 
667  // Calculate elements of rotation matrix from initial coordinate
668  // system to destination coordinte system.
669 
670  double ruu = costh1;
671  double ruw = sinth1;
672 
673  double rvu = -sinth1 * sindphi;
674  double rvv = cosdphi;
675  double rvw = costh1 * sindphi;
676 
677  double rwu = -sinth1 * cosdphi;
678  double rwv = -sindphi;
679  double rww = costh1 * cosdphi;
680 
681  // Calculate the derivative dw2/dw1;
682  // If dw2/dw1 == 0., that means the track is moving parallel
683  // to destination plane.
684  // In this case return propagation failure.
685 
686  double dw2dw1 = dudw1 * rwu + dvdw1 * rwv + rww;
687  if (dw2dw1 == 0.) return false;
688 
689  // Calculate slope in destination plane coordinates.
690 
691  double dudw2 = (dudw1 * ruu + ruw) / dw2dw1;
692  double dvdw2 = (dudw1 * rvu + dvdw1 * rvv + rvw) / dw2dw1;
693 
694  // Calculate direction parameter at destination surface.
695  // Direction will flip if dw2dw1 < 0.;
696 
697  switch (dir) {
698  case Surface::FORWARD: dir = (dw2dw1 > 0.) ? Surface::FORWARD : Surface::BACKWARD; break;
699  case Surface::BACKWARD: dir = (dw2dw1 > 0.) ? Surface::BACKWARD : Surface::FORWARD; break;
700  default:
701  throw cet::exception("PropXYZPlane")
702  << __func__ << ": unexpected direction #" << ((int)dir) << "\n";
703  } // switch
704 
705  // Update propagation matrix (if requested).
706 
707  if (prop_matrix != 0) {
708  TrackMatrix& pm = *prop_matrix;
709  pm.resize(vec.size(), vec.size(), false);
710 
711  // Calculate partial derivatives.
712 
713  pm(0, 0) = ruu - dudw2 * rwu; // du2/du1
714  pm(1, 0) = rvu - dvdw2 * rwu; // dv2/du1
715  pm(2, 0) = 0.; // d(dudw2)/du1
716  pm(3, 0) = 0.; // d(dvdw2)/du1
717  pm(4, 0) = 0.; // d(pinv2)/du1
718 
719  pm(0, 1) = -dudw2 * rwv; // du2/dv1
720  pm(1, 1) = rvv - dvdw2 * rwv; // dv2/dv1
721  pm(2, 1) = 0.; // d(dudw2)/dv1
722  pm(3, 1) = 0.; // d(dvdw2)/dv1
723  pm(4, 1) = 0.; // d(pinv2)/dv1
724 
725  pm(0, 2) = 0.; // du2/d(dudw1);
726  pm(1, 2) = 0.; // dv2/d(dudw1);
727  pm(2, 2) = (ruu - dudw2 * rwu) / dw2dw1; // d(dudw2)/d(dudw1);
728  pm(3, 2) = (rvu - dvdw2 * rwu) / dw2dw1; // d(dvdw2)/d(dudw1);
729  pm(4, 2) = 0.; // d(pinv2)/d(dudw1);
730 
731  pm(0, 3) = 0.; // du2/d(dvdw1);
732  pm(1, 3) = 0.; // dv2/d(dvdw1);
733  pm(2, 3) = -dudw2 * rwv / dw2dw1; // d(dudw2)/d(dvdw1);
734  pm(3, 3) = (rvv - dvdw2 * rwv) / dw2dw1; // d(dvdw2)/d(dvdw1);
735  pm(4, 3) = 0.; // d(pinv2)/d(dvdw1);
736 
737  pm(0, 4) = 0.; // du2/d(pinv1);
738  pm(1, 4) = 0.; // dv2/d(pinv1);
739  pm(2, 4) = 0.; // d(dudw2)/d(pinv1);
740  pm(3, 4) = 0.; // d(dvdw2)/d(pinv1);
741  pm(4, 4) = 1.; // d(pinv2)/d(pinv1);
742  }
743 
744  // Update track vector.
745 
746  vec(0) = 0.;
747  vec(1) = 0.;
748  vec(2) = dudw2;
749  vec(3) = dvdw2;
750 
751  // Done (success).
752 
753  return true;
754  }
755 } // end namespace trkf
TrackDirection
Track direction enum.
Definition: Surface.h:54
bool transformXYZPlane(double theta1, double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform xyz plane -> yz plane.
Propagate to PropYZPlane surface.
double Mass() const
Based on pdg code.
Definition: KTrack.cxx:116
const std::shared_ptr< const Surface > & getSurface() const
Surface.
Definition: KTrack.h:53
General planar surface.
double z0() const
Z origin.
Definition: SurfYZPlane.h:60
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
double x0() const
X origin.
Definition: SurfYZPlane.h:58
void setVector(const TrackVector &vec)
Set state vector.
Definition: KTrack.h:65
void setDirection(Surface::TrackDirection dir)
Set direction.
Definition: KTrack.h:66
Planar surface parallel to x-axis.
const std::shared_ptr< const Interactor > & getInteractor() const
Definition: Propagator.h:109
void setSurface(const std::shared_ptr< const Surface > &psurf)
Set surface.
Definition: KTrack.h:64
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
void getPosition(double xyz[3]) const
Get position of track.
Definition: KTrack.cxx:157
double y0() const
Y origin.
Definition: SurfYZPlane.h:59
bool transformYZPlane(double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform yz plane -> yz plane.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
bool transformYZLine(double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
Transform yz line -> yz plane.
PropYZPlane(detinfo::DetectorPropertiesData const &detProp, double tcut, bool doDedx)
Definition: PropYZPlane.cxx:28
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.
bool getDoDedx() const
Definition: Propagator.h:108
const TrackVector & getVector() const
Track state vector.
Definition: KTrack.h:54
TDirectory * dir
Definition: macro.C:5
std::optional< double > dedx_prop(double pinv, double mass, double s, double *deriv=0) const
Method to calculate updated momentum due to dE/dx.
Definition: Propagator.cxx:447
double phi() const
Rotation angle about x-axis.
Definition: SurfYZPlane.h:61
Interactor for planar surfaces.
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.
Definition: PropYZPlane.cxx:50
Surface::TrackDirection getDirection() const
Track direction.
Definition: KTrack.cxx:64
Line surface perpendicular to x-axis.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool isValid() const
Test if track is valid.
Definition: KTrack.cxx:81
PropDirection
Propagation direction enum.
Definition: Propagator.h:94