ATLAS Offline Software
Loading...
Searching...
No Matches
GaussianSumFitterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7// ATHENA
13
14// ACTS
15#include "Acts/Propagator/MultiEigenStepperLoop.hpp"
16#include "Acts/MagneticField/MagneticFieldContext.hpp"
17#include "Acts/Surfaces/PerigeeSurface.hpp"
18#include "Acts/Utilities/CalibrationContext.hpp"
19#include "Acts/Definitions/TrackParametrization.hpp"
20#include "Acts/Definitions/Units.hpp"
21#include "Acts/Propagator/EigenStepper.hpp"
22#include "Acts/Surfaces/Surface.hpp"
23#include "Acts/TrackFitting/GsfMixtureReduction.hpp"
24#include "Acts/Utilities/Helpers.hpp"
25#include "Acts/EventData/VectorMultiTrajectory.hpp"
26#include "Acts/EventData/VectorTrackContainer.hpp"
27#include "Acts/EventData/TrackParameters.hpp"
28#include "Acts/Utilities/Logger.hpp"
29#include "Acts/Utilities/CalibrationContext.hpp"
31
32// PACKAGE
36#include "ActsInterop/Logger.h"
39#include "Acts/Propagator/DirectNavigator.hpp"
41
42// STL
43#include <vector>
44#include <bitset>
45#include <type_traits>
46#include <system_error>
47
48namespace ActsTrk {
49
51 const std::string& n,
52 const IInterface* p) :
53 base_class(t,n,p)
54{}
55
57 ATH_MSG_DEBUG(name() << "::" << __FUNCTION__);
58
62 if (!m_refitOnly) {
63 ATH_CHECK(m_trkSummaryTool.retrieve());
64 }else{
65 ATH_MSG_INFO("Running GSF without track summary");
66 }
67
68 m_logger = makeActsAthenaLogger(this, "Acts Gaussian Sum Refit");
69
70 auto field = std::make_shared<ATLASMagneticFieldWrapper>();
71 Acts::MultiEigenStepperLoop<> stepper(field);
72 Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometryTool->trackingGeometry() },
73 logger().cloneWithSuffix("Navigator") );
74 Acts::Propagator<Acts::MultiEigenStepperLoop<>, Acts::Navigator> propagator(std::move(stepper),
75 std::move(navigator),
76 logger().cloneWithSuffix("Prop"));
77
78 Acts::AtlasBetheHeitlerApprox<6, 5> bha = Acts::makeDefaultBetheHeitlerApprox();
79 m_fitter = std::make_unique<Fitter>(std::move(propagator), std::move(bha),
80 logger().cloneWithSuffix("GaussianSumFitter"));
81
82 // Direct Fitter
84 Acts::DirectNavigator directNavigator( logger().cloneWithSuffix("DirectNavigator") );
85 Acts::MultiEigenStepperLoop<> stepperDirect(field);
86 Acts::Propagator<Acts::MultiEigenStepperLoop<>, Acts::DirectNavigator> directPropagator(std::move(stepperDirect),
87 std::move(directNavigator),
88 logger().cloneWithSuffix("DirectPropagator"));
89 Acts::AtlasBetheHeitlerApprox<6, 5> bhaDirect = Acts::makeDefaultBetheHeitlerApprox();
90 m_directFitter = std::make_unique<DirectFitter>(std::move(directPropagator),std::move(bhaDirect),
91 logger().cloneWithSuffix("DirectGaussianSumFitter"));
92
93 }
94
96 m_calibrator = std::make_unique<ActsTrk::detail::TrkMeasurementCalibrator>();
98
100 m_gsfExtensions.surfaceAccessor.connect<&detail::TrkMeasSurfaceAccessor::operator()>(&m_surfaceAccessor);
101 m_gsfExtensions.mixtureReducer.connect<&Acts::reduceMixtureWithKLDistance>();
102
103 m_outlierFinder.StateChiSquaredPerNumberDoFCut = m_option_outlierChi2Cut;
104 m_gsfExtensions.outlierFinder.connect<&ActsTrk::detail::FitterHelperFunctions::ATLASOutlierFinder::operator()<ActsTrk::MutableTrackStateBackend>>(&m_outlierFinder);
105 if(m_option_componentMergeMethod == "Mean" ){
106 m_componentMergeMethod = Acts::ComponentMergeMethod::eMean;
107 }else if(m_option_componentMergeMethod == "MaxWeight"){
108 m_componentMergeMethod = Acts::ComponentMergeMethod::eMaxWeight;
109 }else{
110 throw std::runtime_error("Unknown option for ComponentMergeMethod: " + m_option_componentMergeMethod.value());
111 }
112
113 ATH_MSG_INFO("ACTS GSF direct nav " << m_useDirectNavigation.value());
114 ATH_MSG_INFO("ACTS GSF max cmps " << m_maxComponents.value());
115 ATH_MSG_INFO("ACTS GSF merge meth " << m_option_componentMergeMethod.value());
116 ATH_MSG_INFO("ACTS GSF weight ctf " << m_weightCutOff.value());
117 ATH_MSG_INFO("ACTS GSF outlier chi2 " << m_option_outlierChi2Cut.value());
118
119 return StatusCode::SUCCESS;
120}
121
122// refit a track
123// -------------------------------------------------------
124std::unique_ptr<Trk::Track>
125GaussianSumFitterTool::fit(const EventContext& ctx,
126 const Trk::Track& inputTrack,
127 const Trk::RunOutlierRemoval /*runOutlier*/,
128 const Trk::ParticleHypothesis /*prtHypothesis*/) const
129{
130
131
132 std::unique_ptr<Trk::Track> track = nullptr;
133 ATH_MSG_VERBOSE ("--> enter GaussianSumFitter::fit(Track,,) with Track from author = "
134 << inputTrack.info().dumpInfo());
135
136 // protection against not having measurements on the input track
137 if (!inputTrack.measurementsOnTrack() || inputTrack.measurementsOnTrack()->size() < 2) {
138 ATH_MSG_DEBUG("called to refit empty track or track with too little information, reject fit");
139 return nullptr;
140 }
141
142 // protection against not having track parameters on the input track
143 if (!inputTrack.trackParameters() || inputTrack.trackParameters()->empty()) {
144 ATH_MSG_DEBUG("input fails to provide track parameters for seeding the GSF, reject fit");
145 return nullptr;
146 }
147
148 // Construct a perigee surface as the target surface
149 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
150 Acts::Vector3::Zero());
151
152 const Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
153 const Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
154 const Acts::CalibrationContext calContext{getCalibrationContext(ctx)};
155
156 // Set the GaussianSumFitter options
157 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
158 gsfOptions = prepareOptions(tgContext,
159 mfContext,
160 calContext,
161 *pSurface);
162 gsfOptions.maxComponents = m_maxComponents;
163 gsfOptions.weightCutoff = m_weightCutOff;
164 gsfOptions.componentMergeMethod = m_componentMergeMethod;
165
166
167 std::vector<Acts::SourceLink> trackSourceLinks = m_ATLASConverterTool->trkTrackToSourceLinks(inputTrack);
168 const auto initialParams = m_ATLASConverterTool->trkTrackParametersToActsParameters((*inputTrack.perigeeParameters()), tgContext);
169
170 return performFit(ctx,
171 tgContext,
172 gsfOptions,
173 trackSourceLinks,
174 initialParams);
175}
176
177// fit a set of MeasurementBase objects
178// --------------------------------
179std::unique_ptr<Trk::Track>
180GaussianSumFitterTool::fit(const EventContext& ctx,
181 const Trk::MeasurementSet& inputMeasSet,
182 const Trk::TrackParameters& estimatedStartParameters,
183 const Trk::RunOutlierRemoval /*runOutlier*/,
184 const Trk::ParticleHypothesis /*matEffects*/) const
185{
186 std::unique_ptr<Trk::Track> track = nullptr;
187 // protection against not having measurements on the input track
188 if (inputMeasSet.size() < 2) {
189 ATH_MSG_DEBUG("called to refit empty measurement set or a measurement set with too little information, reject fit");
190 return nullptr;
191 }
192
193 // Construct a perigee surface as the target surface
194 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
195 Acts::Vector3::Zero());
196
197 const Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
198 const Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
199 const Acts::CalibrationContext calContext{getCalibrationContext(ctx)};
200
201 // Set the GaussianSumFitter options
202 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
203 gsfOptions = prepareOptions(tgContext,
204 mfContext,
205 calContext,
206 *pSurface);
207
208 // Set abortOnError to false, else the refitting crashes if no forward propagation is done. Here, we just skip the event and continue.
209 gsfOptions.abortOnError = false;
210
211 std::vector< Acts::SourceLink > trackSourceLinks;
212 m_ATLASConverterTool->toSourceLinks(inputMeasSet, trackSourceLinks);
213
214 const auto initialParams = m_ATLASConverterTool->trkTrackParametersToActsParameters(estimatedStartParameters, tgContext);
215
217
218 std::vector<const Acts::Surface*> surfaces;
219 surfaces.reserve(inputMeasSet.size());
220 std::ranges::transform(trackSourceLinks, std::back_inserter(surfaces), m_surfaceAccessor);
221
222 return performDirectFit(ctx,
223 tgContext,
224 gsfOptions,
225 trackSourceLinks,
226 initialParams,
227 surfaces);
228 }else{
229 return performFit(ctx,
230 tgContext,
231 gsfOptions,
232 trackSourceLinks,
233 initialParams);
234 }
235}
236
237// fit a set of PrepRawData objects
238// --------------------------------
239std::unique_ptr<Trk::Track>
240GaussianSumFitterTool::fit(const EventContext& /*ctx*/,
241 const Trk::PrepRawDataSet& /*inputPRDColl*/,
242 const Trk::TrackParameters& /*estimatedStartParameters*/,
243 const Trk::RunOutlierRemoval /*runOutlier*/,
244 const Trk::ParticleHypothesis /*prtHypothesis*/) const
245{
246 ATH_MSG_DEBUG("Fit of PrepRawDataSet not yet implemented");
247 return nullptr;
248}
249
250// extend a track fit to include an additional set of MeasurementBase objects
251// re-implements the TrkFitterUtils/TrackFitter.cxx general code in a more
252// mem efficient and stable way
253// --------------------------------
254std::unique_ptr<Trk::Track>
255GaussianSumFitterTool::fit(const EventContext& ctx,
256 const Trk::Track& inputTrack,
257 const Trk::MeasurementSet& addMeasColl,
258 const Trk::RunOutlierRemoval /*runOutlier*/,
259 const Trk::ParticleHypothesis /*matEffects*/) const
260{
261 ATH_MSG_VERBOSE ("--> enter GaussianSumFitter::fit(Track,Meas'BaseSet,,)");
262 ATH_MSG_VERBOSE (" with Track from author = " << inputTrack.info().dumpInfo());
263
264 // protection, if empty MeasurementSet
265 if (addMeasColl.empty()) {
266 ATH_MSG_DEBUG( "client tries to add an empty MeasurementSet to the track fit." );
267 return fit(ctx,inputTrack);
268 }
269
270 // protection against not having measurements on the input track
271 if (!inputTrack.measurementsOnTrack() || (inputTrack.measurementsOnTrack()->size() < 2 && addMeasColl.empty())) {
272 ATH_MSG_DEBUG("called to refit empty track or track with too little information, reject fit");
273 return nullptr;
274 }
275
276 // protection against not having track parameters on the input track
277 if (!inputTrack.trackParameters() || inputTrack.trackParameters()->empty()) {
278 ATH_MSG_DEBUG("input fails to provide track parameters for seeding the GSF, reject fit");
279 return nullptr;
280 }
281
282 std::unique_ptr<Trk::Track> track = nullptr;
283
284 // Construct a perigee surface as the target surface
285 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3::Zero());
286
287 const Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
288 const Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
289 const Acts::CalibrationContext calContext{getCalibrationContext(ctx)};
290
291 // Set the GaussianSumFitter options
292 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
293 gsfOptions = prepareOptions(tgContext,
294 mfContext,
295 calContext,
296 *pSurface);
297
298 std::vector<Acts::SourceLink> trackSourceLinks = m_ATLASConverterTool->trkTrackToSourceLinks(inputTrack);
299 const auto initialParams = m_ATLASConverterTool->trkTrackParametersToActsParameters(*(inputTrack.perigeeParameters()), tgContext);
300
301 m_ATLASConverterTool->toSourceLinks(addMeasColl, trackSourceLinks);
302
303 return performFit(ctx, tgContext, gsfOptions,
304 trackSourceLinks,
305 initialParams);
306}
307
308// extend a track fit to include an additional set of PrepRawData objects
309// --------------------------------
310std::unique_ptr<Trk::Track>
311GaussianSumFitterTool::fit(const EventContext& /*ctx*/,
312 const Trk::Track& /*inputTrack*/,
313 const Trk::PrepRawDataSet& /*addPrdColl*/,
314 const Trk::RunOutlierRemoval /*runOutlier*/,
315 const Trk::ParticleHypothesis /*matEffects*/) const
316{
317
318 ATH_MSG_DEBUG("Fit of Track with additional PrepRawDataSet not yet implemented");
319 return nullptr;
320}
321
322// combined fit of two tracks
323// --------------------------------
324std::unique_ptr<Trk::Track>
325GaussianSumFitterTool::fit(const EventContext& ctx,
326 const Trk::Track& intrk1,
327 const Trk::Track& intrk2,
328 const Trk::RunOutlierRemoval /*runOutlier*/,
329 const Trk::ParticleHypothesis /*matEffects*/) const
330{
331 ATH_MSG_VERBOSE ("--> enter GaussianSumFitter::fit(Track,Track,)");
332 ATH_MSG_VERBOSE (" with Tracks from #1 = " << intrk1.info().dumpInfo()
333 << " and #2 = " << intrk2.info().dumpInfo());
334
335 // protection, if empty track2
336 if (!intrk2.measurementsOnTrack()) {
337 ATH_MSG_DEBUG( "input #2 is empty try to fit track 1 alone" );
338 return fit(ctx,intrk1);
339 }
340
341 // protection, if empty track1
342 if (!intrk1.measurementsOnTrack()) {
343 ATH_MSG_DEBUG( "input #1 is empty try to fit track 2 alone" );
344 return fit(ctx,intrk2);
345 }
346
347 // protection against not having track parameters on the input track
348 if (!intrk1.trackParameters() || intrk1.trackParameters()->empty()) {
349 ATH_MSG_DEBUG("input #1 fails to provide track parameters for seeding the GSF, reject fit");
350 return nullptr;
351 }
352
353 std::unique_ptr<Trk::Track> track = nullptr;
354
355 // Construct a perigee surface as the target surface
356 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
357 Acts::Vector3::Zero());
358
359 const Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
360 const Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
361 const Acts::CalibrationContext calContext{getCalibrationContext(ctx)};
362
363 // Set the GaussianSumFitter options
364 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
365 gsfOptions = prepareOptions(tgContext,
366 mfContext,
367 calContext,
368 *pSurface);
369
370 std::vector<Acts::SourceLink> trackSourceLinks = m_ATLASConverterTool->trkTrackToSourceLinks(intrk1);
371 std::vector<Acts::SourceLink> trackSourceLinks2 = m_ATLASConverterTool->trkTrackToSourceLinks(intrk2);
372 trackSourceLinks.insert(trackSourceLinks.end(), trackSourceLinks2.begin(), trackSourceLinks2.end());
373 const auto initialParams = m_ATLASConverterTool->trkTrackParametersToActsParameters(*(intrk1.perigeeParameters()), tgContext);
374
375 return performFit(ctx,
376 tgContext,
377 gsfOptions,
378 trackSourceLinks,
379 initialParams);
380}
381
382// Acts track refit
383std::unique_ptr< ActsTrk::MutableTrackContainer >
385 const Acts::BoundTrackParameters& /*initialParams*/,
386 const Acts::GeometryContext& /*tgContext*/,
387 const Acts::MagneticFieldContext& /*mfContext*/,
388 const Acts::CalibrationContext& /*calContext*/,
389 const Acts::Surface& /*targetSurface*/) const
390{
391 ATH_MSG_VERBOSE("ACTS seed refit is not implemented in GaussianSumFitterTool");
392 return nullptr;
393}
394
395std::unique_ptr< ActsTrk::MutableTrackContainer >
396GaussianSumFitterTool::fit(const std::vector< ActsTrk::ATLASUncalibSourceLink> & /*clusterList*/,
397 const Acts::BoundTrackParameters& /*initialParams*/,
398 const Acts::GeometryContext& /*tgContext*/,
399 const Acts::MagneticFieldContext& /*mfContext*/,
400 const Acts::CalibrationContext& /*calContext*/,
401 const Acts::Surface* /*targetSurface*/) const
402{
403 ATH_MSG_VERBOSE("ACTS uncalib slink refit is not implemented in GaussianSumFitterTool");
404 return nullptr;
405}
406
407
409 const EventContext& ctx,
410 const ActsTrk::TrackContainer::ConstTrackProxy& track,
411 ActsTrk::MutableTrackContainer& trackContainer,
412 const Acts::PerigeeSurface& pSurface) const {
413 ATH_MSG_VERBOSE("GaussianSumFitterTool::fit(TrackProxy) called");
414
415 const Acts::BoundTrackParameters initialParams = track.createParametersAtReference();
416 std::vector<Acts::SourceLink> sourceLinks;
417 std::vector<const Acts::Surface*> surfSequence;
418
419 for (auto ts : track.trackStates()){
420 surfSequence.push_back(&ts.referenceSurface());
421 if (!ts.hasCalibrated()) {
422 continue;
423 }
424
425 if (ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
426 sourceLinks.push_back(Acts::SourceLink{detail::RefittingCalibrator::RefittingSourceLink(ts)});
427 }
428 }
429
430 if (sourceLinks.size() < 2) {
431 ATH_MSG_DEBUG("called to refit 0 or 1 sourceLink with too little information, reject fit");
432 return StatusCode::SUCCESS;
433 }
434
435 Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
436 Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
437 Acts::CalibrationContext calContext{};
438
439 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend> gsfOptions = prepareOptions(tgContext, mfContext, calContext, pSurface);
440 const Acts::TrackingGeometry* actsTrackingGeometry = m_trackingGeometryTool->trackingGeometry().get();
441
442 if (!actsTrackingGeometry) {
443 ATH_MSG_ERROR("No Acts tracking geometry.");
444 return StatusCode::FAILURE;
445 }
446
448
449 auto gsfExtensions = m_gsfExtensions;
450 gsfExtensions.calibrator.connect<&detail::RefittingCalibrator::calibrate>(&calibrator);
451 gsfExtensions.surfaceAccessor.connect<&detail::RefittingCalibrator::accessSurface>();
452 gsfOptions.extensions = gsfExtensions;
453 gsfOptions.abortOnError = false;
454
456 m_directFitter->fit(sourceLinks.begin(), sourceLinks.end(), initialParams, gsfOptions, surfSequence, trackContainer);
457 } else {
458 m_fitter->fit(sourceLinks.begin(), sourceLinks.end(), initialParams, gsfOptions, trackContainer);
459 }
460
461 return StatusCode::SUCCESS;
462}
463
464std::unique_ptr<Trk::Track>
465GaussianSumFitterTool::makeTrack(const EventContext& ctx,
466 const Acts::GeometryContext& tgContext,
468 Acts::Result<typename ActsTrk::MutableTrackContainer::TrackProxy, std::error_code>& fitResult) const
469{
470 if (not fitResult.ok())
471 return nullptr;
472
473 std::unique_ptr<Trk::Track> newtrack = nullptr;
474 // Get the fit output object
475 const auto& acts_track = fitResult.value();
476 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
477 // initialise the number of dead Pixel and Acts strip
478 int numberOfDeadPixel = 0;
479 int numberOfDeadSCT = 0;
480
481 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
482 // Loop over all the output state to create track state
483 tracks.trackStateContainer().visitBackwards(acts_track.tipIndex(),
484 [&] (const auto &state) -> void
485 {
486 // First only concider state with an associated detector element not in the TRT
487 auto flag = state.typeFlags();
488 const auto* associatedDetEl = state.referenceSurface().associatedDetectorElement();
489 if (not associatedDetEl)
490 return;
491
492 const auto* actsElement = dynamic_cast<const ActsDetectorElement*>(associatedDetEl);
493 if (not actsElement)
494 return;
495
496 const auto* upstreamDetEl = actsElement->upstreamDetectorElement();
497 if (not upstreamDetEl)
498 return;
499
500 ATH_MSG_VERBOSE("Try casting to TRT for if");
501 if (dynamic_cast<const InDetDD::TRT_BaseElement*>(upstreamDetEl))
502 return;
503
504 const auto* trkDetElem = dynamic_cast<const Trk::TrkDetElementBase*>(upstreamDetEl);
505 if (not trkDetElem)
506 return;
507
508 ATH_MSG_VERBOSE("trkDetElem type: " << static_cast<std::underlying_type_t<Trk::DetectorElemType>>(trkDetElem->detectorType()));
509
510 ATH_MSG_VERBOSE("Try casting to SiDetectorElement");
511 const auto* detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(upstreamDetEl);
512 if (not detElem)
513 return;
514 ATH_MSG_VERBOSE("detElem = " << detElem);
515
516 // We need to determine the type of state
517 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
518 std::unique_ptr<Trk::TrackParameters> parm;
519
520 // State is a hole (no associated measurement), use predicted parameters
521 if (flag.test(Acts::TrackStateFlag::HoleFlag)){
522 ATH_MSG_VERBOSE("State is a hole (no associated measurement), use predicted parameters");
523 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
524 state.predicted(),
525 state.predictedCovariance(),
526 acts_track.particleHypothesis());
527 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
528 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
529 // Check if this is a hole, a dead sensors or a state outside the sensor boundary
530 ATH_MSG_VERBOSE("Check if this is a hole, a dead sensors or a state outside the sensor boundary");
531 if(boundaryCheck == Trk::BoundaryCheckResult::DeadElement){
532 if (detElem->isPixel()) {
533 ++numberOfDeadPixel;
534 }
535 else if (detElem->isSCT()) {
536 ++numberOfDeadSCT;
537 }
538 // Dead sensors states are not stored
539 return;
540 } else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate){
541 // States outside the sensor boundary are ignored
542 return;
543 }
544 typePattern.set(Trk::TrackStateOnSurface::Hole);
545 }
546 // The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters
547 else if (flag.test(Acts::TrackStateFlag::OutlierFlag) or not state.hasSmoothed()) {
548 ATH_MSG_VERBOSE("The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters");
549 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
550 state.filtered(),
551 state.filteredCovariance(),
552 acts_track.particleHypothesis());
553 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
554 typePattern.set(Trk::TrackStateOnSurface::Outlier);
555 }
556 // The state is a measurement state, use smoothed parameters
557 else{
558 ATH_MSG_VERBOSE("The state is a measurement state, use smoothed parameters");
559
560 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
561 state.smoothed(),
562 state.smoothedCovariance(),
563 acts_track.particleHypothesis());
564
565 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
566 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
567 typePattern.set(Trk::TrackStateOnSurface::Measurement);
568 }
569
570 std::unique_ptr<Trk::MeasurementBase> measState;
571 if (state.hasUncalibratedSourceLink()){
572 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
573 assert(sl);
574 measState = sl->uniqueClone();
575 }
576 double nDoF = state.calibratedSize();
577 auto quality =Trk::FitQualityOnSurface(state.chi2(), nDoF);
578 const Trk::TrackStateOnSurface *perState = new Trk::TrackStateOnSurface(quality, std::move(measState), std::move(parm), nullptr, typePattern);
579 // If a state was succesfully created add it to the trajectory
580 if (perState) {
581 ATH_MSG_VERBOSE("State succesfully creates, adding it to the trajectory");
582 finalTrajectory->insert(finalTrajectory->begin(), perState);
583 }
584 });
585
586 // Convert the perigee state and add it to the trajectory
587 const Acts::BoundTrackParameters actsPer(acts_track.referenceSurface().getSharedPtr(),
588 acts_track.parameters(),
589 acts_track.covariance(),
590 acts_track.particleHypothesis());
591 std::unique_ptr<Trk::TrackParameters> per = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
592 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
593 typePattern.set(Trk::TrackStateOnSurface::Perigee);
594 const Trk::TrackStateOnSurface *perState = new Trk::TrackStateOnSurface(nullptr, std::move(per), nullptr, typePattern);
595 if (perState) finalTrajectory->insert(finalTrajectory->begin(), perState);
596
597 // Create the track using the states
599 newInfo.setTrackFitter(Trk::TrackInfo::TrackFitter::GaussianSumFilter); //Mark the fitter as GaussianSumFilter
600 newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory), nullptr);
601 if (newtrack && !m_refitOnly) {
602 // Create the track summary and update the holes information
603 if (!newtrack->trackSummary()) {
604 newtrack->setTrackSummary(std::make_unique<Trk::TrackSummary>());
605 newtrack->trackSummary()->update(Trk::numberOfPixelHoles, 0);
606 newtrack->trackSummary()->update(Trk::numberOfSCTHoles, 0);
607 newtrack->trackSummary()->update(Trk::numberOfTRTHoles, 0);
608 newtrack->trackSummary()->update(Trk::numberOfPixelDeadSensors, numberOfDeadPixel);
609 newtrack->trackSummary()->update(Trk::numberOfSCTDeadSensors, numberOfDeadSCT);
610 }
611 m_trkSummaryTool->updateTrackSummary(ctx, *newtrack, true);
612 }
613
614 return newtrack;
615}
616
617const Acts::GsfExtensions<typename ActsTrk::MutableTrackStateBackend>&
622
624const Acts::Logger&
626{
627 return *m_logger;
628}
629
630Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend>
631GaussianSumFitterTool::prepareOptions(const Acts::GeometryContext& tgContext,
632 const Acts::MagneticFieldContext& mfContext,
633 const Acts::CalibrationContext& calContext,
634 const Acts::PerigeeSurface& surface) const
635{
636 Acts::PropagatorPlainOptions propagationOption(tgContext, mfContext);
637 propagationOption.maxSteps = m_option_maxPropagationStep;
638
639 Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend> gsfOptions(tgContext, mfContext, calContext);
640 gsfOptions.extensions=m_gsfExtensions;
641 gsfOptions.propagatorPlainOptions=propagationOption;
642 gsfOptions.referenceSurface = &surface;
643
644 // Set abortOnError to false, else the refitting crashes if no forward propagation is done. Here, we just skip the event and continue.
645 gsfOptions.abortOnError = false;
646 gsfOptions.maxComponents = m_maxComponents;
647 gsfOptions.weightCutoff = m_weightCutOff;
648 gsfOptions.componentMergeMethod = m_componentMergeMethod;
649
650 return gsfOptions;
651}
652
653}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
if(febId1==febId2)
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
const Acts::Logger & logger() const
Private access to the logger.
detail::TrkMeasSurfaceAccessor m_surfaceAccessor
Gaudi::Property< std::string > m_option_componentMergeMethod
Acts::GsfOptions< ActsTrk::MutableTrackStateBackend > prepareOptions(const Acts::GeometryContext &tgContext, const Acts::MagneticFieldContext &mfContext, const Acts::CalibrationContext &calContext, const Acts::PerigeeSurface &surface) const
std::unique_ptr< ActsTrk::detail::TrkMeasurementCalibrator > m_calibrator
Gaudi::Property< double > m_weightCutOff
Gaudi::Property< int > m_option_maxPropagationStep
ToolHandle< ActsTrk::IActsToTrkConverterTool > m_ATLASConverterTool
std::unique_ptr< Trk::Track > makeTrack(const EventContext &ctx, const Acts::GeometryContext &tgContext, ActsTrk::MutableTrackContainer &tracks, Acts::Result< typename ActsTrk::MutableTrackContainer::TrackProxy, std::error_code > &fitResult) const
Acts::GsfExtensions< ActsTrk::MutableTrackStateBackend > m_gsfExtensions
GaussianSumFitterTool(const std::string &, const std::string &, const IInterface *)
virtual StatusCode initialize() override
std::unique_ptr< Trk::Track > performFit(const EventContext &ctx, const Acts::GeometryContext &tgContext, const Acts::GsfOptions< ActsTrk::MutableTrackStateBackend > &gsfOptions, const std::vector< Acts::SourceLink > &trackSourceLinks, const Acts::BoundTrackParameters &initialParams) const
Acts::ComponentMergeMethod m_componentMergeMethod
Gaudi::Property< double > m_option_outlierChi2Cut
std::unique_ptr< Trk::Track > performDirectFit(const EventContext &ctx, const Acts::GeometryContext &tgContext, const Acts::GsfOptions< ActsTrk::MutableTrackStateBackend > &gsfOptions, const std::vector< Acts::SourceLink > &trackSourceLinks, const Acts::BoundTrackParameters &initialParams, const std::vector< const Acts::Surface * > &surfaces) const
Gaudi::Property< bool > m_useDirectNavigation
std::unique_ptr< Fitter > m_fitter
ToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
std::unique_ptr< const Acts::Logger > m_logger
logging instance
const Acts::GsfExtensions< ActsTrk::MutableTrackStateBackend > & getExtensions() const
std::unique_ptr< DirectFitter > m_directFitter
ActsTrk::detail::FitterHelperFunctions::ATLASOutlierFinder m_outlierFinder
virtual std::unique_ptr< Trk::Track > fit(const EventContext &ctx, const Trk::Track &, const Trk::RunOutlierRemoval runOutlier=false, const Trk::ParticleHypothesis matEffects=Trk::nonInteracting) const override
refit a track
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trkSummaryTool
void calibrate(const Acts::GeometryContext &gctx, const Acts::CalibrationContext &cctx, const Acts::SourceLink &sourceLink, MutableTrackStateProxy trackState) const
static const Acts::Surface * accessSurface(const Acts::SourceLink &sourceLink)
Helper class to access the Acts::Surface for a given Acts::SourceLink which is poiniting to a Trk::Me...
void calibrate(const Acts::GeometryContext &gctx, const Acts::CalibrationContext &cctx, const Acts::SourceLink &sl, TrackState_t< trajectory_t > trackState) const
Calibrator delegate implementation to calibrate the ActsTrk fit from Trk::MeasurementBase objects.
Contains information about the 'fitter' of this track.
std::string dumpInfo() const
Returns a string with the name of the fitter of this track (i.e.
@ GaussianSumFilter
Tracks from Gaussian Sum Filter.
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.
const DataVector< const MeasurementBase > * measurementsOnTrack() const
return a pointer to a vector of MeasurementBase (NOT including any that come from outliers).
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const Perigee * perigeeParameters() const
return Perigee.
int ts
Definition globals.cxx:24
Acts::Result< void > gainMatrixUpdate(const Acts::GeometryContext &gctx, typename trajectory_t::TrackStateProxy trackState, const Acts::Logger &logger)
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Acts::VectorMultiTrajectory MutableTrackStateBackend
Acts::TrackContainer< MutableTrackBackend, MutableTrackStateBackend, Acts::detail::ValueHolder > MutableTrackContainer
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition FitterTypes.h:30
bool RunOutlierRemoval
switch to toggle quality processing after fit
Definition FitterTypes.h:22
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
@ numberOfTRTHoles
number of TRT hits which pass the high threshold (only xenon counted) total number of TRT hits which ...
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))