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

Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Track or Trajectory. More...

#include "TrajectoryMCSFitter.h"

Classes

struct  Config
 
struct  ScanResult
 

Public Types

using Parameters = fhicl::Table< Config >
 

Public Member Functions

 TrajectoryMCSFitter (int pIdHyp, int minNSegs, double segLen, int minHitsPerSegment, int nElossSteps, int eLossMode, double pMin, double pMax, double pStepCoarse, double pStep, double fineScanWindow, const std::array< double, 5 > &angResol, const std::array< double, 5 > &hlParams, double segLenTolerance, bool applySCEcorr)
 
 TrajectoryMCSFitter (const Parameters &p)
 
recob::MCSFitResult fitMcs (const recob::TrackTrajectory &traj) const
 
recob::MCSFitResult fitMcs (const recob::Track &track) const
 
recob::MCSFitResult fitMcs (const recob::Trajectory &traj) const
 
recob::MCSFitResult fitMcs (const recob::TrackTrajectory &traj, int pid) const
 
recob::MCSFitResult fitMcs (const recob::Track &track, int pid) const
 
recob::MCSFitResult fitMcs (const recob::Trajectory &traj, int pid) const
 
void breakTrajInSegments (const recob::TrackTrajectory &traj, std::vector< size_t > &breakpoints, std::vector< float > &segradlengths, std::vector< float > &cumseglens) const
 
void linearRegression (const recob::TrackTrajectory &traj, const size_t firstPoint, const size_t lastPoint, recob::tracking::Vector_t &pcdir) const
 
double mcsLikelihood (double p, double theta0x, std::vector< float > &dthetaij, std::vector< float > &seg_nradl, std::vector< float > &cumLen, bool fwd, int pid) const
 
const ScanResult doLikelihoodScan (std::vector< float > &dtheta, std::vector< float > &seg_nradlengths, std::vector< float > &cumLen, bool fwdFit, int pid, float detAngResol) const
 
const ScanResult doLikelihoodScan (std::vector< float > &dtheta, std::vector< float > &seg_nradlengths, std::vector< float > &cumLen, bool fwdFit, int pid, float pmin, float pmax, float pstep, float detAngResol) const
 
double HighlandFirstTerm (const double p) const
 
double DetectorAngularResolution (const double uz) const
 
double mass (int pid) const
 
double energyLossBetheBloch (const double mass, const double e2) const
 
double energyLossLandau (const double mass2, const double E2, const double x) const
 
double GetE (const double initial_E, const double length_travelled, const double mass) const
 
int minNSegs () const
 
double segLen () const
 
double segLenTolerance () const
 

Private Attributes

int pIdHyp_
 
int minNSegs_
 
double segLen_
 
int minHitsPerSegment_
 
int nElossSteps_
 
int eLossMode_
 
double pMin_
 
double pMax_
 
double pStepCoarse_
 
double pStep_
 
double fineScanWindow_
 
std::array< double, 5 > angResol_
 
std::array< double, 5 > hlParams_
 
double segLenTolerance_
 
bool applySCEcorr_
 

Detailed Description

Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Track or Trajectory.

Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Track or Trajectory.

Inputs are: a Track or Trajectory, and various fit parameters (pIdHypothesis, minNumSegments, segmentLength, pMin, pMax, pStep, angResol)

Outputs are: a recob::MCSFitResult, containing: resulting momentum, momentum uncertainty, and best likelihood value (both for fwd and bwd fit); vector of comulative segment (radiation) lengths, vector of scattering angles, and PID hypothesis used in the fit. Note that the comulative segment length is what is used to compute the energy loss, but the segment length is actually slightly different, so the output can be used to reproduce the original results but they will not be identical (but very close).

For configuration options see TrajectoryMCSFitter::Config

Author
G. Cerati (FNAL, MicroBooNE)
Date
2017
Version
1.0

Definition at line 44 of file TrajectoryMCSFitter.h.

Member Typedef Documentation

Constructor & Destructor Documentation

trkf::TrajectoryMCSFitter::TrajectoryMCSFitter ( int  pIdHyp,
int  minNSegs,
double  segLen,
int  minHitsPerSegment,
int  nElossSteps,
int  eLossMode,
double  pMin,
double  pMax,
double  pStepCoarse,
double  pStep,
double  fineScanWindow,
const std::array< double, 5 > &  angResol,
const std::array< double, 5 > &  hlParams,
double  segLenTolerance,
bool  applySCEcorr 
)
inline

Definition at line 116 of file TrajectoryMCSFitter.h.

