9 #include "TMatrixDSym.h" 10 #include "TMatrixDSymEigen.h" 22 vector<float> segradlengths;
23 vector<float> cumseglens;
24 breakTrajInSegments(traj, breakpoints, segradlengths, cumseglens);
32 for (
unsigned int p = 0; p < segradlengths.size(); p++) {
33 linearRegression(traj, breakpoints[p], breakpoints[p + 1], pcdir1);
35 if (segradlengths[p] < -100. || segradlengths[p - 1] < -100.) { dtheta.push_back(-999.); }
38 pcdir0.X() * pcdir1.X() + pcdir0.Y() * pcdir1.Y() + pcdir0.Z() * pcdir1.Z();
41 double dt = 1000. * acos(cosval);
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]);
58 doLikelihoodScan(dtheta, segradlengths, cumLenFwd,
true, pid, detAngResol);
60 doLikelihoodScan(dtheta, segradlengths, cumLenBwd,
false, pid, detAngResol);
75 vector<float>& segradlengths,
76 vector<float>& cumseglens)
const 80 auto const* _SCE = (applySCEcorr_ ? lar::providerFrom<spacecharge::SpaceChargeService>() : NULL);
82 const double trajlen = traj.
Length();
83 const double thisSegLen =
84 (trajlen > (segLen_ * minNSegs_) ? segLen_ : trajlen /
double(minNSegs_));
87 constexpr
double lar_radl_inv = 1. / 14.0;
88 cumseglens.push_back(0.);
92 breakpoints.push_back(nextValid);
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());
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());
117 auto step = (pos1 - pos0).R();
118 thislen += dir0.Dot(pos1 - pos0);
132 if (thislen >= (thisSegLen - segLenTolerance_)) {
133 breakpoints.push_back(nextValid);
134 if (npoints >= minHitsPerSegment_)
135 segradlengths.push_back(thislen * lar_radl_inv);
137 segradlengths.push_back(-999.);
138 cumseglens.push_back(totlen);
147 segradlengths.push_back(thislen * lar_radl_inv);
148 cumseglens.push_back(cumseglens.back() + thislen);
154 std::vector<float>& dtheta,
155 std::vector<float>& seg_nradlengths,
156 std::vector<float>& cumLen,
162 float detAngResol)
const 165 float best_logL = std::numeric_limits<float>::max();
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) {
173 best_idx = vlogL.size();
175 vlogL.push_back(logL);
181 for (
int j = best_idx - 1; j >= 0; j--) {
182 float dLL = vlogL[j] - vlogL[best_idx];
184 lunc = (best_idx - j) * pstep;
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];
195 runc = (j - best_idx) * pstep;
200 return ScanResult(best_p, std::max(lunc, runc), best_logL);
204 std::vector<float>& dtheta,
205 std::vector<float>& seg_nradlengths,
206 std::vector<float>& cumLen,
209 float detAngResol)
const 213 const ScanResult& coarseRes = doLikelihoodScan(
214 dtheta, seg_nradlengths, cumLen, fwdFit, pid, pMin_, pMax_, pStepCoarse_, detAngResol);
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_);
225 doLikelihoodScan(dtheta, seg_nradlengths, cumLen, fwdFit, pid, pmin, pmax, pStep_, detAngResol);
231 const size_t firstPoint,
232 const size_t lastPoint,
237 auto const* _SCE = (applySCEcorr_ ? lar::providerFrom<spacecharge::SpaceChargeService>() : NULL);
241 size_t nextValid = firstPoint;
244 while (nextValid < lastPoint) {
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());
254 middlePointCalc.
add(tempP);
260 const double norm = 1. / double(npoints);
265 nextValid = firstPoint;
266 while (nextValid < lastPoint) {
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());
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;
291 const TMatrixDSymEigen me(m);
292 const auto& eigenval = me.GetEigenValues();
293 const auto& eigenvec = me.GetEigenVectors();
296 double maxeval = eigenval(0);
297 for (
int i = 1; i < 3; ++i) {
298 if (eigenval(i) > maxeval) {
300 maxeval = eigenval(i);
304 pcdir =
Vector_t(eigenvec(0, maxevalidx), eigenvec(1, maxevalidx), eigenvec(2, maxevalidx));
309 double TrajectoryMCSFitter::mcsLikelihood(
double p,
311 std::vector<float>& dthetaij,
312 std::vector<float>& seg_nradl,
313 std::vector<float>& cumLen,
318 const int beg = (fwd ? 0 : (dthetaij.size() - 1));
319 const int end = (fwd ? dthetaij.size() : -1);
320 const int incr = (fwd ? +1 : -1);
324 const double m = mass(pid);
325 const double m2 = m * m;
326 const double Etot = sqrt(p * p + m2);
329 double const fixedterm = 0.5 * std::log(2.0 * M_PI);
331 for (
int i = beg; i !=
end; i += incr) {
332 if (dthetaij[i] < 0) {
337 const double Eij = GetE(Etot, cumLen[i], m);
341 result = std::numeric_limits<double>::max();
344 const double pij = sqrt(Eij2 - m2);
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));
351 std::cout <<
" Error : RMS cannot be zero ! " << std::endl;
352 return std::numeric_limits<double>::max();
354 const double arg = dthetaij[i] / rms;
355 result += (std::log(rms) + 0.5 * arg * arg + fixedterm);
360 double TrajectoryMCSFitter::energyLossLandau(
const double mass2,
362 const double x)
const 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.;
370 constexpr
double me = 0.511;
371 constexpr
double kappa = 0.307075;
372 constexpr
double j = 0.200;
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;
378 return 0.001 * epsilon * (log(2. * me * beta2 * gamma2 * epsilon * Iinv2) + j - beta2);
381 double TrajectoryMCSFitter::energyLossBetheBloch(
const double mass,
const double e2)
const 384 constexpr
double Iinv = 1. / 188.E-6;
385 constexpr
double matConst = 1.4 * 18. / 40.;
386 constexpr
double me = 0.511;
387 constexpr
double kappa = 0.307075;
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);
395 double dedx = kappa * matConst / beta2;
397 if (mass == 0.0)
return (0.0);
398 if (argument <= exp(beta2)) { dedx = 0.; }
400 dedx *= (log(argument) - beta2) * 1.
E-3;
401 if (dedx < 0.) dedx = 0.;
406 double TrajectoryMCSFitter::GetE(
const double initial_E,
407 const double length_travelled,
408 const double m)
const 411 if (eLossMode_ == 1) {
413 constexpr
double kcal = 0.002105;
414 return (initial_E - kcal * length_travelled);
418 const double step_size = length_travelled / nElossSteps_;
420 double current_E = initial_E;
421 const double m2 = m * m;
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);
430 current_E -= energyLossLandau(m2, current_E * current_E, step_size);
432 if (current_E <= m) {
Utilities related to art service access.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
T DirectionAtPoint(unsigned int p) const
Direction at point p. Use e.g. as:
recob::tracking::Vector_t Vector_t
Helper class to compute the middle point in a point set.
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.
constexpr auto abs(T v)
Returns the absolute value of the argument.
void add(Point const &p)
Accumulates a point.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
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.
A trajectory in space reconstructed from hits.
T LocationAtPoint(unsigned int p) const
Position at point p. Use e.g. as:
Utilities to extend the interface of geometry vectors.
The data type to uniquely identify a TPC.
Class storing the result of the Maximum Likelihood fit of Multiple Coulomb Scattering angles between ...
geo::Point_t middlePoint() const
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.
Vector_t StartDirection() const
Returns the direction of the trajectory at the first point.
recob::tracking::Vector_t Vector_t
art framework interface to geometry description