ATLAS Offline Software
Loading...
Searching...
No Matches
iPatFitter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
5/***************************************************************************
6 least squared fit to track hit data => PerigeeParameters with covariance
7 and fit quality.
8***************************************************************************/
9
11
12#include <cmath>
13#include <iomanip>
14
16#include "GaudiKernel/SystemOfUnits.h"
18#include "Identifier/Identifier.h"
31#include "TrkSurfaces/Surface.h"
36namespace Trk {
37iPatFitter::iPatFitter(const std::string& type, const std::string& name,
38 const IInterface* parent, bool globalFit)
39 : AthAlgTool(type, name, parent),
40 m_globalFit(globalFit),
42 m_messageHelper = std::make_unique<MessageHelper>(*this, 26);
43 declareInterface<ITrackFitter>(this);
44}
45
47 // fill WARNING messages
48 m_messageHelper->setMaxNumberOfMessagesPrinted(m_maxWarnings);
49 m_messageHelper->setMessage(0,
50 "fit (Track): outlier removal not implemented");
51 m_messageHelper->setMessage(1, "fit (Track): track without perigee");
52 m_messageHelper->setMessage(
53 2, "fit (Track): track without trackStateOnSurfaces");
54 m_messageHelper->setMessage(
55 3, "fit (Track + PrepRawDataSet): interface not implemented");
56 m_messageHelper->setMessage(
57 4, "fit (PrepRawDataSet): interface not implemented");
58 m_messageHelper->setMessage(
59 5, "fit (Track + MeasurementSet): outlier removal not implemented");
60 m_messageHelper->setMessage(
61 6, "fit (Track + MeasurementSet): track without trackStateOnSurfaces");
62 m_messageHelper->setMessage(
63 7, "fit (Track + MeasurementSet): track without measuredPerigee");
64 m_messageHelper->setMessage(
65 8, "fit (Track + MeasurementSet): FIX material may get double counted");
66 m_messageHelper->setMessage(
67 9, "fit (Perigee + MeasurementSet): outlier removal not implemented");
68 m_messageHelper->setMessage(10,
69 "fit (Perigee + MeasurementSet): null perigee");
70 m_messageHelper->setMessage(
71 11, "fit (combined muon): outlier removal not implemented");
72 m_messageHelper->setMessage(12,
73 "fit (combined muon): no perigee start value");
74 m_messageHelper->setMessage(
75 13, "fit (combined muon): indet track without trackStateOnSurfaces");
76 m_messageHelper->setMessage(
77 14, "fit (combined muon): indet track without measuredPerigee");
78 m_messageHelper->setMessage(
79 15, "addMeasurements: no intersection to MeasurementSet");
80 m_messageHelper->setMessage(
81 16, "addMeasurements: skip TSOS as not understood. Type: ");
82 m_messageHelper->setMessage(
83 17, "addMeasurements: skip TSOS with missing trackParameters. Type: ");
84 m_messageHelper->setMessage(
85 18,
86 "addMeasurements: skip measurement as fail to intersect associated "
87 "surface from given starting parameters");
88 m_messageHelper->setMessage(19, "addMeasurements: TSOS skipped. Type: ");
89 m_messageHelper->setMessage(20,
90 "fail fit as CaloDeposit outside calo volume");
91 m_messageHelper->setMessage(
92 21, "conflicting energy deposit sign for inDet material");
93 m_messageHelper->setMessage(
94 22, "conflicting energy deposit sign for spectrometer material");
95 m_messageHelper->setMessage(23, "excessive calorimeter energy loss : ");
96 m_messageHelper->setMessage(24, "excessive spectrometer energy loss : ");
97 m_messageHelper->setMessage(25, "flipped track measurement order");
98
102 ATH_CHECK(m_stepPropagator.retrieve());
104
105 // need to create the IndetExit and MuonEntrance TrackingVolumes
106 if (m_trackingVolumesSvc.retrieve().isFailure()) {
107 ATH_MSG_FATAL("Failed to retrieve Svc " << m_trackingVolumesSvc);
108 return StatusCode::FAILURE;
109 }
111 std::make_unique<Trk::Volume>(m_trackingVolumesSvc->volume(
113 m_indetVolume = std::make_unique<Volume>(
115
116 ATH_CHECK(m_trackSummaryTool.retrieve());
117
118 // can now create FitProcedure class
119 m_fitProcedure = std::make_unique<FitProcedure>(
124 1); // useStepPropagator
125 // useStepPropagator 0 means not used (so Intersector used)
126 // 1 Intersector not used and StepPropagator used with FullField
127 // 2 StepPropagator with FastField propagation
128 // 99 debug mode where both are ran with FullField
129 return StatusCode::SUCCESS;
130}
131
133 // print summary statistics
134 const double fits = static_cast<double>(m_countFitAttempts);
135 double goodFit = 0.;
136 double iterations = 0.;
137
138 //avoid printing for 0 fit attempts
139 if (m_countFitAttempts) {
140 goodFit = static_cast<double>(100 * m_countGoodFits) / fits;
141 if (m_countGoodFits) {
142 iterations = static_cast<double>(m_countIterations) /
143 static_cast<double>(m_countGoodFits);
144 }
145 ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
146 << "finalized after " << m_countFitAttempts
147 << " track-fits attempted, out of which " << std::setw(5)
148 << std::setprecision(1) << goodFit
149 << "% converged, taking an average " << std::setw(5)
150 << std::setprecision(2) << iterations << " iterations");
151 }
153 const double refits = static_cast<double>(m_countRefitAttempts);
154 double goodRefit = 0.;
155 double refitIterations = 0.;
157 goodRefit = static_cast<double>(100 * m_countGoodRefits) / refits;
158 }
159 if (m_countGoodRefits) {
160 refitIterations = static_cast<double>(m_countRefitIterations) /
161 static_cast<double>(m_countGoodRefits);
162 }
163 ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
164 << "finalized after " << m_countRefitAttempts
165 << " refits attempted, out of which " << std::setw(5)
166 << std::setprecision(1) << goodRefit
167 << "% converged, taking an average " << std::setw(5)
168 << std::setprecision(2) << refitIterations << " iterations");
169 }
170
171 m_messageHelper->printSummary();
172
173 return StatusCode::SUCCESS;
174}
175
176auto iPatFitter::fitWithState(const EventContext& ctx, const Track& track,
177 const RunOutlierRemoval runOutlier,
178 const ParticleHypothesis particleHypothesis) const
179 -> std::pair<std::unique_ptr<Track>, std::unique_ptr<FitState>> {
180 ATH_MSG_VERBOSE(" track fit ");
181 auto fitState = std::make_unique<FitState>();
182
184 // outlier removal not implemented
185 if (runOutlier) {
186 m_messageHelper->printWarning(0);
187 } // TODO Make thread-safe
188
189 // create Perigee if starting parameters are for a different surface type
190 const Perigee* perigeeParameters = track.perigeeParameters();
191 // Note: we don't own the Perigee from perigeeParameters(), but if it returns
192 // nullptr, we have to make our own, and we need to delete it, so it's put in
193 // this unique_ptr
194 std::unique_ptr<Perigee> newPerigee;
195 std::unique_ptr<PerigeeSurface> perigeeSurface;
196
197 if (!perigeeParameters) {
198 auto i = track.trackStateOnSurfaces()->begin();
199 while (i != track.trackStateOnSurfaces()->end() &&
200 !(**i).trackParameters()) {
201 i++;
202 }
203 const TrackStateOnSurface& s = (**i);
204 if (!s.trackParameters()) {
205 // input track without parameters
206 m_messageHelper->printWarning(1);
207 return {nullptr, std::move(fitState)};
208 }
209
210 const Amg::Vector3D origin(s.trackParameters()->position());
211 perigeeSurface = std::make_unique<PerigeeSurface>(origin);
212 newPerigee = std::make_unique<Perigee>(
213 s.trackParameters()->position(), s.trackParameters()->momentum(),
214 s.trackParameters()->charge(), *perigeeSurface);
215 }
216
217 const Perigee& perigee =
218 newPerigee ? *newPerigee : *perigeeParameters; // Use the valid Perigee
219
220 fitState->parameters = std::make_unique<FitParameters>(perigee);
221
222 // set up the measurements
223 if (!track.trackStateOnSurfaces()) {
224 // input track without trackStateOnSurfaces
225 m_messageHelper->printWarning(2); // TODO Make thread-safe
226 return {nullptr, std::move(fitState)};
227 }
228
229 fitState->newMeasurements();
230
231 bool const haveMaterial =
232 addMeasurements(ctx, fitState->getMeasurements(), *fitState->parameters,
233 particleHypothesis, *track.trackStateOnSurfaces());
234
235 // allocate material
236 Garbage_t garbage;
237 if (!haveMaterial && particleHypothesis != Trk::nonInteracting) {
238 m_materialAllocator->allocateMaterial(
239 fitState->getMeasurements(), particleHypothesis, *fitState->parameters,
240 perigee, garbage);
241 }
242
243 // perform fit and return fitted track
245 trackInfo.addPatternReco(track.info());
246 std::unique_ptr<Trk::Track> fittedTrack{performFit(
247 ctx, *fitState, particleHypothesis, trackInfo, nullptr, nullptr, garbage)};
248
249 // validation
250 for (int i = 0; i < m_forcedRefitsForValidation; ++i) {
251 if (fittedTrack) {
252 refit(ctx, *fitState, *fittedTrack, runOutlier, particleHypothesis);
253 }
254 }
255
256 return {std::move(fittedTrack), std::move(fitState)};
257}
258
259std::unique_ptr<Track> iPatFitter::fit(
260 const EventContext& ctx, const Track& track,
261 const RunOutlierRemoval runOutlier,
262 const ParticleHypothesis particleHypothesis) const {
263 auto [fittedTrack, fitState] =
264 fitWithState(ctx, track, runOutlier, particleHypothesis);
265 // cppcheck-suppress returnStdMoveLocal; clang requires the move() here.
266 return std::move(fittedTrack);
267}
268
269std::unique_ptr<Track> iPatFitter::fit(
270 const EventContext&, const Track& /*track*/,
271 const PrepRawDataSet& /*prepRawDataSet*/,
272 const RunOutlierRemoval /*trackrunOutlier*/,
273 const ParticleHypothesis /*trackparticleHypothesis*/) const {
275 // track + PrepRawDataSet interface not implemented
276 m_messageHelper->printWarning(3);
277 return nullptr;
278}
279
280std::unique_ptr<Track> iPatFitter::fit(
281 const EventContext&, const PrepRawDataSet& /*prepRawDataSet*/,
282 const TrackParameters& /*estimatedParametersNearOrigin*/,
283 const RunOutlierRemoval /*trackrunOutlier*/,
284 const ParticleHypothesis /*trackparticleHypothesis*/) const {
286 // PrepRawDataSet interface not implemented
287 m_messageHelper->printWarning(4);
288 return nullptr;
289}
290
291std::unique_ptr<Track> iPatFitter::fit(
292 const EventContext& ctx, const Track& track,
293 const MeasurementSet& measurementSet, const RunOutlierRemoval runOutlier,
294 const ParticleHypothesis particleHypothesis) const {
295 ATH_MSG_VERBOSE(" track + measurementSet fit ");
297 // outlier removal not implemented
298 if (runOutlier) {
299 m_messageHelper->printWarning(5);
300 }
301
302 // create starting parameters
303 if (!track.trackStateOnSurfaces()) {
304 // track without trackStateOnSurfaces
305 m_messageHelper->printWarning(6);
306 return nullptr;
307 }
308 const Perigee* perigee = dynamic_cast<const Perigee*>(
309 (**track.trackStateOnSurfaces()->begin()).trackParameters());
310 if (!perigee) {
311 // track without measuredPerigee
312 m_messageHelper->printWarning(7);
313 return nullptr;
314 }
315
316 FitState fitState;
317 fitState.parameters = std::make_unique<FitParameters>(*perigee);
318
319 // set up the measurements (and material)
320 fitState.newMeasurements();
321 if (addMeasurements(ctx, fitState.getMeasurements(), *fitState.parameters,
322 particleHypothesis, *track.trackStateOnSurfaces()))
323 m_messageHelper->printWarning(8); // FIX needed: material may
324 // get double counted
325 addMeasurements(ctx, fitState.getMeasurements(), measurementSet,
326 *fitState.parameters);
327 Garbage_t garbage;
328 if (particleHypothesis != Trk::nonInteracting) {
329 const TrackParameters& endParams =
330 *(track.trackStateOnSurfaces()->back()->trackParameters());
331 m_materialAllocator->allocateMaterial(
332 fitState.getMeasurements(), particleHypothesis, *fitState.parameters,
333 endParams, garbage);
334 }
335
336 // perform fit and return fitted track
338 trackInfo.addPatternReco(track.info());
339 return performFit(ctx, fitState, particleHypothesis, trackInfo,
340 track.trackStateOnSurfaces(), track.fitQuality(), garbage);
341}
342
343std::unique_ptr<Trk::Track> iPatFitter::fit(
344 const EventContext& ctx, const MeasurementSet& measurementSet,
345 const TrackParameters& perigeeStartValue,
346 const RunOutlierRemoval runOutlier,
347 const ParticleHypothesis particleHypothesis) const {
348 ATH_MSG_VERBOSE(" fit from measurement set + perigeeStartValue ");
350 // outlier removal not implemented
351 if (runOutlier) {
352 m_messageHelper->printWarning(9);
353 }
354
355 const Perigee* perigee = dynamic_cast<const Perigee*>(&perigeeStartValue);
356 if (!perigee) {
357 // track without Perigee start value
358 m_messageHelper->printWarning(10);
359 return nullptr;
360 }
361
362 FitState fitState;
363 fitState.parameters = std::make_unique<FitParameters>(*perigee);
364
365 // set up the measurements (and material)
366 fitState.newMeasurements();
367 addMeasurements(ctx, fitState.getMeasurements(), measurementSet,
368 *fitState.parameters);
369 Garbage_t garbage;
370 if (particleHypothesis != Trk::nonInteracting) {
371 m_materialAllocator->allocateMaterial(
372 fitState.getMeasurements(), particleHypothesis, *fitState.parameters,
373 perigeeStartValue, garbage);
374 }
375
376 // perform fit and return fitted track
377 TrackInfo const trackInfo(TrackInfo::iPatTrackFitter, particleHypothesis);
378 return performFit(ctx, fitState, particleHypothesis, trackInfo, nullptr, nullptr,
379 garbage);
380}
381
382std::unique_ptr<Track> iPatFitter::fit(
383 const EventContext& ctx, const Track& indetTrack,
384 const Track& spectrometerTrack, const RunOutlierRemoval runOutlier,
385 const ParticleHypothesis particleHypothesis) const {
386 ATH_MSG_VERBOSE(" combined muon fit ");
388 // outlier removal not implemented
389 if (runOutlier) {
390 m_messageHelper->printWarning(11);
391 }
392
393 // indet (full refit to measurements or use measured perigee)
394 bool haveMaterial = true;
395 FitState fitState;
396 fitState.newMeasurements();
397 if (indetTrack.perigeeParameters()) {
398 fitState.parameters =
399 std::make_unique<FitParameters>(*indetTrack.perigeeParameters());
400 } else if (spectrometerTrack.perigeeParameters() &&
401 m_indetVolume->inside(spectrometerTrack.perigeeParameters()
403 .center())) {
404 fitState.parameters =
405 std::make_unique<FitParameters>(*spectrometerTrack.perigeeParameters());
406 } else {
407 // combined muon fit without Perigee start value"
408 m_messageHelper->printWarning(12);
409 return nullptr;
410 }
411
412 // get both perigee parameters, use most precise for momentum starting value
413 const Perigee* indetPerigee =
414 dynamic_cast<const Perigee*>(indetTrack.perigeeParameters());
415 const Perigee* spectrometerPerigee =
416 dynamic_cast<const Perigee*>(spectrometerTrack.perigeeParameters());
417 if (spectrometerPerigee &&
418 !m_indetVolume->inside(
419 spectrometerPerigee->associatedSurface().center())) {
420 spectrometerPerigee = nullptr;
421 }
422 if (!spectrometerTrack.info().trackProperties(
424 spectrometerPerigee) {
426 !indetPerigee || !indetPerigee->covariance()) {
427 fitState.parameters->qOverP(
428 spectrometerPerigee->parameters()[Trk::qOverP]);
429 ATH_MSG_VERBOSE(" set starting momentum from spectrometer "
430 << 1. /
431 (fitState.parameters->qOverP() * Gaudi::Units::GeV)
432 << " GeV");
433 } else if (indetPerigee) {
434 if (spectrometerPerigee->covariance() &&
435 (*spectrometerPerigee->covariance())(Trk::qOverP, Trk::qOverP) <
436 (*indetPerigee->covariance())(Trk::qOverP, Trk::qOverP)) {
437 fitState.parameters->qOverP(
438 spectrometerPerigee->parameters()[Trk::qOverP]);
440 " set starting momentum from spectrometer "
441 << 1. / (fitState.parameters->qOverP() * Gaudi::Units::GeV)
442 << " GeV");
443 }
444 }
445 }
446
447 if (m_fullCombinedFit) {
448 // set up the measurements
449 if (!indetTrack.trackStateOnSurfaces()) {
450 // fail as indet track without trackStateOnSurfaces
451 m_messageHelper->printWarning(13);
452 return nullptr;
453 }
454 if (!addMeasurements(ctx, fitState.getMeasurements(), *fitState.parameters,
455 particleHypothesis,
456 *indetTrack.trackStateOnSurfaces())) {
457 haveMaterial = false;
458 }
459 }
460
461 // add the spectrometer measurements
462 if (!addMeasurements(ctx, fitState.getMeasurements(), *fitState.parameters,
463 particleHypothesis,
464 *spectrometerTrack.trackStateOnSurfaces())) {
465 haveMaterial = false;
466 }
467 Garbage_t garbage;
468 if (!haveMaterial && particleHypothesis != Trk::nonInteracting) {
469 Perigee* startingPerigee = fitState.parameters->startingPerigee();
470 if (startingPerigee) {
471 m_materialAllocator->allocateMaterial(
472 fitState.getMeasurements(), particleHypothesis, *fitState.parameters,
473 *startingPerigee, garbage);
474 delete startingPerigee;
475 }
476 }
477
478 // create starting parameters, perform fit and return fitted track
480 trackInfo.addPatternReco(indetTrack.info());
481 trackInfo.addPatternReco(spectrometerTrack.info());
482 if (m_fullCombinedFit) {
483 std::unique_ptr<Trk::Track> fittedTrack = performFit(
484 ctx, fitState, particleHypothesis, trackInfo, nullptr, nullptr, garbage);
485
486 // validation
487 for (int i = 0; i < m_forcedRefitsForValidation; ++i) {
488 if (fittedTrack) {
489 refit(ctx, fitState, *fittedTrack, runOutlier, particleHypothesis);
490 }
491 }
492
493 return fittedTrack;
494 } // hybrid fit
495 if (!indetPerigee) {
496 // fail combined muon fit as indet track without measuredPerigee
497 m_messageHelper->printWarning(14);
498 return nullptr;
499 }
500 fitState.getMeasurements().insert(fitState.getMeasurements().begin(),
501 new FitMeasurement(*indetPerigee));
502 FitParameters const measuredParameters(*indetPerigee);
503 std::unique_ptr<Trk::Track> fittedTrack = performFit(
504 ctx, fitState, particleHypothesis, trackInfo,
505 indetTrack.trackStateOnSurfaces(), indetTrack.fitQuality(), garbage);
506
507 // validation
508 for (int i = 0; i < m_forcedRefitsForValidation; ++i) {
509 if (fittedTrack) {
510 refit(ctx, fitState, *fittedTrack, runOutlier, particleHypothesis);
511 }
512 }
513
514 return fittedTrack;
515}
516
517void iPatFitter::addMeasurements(const EventContext& ctx,
518 std::vector<FitMeasurement*>& measurements,
519 const MeasurementSet& measurementSet,
520 const FitParameters& parameters) const {
521 // extrapolation to set FittedTrajectory
522 const double qOverP = parameters.qOverP();
523 double previousDistance = -m_orderingTolerance;
524 double previousDistanceR = previousDistance;
525 double previousDistanceZ = previousDistance;
526 bool reorder = false;
527
528 Amg::Vector3D startDirection = parameters.direction();
529 Amg::Vector3D startPosition = parameters.position();
531 TrackSurfaceIntersection intersection = parameters.intersection();
532
533 TrackSurfaceIntersection startIntersection = intersection ;
534 int hit = measurements.size();
535 for (MeasurementSet::const_iterator m = measurementSet.begin();
536 m != measurementSet.end(); ++m, ++hit) {
537 std::optional<TrackSurfaceIntersection> newIntersection{
538 m_stepPropagator->intersectSurface(ctx, (**m).associatedSurface(),
539 startIntersection, qOverP,
541 if (newIntersection) {
542 intersection = std::move(*newIntersection);
543
544 // check if ordering OK
545 if (!reorder) {
546 const double distance =
547 startDirection.dot(intersection.position() - startPosition);
548 Amg::Vector3D positionMst = (**m).globalPosition();
549 const double distanceR = std::sqrt((positionMst.x() - startPosition.x()) *
550 (positionMst.x() - startPosition.x()) +
551 (positionMst.y() - startPosition.y()) *
552 (positionMst.y() - startPosition.y()));
553 double distanceZ = (positionMst.z() - startPosition.z());
554 if (startDirection.z() < 0) {
555 distanceZ = -distanceZ;
556 }
557 if (distance < previousDistance && distanceR < previousDistanceR &&
558 distanceZ < previousDistanceZ) {
559 reorder = true;
560 ATH_MSG_DEBUG(" reorder 3D distance "
561 << distance - previousDistance << " R distance "
562 << distanceR - previousDistanceR << " Z distance "
563 << distanceZ - previousDistanceZ);
564 }
565 previousDistance = distance - m_orderingTolerance;
566 previousDistanceR = distanceR - m_orderingTolerance;
567 previousDistanceZ = distanceZ - m_orderingTolerance;
568 }
569 } else {
570 // FIXME
571 // no intersection to MeasurementSet
572 m_messageHelper->printWarning(15);
573 continue;
574 }
575 auto measurement = std::make_unique<FitMeasurement>(hit, nullptr, *m);
576 measurement->intersection(type, intersection);
577 measurement->qOverP(qOverP);
578 measurements.push_back(measurement.release());
579 // remember the last intersection for the next loop iteration
580 startIntersection = (measurements.back()->intersection(type));
581 }
582
583 // reorder if necessary
584 if (reorder) {
585 m_materialAllocator->orderMeasurements(measurements, startDirection,
586 startPosition);
587 }
588}
589
591 const EventContext& ctx, std::vector<FitMeasurement*>& measurements,
592 const FitParameters& parameters, ParticleHypothesis particleHypothesis,
593 const Trk::TrackStates& trackStateOnSurfaces) const {
594 // create vector of any TSOS'es which require fitted alignment corrections
595 std::vector<Identifier> misAlignedTSOS;
596 std::vector<int> misAlignmentNumbers;
597 int misAlignmentNumber = 0;
598 int tsos = 0;
599 // BUG that shifts ... misAlignmentNumbers.push_back(misAlignmentNumber);
600 for (Trk::TrackStates::const_iterator i = trackStateOnSurfaces.begin();
601 i != trackStateOnSurfaces.end(); ++i, ++tsos) {
602 const TrackStateOnSurface& r = (**i);
603 if (!r.alignmentEffectsOnTrack() || !r.trackParameters()) {
604 continue;
605 }
606 const AlignmentEffectsOnTrack& AEOT = *r.alignmentEffectsOnTrack();
607 ++misAlignmentNumber;
608 for (const Identifier& a : AEOT.vectorOfAffectedTSOS()) {
609 misAlignedTSOS.push_back(a);
610 misAlignmentNumbers.push_back(misAlignmentNumber);
611 }
612 if (m_extendedDebug) {
614 " tsos " << tsos << " misAlignedTSOS.size() " << misAlignedTSOS.size()
615 << " misAlignmentNumber " << misAlignmentNumber
616 << " offset " << AEOT.deltaTranslation() << " +- "
617 << AEOT.sigmaDeltaTranslation() << " rotation "
618 << AEOT.deltaAngle() << " +- " << AEOT.sigmaDeltaAngle());
619 }
620 }
621
622 // create ordered list of FitMeasurements
623 bool haveMaterial = false;
624 bool haveMeasurement = false;
625 int hit = measurements.size();
626 double previousDistance = -m_orderingTolerance;
627 double previousDistanceR = previousDistance;
628 double previousDistanceZ = previousDistance;
629 bool reorder = false;
630 const bool skipVertexMeasurement = !measurements.empty();
631 const Amg::Vector3D startDirection = parameters.direction();
632 const Amg::Vector3D& startPosition = parameters.position();
633 const TrackSurfaceIntersection& vertex = parameters.intersection();
635 bool measurementsFlipped = false;
636 double qOverP = parameters.qOverP();
638 tsos = 0;
639 for (Trk::TrackStates::const_iterator i = trackStateOnSurfaces.begin();
640 i != trackStateOnSurfaces.end(); ++i, ++hit, ++tsos) {
641 const TrackStateOnSurface& s = (**i);
642 std::unique_ptr<FitMeasurement> measurement1;
643 std::unique_ptr<FitMeasurement> measurement2;
644 const Surface* surface = nullptr;
645 if (s.materialEffectsOnTrack() && s.trackParameters()) {
646 const Amg::Vector3D position = s.trackParameters()->position();
647 bool const calo = (!m_indetVolume->inside(position) &&
649 qOverP = s.trackParameters()->parameters()[Trk::qOverP];
650 surface = &s.trackParameters()->associatedSurface();
651
652 // skip negligibly thin scatterers (exception for CaloEnergy)
653 bool keepScatterer = true;
654 if (s.materialEffectsOnTrack()->thicknessInX0() < 0.0001) {
655 keepScatterer = false;
656 if (calo) {
657 const MaterialEffectsOnTrack* meot =
658 dynamic_cast<const MaterialEffectsOnTrack*>(
659 s.materialEffectsOnTrack());
660 if (meot) {
661 const EnergyLoss* energyLoss = meot->energyLoss();
662 if (energyLoss &&
663 std::abs(energyLoss->deltaE()) > 0.1 * Gaudi::Units::MeV) {
664 keepScatterer = true;
665 }
666 }
667 }
668 }
669 if (keepScatterer) {
670 measurement1 = std::make_unique<FitMeasurement>(
671 s.materialEffectsOnTrack(),
672 Trk::ParticleMasses::mass[particleHypothesis], position, qOverP,
673 calo);
674 if (!calo && !haveMaterial &&
675 (haveMeasurement || s.measurementOnTrack())) {
676 haveMaterial = true;
677 }
678 } else {
679 ATH_MSG_DEBUG("don't keep thin scatterer");
680 continue;
681 }
682 } else if (s.alignmentEffectsOnTrack() && s.trackParameters()) {
683 const Amg::Vector3D direction = s.trackParameters()->momentum().unit();
684 const Amg::Vector3D position = s.trackParameters()->position();
685 measurement1 = std::make_unique<FitMeasurement>(
686 s.alignmentEffectsOnTrack(), direction, position);
687 }
688 const Trk::MeasurementBase* measurementBase = s.measurementOnTrack();
689 if (measurementBase) {
690 if (!Amg::hasPositiveDiagElems(measurementBase->localCovariance())) {
691 continue;
692 }
693 // option to skip vertex measurement (i.e. when not at front of list)
694 if (skipVertexMeasurement &&
695 dynamic_cast<const PerigeeSurface*>(&s.surface())) {
696 measurement1.reset();
697 continue;
698 }
699 haveMeasurement = true;
700 surface = &s.measurementOnTrack()->associatedSurface();
701 measurement2 =
702 std::make_unique<FitMeasurement>(hit, nullptr, measurementBase);
703 if (s.type(TrackStateOnSurface::Outlier)) {
704 measurement2->setOutlier();
705 }
706 // redundant surely??
707 // if (measurement2->isCluster() || measurement2->isDrift())
708 // haveMeasurement = true;
709 // if (misAlignmentNumber && misAlignedTSOS.back() == *s)
710 // {
711 // measurement2->alignmentParameter(misAlignmentNumber);
712 // misAlignedTSOS.pop_back();
713 // misAlignmentNumbers.pop_back();
714 // misAlignmentNumber = misAlignmentNumbers.back();
715 // }
716 //
717 // Peter
718 // measurement2->alignmentParameter(0);
719 if (misAlignmentNumber) {
720 Identifier id = Identifier();
721 if (measurementBase) {
722 const Trk::RIO_OnTrack* rot =
723 dynamic_cast<const Trk::RIO_OnTrack*>(measurementBase);
724 if (rot) {
725 id = rot->identify();
726 } else {
728 dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(
729 measurementBase);
730 if (crot && !crot->containedROTs().empty() &&
731 crot->containedROTs().front()) {
732 id = crot->containedROTs().front()->identify();
733 }
734 }
735 }
736 for (unsigned int im = 0; im < misAlignedTSOS.size(); ++im) {
737 if (misAlignedTSOS[im] != id) {
738 continue;
739 }
740 measurement2->alignmentParameter(misAlignmentNumbers[im]);
741 }
742 if (m_extendedDebug) {
743 for (unsigned int im = 0; im < misAlignedTSOS.size(); ++im) {
744 if (misAlignedTSOS[im] != id) {
745 continue;
746 }
747 if (measurement2->isDrift()) {
748 ATH_MSG_DEBUG(" tsos " << tsos << " Drift Measurement im " << im
749 << " with misAlignmentNumber "
750 << misAlignmentNumbers[im]);
751 } else {
752 ATH_MSG_DEBUG(" tsos " << tsos << " Cluster Measurement im " << im
753 << " with misAlignmentNumber "
754 << misAlignmentNumbers[im]);
755 }
756 }
757 }
758 }
759 } else if (!measurement1 && s.trackParameters()) {
760 if (s.type(TrackStateOnSurface::Hole)) {
761 measurement2 = std::make_unique<FitMeasurement>(s);
762 } else if (s.type(TrackStateOnSurface::Perigee)) {
763 if (i == trackStateOnSurfaces.begin()) {
764 continue;
765 }
766 const Perigee* perigee =
767 dynamic_cast<const Perigee*>(s.trackParameters());
768 if (!perigee) {
769 continue;
770 }
771 measurement2 = std::make_unique<FitMeasurement>(*perigee);
772 } else if (s.type(TrackStateOnSurface::Parameter)) {
773 continue;
774 } else {
775 // TSOS type not understood.
776 m_messageHelper->printWarning(16, s.dumpType());
777 continue;
778 }
779 } else if (s.materialEffectsOnTrack()) {
780 surface = &s.materialEffectsOnTrack()->associatedSurface();
781 } else if (s.alignmentEffectsOnTrack()) {
782 surface = &s.alignmentEffectsOnTrack()->associatedSurface();
783 } else {
784 // skip TSOS with missing trackParameters
785 // this should never happen (i.e. where's the surface?)
786 m_messageHelper->printWarning(17, s.dumpType());
787 continue;
788 }
789
790 // current intersection
791 if (s.trackParameters() && (measurement1 || measurement2)) {
792 Amg::Vector3D direction = s.trackParameters()->momentum().unit();
793 if (startDirection.dot(direction) < 0.) {
794 measurementsFlipped = true;
796 if (measurement1) {
797 measurement1->flipDriftDirection();
798 }
799 if (measurement2) {
800 measurement2->flipDriftDirection();
801 }
802 }
803 qOverP = s.trackParameters()->parameters()[Trk::qOverP];
805 s.trackParameters()->position(), direction, 0.);
806 } else if (surface) {
807 std::optional<TrackSurfaceIntersection> newIntersection =
808 m_stepPropagator->intersectSurface(ctx, *surface, intersection,
810
811 if (!newIntersection) {
812 m_messageHelper->printWarning(18);
813 measurement2.reset();
814 continue;
815 }
816
817 intersection = std::move(*newIntersection);
818 if (s.materialEffectsOnTrack()) {
819 const Amg::Vector3D& position = intersection.position();
820 bool const calo = (!m_indetVolume->inside(position) &&
822 measurement1 = std::make_unique<FitMeasurement>(
823 s.materialEffectsOnTrack(),
824 Trk::ParticleMasses::mass[particleHypothesis],
825 intersection.position(), qOverP, calo);
826 if (!calo && !haveMaterial && haveMeasurement) {
827 haveMaterial = true;
828 }
829 } else if (!measurement2) {
830 // TSOS skipped
831 m_messageHelper->printWarning(19, s.dumpType());
832 // delete intersection;
833 continue;
834 }
835 }
836
837 // check if ordering OK
838 if (!reorder) {
839 const double distance =
840 startDirection.dot(intersection.position() - startPosition);
841 Amg::Vector3D positionMst = startPosition;
842 if (s.measurementOnTrack()) {
843 positionMst = s.measurementOnTrack()->globalPosition();
844 }
845 if (s.materialEffectsOnTrack()) {
846 positionMst = s.materialEffectsOnTrack()->associatedSurface().center();
847 }
848 const double distanceR = std::sqrt((positionMst.x() - startPosition.x()) *
849 (positionMst.x() - startPosition.x()) +
850 (positionMst.y() - startPosition.y()) *
851 (positionMst.y() - startPosition.y()));
852 double distanceZ = (positionMst.z() - startPosition.z());
853 if (startDirection.z() < 0) {
854 distanceZ = -distanceZ;
855 }
856 if (distance < previousDistance && distanceR < previousDistanceR &&
857 distanceZ < previousDistanceZ) {
858 reorder = true;
859 ATH_MSG_DEBUG(" reorder 3D distance "
860 << distance - previousDistance << " R distance "
861 << distanceR - previousDistanceR << " Z distance "
862 << distanceZ - previousDistanceZ);
863 }
864 previousDistance = distance - m_orderingTolerance;
865 previousDistanceR = distanceR - m_orderingTolerance;
866 previousDistanceZ = distanceZ - m_orderingTolerance;
867 }
868
869 // insert measurement(s) in list
870 if (measurement1) {
871 if (measurement2) {
872 TrackSurfaceIntersection intersectionCopy = intersection;
873 measurement1->intersection(type, intersectionCopy);
874 measurements.push_back(measurement1.release());
875 } else {
876 measurement1->intersection(type, intersection);
877 measurement1->qOverP(qOverP);
878 measurements.push_back(measurement1.release());
879 }
880 }
881 if (measurement2) {
882 measurement2->intersection(type, intersection);
883 measurement2->qOverP(qOverP);
884 measurements.push_back(measurement2.release());
885 }
886 }
887
888 // reorder if necessary
889 if (reorder) {
890 m_materialAllocator->orderMeasurements(measurements, startDirection,
891 startPosition);
892 }
893 if (measurementsFlipped) {
894 ATH_MSG_VERBOSE("flipped track measurement order");
895 }
896
897 // flag whether material has already been allocated
898 return haveMaterial;
899}
900
901std::unique_ptr<Trk::Track> iPatFitter::performFit(
902 const EventContext& ctx,
903 FitState& fitState, const ParticleHypothesis particleHypothesis,
904 const TrackInfo& trackInfo, const Trk::TrackStates* leadingTSOS,
905 const FitQuality* perigeeQuality, Garbage_t& garbage) const {
906 std::vector<FitMeasurement*>& measurements = fitState.getMeasurements();
907 FitParameters* parameters = fitState.parameters.get();
908 // initialize the scattering centres
909 m_materialAllocator->initializeScattering(measurements);
910
911 // set fixed momentum in lineFit case according to configuration
912 if (m_lineFit) {
913 parameters->fitMomentum(false);
914 if (m_lineMomentum > 0.) {
915 parameters->qOverP(1. / m_lineMomentum);
916 }
917 }
918
919 // perform fit
920 MsgStream log(msgSvc(), name());
921 Trk::FitProcedure::Cache cache(m_fitProcedure->constrainedAlignmentEffects());
922
923 // This lock should no be needed , leaving it for now
924 // until we are sure all function pass thread safety
925 // requirements
927
928 const FitProcedureQuality& quality =
929 m_fitProcedure->execute(cache, m_asymmetricCaloEnergy, log, measurements,
930 parameters, perigeeQuality);
931 std::unique_ptr<Track> fittedTrack;
932 if (!quality.fitCode()) {
933 // include leading material
934 m_materialAllocator->addLeadingMaterial(measurements, particleHypothesis,
935 *parameters, garbage);
936
937 // construct the fitted track
938 fittedTrack.reset(Trk::FitProcedure::constructTrack(
939 cache, measurements, *parameters, trackInfo, leadingTSOS));
940 if (fittedTrack) {
941 // set StraightLine when momentum unfitted
942 if (!parameters->fitMomentum()) {
943 fittedTrack->info().setTrackProperties(TrackInfo::StraightTrack);
944 }
945
946 // special check for CaloDeposit - parameters must be inside calorimeter
947 for (const Trk::TrackStateOnSurface* tsos :
948 *fittedTrack->trackStateOnSurfaces()) {
949 if (!tsos->type(TrackStateOnSurface::CaloDeposit)) {
950 continue;
951 }
952 if (tsos->trackParameters()) {
953 const Amg::Vector3D position = tsos->trackParameters()->position();
954 if (!m_indetVolume->inside(position) &&
955 m_calorimeterVolume->inside(position)) {
956 break;
957 }
958 }
959 // something badly wrong: WARN and kill track
960 // fail fit as CaloDeposit outside calo volume
962 "fail fit as CaloDeposit outside calo volume: " << (*fittedTrack));
963 fittedTrack.reset();
964 break;
965 }
966 }
967
968 // statistics for successful fit
969 if (fittedTrack) {
971 m_countIterations += quality.iterations();
972 fitState.iterations = quality.iterations();
973
974 // report material
975 if (msgLvl(MSG::DEBUG)) {
976 int calo = 0;
977 double caloX0 = 0.;
978 double caloEloss = 0.;
979 int indet = 0;
980 double indetX0 = 0.;
981 double indetEloss = 0.;
982 int spect = 0;
983 double spectX0 = 0.;
984 double spectEloss = 0.;
985 for (FitMeasurement* m : measurements) {
986 if (m->isEnergyDeposit()) {
987 calo++;
988 caloEloss += m->energyLoss();
989 } else if (!m->isScatterer()) {
990 continue;
991 }
992
993 if (m_indetVolume->inside(m->position())) {
994 indet++;
995 indetX0 += m->materialEffects()->thicknessInX0();
996 indetEloss += m->energyLoss();
997 // conflicting energy deposit sign for inDet material
998 if (m->energyLoss() * indetEloss < 0.) {
999 m_messageHelper->printWarning(21);
1000 }
1001 continue;
1002 }
1003 if (m_calorimeterVolume->inside(
1004 m->intersection(FittedTrajectory).position())) {
1005 calo++;
1006 caloX0 += m->materialEffects()->thicknessInX0();
1007 continue;
1008 }
1009
1010 spect++;
1011 spectX0 += m->materialEffects()->thicknessInX0();
1012 spectEloss += m->energyLoss();
1013 // conflicting energy deposit sign for spectrometer material
1014 if (m->energyLoss() * spectEloss < 0.) {
1015 m_messageHelper->printWarning(22);
1016 }
1017 }
1018
1019 // WARN in case of bug #56297
1020 if (calo) {
1021 // excessive calorimeter energy loss
1022 if (std::abs(caloEloss) > 200. * Gaudi::Units::GeV &&
1023 m_messageHelper->wouldPrintWarning(23)) {
1024 std::stringstream ss;
1025 ss << caloEloss / Gaudi::Units::GeV << " for track with P "
1026 << fittedTrack->perigeeParameters()->momentum().mag() /
1027 Gaudi::Units::GeV
1028 << " GeV";
1029 m_messageHelper->printWarning(23, ss.str());
1030 }
1031
1032 // excessive spectrometer energy loss
1033 if ((std::abs(spectEloss) > (0.5 * Gaudi::Units::GeV)) &&
1034 (std::abs(spectEloss * caloX0) >
1035 std::abs(4. * caloEloss * spectX0)) &&
1036 m_messageHelper->wouldPrintWarning(24)) {
1037 std::stringstream ss;
1038 ss << spectEloss / Gaudi::Units::GeV << " ( "
1039 << caloEloss / Gaudi::Units::GeV
1040 << " calorimeter energy loss). Track has P "
1041 << fittedTrack->perigeeParameters()->momentum().mag() /
1042 Gaudi::Units::GeV
1043 << " GeV";
1044 m_messageHelper->printWarning(24, ss.str());
1045 }
1046 }
1047
1048 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed);
1049 if (indet) {
1050 msg() << std::setw(5) << indet << " indet scatterers with"
1051 << " material: X0" << std::setw(6) << std::setprecision(3)
1052 << indetX0;
1053 if (calo && caloEloss < 0.) {
1054 msg() << " energyGain";
1055 } else {
1056 msg() << " energyLoss";
1057 }
1058 msg() << std::setw(6) << std::setprecision(3)
1059 << indetEloss / Gaudi::Units::GeV << ",";
1060 }
1061
1062 if (spect) {
1063 msg() << std::setw(5) << spect << " spectrometer scatterers with"
1064 << " material: X0" << std::setw(8) << std::setprecision(3)
1065 << spectX0;
1066 if (calo && caloEloss < 0.) {
1067 msg() << " energyGain";
1068 } else {
1069 msg() << " energyLoss";
1070 }
1071 msg() << std::setw(7) << std::setprecision(3)
1072 << spectEloss / Gaudi::Units::GeV;
1073 }
1074
1075 if (!indet && !spect) {
1076 msg() << " 0 scatterers - no tracking material";
1077 }
1078 msg() << endmsg;
1079 }
1080 }
1081 }
1082
1083 // generate a track summary for this candidate
1084 if ((m_trackSummaryTool.isEnabled()) && (fittedTrack != nullptr)) {
1085 m_trackSummaryTool->computeAndReplaceTrackSummary(ctx, *fittedTrack, false);
1086 }
1087
1088 return fittedTrack;
1089}
1090
1091void iPatFitter::printTSOS(const Track& track) const {
1092 // debugging aid
1093 MsgStream log(msgSvc(), name());
1094
1095 msg(MSG::INFO) << " track with " << track.trackStateOnSurfaces()->size()
1096 << " TSOS " << endmsg;
1097 int tsos = 0;
1099 track.trackStateOnSurfaces()->begin();
1100 t != track.trackStateOnSurfaces()->end(); ++t, ++tsos) {
1101 msg() << std::setiosflags(std::ios::fixed | std::ios::right) << " TSOS# "
1102 << std::setw(3) << tsos << " parameters: " << std::setw(7)
1103 << std::setprecision(1) << (**t).trackParameters()->position().perp()
1104 << std::setw(8) << std::setprecision(4)
1105 << (**t).trackParameters()->position().phi() << std::setw(9)
1106 << std::setprecision(1) << (**t).trackParameters()->position().z()
1107 << " position " << std::setw(8) << std::setprecision(4)
1108 << (**t).trackParameters()->momentum().phi() << " phi "
1109 << std::setw(7) << std::setprecision(4)
1110 << (**t).trackParameters()->momentum().theta() << " theta "
1111 << std::setw(9) << std::setprecision(4)
1112 << (**t).trackParameters()->momentum().mag() / Gaudi::Units::GeV
1113 << " GeV";
1114
1115 if ((**t).measurementOnTrack()) {
1116 msg() << " meas ";
1117 } else {
1118 msg() << " ";
1119 }
1120 if ((**t).materialEffectsOnTrack()) {
1121 msg() << " scat ";
1122 } else {
1123 msg() << " ";
1124 }
1125 msg() << (**t).dumpType() << endmsg;
1126 }
1127}
1128
1129void iPatFitter::refit(const EventContext& ctx, FitState& fitState,
1130 const Track& track, const RunOutlierRemoval runOutlier,
1131 const ParticleHypothesis particleHypothesis) const {
1132 ATH_MSG_VERBOSE(" refit ");
1133 const unsigned countGoodFits = m_countGoodFits;
1134 const unsigned countIterations = m_countIterations;
1136 // outlier removal not implemented
1137 if (runOutlier) {
1138 m_messageHelper->printWarning(0);
1139 }
1140
1141 // create Perigee if starting parameters are for a different surface type
1142 const Perigee* perigeeParameters = track.perigeeParameters();
1143 // Note: we don't own the Perigee from perigeeParameters(), but if it returns
1144 // nullptr, we have to make our own, and we need to delete it, so it's put in
1145 // this unique_ptr
1146 std::unique_ptr<Perigee> newPerigee;
1147 std::unique_ptr<PerigeeSurface> perigeeSurface;
1148
1149 if (!perigeeParameters) {
1150 auto i = track.trackStateOnSurfaces()->begin();
1151 while (i != track.trackStateOnSurfaces()->end() &&
1152 !(**i).trackParameters()) {
1153 i++;
1154 }
1155 const TrackStateOnSurface& s = (**i);
1156 if (!s.trackParameters()) {
1157 // input track without parameters
1158 m_messageHelper->printWarning(1);
1159 m_countGoodRefits += m_countGoodFits - countGoodFits;
1160 m_countGoodFits = countGoodFits;
1161 m_countRefitIterations += m_countIterations - countIterations;
1162 m_countIterations = countIterations;
1163 return;
1164 }
1165
1166 const Amg::Vector3D origin(s.trackParameters()->position());
1167 perigeeSurface = std::make_unique<PerigeeSurface>(origin);
1168 newPerigee = std::make_unique<Perigee>(
1169 s.trackParameters()->position(), s.trackParameters()->momentum(),
1170 s.trackParameters()->charge(), *perigeeSurface);
1171 }
1172
1173 const Perigee& perigee =
1174 newPerigee ? *newPerigee : *perigeeParameters; // Use the valid Perigee
1175
1176 fitState.parameters = std::make_unique<FitParameters>(perigee);
1177
1178 // set up the measurements
1179 if (!track.trackStateOnSurfaces()) {
1180 // input track without trackStateOnSurfaces
1181 m_messageHelper->printWarning(2);
1182 m_countGoodRefits += m_countGoodFits - countGoodFits;
1183 m_countGoodFits = countGoodFits;
1184 m_countRefitIterations += m_countIterations - countIterations;
1185 m_countIterations = countIterations;
1186 return;
1187 }
1188
1189 fitState.newMeasurements();
1190
1191 bool const haveMaterial =
1192 addMeasurements(ctx, fitState.getMeasurements(), *fitState.parameters,
1193 particleHypothesis, *track.trackStateOnSurfaces());
1194
1195 // allocate material
1196 Garbage_t garbage;
1197 if (!haveMaterial && particleHypothesis != Trk::nonInteracting) {
1198 m_materialAllocator->allocateMaterial(
1199 fitState.getMeasurements(), particleHypothesis, *fitState.parameters,
1200 perigee, garbage);
1201 }
1202
1203 // perform fit and return fitted track
1204 TrackInfo trackInfo(TrackInfo::iPatTrackFitter, particleHypothesis);
1205 trackInfo.addPatternReco(track.info());
1206 const std::unique_ptr<Trk::Track> fittedTrack{performFit(
1207 ctx, fitState, particleHypothesis, trackInfo, nullptr, nullptr, garbage)};
1208
1209 m_countGoodRefits += m_countGoodFits - countGoodFits;
1210 m_countGoodFits = countGoodFits;
1211 m_countRefitIterations += m_countIterations - countIterations;
1212 m_countIterations = countIterations;
1213}
1214} // namespace Trk
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static Double_t a
static Double_t ss
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< std::unique_ptr< const MuonClusterOnTrack > > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
Class to represent misalignments or 'discontinuities' on tracks These have a surface where the z axis...
double sigmaDeltaAngle() const
returns the
const std::vector< Identifier > & vectorOfAffectedTSOS() const
Returns a vector of the affected TSOS in the track.
double deltaAngle() const
returns the
double sigmaDeltaTranslation() const
returns the
double deltaTranslation() const
returns the
This class describes energy loss material effects in the ATLAS tracking EDM.
Definition EnergyLoss.h:34
double deltaE() const
returns the
static Track * constructTrack(FitProcedure::Cache &cache, const std::vector< FitMeasurement * > &measurements, FitParameters &parameters, const TrackInfo &trackInfo, const DataVector< const TrackStateOnSurface > *leadingTSOS=nullptr)
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
@ CalorimeterEntryLayer
Tracking Volume which defines the entrance srufaces of the calorimeter.
@ MuonSpectrometerEntryLayer
Tracking Volume which defines the entrance surfaces of the MS.
magnetic field properties to steer the behavior of the extrapolation
represents the full description of deflection and e-loss of a track in material.
const EnergyLoss * energyLoss() const
returns the energy loss object.
This class is the pure abstract base class for all fittable tracking measurements.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
virtual const S & associatedSurface() const override final
Access to the Surface method.
Class describing the Line to which the Perigee refers to.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Contains information about the 'fitter' of this track.
bool trackProperties(const TrackProperties &property) const
Access methods for track properties.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Parameter
This TSOS contains a Trk::ParameterBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
@ CaloDeposit
This TSOS contains a CaloEnergy object.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const Perigee * perigeeParameters() const
return Perigee.
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
std::vector< FitMeasurement * > & getMeasurements()
Definition iPatFitter.h:116
std::unique_ptr< FitParameters > parameters
Definition iPatFitter.h:134
std::unique_ptr< Trk::Volume > m_calorimeterVolume
Definition iPatFitter.h:226
iPatFitter(const std::string &type, const std::string &name, const IInterface *parent, bool isGlobalFit=false)
Gaudi::Property< unsigned > m_maxWarnings
Definition iPatFitter.h:213
ToolHandle< IMaterialAllocator > m_materialAllocator
Definition iPatFitter.h:192
std::atomic< unsigned > m_countGoodRefits
Definition iPatFitter.h:235
std::unique_ptr< Trk::Volume > m_indetVolume
Definition iPatFitter.h:227
virtual StatusCode initialize() override
Gaudi::Property< bool > m_constrainedAlignmentEffects
Definition iPatFitter.h:218
Gaudi::Property< double > m_orderingTolerance
Definition iPatFitter.h:211
std::pair< std::unique_ptr< Track >, std::unique_ptr< FitState > > fitWithState(const EventContext &ctx, const Track &, const RunOutlierRemoval runOutlier=false, const ParticleHypothesis particleHypothesis=Trk::nonInteracting) const
std::atomic< unsigned > m_countGoodFits
Definition iPatFitter.h:232
IMaterialAllocator::Garbage_t Garbage_t
Definition iPatFitter.h:39
Gaudi::Property< int > m_forcedRefitsForValidation
Definition iPatFitter.h:221
Trk::MagneticFieldProperties m_stepField
Definition iPatFitter.h:228
std::atomic< unsigned > m_countFitAttempts
Definition iPatFitter.h:231
Gaudi::Property< bool > m_asymmetricCaloEnergy
Definition iPatFitter.h:185
ServiceHandle< ITrackingVolumesSvc > m_trackingVolumesSvc
Definition iPatFitter.h:205
std::atomic< unsigned > m_countRefitAttempts
Definition iPatFitter.h:234
Gaudi::Property< bool > m_lineFit
Definition iPatFitter.h:188
ToolHandle< IIntersector > m_straightLineIntersector
Definition iPatFitter.h:202
Gaudi::Property< double > m_lineMomentum
Definition iPatFitter.h:189
Gaudi::Property< bool > m_fullCombinedFit
Definition iPatFitter.h:187
ToolHandle< IPropagator > m_stepPropagator
Definition iPatFitter.h:200
void addMeasurements(const EventContext &ctx, std::vector< FitMeasurement * > &measurements, const MeasurementSet &measurementSet, const FitParameters &parameters) const
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
Definition iPatFitter.h:207
std::unique_ptr< FitProcedure > m_fitProcedure
Definition iPatFitter.h:148
std::atomic< unsigned > m_countRefitIterations
Definition iPatFitter.h:236
virtual StatusCode finalize() override
const bool m_globalFit
Definition iPatFitter.h:152
std::atomic< unsigned > m_countIterations
Definition iPatFitter.h:233
void printTSOS(const Track &) const
virtual std::unique_ptr< Track > fit(const EventContext &ctx, const Track &, const RunOutlierRemoval runOutlier=false, const ParticleHypothesis particleHypothesis=Trk::nonInteracting) const override
RE-FIT A TRACK.
void refit(const EventContext &ctx, FitState &fitState, const Track &track, const RunOutlierRemoval runOutlier, const ParticleHypothesis particleHypothesis) const
std::unique_ptr< Track > performFit(const EventContext &ctx, FitState &fitState, const ParticleHypothesis particleHypothesis, const TrackInfo &trackInfo, const Trk::TrackStates *leadingTSOS, const FitQuality *perigeeQuality, Garbage_t &garbage) const
std::unique_ptr< MessageHelper > m_messageHelper
Definition iPatFitter.h:239
Gaudi::Property< int > m_maxIterations
Definition iPatFitter.h:223
ToolHandle< IIntersector > m_solenoidalIntersector
Definition iPatFitter.h:197
ToolHandle< IIntersector > m_rungeKuttaIntersector
Definition iPatFitter.h:194
Gaudi::Property< bool > m_extendedDebug
Definition iPatFitter.h:220
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
int r
Definition globals.cxx:22
bool hasPositiveDiagElems(const AmgSymMatrix(N) &mat)
Returns true if all diagonal elements of the covariance matrix are finite aka sane in the above defin...
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Ensure that the ATLAS eigen extensions are properly loaded.
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition FitterTypes.h:30
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ perigeeParameters
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.
bool RunOutlierRemoval
switch to toggle quality processing after fit
Definition FitterTypes.h:22
@ FullField
Field is set to be realistic, but within a given Volume.
TrackSurfaceIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, double path)
Constructor.
@ qOverP
perigee
Definition ParamDefs.h:67
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
ParametersBase< TrackParametersDim, Charged > TrackParameters
const IIntersectionCache * cache() const
Retrieve the associated cache block, if it exists.
std::vector< const PrepRawData * > PrepRawDataSet
vector of clusters and drift circles
Definition FitterTypes.h:26
@ FittedTrajectory
TrackSurfaceIntersection()=default