References trkf::TrajectoryMCSFitter::Config::angResol, angResol_, trkf::TrajectoryMCSFitter::Config::applySCEcorr, applySCEcorr_, trkf::TrajectoryMCSFitter::Config::eLossMode, eLossMode_, trkf::TrajectoryMCSFitter::Config::fineScanWindow, fineScanWindow_, trkf::TrajectoryMCSFitter::Config::hlParams, hlParams_, trkf::TrajectoryMCSFitter::Config::minHitsPerSegment, minHitsPerSegment_, minNSegs(), minNSegs_, trkf::TrajectoryMCSFitter::Config::nElossSteps, nElossSteps_, pIdHyp_, trkf::TrajectoryMCSFitter::Config::pMax, pMax_, trkf::TrajectoryMCSFitter::Config::pMin, pMin_, trkf::TrajectoryMCSFitter::Config::pStep, pStep_, trkf::TrajectoryMCSFitter::Config::pStepCoarse, pStepCoarse_, segLen(), segLen_, trkf::TrajectoryMCSFitter::Config::segLenTolerance, and segLenTolerance_.

131  {
132  pIdHyp_ = pIdHyp;
134  segLen_ = segLen;
135  minHitsPerSegment_ = minHitsPerSegment;
136  nElossSteps_ = nElossSteps;
137  eLossMode_ = eLossMode;
138  pMin_ = pMin;
139  pMax_ = pMax;
140  pStepCoarse_ = pStepCoarse;
141  pStep_ = pStep;
142  fineScanWindow_ = fineScanWindow;
143  angResol_ = angResol;
144  hlParams_ = hlParams;
146  applySCEcorr_ = applySCEcorr;
147  }
std::array< double, 5 > angResol_
std::array< double, 5 > hlParams_
trkf::TrajectoryMCSFitter::TrajectoryMCSFitter ( const Parameters p)
inlineexplicit

Definition at line 148 of file TrajectoryMCSFitter.h.

149  : TrajectoryMCSFitter(p().pIdHypothesis(),
150  p().minNumSegments(),
151  p().segmentLength(),
152  p().minHitsPerSegment(),
153  p().nElossSteps(),
154  p().eLossMode(),
155  p().pMin(),
156  p().pMax(),
157  p().pStepCoarse(),
158  p().pStep(),
159  p().fineScanWindow(),
160  p().angResol(),
161  p().hlParams(),
162  p().segLenTolerance(),
163  p().applySCEcorr())
164  {}
TrajectoryMCSFitter(int pIdHyp, int minNSegs, double segLen, int minHitsPerSegment, int nElossSteps, int eLossMode, double pMin, double pMax, double pStepCoarse, double pStep, double fineScanWindow, const std::array< double, 5 > &angResol, const std::array< double, 5 > &hlParams, double segLenTolerance, bool applySCEcorr)

Member Function Documentation

void TrajectoryMCSFitter::breakTrajInSegments ( const recob::TrackTrajectory traj,
std::vector< size_t > &  breakpoints,
std::vector< float > &  segradlengths,
std::vector< float > &  cumseglens 
) const

Definition at line 73 of file TrajectoryMCSFitter.cxx.

References recob::TrackTrajectory::DirectionAtPoint(), geo::GeometryCore::FindTPCAtPosition(), recob::TrackTrajectory::FirstValidPoint(), recob::TrackTrajectory::InvalidIndex, geo::CryostatID::isValid, recob::TrackTrajectory::LastValidPoint(), recob::TrackTrajectory::Length(), recob::TrackTrajectory::LocationAtPoint(), recob::TrackTrajectory::NextValidPoint(), and geo::TPCID::TPC.

Referenced by fitMcs().

