LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
trkf::PropYZPlane Class Reference

#include "PropYZPlane.h"

Inheritance diagram for trkf::PropYZPlane:
trkf::Propagator

Public Types

enum  PropDirection { FORWARD, BACKWARD, UNKNOWN }
 Propagation direction enum. More...
 

Public Member Functions

 PropYZPlane (detinfo::DetectorPropertiesData const &detProp, double tcut, bool doDedx)
 
Propagatorclone () const override
 Clone method. More...
 
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. More...
 
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. More...
 
double getTcut () const
 
bool getDoDedx () const
 
const std::shared_ptr< const Interactor > & getInteractor () const
 
std::optional< double > vec_prop (KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
 Propagate without error (long distance). More...
 
std::optional< double > lin_prop (KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
 Linearized propagate without error. More...
 
std::optional< double > err_prop (KETrack &tre, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0) const
 Propagate with error, but without noise. More...
 
std::optional< double > noise_prop (KETrack &tre, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0) const
 Propagate with error and noise. More...
 
std::optional< double > dedx_prop (double pinv, double mass, double s, double *deriv=0) const
 Method to calculate updated momentum due to dE/dx. More...
 

Private Member Functions

bool transformYZLine (double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
 Transform yz line -> yz plane. More...
 
bool transformYZPlane (double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
 Transform yz plane -> yz plane. More...
 
bool transformXYZPlane (double theta1, double phi1, double phi2, TrackVector &vec, Surface::TrackDirection &dir, TrackMatrix *prop_matrix) const
 Transform xyz plane -> yz plane. More...
 

Detailed Description

Definition at line 24 of file PropYZPlane.h.

Member Enumeration Documentation

Propagation direction enum.

Enumerator
FORWARD 
BACKWARD 
UNKNOWN 

Definition at line 94 of file Propagator.h.

Constructor & Destructor Documentation

trkf::PropYZPlane::PropYZPlane ( detinfo::DetectorPropertiesData const &  detProp,
double  tcut,
bool  doDedx 
)

Constructor.

Arguments.

tcut - Delta ray energy cutoff for calculating dE/dx. doDedx - dE/dx enable flag.

Definition at line 28 of file PropYZPlane.cxx.

29  : Propagator{detProp,
30  tcut,
31  doDedx,
32  (tcut >= 0. ? std::make_shared<InteractPlane const>(detProp, tcut) :
33  std::shared_ptr<Interactor const>{})}
34  {}
Propagator(detinfo::DetectorPropertiesData const &detProp, double tcut, bool doDedx, const std::shared_ptr< const Interactor > &interactor)
Constructor.
Definition: Propagator.cxx:26

Member Function Documentation

Propagator* trkf::PropYZPlane::clone ( ) const
inlineoverridevirtual

Clone method.

Implements trkf::Propagator.

Definition at line 29 of file PropYZPlane.h.

References dir.

29 { return new PropYZPlane(*this); }
PropYZPlane(detinfo::DetectorPropertiesData const &detProp, double tcut, bool doDedx)
Definition: PropYZPlane.cxx:28
std::optional< double > trkf::Propagator::dedx_prop ( double  pinv,
double  mass,
double  s,
double *  deriv = 0 
) const
inherited

Method to calculate updated momentum due to dE/dx.

Method to calculate updated momentum due to dE/dx.

Arguments:

pinv - Initial inverse momentum (units c/GeV). mass - Particle mass (GeV/c^2). s - Path distance. deriv - Pointer to store derivative d(pinv2)/d(pinv1) if nonzero.

Returns: Final inverse momentum (pinv2) + success flag.

Failure is returned in case of range out.

Inverse momentum can be signed (q/p). Returned inverse momentum has the same sign as the input.

In this method, we are solving the differential equation in terms of energy.

dE/dx = -f(E)

where f(E) is the stopping power returned by method LArProperties::Eloss.

We expect that this method will be called exclusively for short distance propagation. The differential equation is solved using the midpoint method using a single step, which requires two evaluations of f(E).

dE = -s*f(E1) E2 = E1 - s*f(E1 + 0.5*dE)

The derivative is calculated assuming E2 = E1 + constant, giving

d(pinv2)/d(pinv1) = pinv2^3 E2 / (pinv1^3 E1).

Definition at line 447 of file Propagator.cxx.

References util::abs(), detinfo::DetectorPropertiesData::Eloss(), trkf::Propagator::fDetProp, and trkf::Propagator::fTcut.

Referenced by trkf::PropYZLine::short_vec_prop(), short_vec_prop(), and trkf::PropXYZPlane::short_vec_prop().

451  {
452  // For infinite initial momentum, return with success status,
453  // still infinite momentum.
454 
455  if (pinv == 0.) return std::make_optional(0.);
456 
457  // Set the default return value to be uninitialized with value 0.
458 
459  std::optional<double> result{std::nullopt};
460 
461  // Calculate final energy.
462 
463  double p1 = 1. / std::abs(pinv);
464  double e1 = std::hypot(p1, mass);
465  double de = -0.001 * s * fDetProp.Eloss(p1, mass, fTcut);
466  double emid = e1 + 0.5 * de;
467  if (emid > mass) {
468  double pmid = std::sqrt(emid * emid - mass * mass);
469  double e2 = e1 - 0.001 * s * fDetProp.Eloss(pmid, mass, fTcut);
470  if (e2 > mass) {
471  double p2 = std::sqrt(e2 * e2 - mass * mass);
472  double pinv2 = 1. / p2;
473  if (pinv < 0.) pinv2 = -pinv2;
474 
475  // Calculation was successful, update result.
476 
477  result = std::make_optional(pinv2);
478 
479  // Also calculate derivative, if requested.
480 
481  if (deriv != 0) *deriv = pinv2 * pinv2 * pinv2 * e2 / (pinv * pinv * pinv * e1);
482  }
483  }
484 
485  // Done.
486 
487  return result;
488  }
constexpr auto abs(T v)
Returns the absolute value of the argument.
double fTcut
Maximum delta ray energy for dE/dx.
Definition: Propagator.h:165
detinfo::DetectorPropertiesData const & fDetProp
Definition: Propagator.h:164
double Eloss(double mom, double mass, double tcut) const
Restricted mean energy loss (dE/dx)
std::optional< double > trkf::Propagator::err_prop ( KETrack tre,
const std::shared_ptr< const Surface > &  psurf,
PropDirection  dir,
bool  doDedx,
KTrack ref = 0,
TrackMatrix prop_matrix = 0 
) const
inherited

Propagate with error, but without noise.

Propagate with error, but without noise (i.e. reversibly).

Arguments:

tre - Track to propagate. psurf - Destination surface. dir - Propagation direction (FORWARD, BACKWARD, or UNKNOWN). doDedx - dE/dx enable/disable flag. ref - Reference track (for linearized propagation). Can be null. prop_matrix - Return propagation matrix if not null.

Returned value: propagation distance + success flag.

Definition at line 343 of file Propagator.cxx.

References trkf::KETrack::getError(), trkf::Propagator::lin_prop(), and trkf::KETrack::setError().

Referenced by trkf::KGTrack::fillTrack(), trkf::KalmanFilterAlg::fitMomentumMS(), and trkf::KHit< N >::predict().

349  {
350  // Propagate without error, get propagation matrix.
351 
352  TrackMatrix prop_temp;
353  if (prop_matrix == 0) prop_matrix = &prop_temp;
354  std::optional<double> result = lin_prop(tre, psurf, dir, doDedx, ref, prop_matrix, 0);
355 
356  // If propagation succeeded, update track error matrix.
357 
358  if (!!result) {
359  TrackMatrix temp = prod(tre.getError(), trans(*prop_matrix));
360  TrackMatrix temp2 = prod(*prop_matrix, temp);
361  TrackError newerr = ublas::symmetric_adaptor<TrackMatrix>(temp2);
362  tre.setError(newerr);
363  }
364 
365  // Done.
366 
367  return result;
368  }
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
std::optional< double > lin_prop(KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
Linearized propagate without error.
Definition: Propagator.cxx:249
TDirectory * dir
Definition: macro.C:5
bool trkf::Propagator::getDoDedx ( ) const
inlineinherited

Definition at line 108 of file Propagator.h.

Referenced by trkf::PropYZLine::short_vec_prop(), short_vec_prop(), trkf::PropXYZPlane::short_vec_prop(), and trkf::Propagator::vec_prop().

108 { return fDoDedx; }
bool fDoDedx
Energy loss enable flag.
Definition: Propagator.h:166
const std::shared_ptr<const Interactor>& trkf::Propagator::getInteractor ( ) const
inlineinherited

Definition at line 109 of file Propagator.h.

References dir.

Referenced by trkf::PropYZLine::short_vec_prop(), short_vec_prop(), and trkf::PropXYZPlane::short_vec_prop().

109 { return fInteractor; }
std::shared_ptr< const Interactor > fInteractor
Interactor (for calculating noise).
Definition: Propagator.h:167
double trkf::Propagator::getTcut ( ) const
inlineinherited

Definition at line 107 of file Propagator.h.

107 { return fTcut; }
double fTcut
Maximum delta ray energy for dE/dx.
Definition: Propagator.h:165
std::optional< double > trkf::Propagator::lin_prop ( KTrack trk,
const std::shared_ptr< const Surface > &  psurf,
PropDirection  dir,
bool  doDedx,
KTrack ref = 0,
TrackMatrix prop_matrix = 0,
TrackError noise_matrix = 0 
) const
inherited

Linearized propagate without error.

Linearized propagate without error.

Arguments:

trk - Track to propagate. psurf - Destination surface. dir - Propagation direction (FORWARD, BACKWARD, or UNKNOWN). doDedx - dE/dx enable/disable flag. ref - Reference track (for linearized propagation). Can be null. prop_matrix - Return propagation matrix if not null. noise_matrix - Return noise matrix if not null.

Returned value: Propagation distance & success flag.

If the reference track is null, this method simply calls vec_prop.

Definition at line 249 of file Propagator.cxx.

References trkf::KTrack::getDirection(), trkf::KTrack::getSurface(), trkf::KTrack::getVector(), trkf::KTrack::isValid(), trkf::KTrack::setDirection(), trkf::KTrack::setSurface(), trkf::KTrack::setVector(), and trkf::Propagator::vec_prop().

Referenced by trkf::Propagator::err_prop(), and trkf::Propagator::noise_prop().

256  {
257  // Default result.
258 
259  std::optional<double> result;
260 
261  if (ref == 0)
262  result = vec_prop(trk, psurf, dir, doDedx, prop_matrix, noise_matrix);
263  else {
264 
265  // A reference track has been provided.
266 
267  // It is an error (throw exception) if the reference track and
268  // the track to be propagted are not on the same surface.
269 
270  if (!trk.getSurface()->isEqual(*(ref->getSurface())))
271  throw cet::exception("Propagator")
272  << "Input track and reference track not on same surface.\n";
273 
274  // Remember the starting track and reference track.
275 
276  KTrack trk0(trk);
277  KTrack ref0(*ref);
278 
279  // Propagate the reference track. Make sure we calculate the
280  // propagation matrix.
281 
282  TrackMatrix prop_temp;
283  if (prop_matrix == 0) prop_matrix = &prop_temp;
284 
285  // Do the propgation. The returned result will be the result of
286  // this propagatrion.
287 
288  result = vec_prop(*ref, psurf, dir, doDedx, prop_matrix, noise_matrix);
289  if (!!result) {
290 
291  // Propagation of reference track succeeded. Update the track
292  // state vector and surface of the track to be propagated.
293 
294  TrackVector diff = trk.getSurface()->getDiff(trk.getVector(), ref0.getVector());
295  TrackVector newvec = ref->getVector() + prod(*prop_matrix, diff);
296 
297  // Store updated state vector and surface.
298 
299  trk.setVector(newvec);
300  trk.setSurface(psurf);
301  trk.setDirection(ref->getDirection());
302  if (!trk.getSurface()->isEqual(*(ref->getSurface())))
303  throw cet::exception("Propagator") << __func__ << ": surface mismatch";
304 
305  // Final validity check. In case of failure, restore the track
306  // and reference track to their starting values.
307 
308  if (!trk.isValid()) {
309  result = std::nullopt;
310  trk = trk0;
311  *ref = ref0;
312  }
313  }
314  else {
315 
316  // Propagation failed.
317  // Restore the reference track to its starting value, so that we ensure
318  // the reference track and the actual track remain on the same surface.
319 
320  trk = trk0;
321  *ref = ref0;
322  }
323  }
324 
325  // Done.
326 
327  return result;
328  }
std::optional< double > vec_prop(KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
Propagate without error (long distance).
Definition: Propagator.cxx:52
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
TDirectory * dir
Definition: macro.C:5
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::optional< double > trkf::Propagator::noise_prop ( KETrack tre,
const std::shared_ptr< const Surface > &  psurf,
PropDirection  dir,
bool  doDedx,
KTrack ref = 0 
) const
inherited

Propagate with error and noise.

Propagate with error and noise.

Arguments:

tre - Track to propagate. psurf - Destination surface. dir - Propagation direction (FORWARD, BACKWARD, or UNKNOWN). doDedx - dE/dx enable/disable flag. ref - Reference track (for linearized propagation). Can be null.

Returned value: propagation distance + success flag.

Definition at line 382 of file Propagator.cxx.

References trkf::KETrack::getError(), trkf::Propagator::lin_prop(), and trkf::KETrack::setError().

Referenced by trkf::KalmanFilterAlg::buildTrack(), trkf::KalmanFilterAlg::extendTrack(), trkf::KalmanFilterAlg::fitMomentumMS(), trkf::KalmanFilterAlg::smoothTrack(), and trkf::KalmanFilterAlg::updateMomentum().

387  {
388  // Propagate without error, get propagation matrix and noise matrix.
389 
390  TrackMatrix prop_matrix;
391  TrackError noise_matrix;
392  std::optional<double> result =
393  lin_prop(tre, psurf, dir, doDedx, ref, &prop_matrix, &noise_matrix);
394 
395  // If propagation succeeded, update track error matrix.
396 
397  if (!!result) {
398  TrackMatrix temp = prod(tre.getError(), trans(prop_matrix));
399  TrackMatrix temp2 = prod(prop_matrix, temp);
400  TrackError newerr = ublas::symmetric_adaptor<TrackMatrix>(temp2);
401  newerr += noise_matrix;
402  tre.setError(newerr);
403  }
404 
405  // Done.
406 
407  return result;
408  }
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
std::optional< double > lin_prop(KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
Linearized propagate without error.
Definition: Propagator.cxx:249
TDirectory * dir
Definition: macro.C:5
std::optional< double > trkf::PropYZPlane::origin_vec_prop ( KTrack trk,
const std::shared_ptr< const Surface > &  porient,
TrackMatrix prop_matrix = 0 
) const
overridevirtual

Propagate without error to surface whose origin parameters coincide with track position.

Propagate without error to dynamically generated origin surface. Optionally return propagation matrix.

Arguments:

trk - Track to propagate. porient - Orientation surface. prop_matrix - Pointer to optional propagation matrix.

Returned value: propagation distance + success flag.

Propagation distance is always zero after successful propagation.

Implements trkf::Propagator.

Definition at line 257 of file PropYZPlane.cxx.

References dir, trkf::KTrack::getDirection(), trkf::KTrack::getPosition(), trkf::KTrack::getSurface(), trkf::KTrack::getVector(), trkf::KTrack::isValid(), trkf::SurfYZPlane::phi(), trkf::KTrack::setDirection(), trkf::KTrack::setSurface(), trkf::KTrack::setVector(), transformXYZPlane(), transformYZLine(), and transformYZPlane().

Referenced by trkf::PropAny::origin_vec_prop(), and short_vec_prop().

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";
276  Surface::TrackDirection dir = trk.getDirection();
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  }
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.
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.
TDirectory * dir
Definition: macro.C:5
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::optional< double > trkf::PropYZPlane::short_vec_prop ( KTrack trk,
const std::shared_ptr< const Surface > &  psurf,
Propagator::PropDirection  dir,
bool  doDedx,
TrackMatrix prop_matrix = 0,
TrackError noise_matrix = 0 
) const
overridevirtual

Propagate without error.

Propagate without error. Optionally return propagation matrix and noise matrix.

Arguments:

trk - Track to propagate. psurf - Destination surface. dir - Propagation direction (FORWARD, BACKWARD, or UNKNOWN). doDedx - dE/dx enable/disable flag. prop_matrix - Pointer to optional propagation matrix. noise_matrix - Pointer to optional noise matrix.

Returned value: propagation distance + success flag.

Implements trkf::Propagator.

Definition at line 50 of file PropYZPlane.cxx.

References trkf::Surface::BACKWARD, trkf::Propagator::BACKWARD, trkf::Propagator::dedx_prop(), trkf::Propagator::FORWARD, trkf::KTrack::getDirection(), trkf::Propagator::getDoDedx(), trkf::Propagator::getInteractor(), trkf::KTrack::getPosition(), trkf::KTrack::getVector(), trkf::KTrack::Mass(), origin_vec_prop(), trkf::SurfYZPlane::phi(), trkf::KTrack::setSurface(), trkf::KTrack::setVector(), trkf::Surface::UNKNOWN, trkf::Propagator::UNKNOWN, trkf::SurfYZPlane::x0(), trkf::SurfYZPlane::y0(), and trkf::SurfYZPlane::z0().

Referenced by trkf::PropAny::short_vec_prop().

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);
101  Surface::TrackDirection dir1 = trk.getDirection();
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  }
TrackDirection
Track direction enum.
Definition: Surface.h:54
const std::shared_ptr< const Interactor > & getInteractor() const
Definition: Propagator.h:109
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
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
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
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool trkf::PropYZPlane::transformXYZPlane ( double  theta1,
double  phi1,
double  phi2,
TrackVector vec,
Surface::TrackDirection dir,
TrackMatrix prop_matrix 
) const
private

Transform xyz plane -> yz plane.

Definition at line 643 of file PropYZPlane.cxx.

References trkf::Surface::BACKWARD, trkf::Surface::FORWARD, and trkf::Surface::UNKNOWN.

Referenced by origin_vec_prop().

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  }
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
TDirectory * dir
Definition: macro.C:5
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool trkf::PropYZPlane::transformYZLine ( double  phi1,
double  phi2,
TrackVector vec,
Surface::TrackDirection dir,
TrackMatrix prop_matrix 
) const
private

Transform yz line -> yz plane.

The following methods transform the track parameters from initial surface to SurfYZPlane origin surface, and generate a propagation matrix. The first group of function parameters are the orientation surface parameters of the initial surface. The second group of function parameters are the orientation parameters of the of the destination surface. The origin parameters of the destination surface are assumed to match the position of the track.

Definition at line 357 of file PropYZPlane.cxx.

Referenced by origin_vec_prop().

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  }
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
TDirectory * dir
Definition: macro.C:5
bool trkf::PropYZPlane::transformYZPlane ( double  phi1,
double  phi2,
TrackVector vec,
Surface::TrackDirection dir,
TrackMatrix prop_matrix 
) const
private

Transform yz plane -> yz plane.

Definition at line 548 of file PropYZPlane.cxx.

References trkf::Surface::BACKWARD, trkf::Surface::FORWARD, and trkf::Surface::UNKNOWN.

Referenced by origin_vec_prop().

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  }
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
TDirectory * dir
Definition: macro.C:5
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::optional< double > trkf::Propagator::vec_prop ( KTrack trk,
const std::shared_ptr< const Surface > &  psurf,
PropDirection  dir,
bool  doDedx,
TrackMatrix prop_matrix = 0,
TrackError noise_matrix = 0 
) const
inherited

Propagate without error (long distance).

Propagate without error (long distance).

Arguments:

trk - Track to propagate. psurf - Destination surface. dir - Propagation direction (FORWARD, BACKWARD, or UNKNOWN). doDedx - dE/dx enable/disable flag. prop_matrix - Return propagation matrix if not null. noise_matrix - Return noise matrix if not null.

Returned value: Propagation distance & success flag.

This method calls virtual method short_vec_prop in steps of some maximum size.

Definition at line 52 of file Propagator.cxx.

References util::abs(), larg4::dist(), e, detinfo::DetectorPropertiesData::Eloss(), trkf::Propagator::fDetProp, trkf::Propagator::fTcut, trkf::Propagator::getDoDedx(), trkf::KTrack::getMomentum(), trkf::KTrack::getPosition(), trkf::KTrack::getVector(), trkf::KTrack::Mass(), and trkf::Propagator::short_vec_prop().

Referenced by trkf::KalmanFilterAlg::fitMomentumMS(), trkf::Propagator::lin_prop(), trkf::KHitContainer::sort(), and trkf::KalmanFilterAlg::updateMomentum().

58  {
59  std::optional<double> result{std::nullopt};
60 
61  // Get the inverse momentum (assumed to be track parameter four).
62 
63  double pinv = trk.getVector()(4);
64 
65  // If dE/dx is not requested, or if inverse momentum is zero, then
66  // it is safe to propagate in one step. In this case, just pass
67  // the call to short_vec_prop with unlimited distance.
68 
69  bool dedx = getDoDedx() && doDedx;
70  if (!dedx || pinv == 0.)
71  result = short_vec_prop(trk, psurf, dir, dedx, prop_matrix, noise_matrix);
72 
73  else {
74 
75  // dE/dx is requested. In this case we limit the maximum
76  // propagation distance such that the kinetic energy of the
77  // particle should not change by more thatn 10%.
78 
79  // Initialize propagation matrix to unit matrix (if specified).
80 
81  int nvec = trk.getVector().size();
82  if (prop_matrix) *prop_matrix = ublas::identity_matrix<TrackVector::value_type>(nvec);
83 
84  // Initialize noise matrix to zero matrix (if specified).
85 
86  if (noise_matrix) {
87  noise_matrix->resize(nvec, nvec, false);
88  noise_matrix->clear();
89  }
90 
91  // Remember the starting track.
92 
93  KTrack trk0(trk);
94 
95  // Make pointer variables pointing to local versions of the
96  // propagation and noise matrices, or null if not specified.
97 
98  TrackMatrix local_prop_matrix;
99  TrackMatrix* plocal_prop_matrix = (prop_matrix == 0 ? 0 : &local_prop_matrix);
100  TrackError local_noise_matrix;
101  TrackError* plocal_noise_matrix = (noise_matrix == 0 ? 0 : &local_noise_matrix);
102 
103  // Cumulative propagation distance.
104 
105  double s = 0.;
106 
107  // Begin stepping loop.
108  // We put a maximum iteration count to prevent infinite loops caused by
109  // floating point pathologies. The iteration count is large enough to reach
110  // any point in the tpc using the minimum step size (for a reasonable tpc).
111 
112  bool done = false;
113  int nitmax = 10000; // Maximum number of iterations.
114  int nit = 0; // Iteration count.
115  while (!done) {
116 
117  // If the iteration count exceeds the maximum, return failure.
118 
119  ++nit;
120  if (nit > nitmax) {
121  trk = trk0;
122  result = std::nullopt;
123  return result;
124  }
125 
126  // Estimate maximum step distance according to the above
127  // stated principle.
128 
129  pinv = trk.getVector()(4);
130  double mass = trk.Mass();
131  double p = 1. / std::abs(pinv);
132  double e = std::hypot(p, mass);
133  double t = p * p / (e + mass);
134  double dedx = 0.001 * fDetProp.Eloss(p, mass, fTcut);
135  double smax = 0.1 * t / dedx;
136  if (smax <= 0.)
137  throw cet::exception("Propagator") << __func__ << ": maximum step " << smax << "\n";
138 
139  // Always allow a step of at least 0.3 cm (about one wire spacing).
140 
141  if (smax < 0.3) smax = 0.3;
142 
143  // First do a test propagation (without dE/dx and errors) to
144  // find the distance to the destination surface.
145 
146  KTrack trktest(trk);
147  std::optional<double> dist = short_vec_prop(trktest, psurf, dir, false, 0, 0);
148 
149  // If the test propagation failed, return failure.
150 
151  if (!dist) {
152  trk = trk0;
153  return dist;
154  }
155 
156  // Generate destionation surface for this step (either final
157  // destination, or some intermediate surface).
158 
159  std::shared_ptr<const Surface> pstep;
160  if (std::abs(*dist) <= smax) {
161  done = true;
162  pstep = psurf;
163  }
164  else {
165 
166  // Generate intermediate surface.
167  // First get point where track will intersect intermediate surface.
168 
169  double xyz0[3]; // Starting point.
170  trk.getPosition(xyz0);
171  double xyz1[3]; // Destination point.
172  trktest.getPosition(xyz1);
173  double frac = smax / std::abs(*dist);
174  double xyz[3]; // Intermediate point.
175  xyz[0] = xyz0[0] + frac * (xyz1[0] - xyz0[0]);
176  xyz[1] = xyz0[1] + frac * (xyz1[1] - xyz0[1]);
177  xyz[2] = xyz0[2] + frac * (xyz1[2] - xyz0[2]);
178 
179  // Choose orientation of intermediate surface perpendicular
180  // to track.
181 
182  double mom[3];
183  trk.getMomentum(mom);
184 
185  // Make intermediate surface object.
186 
187  pstep = std::shared_ptr<const Surface>(
188  new SurfXYZPlane(xyz[0], xyz[1], xyz[2], mom[0], mom[1], mom[2]));
189  }
190 
191  // Do the actual step propagation.
192 
193  dist = short_vec_prop(trk, pstep, dir, doDedx, plocal_prop_matrix, plocal_noise_matrix);
194 
195  // If the step propagation failed, return failure.
196 
197  if (!dist) {
198  trk = trk0;
199  return dist;
200  }
201 
202  // Update cumulative propagation distance.
203 
204  s += *dist;
205 
206  // Update cumulative propagation matrix (left-multiply).
207 
208  if (prop_matrix != 0) {
209  TrackMatrix temp = prod(*plocal_prop_matrix, *prop_matrix);
210  *prop_matrix = temp;
211  }
212 
213  // Update cumulative noise matrix.
214 
215  if (noise_matrix != 0) {
216  TrackMatrix temp = prod(*noise_matrix, trans(*plocal_prop_matrix));
217  TrackMatrix temp2 = prod(*plocal_prop_matrix, temp);
218  *noise_matrix = ublas::symmetric_adaptor<TrackMatrix>(temp2);
219  *noise_matrix += *plocal_noise_matrix;
220  }
221  }
222 
223  // Set the final result (distance + success).
224 
225  result = std::make_optional(s);
226  }
227 
228  // Done.
229 
230  return result;
231  }
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
constexpr auto abs(T v)
Returns the absolute value of the argument.
double fTcut
Maximum delta ray energy for dE/dx.
Definition: Propagator.h:165
virtual std::optional< double > short_vec_prop(KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const =0
Propagate without error (short distance).
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
detinfo::DetectorPropertiesData const & fDetProp
Definition: Propagator.h:164
double Eloss(double mom, double mass, double tcut) const
Restricted mean energy loss (dE/dx)
bool getDoDedx() const
Definition: Propagator.h:108
TDirectory * dir
Definition: macro.C:5
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Float_t e
Definition: plot.C:35
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33

The documentation for this class was generated from the following files: