126 LOG(debug) <<
"CosmicTracker::Fit : Number of Points: X-Z: " <<
fXZ.GetN() <<
" Y-Z: " <<
fYZ.GetN();
130 LOG(debug) <<
"CosmicTracker::Fit : Not enough Points to make reasonable fit.";
137 LOG(debug) <<
"CosmicTracker::Fit : Not enough Points to make reasonable fit after "
138 "horizontal filtering.";
145 LOG(debug) <<
"CosmicTracker::Fit : Not enough Points to make reasonable fit after vertical "
153 TVector3& direction =
fTrack.Direction;
154 TVector3& entryPoint =
fTrack.EntryPoint;
155 TVector3& invDirection =
fTrack.InvDirection;
157 const auto yFit =
fit(
fYZ);
160 LOG(debug) <<
"CosmicTracker::Fit : Could not get a reasonable vertical fit.";
164 if (fabs(yFit[0]) < 0.1)
166 LOG(debug) <<
"CosmicTracker::Fit : Y-Slope too small. Better reject this Track.";
170 const auto xFit =
fit(
fXZ);
173 LOG(debug) <<
"CosmicTracker::Fit : Could not get a reasonable horizontal fit.";
177 direction[0] = xFit[0];
178 entryPoint[0] = xFit[1];
180 direction[1] = yFit[0];
181 entryPoint[1] = yFit[1];
186 if (direction[1] > 0)
191 entryPoint[0] += direction[0] * entryPoint[2];
192 entryPoint[1] += direction[1] * entryPoint[2];
194 for (
int i = 0; i < 3; ++i)
195 direction[i] *= -1.0;
199 const auto scale =
CLight / direction.Mag();
200 for (
int i = 0; i < 3; ++i)
202 direction[i] *= scale;
203 invDirection[i] = 1.0 / direction[i];
214 if (isnan(flightTimeEntry))
217 entryPoint += direction * (flightTimeEntry -
TimeEps);
219 LOG(debug) <<
"X: " << entryPoint[0] <<
" + t * " << direction[0];
220 LOG(debug) <<
"Y: " << entryPoint[1] <<
" + t * " << direction[1];
221 LOG(debug) <<
"Z: " << entryPoint[2] <<
" + t * " << direction[2];
224 if (
fTrack.Interactions.size() < 3)
226 fTrack.Interactions.clear();
227 fTrack.TotalTrackLength = 0.;
230 LOG(debug) <<
"Interactions: " <<
fTrack.Interactions.size();
237 std::array<Int_t, 256> remove;
240 auto nPoints = graph.GetN();
241 auto x = graph.GetX();
242 auto y = graph.GetY();
246 for (
auto p = 0; p < nPoints; ++p)
248 Bool_t foundClose =
false;
249 for (
auto op = 0; op < nPoints; ++op)
253 const auto dist2 =
Sqr(x[p] - x[op]) +
Sqr(y[p] - y[op]);
264 if (++nRemove == remove.size())
272 LOG(debug) <<
" Removed : " << nRemove;
277 const auto totalPoints = nPoints - nRemove;
278 for (
auto p = remove[0]; p < totalPoints; ++p)
280 if (offset < nRemove && p + offset == remove[offset])
287 x[p] = x[p + offset];
288 y[p] = y[p + offset];
291 graph.Set(totalPoints);
296 nPoints = graph.GetN();
298 const auto factor = 1. / (
Sqr(linReg[1]) + 1.);
302 for (
auto p = nPoints - 1; p >= 0; --p)
304 const auto dist2 =
Sqr(linReg[1] * x[p] - y[p] + linReg[0]) * factor;
318 graph.RemovePoint(p);
343 const auto linReg =
linearRegression(graph.GetX(), graph.GetY(), graph.GetN());
344 if (!isfinite(linReg[0]))
347 fFit.SetParameter(0, linReg[0]);
348 fFit.SetParameter(1, linReg[1]);
350 TFitResultPtr resultptr = graph.Fit(&
fFit,
"NQS");
352 const auto slope =
fFit.GetParameter(1);
353 const auto yIntercept =
fFit.GetParameter(0);
355 auto redchi2 = resultptr->Chi2() / resultptr->Ndf();
361 return { slope, yIntercept };
365 const TVector3& direction,
366 const TVector3& invDirection,
367 const DPair& xBounds,
368 const DPair& yBounds,
369 const DPair& zBounds)
const
371 const auto invert = (
WithinBounds(point, xBounds, yBounds, zBounds) ? -1. : 1.);
375 if (invert * invDirection[0] > 0)
377 crossPoint[0] = xBounds[0];
381 crossPoint[0] = xBounds[1];
384 if (invert * invDirection[1] > 0)
386 crossPoint[1] = yBounds[0];
390 crossPoint[1] = yBounds[1];
393 if (invert * invDirection[2] > 0)
395 crossPoint[2] = zBounds[0];
399 crossPoint[2] = zBounds[1];
402 auto wasHit = kFALSE;
404 for (
int i = 0; i < 3; ++i)
406 const auto flightTime = (crossPoint[i] - point[i]) * invDirection[i];
407 if (flightTime > 0. &&
408 WithinBounds(point + direction * (flightTime + invert *
TimeEps), xBounds, yBounds, zBounds))
418 const auto invPoints = 1. / points;
419 const auto invRedPoints = 1. / (points - 1);
420 const auto xMean = invPoints * std::accumulate(x, x + points, 0.);
421 const auto yMean = std::accumulate(y, y + points, 0.) / points;
422 const auto xVar = invRedPoints * std::accumulate(x,
425 [xMean](
const Double_t acc,
const Double_t val)
426 {
return acc +
Sqr(val - xMean); });
431 return {
Inf, xMean };
433 const auto yVar = invRedPoints * std::accumulate(y,
436 [yMean](
const Double_t acc,
const Double_t val)
437 {
return acc +
Sqr(val - yMean); });
440 for (
auto p = 0; p < points; ++p)
441 xyVar += (x[p] - xMean) * (y[p] - yMean);
442 xyVar *= invRedPoints;
444 const auto slope = (yVar - xVar + std::sqrt(
Sqr(yVar - xVar) + 4 *
Sqr(xyVar))) / (2 * xyVar);
445 const auto yIntercept = yMean - slope * xMean;
450 return { yIntercept, slope };
455 auto nMissedHits = 0;
456 auto lastValidSize = 0;
457 auto missedEnergy = 0.;
459 std::array<Int_t, 3> barDirections;
460 for (
auto i = 0; i < 3; ++i)
462 barDirections[i] = (track.Direction[i] > 0. ? 1 : -1);
466 Int_t currentPlane = 0, currentBar;
467 track.EntryPoint += track.Direction *
TimeEps;
469 while (currentPlane <
fDistances.size() - 1 &&
480 if (track.Direction.Z() > 0.)
486 const auto crossTime =
490 { -0.5 * BarLength, 0.5 * BarLength },
491 { -0.5 * BarLength, 0.5 * BarLength },
492 { fDistances[currentPlane], fDistances[currentPlane] + BarSize_Z });
494 if (isnan(crossTime))
497 track.EntryPoint += track.Direction * crossTime;
502 auto planeChanged = kTRUE;
503 DPair xBorder, yBorder;
504 auto currentPoint = track.EntryPoint;
507 LOG(debug) <<
"Entry Plane: " << currentPlane <<
" at " << currentPoint.X() <<
" " << currentPoint.Y()
508 <<
" " << currentPoint.Z();
533 currentBar += barDirections[1];
539 currentBar += barDirections[0];
544 const auto crossTime =
550 { fDistances[currentPlane], fDistances[currentPlane] + BarSize_Z });
552 if (isnan(crossTime))
555 const auto barID = currentBar + currentPlane *
BarsPerPlane;
556 const auto trackLength = crossTime *
CLight;
559 track.Interactions.emplace_back(barID,
563 currentPoint.X() + crossTime * track.Direction.X(),
569 track.Interactions.emplace_back(barID,
573 currentPoint.Y() + crossTime * track.Direction.Y(),
582 lastValidSize = track.Interactions.size();
588 if (missedEnergy > 10. || (missedEnergy > 7. && nMissedHits > 1))
590 if (lastValidSize == 0)
594 track.Interactions.resize(lastValidSize);
595 track.TotalTrackLength = track.Interactions.back().ExitTime *
CLight;
596 track.Stopped = kTRUE;
602 currentPoint = track.EntryPoint + track.Direction * tof;
610 LOG(debug) <<
"Left NeuLAND at Plane " << currentPlane <<
" with " << currentPoint.X() <<
" "
611 << currentPoint.Y() <<
" " << currentPoint.Z();
620 currentPlane += barDirections[2];
630 { -0.5 * BarLength, 0.5 * BarLength },
631 { -0.5 * BarLength, 0.5 * BarLength },
632 { fDistances[currentPlane], fDistances[currentPlane] + BarSize_Z });
638 currentPoint = track.EntryPoint + track.Direction * tof;
642 track.TotalTrackLength = tof *
CLight;