77 {
78  //
80  auto const* _SCE = (applySCEcorr_ ? lar::providerFrom<spacecharge::SpaceChargeService>() : NULL);
81  //
82  const double trajlen = traj.Length();
83  const double thisSegLen =
84  (trajlen > (segLen_ * minNSegs_) ? segLen_ : trajlen / double(minNSegs_));
85  // std::cout << "track with length=" << trajlen << " broken in nseg=" << std::max(minNSegs_,int(trajlen/segLen_)) << " of length=" << thisSegLen << " where segLen_=" << segLen_ << std::endl;
86  //
87  constexpr double lar_radl_inv = 1. / 14.0;
88  cumseglens.push_back(0.); //first segment has zero cumulative length from previous segments
89  double thislen = 0.;
90  double totlen = 0.;
91  auto nextValid = traj.FirstValidPoint();
92  breakpoints.push_back(nextValid);
93  auto pos0 = traj.LocationAtPoint(nextValid);
94  if (applySCEcorr_) {
95  geo::TPCID tpcid = geom->FindTPCAtPosition(pos0);
96  geo::Vector_t pos0_offset(0., 0., 0.);
97  if (tpcid.isValid) { pos0_offset = _SCE->GetCalPosOffsets(pos0, tpcid.TPC); }
98  pos0.SetX(pos0.X() - pos0_offset.X());
99  pos0.SetY(pos0.Y() + pos0_offset.Y());
100  pos0.SetZ(pos0.Z() + pos0_offset.Z());
101  }
102  auto dir0 = traj.DirectionAtPoint(nextValid);
103  nextValid = traj.NextValidPoint(nextValid + 1);
104  int npoints = 0;
105  while (nextValid != recob::TrackTrajectory::InvalidIndex) {
106  if (npoints == 0) dir0 = traj.DirectionAtPoint(nextValid);
107  auto pos1 = traj.LocationAtPoint(nextValid);
108  if (applySCEcorr_) {
109  geo::TPCID tpcid = geom->FindTPCAtPosition(pos1);
110  geo::Vector_t pos1_offset(0., 0., 0.);
111  if (tpcid.isValid) { pos1_offset = _SCE->GetCalPosOffsets(pos1, tpcid.TPC); }
112  pos1.SetX(pos1.X() - pos1_offset.X());
113  pos1.SetY(pos1.Y() + pos1_offset.Y());
114  pos1.SetZ(pos1.Z() + pos1_offset.Z());
115  }
116  //increments along the initial direction of the segment
117  auto step = (pos1 - pos0).R();
118  thislen += dir0.Dot(pos1 - pos0);
119  totlen += step;
120  pos0 = pos1;
121  // //fixme: testing alternative approaches here
122  // //test1: increments following scatters
123  // auto step = (pos1-pos0).R();
124  // thislen += step;
125  // totlen += step;
126  // pos0=pos1;
127  // //test2: end-start distance along the initial direction of the segment
128  // thislen = dir0.Dot(pos1-pos0);
129  // totlen = (pos1-pos0).R();
130  //
131  npoints++;
132  if (thislen >= (thisSegLen - segLenTolerance_)) {
133  breakpoints.push_back(nextValid);
134  if (npoints >= minHitsPerSegment_)
135  segradlengths.push_back(thislen * lar_radl_inv);
136  else
137  segradlengths.push_back(-999.);
138  cumseglens.push_back(totlen);
139  thislen = 0.;
140  npoints = 0;
141  }
142  nextValid = traj.NextValidPoint(nextValid + 1);
143  }
144  //then add last segment
145  if (thislen > 0.) {
146  breakpoints.push_back(traj.LastValidPoint() + 1);
147  segradlengths.push_back(thislen * lar_radl_inv);
148  cumseglens.push_back(cumseglens.back() + thislen);
149  }
150  return;
151 }
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
T DirectionAtPoint(unsigned int p) const
Direction at point p. Use e.g. as:
size_t LastValidPoint() const
Returns the index of the last valid point in the trajectory.
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:210
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
double Length(size_t startAt=0) const
Returns the approximate length of the trajectory.
T LocationAtPoint(unsigned int p) const
Position at point p. Use e.g. as:
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
size_t FirstValidPoint() const
Returns the index of the first valid point in the trajectory.
static constexpr size_t InvalidIndex
Value returned on failed index queries.
size_t NextValidPoint(size_t index) const
Returns the index of the next valid point in the trajectory.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:399
double trkf::TrajectoryMCSFitter::DetectorAngularResolution ( const double  uz) const
inline

Definition at line 231 of file TrajectoryMCSFitter.h.

References angResol_.

232  {
233  return angResol_[0] / (uz * uz) + angResol_[1] / uz + angResol_[2] + angResol_[3] * uz +
234  angResol_[4] * uz * uz;
235  }
std::array< double, 5 > angResol_
const TrajectoryMCSFitter::ScanResult TrajectoryMCSFitter::doLikelihoodScan ( std::vector< float > &  dtheta,
std::vector< float > &  seg_nradlengths,
std::vector< float > &  cumLen,
bool  fwdFit,
int  pid,
float  detAngResol 
) const

Definition at line 203 of file TrajectoryMCSFitter.cxx.

References trkf::TrajectoryMCSFitter::ScanResult::p, and trkf::TrajectoryMCSFitter::ScanResult::pUnc.

