LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TrackStatePropagator.cxx
Go to the documentation of this file.
6 
7 using namespace recob::tracking;
8 
9 namespace trkf {
10 
11  TrackStatePropagator::TrackStatePropagator(double minStep,
12  double maxElossFrac,
13  int maxNit,
14  double tcut,
15  double wrongDirDistTolerance,
16  bool propPinvErr)
17  : fMinStep(minStep)
18  , fMaxElossFrac(maxElossFrac)
19  , fMaxNit(maxNit)
20  , fTcut(tcut)
21  , fWrongDirDistTolerance(wrongDirDistTolerance)
22  , fPropPinvErr(propPinvErr)
23  {
24  larprop = lar::providerFrom<detinfo::LArPropertiesService>();
25  }
26 
28 
30  const detinfo::DetectorPropertiesData& detProp,
31  const TrackState& origin,
32  const Plane& target,
33  bool dodedx,
34  bool domcs,
35  PropDirection dir) const
36  {
37  //
38  // 1- find distance to target plane
39  auto [distance, sperp] = distancePairToPlane(success, origin, target);
40  //
41  if ((distance < -fWrongDirDistTolerance && dir == FORWARD) ||
42  (distance > fWrongDirDistTolerance && dir == BACKWARD)) {
43  success = false;
44  return origin;
45  }
46  //
47  // 2- propagate 3d position by distance, form propagated state on plane parallel to origin plane
49  origin.position(), origin.momentum() * origin.parameters()[4], distance);
50  TrackState tmpState(
51  SVector5(0., 0., origin.parameters()[2], origin.parameters()[3], origin.parameters()[4]),
52  origin.covariance(),
53  Plane(p, origin.plane().direction()),
54  origin.isTrackAlongPlaneDir(),
55  origin.pID());
56  //
57  // 3- rotate state to target plane
58  double dw2dw1 = 0;
59  tmpState = rotateToPlane(success, tmpState, target, dw2dw1);
60  SVector5 par5d = tmpState.parameters();
61  SMatrixSym55 cov5d = tmpState.covariance();
62  //
63  // 4- compute jacobian to propagate uncertainties
64  SMatrix55 pm = ROOT::Math::SMatrixIdentity(); //diagonal elements are 1
65  pm(0, 2) = sperp; // du2/d(dudw1);
66  pm(1, 3) = sperp; // dv2/d(dvdw1);
67  //
68  // 5- apply material effects, performing more iterations if the distance is long
69  bool arrived = false;
70  int nit = 0; // Iteration count.
71  double deriv = 1.;
72  SMatrixSym55 noise_matrix;
73  while (!arrived) {
74  ++nit;
75  if (nit > fMaxNit) {
76  success = false;
77  return origin;
78  }
79  // Estimate maximum step distance, such that fMaxElossFrac of initial energy is lost by dedx
80  const double mass = origin.mass();
81  const double p = 1. / par5d[4];
82  const double e = std::hypot(p, mass);
83  const double t = e - mass;
84  const double dedx = 0.001 * detProp.Eloss(std::abs(p), mass, fTcut);
85  const double range = t / dedx;
86  const double smax = std::max(fMinStep, fMaxElossFrac * range);
87  double s = distance;
88  if (domcs && smax > 0 && std::abs(s) > smax) {
89  if (fMaxNit == 1) {
90  success = false;
91  return origin;
92  }
93  s = (s > 0 ? smax : -smax);
94  distance -= s;
95  }
96  else
97  arrived = true;
98  // now apply material effects
99  if (domcs) {
100  bool flip = false;
101  if (origin.isTrackAlongPlaneDir() == true && dw2dw1 < 0.) flip = true;
102  if (origin.isTrackAlongPlaneDir() == false && dw2dw1 > 0.) flip = true;
103  bool ok = apply_mcs(detProp,
104  par5d[2],
105  par5d[3],
106  par5d[4],
107  origin.mass(),
108  s,
109  range,
110  p,
111  e * e,
112  flip,
113  noise_matrix);
114  if (!ok) {
115  success = false;
116  return origin;
117  }
118  }
119  if (dodedx) { apply_dedx(par5d(4), detProp, dedx, e, origin.mass(), s, deriv); }
120  }
121  if (fPropPinvErr) pm(4, 4) *= deriv;
122  //
123  // 6- create final track state
124  cov5d = ROOT::Math::Similarity(pm, cov5d); //*rj
125  cov5d = cov5d + noise_matrix;
126  TrackState trackState(
127  par5d, cov5d, target, origin.momentum().Dot(target.direction()) > 0, origin.pID());
128  return trackState;
129  }
130 
132  const TrackState& origin,
133  const Plane& target,
134  double& dw2dw1) const
135  {
136  const bool isTrackAlongPlaneDir = origin.momentum().Dot(target.direction()) > 0;
137  //
138  SVector5 par5 = origin.parameters();
139  const double sinA1 = origin.plane().sinAlpha();
140  const double cosA1 = origin.plane().cosAlpha();
141  const double sinA2 = target.sinAlpha();
142  const double cosA2 = target.cosAlpha();
143  const double sinB1 = origin.plane().sinBeta();
144  const double cosB1 = origin.plane().cosBeta();
145  const double sinB2 = target.sinBeta();
146  const double cosB2 = target.cosBeta();
147  const double sindB = -sinB1 * cosB2 + cosB1 * sinB2;
148  const double cosdB = cosB1 * cosB2 + sinB1 * sinB2;
149  const double ruu = cosA1 * cosA2 + sinA1 * sinA2 * cosdB;
150  const double ruv = sinA2 * sindB;
151  const double ruw = sinA1 * cosA2 - cosA1 * sinA2 * cosdB;
152  const double rvu = -sinA1 * sindB;
153  const double rvv = cosdB;
154  const double rvw = cosA1 * sindB;
155  const double rwu = cosA1 * sinA2 - sinA1 * cosA2 * cosdB;
156  const double rwv = -cosA2 * sindB;
157  const double rww = sinA1 * sinA2 + cosA1 * cosA2 * cosdB;
158  dw2dw1 = par5[2] * rwu + par5[3] * rwv + rww;
159  if (dw2dw1 == 0.) {
160  success = false;
161  return origin;
162  }
163  const double dudw2 = (par5[2] * ruu + par5[3] * ruv + ruw) / dw2dw1;
164  const double dvdw2 = (par5[2] * rvu + par5[3] * rvv + rvw) / dw2dw1;
165  SMatrix55 pm;
166  //
167  pm(0, 0) = ruu - dudw2 * rwu; // du2/du1
168  pm(1, 0) = rvu - dvdw2 * rwu; // dv2/du1
169  pm(2, 0) = 0.; // d(dudw2)/du1
170  pm(3, 0) = 0.; // d(dvdw2)/du1
171  pm(4, 0) = 0.; // d(pinv2)/du1
172  //
173  pm(0, 1) = ruv - dudw2 * rwv; // du2/dv1
174  pm(1, 1) = rvv - dvdw2 * rwv; // dv2/dv1
175  pm(2, 1) = 0.; // d(dudw2)/dv1
176  pm(3, 1) = 0.; // d(dvdw2)/dv1
177  pm(4, 1) = 0.; // d(pinv2)/dv1
178  //
179  pm(0, 2) = 0.; // du2/d(dudw1);
180  pm(1, 2) = 0.; // dv2/d(dudw1);
181  pm(2, 2) = (ruu - dudw2 * rwu) / dw2dw1; // d(dudw2)/d(dudw1);
182  pm(3, 2) = (rvu - dvdw2 * rwu) / dw2dw1; // d(dvdw2)/d(dudw1);
183  pm(4, 2) = 0.; // d(pinv2)/d(dudw1);
184  //
185  pm(0, 3) = 0.; // du2/d(dvdw1);
186  pm(1, 3) = 0.; // dv2/d(dvdw1);
187  pm(2, 3) = (ruv - dudw2 * rwv) / dw2dw1; // d(dudw2)/d(dvdw1);
188  pm(3, 3) = (rvv - dvdw2 * rwv) / dw2dw1; // d(dvdw2)/d(dvdw1);
189  pm(4, 3) = 0.; // d(pinv2)/d(dvdw1);
190  //
191  pm(0, 4) = 0.; // du2/d(pinv1);
192  pm(1, 4) = 0.; // dv2/d(pinv1);
193  pm(2, 4) = 0.; // d(dudw2)/d(pinv1);
194  pm(3, 4) = 0.; // d(dvdw2)/d(pinv1);
195  pm(4, 4) = 1.; // d(pinv2)/d(pinv1);
196  //
197  par5[0] = (origin.position().X() - target.position().X()) * cosA2 +
198  (origin.position().Y() - target.position().Y()) * sinA2 * sinB2 -
199  (origin.position().Z() - target.position().Z()) * sinA2 * cosB2;
200  par5[1] = (origin.position().Y() - target.position().Y()) * cosB2 +
201  (origin.position().Z() - target.position().Z()) * sinB2;
202  par5[2] = dudw2;
203  par5[3] = dvdw2;
204  //
205  success = true;
206  return TrackState(par5,
207  ROOT::Math::Similarity(pm, origin.covariance()),
208  Plane(origin.position(), target.direction()),
209  isTrackAlongPlaneDir,
210  origin.pID());
211  }
212 
214  const Point_t& origpos,
215  const Vector_t& origmom,
216  const Plane& target) const
217  {
218  const Point_t& targpos = target.position();
219  const Vector_t& targdir = target.direction();
220  //check that origmom is not along the plane, i.e. targdir.Dot(origmom.Unit())=0
221  if (targdir.Dot(origmom.Unit()) == 0) {
222  success = false;
223  return DBL_MAX;
224  }
225  //distance along track direction
226  double s = targdir.Dot(targpos - origpos) / targdir.Dot(origmom.Unit());
227  success = true;
228  return s;
229  }
230 
232  const Point_t& origpos,
233  const Plane& target) const
234  {
235  const Point_t& targpos = target.position();
236  const Vector_t& targdir = target.direction();
237  //point-plane distance projected along direction orthogonal to the plane
238  double sperp = targdir.Dot(targpos - origpos);
239  success = true;
240  return sperp;
241  }
242 
243  std::pair<double, double> TrackStatePropagator::distancePairToPlane(bool& success,
244  const Point_t& origpos,
245  const Vector_t& origmom,
246  const Plane& target) const
247  {
248  const Point_t& targpos = target.position();
249  const Vector_t& targdir = target.direction();
250  //check that origmom is not along the plane, i.e. targdir.Dot(origmom.Unit())=0
251  if (targdir.Dot(origmom.Unit()) == 0) {
252  success = false;
253  return std::pair<double, double>(DBL_MAX, DBL_MAX);
254  }
255  //point-plane distance projected along direction orthogonal to the plane
256  double sperp = targdir.Dot(targpos - origpos);
257  //distance along track direction
258  double s = sperp / targdir.Dot(origmom.Unit());
259  success = true;
260  return std::pair<double, double>(s, sperp);
261  }
262 
264  detinfo::DetectorPropertiesData const& detProp,
265  double dedx,
266  double e1,
267  double mass,
268  double s,
269  double& deriv) const
270  {
271  // For infinite initial momentum, return with infinite momentum.
272  if (pinv == 0.) return;
273  //
274  const double emid = e1 - 0.5 * s * dedx;
275  if (emid > mass) {
276  const double pmid = std::sqrt(emid * emid - mass * mass);
277  const double e2 = e1 - 0.001 * s * detProp.Eloss(pmid, mass, fTcut);
278  if (e2 > mass) {
279  const double p2 = std::sqrt(e2 * e2 - mass * mass);
280  double pinv2 = 1. / p2;
281  if (pinv < 0.) pinv2 = -pinv2;
282  // derivative
283  deriv = pinv2 * pinv2 * pinv2 * e2 / (pinv * pinv * pinv * e1);
284  // update result.
285  pinv = pinv2;
286  }
287  }
288  return;
289  }
290 
292  double dudw,
293  double dvdw,
294  double pinv,
295  double mass,
296  double s,
297  double range,
298  double p,
299  double e2,
300  bool flipSign,
301  SMatrixSym55& noise_matrix) const
302  {
303  // If distance is zero, or momentum is infinite, return zero noise.
304 
305  if (pinv == 0. || s == 0.) return true;
306 
307  // Use crude estimate of the range of the track.
308  if (range > 100.) range = 100.;
309  const double p2 = p * p;
310 
311  // Calculate the radiation length in cm.
312  const double x0 = larprop->RadiationLength() / detProp.Density();
313 
314  // Calculate projected rms scattering angle.
315  // Use the estimted range in the logarithm factor.
316  // Use the incremental propagation distance in the square root factor.
317  const double betainv = std::sqrt(1. + pinv * pinv * mass * mass);
318  const double theta_fact = (0.0136 * pinv * betainv) * (1. + 0.038 * std::log(range / x0));
319  const double theta02 = theta_fact * theta_fact * std::abs(s / x0);
320 
321  // Calculate some common factors needed for multiple scattering.
322  const double ufact2 = 1. + dudw * dudw;
323  const double vfact2 = 1. + dvdw * dvdw;
324  const double uvfact2 = 1. + dudw * dudw + dvdw * dvdw;
325  const double uvfact = std::sqrt(uvfact2);
326  const double uv = dudw * dvdw;
327  const double dist2_3 = s * s / 3.;
328  double dist_2 = std::abs(s) / 2.;
329  if (flipSign) dist_2 = -dist_2;
330 
331  // Calculate energy loss fluctuations.
332 
333  const double evar = 1.e-6 * detProp.ElossVar(p, mass) * std::abs(s); // E variance (GeV^2).
334  const double pinvvar = evar * e2 / (p2 * p2 * p2); // Inv. p variance (1/GeV^2)
335 
336  // Update elements of noise matrix.
337 
338  // Position submatrix.
339  noise_matrix(0, 0) += dist2_3 * theta02 * ufact2; // sigma^2(u,u)
340  noise_matrix(1, 0) += dist2_3 * theta02 * uv; // sigma^2(u,v)
341  noise_matrix(1, 1) += dist2_3 * theta02 * vfact2; // sigma^2(v,v)
342 
343  // Slope submatrix.
344  noise_matrix(2, 2) += theta02 * uvfact2 * ufact2; // sigma^2(u', u')
345  noise_matrix(3, 2) += theta02 * uvfact2 * uv; // sigma^2(v', u')
346  noise_matrix(3, 3) += theta02 * uvfact2 * vfact2; // sigma^2(v', v')
347 
348  // Same-view position-slope correlations.
349  noise_matrix(2, 0) += dist_2 * theta02 * uvfact * ufact2; // sigma^2(u', u)
350  noise_matrix(3, 1) += dist_2 * theta02 * uvfact * vfact2; // sigma^2(v', v)
351 
352  // Opposite-view position-slope correlations.
353  noise_matrix(2, 1) += dist_2 * theta02 * uvfact * uv; // sigma^2(u', v)
354  noise_matrix(3, 0) += dist_2 * theta02 * uvfact * uv; // sigma^2(v', u)
355 
356  // Momentum correlations (zero).
357  // noise_matrix(4,0) += 0.; // sigma^2(pinv, u)
358  // noise_matrix(4,1) += 0.; // sigma^2(pinv, v)
359  // noise_matrix(4,2) += 0.; // sigma^2(pinv, u')
360  // noise_matrix(4,3) += 0.; // sigma^2(pinv, v')
361 
362  // Energy loss fluctuations.
363  if (fPropPinvErr) noise_matrix(4, 4) += pinvvar; // sigma^2(pinv, pinv)
364 
365  // Done (success).
366  return true;
367  }
368 
369 } // end namespace trkf
double cosAlpha() const
Return cached values of trigonometric function for angles defining the plane.
recob::tracking::Plane Plane
Class for track parameters (and errors) defined on a recob::tracking::Plane.
Definition: TrackState.h:93
Vector_t const & direction() const
Reference direction orthogonal to the plane.
Definition: TrackingPlane.h:70
int fMaxNit
Maximum number of iterations.
double ElossVar(double mom, double mass) const
Energy loss fluctuation ( )
Utilities related to art service access.
const Vector_t & momentum() const
momentum of the track
Definition: TrackState.h:116
const SVector5 & parameters() const
track parameters defined on the plane
Definition: TrackState.h:108
recob::tracking::SMatrixSym55 SMatrixSym55
Definition: TrackState.h:15
constexpr auto abs(T v)
Returns the absolute value of the argument.
double cosBeta() const
Return cached values of trigonometric function for angles defining the plane.
recob::tracking::SMatrix55 SMatrix55
Definition: TrackState.h:14
TrackState propagateToPlane(bool &success, const detinfo::DetectorPropertiesData &detProp, const TrackState &origin, const Plane &target, bool dodedx, bool domcs, PropDirection dir=FORWARD) const
Main function for propagation of a TrackState to a Plane.
double distanceToPlane(bool &success, const Point_t &origpos, const Vector_t &origdir, const Plane &target) const
Distance of a TrackState (Point and Vector) to a Plane, along the TrackState direction.
bool apply_mcs(detinfo::DetectorPropertiesData const &detProp, double dudw, double dvdw, double pinv, double mass, double s, double range, double p, double e2, bool flipSign, SMatrixSym55 &noise_matrix) const
Apply multiple coulomb scattering.
recob::tracking::Point_t Point_t
double mass() const
mass hypthesis of the track
Definition: TrackState.h:120
double fMinStep
Minimum propagation step length guaranteed.
void apply_dedx(double &pinv, detinfo::DetectorPropertiesData const &detProp, double dedx, double e1, double mass, double s, double &deriv) const
Apply energy loss.
const Point_t & position() const
position of the track
Definition: TrackState.h:114
double fTcut
Maximum delta ray energy for dE/dx.
bool isTrackAlongPlaneDir() const
is the track momentum along the plane direction?
Definition: TrackState.h:141
recob::tracking::SVector5 SVector5
Definition: TrackState.h:12
PropDirection
Propagation direction enum.
int pID() const
particle id hypthesis of the track
Definition: TrackState.h:118
Point_t const & position() const
Reference position on the plane.
Definition: TrackingPlane.h:66
TrackState rotateToPlane(bool &success, const TrackState &origin, const Plane &target) const
Rotation of a TrackState to a Plane (zero distance propagation)
Point_t propagatedPosByDistance(const Point_t &origpos, const Vector_t &origdir, double distance) const
Quick accesss to the propagated position given a distance.
double perpDistanceToPlane(bool &success, const Point_t &origpos, const Plane &target) const
Distance of a TrackState (Point) to a Plane along the direction orthogonal to the Plane...
double Density(double temperature=0.) const
Returns argon density at a given temperature.
std::pair< double, double > distancePairToPlane(bool &success, const Point_t &origpos, const Vector_t &origdir, const Plane &target) const
Return both direction types in one go.
const detinfo::LArProperties * larprop
Class defining a plane for tracking. It provides various functionalities to convert track parameters ...
Definition: TrackingPlane.h:37
double Eloss(double mom, double mass, double tcut) const
Restricted mean energy loss (dE/dx)
bool fPropPinvErr
Propagate error on 1/p or not (in order to avoid infs, it should be set to false when 1/p not updated...
TDirectory * dir
Definition: macro.C:5
double fWrongDirDistTolerance
Allowed propagation distance in the wrong direction.
double sinAlpha() const
Return cached values of trigonometric function for angles defining the plane.
virtual double RadiationLength() const =0
const SMatrixSym55 & covariance() const
track parameter covariance matrix on the plane
Definition: TrackState.h:110
cout<< "-> Edep in the target
Definition: analysis.C:53
double fMaxElossFrac
Maximum propagation step length based on fraction of energy loss.
double sinBeta() const
Return cached values of trigonometric function for angles defining the plane.
Float_t e
Definition: plot.C:35
const Plane & plane() const
plane where the parameters are defined
Definition: TrackState.h:112
recob::tracking::Vector_t Vector_t
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:229