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