210 {
211 
212  //do a first, coarse scan
213  const ScanResult& coarseRes = doLikelihoodScan(
214  dtheta, seg_nradlengths, cumLen, fwdFit, pid, pMin_, pMax_, pStepCoarse_, detAngResol);
215 
216  float pmax = std::min(coarseRes.p + fineScanWindow_, pMax_);
217  float pmin = std::max(coarseRes.p - fineScanWindow_, pMin_);
218  if (coarseRes.pUnc < (std::numeric_limits<float>::max() - 1.)) {
219  pmax = std::min(coarseRes.p + 2 * coarseRes.pUnc, pMax_);
220  pmin = std::max(coarseRes.p - 2 * coarseRes.pUnc, pMin_);
221  }
222 
223  //do the fine grained scan in a smaller region
224  const ScanResult& refineRes =
225  doLikelihoodScan(dtheta, seg_nradlengths, cumLen, fwdFit, pid, pmin, pmax, pStep_, detAngResol);
226 
227  return refineRes;
228 }
const ScanResult doLikelihoodScan(std::vector< float > &dtheta, std::vector< float > &seg_nradlengths, std::vector< float > &cumLen, bool fwdFit, int pid, float detAngResol) const
const TrajectoryMCSFitter::ScanResult TrajectoryMCSFitter::doLikelihoodScan ( std::vector< float > &  dtheta,
std::vector< float > &  seg_nradlengths,
std::vector< float > &  cumLen,
bool  fwdFit,
int  pid,
float  pmin,
float  pmax,
float  pstep,
float  detAngResol 
) const

Definition at line 153 of file TrajectoryMCSFitter.cxx.

163 {
164  int best_idx = -1;
165  float best_logL = std::numeric_limits<float>::max();
166  float best_p = -1.0;
167  std::vector<float> vlogL;
168  for (float p_test = pmin; p_test <= pmax; p_test += pstep) {
169  float logL = mcsLikelihood(p_test, detAngResol, dtheta, seg_nradlengths, cumLen, fwdFit, pid);
170  if (logL < best_logL) {
171  best_p = p_test;
172  best_logL = logL;
173  best_idx = vlogL.size();
174  }
175  vlogL.push_back(logL);
176  }
177  //
178  //uncertainty from left side scan
179  float lunc = -1.;
180  if (best_idx > 0) {
181  for (int j = best_idx - 1; j >= 0; j--) {
182  float dLL = vlogL[j] - vlogL[best_idx];
183  if (dLL >= 0.5) {
184  lunc = (best_idx - j) * pstep;
185  break;
186  }
187  }
188  }
189  //uncertainty from right side scan
190  float runc = -1.;
191  if (best_idx < int(vlogL.size() - 1)) {
192  for (unsigned int j = best_idx + 1; j < vlogL.size(); j++) {
193  float dLL = vlogL[j] - vlogL[best_idx];
194  if (dLL >= 0.5) {
195  runc = (j - best_idx) * pstep;
196  break;
197  }
198  }
199  }
200  return ScanResult(best_p, std::max(lunc, runc), best_logL);
201 }
double mcsLikelihood(double p, double theta0x, std::vector< float > &dthetaij, std::vector< float > &seg_nradl, std::vector< float > &cumLen, bool fwd, int pid) const
double TrajectoryMCSFitter::energyLossBetheBloch ( const double  mass,
const double  e2 
) const

Definition at line 381 of file TrajectoryMCSFitter.cxx.

References E.

Referenced by mass().

382 {
383  // stolen, mostly, from GFMaterialEffects.
384  constexpr double Iinv = 1. / 188.E-6;
385  constexpr double matConst = 1.4 * 18. / 40.; //density*Z/A
386  constexpr double me = 0.511;
387  constexpr double kappa = 0.307075;
388  //
389  const double beta2 = (e2 - mass * mass) / e2;
390  const double gamma2 = 1. / (1.0 - beta2);
391  const double massRatio = me / mass;
392  const double argument = (2. * me * gamma2 * beta2 * Iinv) *
393  std::sqrt(1 + 2 * std::sqrt(gamma2) * massRatio + massRatio * massRatio);
394  //
395  double dedx = kappa * matConst / beta2;
396  //
397  if (mass == 0.0) return (0.0);
398  if (argument <= exp(beta2)) { dedx = 0.; }
399  else {
400  dedx *= (log(argument) - beta2) * 1.E-3; // Bethe-Bloch, converted to GeV/cm
401  if (dedx < 0.) dedx = 0.;
402  }
403  return dedx;
404 }
double mass(int pid) const
Float_t E
Definition: plot.C:20
double TrajectoryMCSFitter::energyLossLandau ( const double  mass2,
const double  E2,
const double  x 
) const

Definition at line 360 of file TrajectoryMCSFitter.cxx.

Referenced by mass().

