ATLAS Offline Software
Loading...
Searching...
No Matches
iPatFitter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 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 *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(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(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 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 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) &&
648 m_calorimeterVolume->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;
795 direction = -direction;
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) &&
821 m_calorimeterVolume->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 FitState& fitState, const ParticleHypothesis particleHypothesis,
903 const TrackInfo& trackInfo, const Trk::TrackStates* leadingTSOS,
904 const FitQuality* perigeeQuality, Garbage_t& garbage) const {
905 std::vector<FitMeasurement*>& measurements = fitState.getMeasurements();
906 FitParameters* parameters = fitState.parameters.get();
907 // initialize the scattering centres
908 m_materialAllocator->initializeScattering(measurements);
909
910 // set fixed momentum in lineFit case according to configuration
911 if (m_lineFit) {
912 parameters->fitMomentum(false);
913 if (m_lineMomentum > 0.) {
914 parameters->qOverP(1. / m_lineMomentum);
915 }
916 }
917
918 // perform fit
919 MsgStream log(msgSvc(), name());
920 Trk::FitProcedure::Cache cache(m_fitProcedure->constrainedAlignmentEffects());
921
922 // This lock should no be needed , leaving it for now
923 // until we are sure all function pass thread safety
924 // requirements
926
927 const FitProcedureQuality& quality =
928 m_fitProcedure->execute(cache, m_asymmetricCaloEnergy, log, measurements,
929 parameters, perigeeQuality);
930 std::unique_ptr<Track> fittedTrack;
931 if (!quality.fitCode()) {
932 // include leading material
933 m_materialAllocator->addLeadingMaterial(measurements, particleHypothesis,
934 *parameters, garbage);
935
936 // construct the fitted track
937 fittedTrack.reset(Trk::FitProcedure::constructTrack(
938 cache, measurements, *parameters, trackInfo, leadingTSOS));
939 if (fittedTrack) {
940 // set StraightLine when momentum unfitted
941 if (!parameters->fitMomentum()) {
942 fittedTrack->info().setTrackProperties(TrackInfo::StraightTrack);
943 }
944
945 // special check for CaloDeposit - parameters must be inside calorimeter
946 for (const Trk::TrackStateOnSurface* tsos :
947 *fittedTrack->trackStateOnSurfaces()) {
948 if (!tsos->type(TrackStateOnSurface::CaloDeposit)) {
949 continue;
950 }
951 if (tsos->trackParameters()) {
952 const Amg::Vector3D position = tsos->trackParameters()->position();
953 if (!m_indetVolume->inside(position) &&
954 m_calorimeterVolume->inside(position)) {
955 break;
956 }
957 }
958 // something badly wrong: WARN and kill track
959 // fail fit as CaloDeposit outside calo volume
961 "fail fit as CaloDeposit outside calo volume: " << (*fittedTrack));
962 fittedTrack.reset();
963 break;
964 }
965 }
966
967 // statistics for successful fit
968 if (fittedTrack) {
970 m_countIterations += quality.iterations();
971 fitState.iterations = quality.iterations();
972
973 // report material
974 if (msgLvl(MSG::DEBUG)) {
975 int calo = 0;
976 double caloX0 = 0.;
977 double caloEloss = 0.;
978 int indet = 0;
979 double indetX0 = 0.;
980 double indetEloss = 0.;
981 int spect = 0;
982 double spectX0 = 0.;
983 double spectEloss = 0.;
984 for (FitMeasurement* m : measurements) {
985 if (m->isEnergyDeposit()) {
986 calo++;
987 caloEloss += m->energyLoss();
988 } else if (!m->isScatterer()) {
989 continue;
990 }
991
992 if (m_indetVolume->inside(m->position())) {
993 indet++;
994 indetX0 += m->materialEffects()->thicknessInX0();
995 indetEloss += m->energyLoss();
996 // conflicting energy deposit sign for inDet material
997 if (m->energyLoss() * indetEloss < 0.) {
998 m_messageHelper->printWarning(21);
999 }
1000 continue;
1001 }
1002 if (m_calorimeterVolume->inside(
1003 m->intersection(FittedTrajectory).position())) {
1004 calo++;
1005 caloX0 += m->materialEffects()->thicknessInX0();
1006 continue;
1007 }
1008
1009 spect++;
1010 spectX0 += m->materialEffects()->thicknessInX0();
1011 spectEloss += m->energyLoss();
1012 // conflicting energy deposit sign for spectrometer material
1013 if (m->energyLoss() * spectEloss < 0.) {
1014 m_messageHelper->printWarning(22);
1015 }
1016 }
1017
1018 // WARN in case of bug #56297
1019 if (calo) {
1020 // excessive calorimeter energy loss
1021 if (std::abs(caloEloss) > 200. * Gaudi::Units::GeV &&
1022 m_messageHelper->wouldPrintWarning(23)) {
1023 std::stringstream ss;
1024 ss << caloEloss / Gaudi::Units::GeV << " for track with P "
1025 << fittedTrack->perigeeParameters()->momentum().mag() /
1026 Gaudi::Units::GeV
1027 << " GeV";
1028 m_messageHelper->printWarning(23, ss.str());
1029 }
1030
1031 // excessive spectrometer energy loss
1032 if ((std::abs(spectEloss) > (0.5 * Gaudi::Units::GeV)) &&
1033 (std::abs(spectEloss * caloX0) >
1034 std::abs(4. * caloEloss * spectX0)) &&
1035 m_messageHelper->wouldPrintWarning(24)) {
1036 std::stringstream ss;
1037 ss << spectEloss / Gaudi::Units::GeV << " ( "
1038 << caloEloss / Gaudi::Units::GeV
1039 << " calorimeter energy loss). Track has P "
1040 << fittedTrack->perigeeParameters()->momentum().mag() /
1041 Gaudi::Units::GeV
1042 << " GeV";
1043 m_messageHelper->printWarning(24, ss.str());
1044 }
1045 }
1046
1047 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed);
1048 if (indet) {
1049 msg() << std::setw(5) << indet << " indet scatterers with"
1050 << " material: X0" << std::setw(6) << std::setprecision(3)
1051 << indetX0;
1052 if (calo && caloEloss < 0.) {
1053 msg() << " energyGain";
1054 } else {
1055 msg() << " energyLoss";
1056 }
1057 msg() << std::setw(6) << std::setprecision(3)
1058 << indetEloss / Gaudi::Units::GeV << ",";
1059 }
1060
1061 if (spect) {
1062 msg() << std::setw(5) << spect << " spectrometer scatterers with"
1063 << " material: X0" << std::setw(8) << std::setprecision(3)
1064 << spectX0;
1065 if (calo && caloEloss < 0.) {
1066 msg() << " energyGain";
1067 } else {
1068 msg() << " energyLoss";
1069 }
1070 msg() << std::setw(7) << std::setprecision(3)
1071 << spectEloss / Gaudi::Units::GeV;
1072 }
1073
1074 if (!indet && !spect) {
1075 msg() << " 0 scatterers - no tracking material";
1076 }
1077 msg() << endmsg;
1078 }
1079 }
1080 }
1081
1082 // generate a track summary for this candidate
1083 if ((m_trackSummaryTool.isEnabled()) && (fittedTrack != nullptr)) {
1084 m_trackSummaryTool->computeAndReplaceTrackSummary(*fittedTrack, false);
1085 }
1086
1087 return fittedTrack;
1088}
1089
1090void iPatFitter::printTSOS(const Track& track) const {
1091 // debugging aid
1092 MsgStream log(msgSvc(), name());
1093
1094 msg(MSG::INFO) << " track with " << track.trackStateOnSurfaces()->size()
1095 << " TSOS " << endmsg;
1096 int tsos = 0;
1098 track.trackStateOnSurfaces()->begin();
1099 t != track.trackStateOnSurfaces()->end(); ++t, ++tsos) {
1100 msg() << std::setiosflags(std::ios::fixed | std::ios::right) << " TSOS# "
1101 << std::setw(3) << tsos << " parameters: " << std::setw(7)
1102 << std::setprecision(1) << (**t).trackParameters()->position().perp()
1103 << std::setw(8) << std::setprecision(4)
1104 << (**t).trackParameters()->position().phi() << std::setw(9)
1105 << std::setprecision(1) << (**t).trackParameters()->position().z()
1106 << " position " << std::setw(8) << std::setprecision(4)
1107 << (**t).trackParameters()->momentum().phi() << " phi "
1108 << std::setw(7) << std::setprecision(4)
1109 << (**t).trackParameters()->momentum().theta() << " theta "
1110 << std::setw(9) << std::setprecision(4)
1111 << (**t).trackParameters()->momentum().mag() / Gaudi::Units::GeV
1112 << " GeV";
1113
1114 if ((**t).measurementOnTrack()) {
1115 msg() << " meas ";
1116 } else {
1117 msg() << " ";
1118 }
1119 if ((**t).materialEffectsOnTrack()) {
1120 msg() << " scat ";
1121 } else {
1122 msg() << " ";
1123 }
1124 msg() << (**t).dumpType() << endmsg;
1125 }
1126}
1127
1128void iPatFitter::refit(const EventContext& ctx, FitState& fitState,
1129 const Track& track, const RunOutlierRemoval runOutlier,
1130 const ParticleHypothesis particleHypothesis) const {
1131 ATH_MSG_VERBOSE(" refit ");
1132 const unsigned countGoodFits = m_countGoodFits;
1133 const unsigned countIterations = m_countIterations;
1135 // outlier removal not implemented
1136 if (runOutlier) {
1137 m_messageHelper->printWarning(0);
1138 }
1139
1140 // create Perigee if starting parameters are for a different surface type
1141 const Perigee* perigeeParameters = track.perigeeParameters();
1142 // Note: we don't own the Perigee from perigeeParameters(), but if it returns
1143 // nullptr, we have to make our own, and we need to delete it, so it's put in
1144 // this unique_ptr
1145 std::unique_ptr<Perigee> newPerigee;
1146 std::unique_ptr<PerigeeSurface> perigeeSurface;
1147
1148 if (!perigeeParameters) {
1149 auto i = track.trackStateOnSurfaces()->begin();
1150 while (i != track.trackStateOnSurfaces()->end() &&
1151 !(**i).trackParameters()) {
1152 i++;
1153 }
1154 const TrackStateOnSurface& s = (**i);
1155 if (!s.trackParameters()) {
1156 // input track without parameters
1157 m_messageHelper->printWarning(1);
1158 m_countGoodRefits += m_countGoodFits - countGoodFits;
1159 m_countGoodFits = countGoodFits;
1160 m_countRefitIterations += m_countIterations - countIterations;
1161 m_countIterations = countIterations;
1162 return;
1163 }
1164
1165 const Amg::Vector3D origin(s.trackParameters()->position());
1166 perigeeSurface = std::make_unique<PerigeeSurface>(origin);
1167 newPerigee = std::make_unique<Perigee>(
1168 s.trackParameters()->position(), s.trackParameters()->momentum(),
1169 s.trackParameters()->charge(), *perigeeSurface);
1170 }
1171
1172 const Perigee& perigee =
1173 newPerigee ? *newPerigee : *perigeeParameters; // Use the valid Perigee
1174
1175 fitState.parameters = std::make_unique<FitParameters>(perigee);
1176
1177 // set up the measurements
1178 if (!track.trackStateOnSurfaces()) {
1179 // input track without trackStateOnSurfaces
1180 m_messageHelper->printWarning(2);
1181 m_countGoodRefits += m_countGoodFits - countGoodFits;
1182 m_countGoodFits = countGoodFits;
1183 m_countRefitIterations += m_countIterations - countIterations;
1184 m_countIterations = countIterations;
1185 return;
1186 }
1187
1188 fitState.newMeasurements();
1189
1190 bool const haveMaterial =
1191 addMeasurements(ctx, fitState.getMeasurements(), *fitState.parameters,
1192 particleHypothesis, *track.trackStateOnSurfaces());
1193
1194 // allocate material
1195 Garbage_t garbage;
1196 if (!haveMaterial && particleHypothesis != Trk::nonInteracting) {
1197 m_materialAllocator->allocateMaterial(
1198 fitState.getMeasurements(), particleHypothesis, *fitState.parameters,
1199 perigee, garbage);
1200 }
1201
1202 // perform fit and return fitted track
1203 TrackInfo trackInfo(TrackInfo::iPatTrackFitter, particleHypothesis);
1204 trackInfo.addPatternReco(track.info());
1205 const std::unique_ptr<Trk::Track> fittedTrack{performFit(
1206 fitState, particleHypothesis, trackInfo, nullptr, nullptr, garbage)};
1207
1208 m_countGoodRefits += m_countGoodFits - countGoodFits;
1209 m_countGoodFits = countGoodFits;
1210 m_countRefitIterations += m_countIterations - countIterations;
1211 m_countIterations = countIterations;
1212}
1213} // 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< 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.
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.
An intersection with a Surface is given by.
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:225
std::unique_ptr< Track > performFit(FitState &fitState, const ParticleHypothesis particleHypothesis, const TrackInfo &trackInfo, const Trk::TrackStates *leadingTSOS, const FitQuality *perigeeQuality, Garbage_t &garbage) const
iPatFitter(const std::string &type, const std::string &name, const IInterface *parent, bool isGlobalFit=false)
Gaudi::Property< unsigned > m_maxWarnings
Definition iPatFitter.h:212
ToolHandle< IMaterialAllocator > m_materialAllocator
Definition iPatFitter.h:191
std::atomic< unsigned > m_countGoodRefits
Definition iPatFitter.h:234
std::unique_ptr< Trk::Volume > m_indetVolume
Definition iPatFitter.h:226
virtual StatusCode initialize() override
Gaudi::Property< bool > m_constrainedAlignmentEffects
Definition iPatFitter.h:217
Gaudi::Property< double > m_orderingTolerance
Definition iPatFitter.h:210
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:231
IMaterialAllocator::Garbage_t Garbage_t
Definition iPatFitter.h:39
Gaudi::Property< int > m_forcedRefitsForValidation
Definition iPatFitter.h:220
Trk::MagneticFieldProperties m_stepField
Definition iPatFitter.h:227
std::atomic< unsigned > m_countFitAttempts
Definition iPatFitter.h:230
Gaudi::Property< bool > m_asymmetricCaloEnergy
Definition iPatFitter.h:184
ServiceHandle< ITrackingVolumesSvc > m_trackingVolumesSvc
Definition iPatFitter.h:204
std::atomic< unsigned > m_countRefitAttempts
Definition iPatFitter.h:233
Gaudi::Property< bool > m_lineFit
Definition iPatFitter.h:187
ToolHandle< IIntersector > m_straightLineIntersector
Definition iPatFitter.h:201
Gaudi::Property< double > m_lineMomentum
Definition iPatFitter.h:188
Gaudi::Property< bool > m_fullCombinedFit
Definition iPatFitter.h:186
ToolHandle< IPropagator > m_stepPropagator
Definition iPatFitter.h:199
void addMeasurements(const EventContext &ctx, std::vector< FitMeasurement * > &measurements, const MeasurementSet &measurementSet, const FitParameters &parameters) const
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
Definition iPatFitter.h:206
std::unique_ptr< FitProcedure > m_fitProcedure
Definition iPatFitter.h:148
std::atomic< unsigned > m_countRefitIterations
Definition iPatFitter.h:235
virtual StatusCode finalize() override
const bool m_globalFit
Definition iPatFitter.h:152
std::atomic< unsigned > m_countIterations
Definition iPatFitter.h:232
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< MessageHelper > m_messageHelper
Definition iPatFitter.h:238
Gaudi::Property< int > m_maxIterations
Definition iPatFitter.h:222
ToolHandle< IIntersector > m_solenoidalIntersector
Definition iPatFitter.h:196
ToolHandle< IIntersector > m_rungeKuttaIntersector
Definition iPatFitter.h:193
Gaudi::Property< bool > m_extendedDebug
Definition iPatFitter.h:219
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
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.
@ qOverP
perigee
Definition ParamDefs.h:67
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
std::vector< const PrepRawData * > PrepRawDataSet
vector of clusters and drift circles
Definition FitterTypes.h:26
@ FittedTrajectory