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