363 {
364  //
365  // eq. (33.11) in http://pdg.lbl.gov/2016/reviews/rpp2016-rev-passage-particles-matter.pdf (except density correction is ignored)
366  //
367  if (x <= 0.) return 0.;
368  constexpr double Iinv2 = 1. / (188.E-6 * 188.E-6);
369  constexpr double matConst = 1.4 * 18. / 40.; //density*Z/A
370  constexpr double me = 0.511;
371  constexpr double kappa = 0.307075;
372  constexpr double j = 0.200;
373  //
374  const double beta2 = (e2 - mass2) / e2;
375  const double gamma2 = 1. / (1.0 - beta2);
376  const double epsilon = 0.5 * kappa * x * matConst / beta2;
377  //
378  return 0.001 * epsilon * (log(2. * me * beta2 * gamma2 * epsilon * Iinv2) + j - beta2);
379 }
Float_t x
Definition: compare.C:6
recob::MCSFitResult trkf::TrajectoryMCSFitter::fitMcs ( const recob::TrackTrajectory traj) const
inline

Definition at line 166 of file TrajectoryMCSFitter.h.

References pIdHyp_.

Referenced by fitMcs(), trkmkr::KalmanFilterFitTrackMaker::getMomentum(), and trkf::MCSFitProducer::produce().

167  {
168  return fitMcs(traj, pIdHyp_);
169  }
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
recob::MCSFitResult trkf::TrajectoryMCSFitter::fitMcs ( const recob::Track track) const
inline

Definition at line 170 of file TrajectoryMCSFitter.h.

References fitMcs(), and pIdHyp_.

Referenced by fitMcs().

170 { return fitMcs(track, pIdHyp_); }
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
recob::MCSFitResult trkf::TrajectoryMCSFitter::fitMcs ( const recob::Trajectory traj) const
inline

Definition at line 171 of file TrajectoryMCSFitter.h.

References fitMcs(), and pIdHyp_.

172  {
173  return fitMcs(traj, pIdHyp_);
174  }
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
recob::MCSFitResult TrajectoryMCSFitter::fitMcs ( const recob::TrackTrajectory traj,
int  pid 
) const

Definition at line 16 of file TrajectoryMCSFitter.cxx.

References util::abs(), trkf::TrajectoryMCSFitter::ScanResult::logL, trkf::TrajectoryMCSFitter::ScanResult::p, trkf::TrajectoryMCSFitter::ScanResult::pUnc, and recob::TrackTrajectory::StartDirection().

17 {
18  //
19  // Break the trajectory in segments of length approximately equal to segLen_
20  //
21  vector<size_t> breakpoints;
22  vector<float> segradlengths;
23  vector<float> cumseglens;
24  breakTrajInSegments(traj, breakpoints, segradlengths, cumseglens);
25  //
26  // Fit segment directions, and get 3D angles between them
27  //
28  if (segradlengths.size() < 2) return recob::MCSFitResult();
29  vector<float> dtheta;
30  Vector_t pcdir0;
31  Vector_t pcdir1;
32  for (unsigned int p = 0; p < segradlengths.size(); p++) {
33  linearRegression(traj, breakpoints[p], breakpoints[p + 1], pcdir1);
34  if (p > 0) {
35  if (segradlengths[p] < -100. || segradlengths[p - 1] < -100.) { dtheta.push_back(-999.); }
36  else {
37  const double cosval =
38  pcdir0.X() * pcdir1.X() + pcdir0.Y() * pcdir1.Y() + pcdir0.Z() * pcdir1.Z();
39  //assert(std::abs(cosval)<=1);
40  //units are mrad
41  double dt = 1000. * acos(cosval); //should we try to use expansion for small angles?
42  dtheta.push_back(dt);
43  }
44  }
45  pcdir0 = pcdir1;
46  }
47  //
48  // Perform likelihood scan in forward and backward directions
49  //
50  vector<float> cumLenFwd;
51  vector<float> cumLenBwd;
52  for (unsigned int i = 0; i < cumseglens.size() - 2; i++) {
53  cumLenFwd.push_back(cumseglens[i]);
54  cumLenBwd.push_back(cumseglens.back() - cumseglens[i + 2]);
55  }
56  double detAngResol = DetectorAngularResolution(std::abs(traj.StartDirection().Z()));
57  const ScanResult fwdResult =
58  doLikelihoodScan(dtheta, segradlengths, cumLenFwd, true, pid, detAngResol);
59  const ScanResult bwdResult =
60  doLikelihoodScan(dtheta, segradlengths, cumLenBwd, false, pid, detAngResol);
61  //
62  return recob::MCSFitResult(pid,
63  fwdResult.p,
64  fwdResult.pUnc,
65  fwdResult.logL,
66  bwdResult.p,
67  bwdResult.pUnc,
68  bwdResult.logL,
69  segradlengths,
70  dtheta);
71 }
void breakTrajInSegments(const recob::TrackTrajectory &traj, std::vector< size_t > &breakpoints, std::vector< float > &segradlengths, std::vector< float > &cumseglens) const
double DetectorAngularResolution(const double uz) const
recob::tracking::Vector_t Vector_t
Definition: TrackState.h:19
constexpr auto abs(T v)
Returns the absolute value of the argument.
const ScanResult doLikelihoodScan(std::vector< float > &dtheta, std::vector< float > &seg_nradlengths, std::vector< float > &cumLen, bool fwdFit, int pid, float detAngResol) const
void linearRegression(const recob::TrackTrajectory &traj, const size_t firstPoint, const size_t lastPoint, recob::tracking::Vector_t &pcdir) const
Class storing the result of the Maximum Likelihood fit of Multiple Coulomb Scattering angles between ...
Definition: MCSFitResult.h:19
Vector_t StartDirection() const
Returns the direction of the trajectory at the first point.
recob::MCSFitResult trkf::TrajectoryMCSFitter::fitMcs ( const recob::Track track,
int  pid 
) const
inline

Definition at line 177 of file TrajectoryMCSFitter.h.

References fitMcs(), and recob::Track::Trajectory().

178  {
179  return fitMcs(track.Trajectory(), pid);
180  }
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Definition: Track.h:132
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
recob::MCSFitResult trkf::TrajectoryMCSFitter::fitMcs ( const recob::Trajectory traj,
int  pid 
) const
inline

Definition at line 181 of file TrajectoryMCSFitter.h.

References breakTrajInSegments(), fitMcs(), linearRegression(), mcsLikelihood(), and recob::Trajectory::NPoints().

182  {
184  const recob::TrackTrajectory tt(traj, std::move(flags));
185  return fitMcs(tt, pid);
186  }
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
Definition: type_traits.h:61
size_t NPoints() const
Returns the number of stored trajectory points.
Definition: Trajectory.h:153
A trajectory in space reconstructed from hits.
std::vector< PointFlags_t > Flags_t
Type of point flag list.
double TrajectoryMCSFitter::GetE ( const double  initial_E,
const double  length_travelled,
const double  mass 
) const

Definition at line 406 of file TrajectoryMCSFitter.cxx.

Referenced by mass().

409 {
410  //
411  if (eLossMode_ == 1) {
412  // ELoss mode: MIP (constant)
413  constexpr double kcal = 0.002105;
414  return (initial_E - kcal * length_travelled); //energy at this segment
415  }
416  //
417  // Non constant energy loss distribution
418  const double step_size = length_travelled / nElossSteps_;
419  //
420  double current_E = initial_E;
421  const double m2 = m * m;
422  //
423  for (auto i = 0; i < nElossSteps_; ++i) {
424  if (eLossMode_ == 2) {
425  double dedx = energyLossBetheBloch(m, current_E);
426  current_E -= (dedx * step_size);
427  }
428  else {
429  // MPV of Landau energy loss distribution
430  current_E -= energyLossLandau(m2, current_E * current_E, step_size);
431  }
432  if (current_E <= m) {
433  // std::cout<<"WARNING: current_E less than mu mass. it is "<<current_E<<std::endl;
434  return 0.;
435  }
436  }
437  return current_E;
438 }
double energyLossBetheBloch(const double mass, const double e2) const
double energyLossLandau(const double mass2, const double E2, const double x) const
double trkf::TrajectoryMCSFitter::HighlandFirstTerm ( const double  p) const
inline

Definition at line 226 of file TrajectoryMCSFitter.h.

References hlParams_.

227  {
228  return hlParams_[0] / (p * p) + hlParams_[1] / p + hlParams_[2] + hlParams_[3] * p +
229  hlParams_[4] * p * p;
230  }
std::array< double, 5 > hlParams_
void TrajectoryMCSFitter::linearRegression ( const recob::TrackTrajectory traj,
const size_t  firstPoint,
const size_t  lastPoint,
recob::tracking::Vector_t pcdir 
) const

Definition at line 230 of file TrajectoryMCSFitter.cxx.

References geo::vect::MiddlePointAccumulatorDim< N >::add(), recob::TrackTrajectory::DirectionAtPoint(), geo::GeometryCore::FindTPCAtPosition(), geo::CryostatID::isValid, recob::TrackTrajectory::LocationAtPoint(), geo::vect::MiddlePointAccumulatorDim< N >::middlePoint(), recob::TrackTrajectory::NextValidPoint(), norm, and geo::TPCID::TPC.

Referenced by fitMcs().

234 {
235  //
237  auto const* _SCE = (applySCEcorr_ ? lar::providerFrom<spacecharge::SpaceChargeService>() : NULL);
238  //
239  int npoints = 0;
240  geo::vect::MiddlePointAccumulator middlePointCalc;
241  size_t nextValid = firstPoint;
242  //fixme explore a max number of points to use for linear regression
243  //while (nextValid<std::min(firstPoint+10,lastPoint)) {
244  while (nextValid < lastPoint) {
245  auto tempP = traj.LocationAtPoint(nextValid);
246  if (applySCEcorr_) {
247  geo::TPCID tpcid = geom->FindTPCAtPosition(tempP);
248  geo::Vector_t tempP_offset(0., 0., 0.);
249  if (tpcid.isValid) { tempP_offset = _SCE->GetCalPosOffsets(tempP, tpcid.TPC); }
250  tempP.SetX(tempP.X() - tempP_offset.X());
251  tempP.SetY(tempP.Y() + tempP_offset.Y());
252  tempP.SetZ(tempP.Z() + tempP_offset.Z());
253  }
254  middlePointCalc.add(tempP);
255  //middlePointCalc.add(traj.LocationAtPoint(nextValid));
256  nextValid = traj.NextValidPoint(nextValid + 1);
257  npoints++;
258  }
259  const auto avgpos = middlePointCalc.middlePoint();
260  const double norm = 1. / double(npoints);
261  //
262  //assert(npoints>0);
263  //
264  TMatrixDSym m(3);
265  nextValid = firstPoint;
266  while (nextValid < lastPoint) {
267  auto p = traj.LocationAtPoint(nextValid);
268  if (applySCEcorr_) {
269  geo::TPCID tpcid = geom->FindTPCAtPosition(p);
270  geo::Vector_t p_offset(0., 0., 0.);
271  if (tpcid.isValid) { p_offset = _SCE->GetCalPosOffsets(p, tpcid.TPC); }
272  p.SetX(p.X() - p_offset.X());
273  p.SetY(p.Y() + p_offset.Y());
274  p.SetZ(p.Z() + p_offset.Z());
275  }
276  const double xxw0 = p.X() - avgpos.X();
277  const double yyw0 = p.Y() - avgpos.Y();
278  const double zzw0 = p.Z() - avgpos.Z();
279  m(0, 0) += xxw0 * xxw0 * norm;
280  m(0, 1) += xxw0 * yyw0 * norm;
281  m(0, 2) += xxw0 * zzw0 * norm;
282  m(1, 0) += yyw0 * xxw0 * norm;
283  m(1, 1) += yyw0 * yyw0 * norm;
284  m(1, 2) += yyw0 * zzw0 * norm;
285  m(2, 0) += zzw0 * xxw0 * norm;
286  m(2, 1) += zzw0 * yyw0 * norm;
287  m(2, 2) += zzw0 * zzw0 * norm;
288  nextValid = traj.NextValidPoint(nextValid + 1);
289  }
290  //
291  const TMatrixDSymEigen me(m);
292  const auto& eigenval = me.GetEigenValues();
293  const auto& eigenvec = me.GetEigenVectors();
294  //
295  int maxevalidx = 0;
296  double maxeval = eigenval(0);
297  for (int i = 1; i < 3; ++i) {
298  if (eigenval(i) > maxeval) {
299  maxevalidx = i;
300  maxeval = eigenval(i);
301  }
302  }
303  //
304  pcdir = Vector_t(eigenvec(0, maxevalidx), eigenvec(1, maxevalidx), eigenvec(2, maxevalidx));
305  if (traj.DirectionAtPoint(firstPoint).Dot(pcdir) < 0.) pcdir *= -1.;
306  //
307 }
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
T DirectionAtPoint(unsigned int p) const
Direction at point p. Use e.g. as:
recob::tracking::Vector_t Vector_t
Definition: TrackState.h:19
Helper class to compute the middle point in a point set.
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:210
void add(Point const &p)
Accumulates a point.
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
T LocationAtPoint(unsigned int p) const
Position at point p. Use e.g. as:
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
Float_t norm
size_t NextValidPoint(size_t index) const
Returns the index of the next valid point in the trajectory.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:399
double trkf::TrajectoryMCSFitter::mass ( int  pid) const
inline

Definition at line 236 of file TrajectoryMCSFitter.h.

References util::abs(), energyLossBetheBloch(), energyLossLandau(), GetE(), util::kBogusD, and x.

237  {
238  if (abs(pid) == 13) { return mumass; }
239  if (abs(pid) == 211) { return pimass; }
240  if (abs(pid) == 321) { return kmass; }
241  if (abs(pid) == 2212) { return pmass; }
242  return util::kBogusD;
243  }
constexpr auto abs(T v)
Returns the absolute value of the argument.
constexpr double kBogusD
obviously bogus double value
double TrajectoryMCSFitter::mcsLikelihood ( double  p,
double  theta0x,
std::vector< float > &  dthetaij,
std::vector< float > &  seg_nradl,
std::vector< float > &  cumLen,
bool  fwd,
int  pid 
) const

Definition at line 309 of file TrajectoryMCSFitter.cxx.

References util::end().

Referenced by fitMcs().

316 {
317  //
318  const int beg = (fwd ? 0 : (dthetaij.size() - 1));
319  const int end = (fwd ? dthetaij.size() : -1);
320  const int incr = (fwd ? +1 : -1);
321  //
322  // bool print = false;
323  //
324  const double m = mass(pid);
325  const double m2 = m * m;
326  const double Etot = sqrt(p * p + m2); //Initial energy
327  double Eij2 = 0.;
328  //
329  double const fixedterm = 0.5 * std::log(2.0 * M_PI);
330  double result = 0;
331  for (int i = beg; i != end; i += incr) {
332  if (dthetaij[i] < 0) {
333  //cout << "skip segment with too few points" << endl;
334  continue;
335  }
336  //
337  const double Eij = GetE(Etot, cumLen[i], m);
338  Eij2 = Eij * Eij;
339  //
340  if (Eij2 <= m2) {
341  result = std::numeric_limits<double>::max();
342  break;
343  }
344  const double pij = sqrt(Eij2 - m2); //momentum at this segment
345  const double beta = sqrt(1. - ((m2) / (pij * pij + m2)));
346  constexpr double HighlandSecondTerm = 0.038;
347  const double tH0 = (HighlandFirstTerm(pij) / (pij * beta)) *
348  (1.0 + HighlandSecondTerm * std::log(seg_nradl[i])) * sqrt(seg_nradl[i]);
349  const double rms = sqrt(2.0 * (tH0 * tH0 + theta0x * theta0x));
350  if (rms == 0.0) {
351  std::cout << " Error : RMS cannot be zero ! " << std::endl;
352  return std::numeric_limits<double>::max();
353  }
354  const double arg = dthetaij[i] / rms;
355  result += (std::log(rms) + 0.5 * arg * arg + fixedterm);
356  }
357  return result;
358 }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
double mass(int pid) const
double GetE(const double initial_E, const double length_travelled, const double mass) const
double HighlandFirstTerm(const double p) const
int trkf::TrajectoryMCSFitter::minNSegs ( ) const
inline

Definition at line 249 of file TrajectoryMCSFitter.h.

References minNSegs_.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::segLen ( ) const
inline

Definition at line 250 of file TrajectoryMCSFitter.h.

References segLen_.

Referenced by TrajectoryMCSFitter().

250 { return segLen_; }
double trkf::TrajectoryMCSFitter::segLenTolerance ( ) const
inline

Definition at line 251 of file TrajectoryMCSFitter.h.

References segLenTolerance_.

Member Data Documentation

std::array<double, 5> trkf::TrajectoryMCSFitter::angResol_
private

Definition at line 265 of file TrajectoryMCSFitter.h.

Referenced by DetectorAngularResolution(), and TrajectoryMCSFitter().

bool trkf::TrajectoryMCSFitter::applySCEcorr_
private

Definition at line 268 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

int trkf::TrajectoryMCSFitter::eLossMode_
private

Definition at line 259 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::fineScanWindow_
private

Definition at line 264 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

std::array<double, 5> trkf::TrajectoryMCSFitter::hlParams_
private

Definition at line 266 of file TrajectoryMCSFitter.h.

Referenced by HighlandFirstTerm(), and TrajectoryMCSFitter().

int trkf::TrajectoryMCSFitter::minHitsPerSegment_
private

Definition at line 257 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

int trkf::TrajectoryMCSFitter::minNSegs_
private

Definition at line 255 of file TrajectoryMCSFitter.h.

Referenced by minNSegs(), and TrajectoryMCSFitter().

int trkf::TrajectoryMCSFitter::nElossSteps_
private

Definition at line 258 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

int trkf::TrajectoryMCSFitter::pIdHyp_
private

Definition at line 254 of file TrajectoryMCSFitter.h.

Referenced by fitMcs(), and TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::pMax_
private

Definition at line 261 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::pMin_
private

Definition at line 260 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::pStep_
private

Definition at line 263 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::pStepCoarse_
private

Definition at line 262 of file TrajectoryMCSFitter.h.

Referenced by TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::segLen_
private

Definition at line 256 of file TrajectoryMCSFitter.h.

Referenced by segLen(), and TrajectoryMCSFitter().

double trkf::TrajectoryMCSFitter::segLenTolerance_
private

Definition at line 267 of file TrajectoryMCSFitter.h.

Referenced by segLenTolerance(), and TrajectoryMCSFitter().


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