ATLAS Offline Software
Loading...
Searching...
No Matches
GsfExtrapolator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
11
13//
16//
17#include "TrkGeometry/Layer.h"
22#include "TrkSurfaces/Surface.h"
23//
25//
30//
31#include <boost/container/flat_set.hpp>
32#include <boost/container/small_vector.hpp>
33#include <utility>
34
35namespace {
36constexpr bool useBoundaryMaterialUpdate(true);
37
38// We have cases where the MultiComponentState is not owned
39// so we need to set just the cache ptr pointing to that.
40// In other cases we need to add it to the cache
41// and make it to point to the last element we push to the m_mcsRecycleBin
42inline void
43addMultiComponentToCache(Trk::IMultiStateExtrapolator::Cache& cache,
45 cache.m_mcsRecycleBin.emplace_back(std::move(input));
46 cache.m_stateAtBoundary = &(cache.m_mcsRecycleBin.back());
47}
48
49inline void
50setRecallInformation(Trk::IMultiStateExtrapolator::Cache& cache,
51 const Trk::Surface& recallSurface,
52 const Trk::Layer& recallLayer,
53 const Trk::TrackingVolume& recallTrackingVolume)
54{
55 cache.m_recallSurface = &recallSurface;
56 cache.m_recallLayer = &recallLayer;
57 cache.m_recallTrackingVolume = &recallTrackingVolume;
58}
59
60inline void
61resetRecallInformation(Trk::IMultiStateExtrapolator::Cache& cache)
62{
63 cache.m_recallSurface = nullptr;
64 cache.m_recallLayer = nullptr;
65 cache.m_recallTrackingVolume = nullptr;
66}
67
68inline void
69emptyRecycleBins(Trk::IMultiStateExtrapolator::Cache& cache)
70{
71 // Reset the boundary information
72 cache.m_stateAtBoundary = nullptr;
73 cache.m_navigationParameters = nullptr;
74 cache.m_trackingVolume = nullptr;
75 cache.m_mcsRecycleBin.clear();
76}
77
78int
79radialDirection(const Trk::MultiComponentState& pars, Trk::PropDirection dir)
80{
81 // safe inbound/outbound estimation
82 const double prePositionR = pars.begin()->params->position().perp();
83 return (prePositionR > (pars.begin()->params->position() +
84 static_cast<int>(dir) * 0.5 * prePositionR *
85 pars.begin()->params->momentum().unit())
86 .perp())
87 ? -1
88 : 1;
89}
94inline bool
95radialDirectionCheck(const EventContext& ctx,
96 const Trk::IPropagator& prop,
97 const Trk::MultiComponentState& startParm,
98 const Trk::MultiComponentState& parsOnLayer,
99 const Trk::TrackingVolume& tvol,
100 const Trk::MagneticFieldProperties& fieldProperties,
101 const Trk::PropDirection dir)
102{
103 const Amg::Vector3D& startPosition = startParm.begin()->params->position();
104 const Amg::Vector3D& onLayerPosition = parsOnLayer.begin()->params->position();
105
106 // the 3D distance to the layer intersection
107 const double distToLayer = (startPosition - onLayerPosition).mag();
108 // get the innermost contained surface for crosscheck
109 const auto& boundarySurfaces = tvol.boundarySurfaces();
110 // only for tubes the crossing makes sense to check for validity
111 if (boundarySurfaces.size() == 4) {
112 // propagate to the inside surface and compare the distance:
113 // it can be either the next layer from the initial point, or the inner tube
114 // boundary surface
115 const Trk::Surface& insideSurface =
116 (boundarySurfaces[Trk::tubeInnerCover])->surfaceRepresentation();
117 auto parsOnInsideSurface =
118 prop.propagateParameters(ctx,
119 *(startParm.begin()->params),
120 insideSurface,
121 dir,
122 true,
123 fieldProperties,
125 const double distToInsideSurface =
126 parsOnInsideSurface
127 ? (startPosition - (parsOnInsideSurface->position())).mag()
128 : 10e10;
129 // the intersection with the original layer is valid if it is before the
130 // inside surface
131 return distToLayer < distToInsideSurface;
132 }
133 return true;
134}
135
136} // end of anonymous namespace
137
138/*
139 * AlgTool implementations
140 */
142 const std::string& name,
143 const IInterface* parent)
144 : AthAlgTool(type, name, parent)
145{
146 declareInterface<IMultiStateExtrapolator>(this);
147}
148
150
151StatusCode
164
165/************************************************************/
166/*
167 * Implement the public extrapolate methods
168 */
169/************************************************************/
170/*
171 * Extrapolate Interface
172 */
175 const EventContext& ctx,
176 Cache& cache,
177 const Trk::MultiComponentState& multiComponentState,
178 const Trk::Surface& surface,
180 const Trk::BoundaryCheck& boundaryCheck) const
181{
182 if (multiComponentState.empty()) {
183 return {};
184 }
185 return extrapolateImpl(ctx,
186 cache,
187 multiComponentState,
188 surface,
189 direction,
190 boundaryCheck);
191}
192
193/*
194 * Extrapolate Directly method. Does not use a cache
195 */
198 const EventContext& ctx,
199 const Trk::MultiComponentState& multiComponentState,
200 const Trk::Surface& surface,
202 const Trk::BoundaryCheck& boundaryCheck) const
203{
204 if (multiComponentState.empty()) {
205 return {};
206 }
207
208 const Trk::TrackingVolume* currentVolume = m_navigator->highestVolume(ctx);
209 if (!currentVolume) {
211 "Current tracking volume could not be determined... returning {}");
212 return {};
213 }
214 return extrapolateDirectlyImpl(ctx,
215 multiComponentState,
216 surface,
217 direction,
218 boundaryCheck);
219}
220
221/************************************************************/
222/*
223 * Now the implementation of all the internal methods
224 * that perform the actual calculations
225 */
226/************************************************************/
227
228/*
229 * This is the actual extrapolation method implementation
230 */
233 const EventContext& ctx,
234 Cache& cache,
235 const Trk::MultiComponentState& multiComponentState,
236 const Trk::Surface& surface,
238 const Trk::BoundaryCheck& boundaryCheck) const
239{
240
241 // Empty the garbage bin
242 emptyRecycleBins(cache);
243 const Trk::Layer* associatedLayer = nullptr;
244 const Trk::TrackingVolume* startVolume = nullptr;
245 const Trk::TrackingVolume* destinationVolume = nullptr;
246 std::unique_ptr<Trk::TrackParameters> referenceParameters =
247 initialiseNavigation(ctx, cache, multiComponentState, surface,
248 associatedLayer, startVolume, destinationVolume,
249 direction);
250
251 // Bail to direct extrapolation if the direction cannot be determined
253 return extrapolateDirectlyImpl(ctx,
254 multiComponentState,
255 surface,
256 direction,
257 boundaryCheck);
258 }
259
260 const Trk::TrackParameters* combinedState =
261 multiComponentState.begin()->params.get();
262
263 const Trk::MultiComponentState* currentState = &multiComponentState;
264
265 /* Define the initial distance between destination and current position.
266 Destination should be determined from either
267 - reference parameters (prefered if they exist) or
268 - destination surface
269 */
270 const Amg::Vector3D globalSeparation =
271 referenceParameters
272 ? referenceParameters->position() - combinedState->position()
273 : surface.globalReferencePoint() - combinedState->position();
274 const double initialDistance = globalSeparation.mag();
275 // Clean up memory from combiner. It is no longer needed
276 combinedState = nullptr;
277
278 /* There are two parts to the extrapolation:
279 - Extrapolate from start point to volume boundary
280 - Extrapolate from volume boundary to destination surface
281 */
282 /*
283 * Extrapolation to destination volume boundary
284 */
285 bool foundFinalBoundary(true);
286 int fallbackOscillationCounter(0);
287 const Trk::TrackingVolume* currentVolume = startVolume;
288 const Trk::TrackingVolume* previousVolume = nullptr;
289
290 while (currentVolume && currentVolume != destinationVolume) {
291 // Extrapolate to volume boundary
293 cache,
294 *currentState,
295 associatedLayer,
296 *currentVolume,
297 direction);
298
299 // New current state is the state extrapolated to the tracking volume
300 // boundary.
301 currentState = cache.m_stateAtBoundary;
302 // The volume that the extrapolation is about to enter into is called the
303 // nextVolume
304 const Trk::TrackingVolume* nextVolume = cache.m_trackingVolume;
305 // Break the loop if the next tracking volume is the same as the current one
306 if (!nextVolume || nextVolume == currentVolume) {
307 foundFinalBoundary = false;
308 break;
309 }
310 // Break the loop if an oscillation is detected
311 if (previousVolume == nextVolume) {
312 ++fallbackOscillationCounter;
313 }
314 if (fallbackOscillationCounter > 10) {
315 foundFinalBoundary = false;
316 break;
317 }
318 // Break the loop if the distance between the surface and the track
319 // parameters has increased
320 combinedState = currentState->begin()->params.get();
321
322 auto parametersAtDestination =
323 m_propagator->propagateParameters(ctx,
324 *combinedState,
325 surface,
326 direction,
327 false,
330 Amg::Vector3D newDestination;
331 if (parametersAtDestination) {
332 newDestination = parametersAtDestination->position();
333 // delete parametersAtDestination;
334 } else {
335 newDestination = surface.center();
336 }
337
338 const double revisedDistance =
339 (cache.m_navigationParameters->position() - newDestination).mag();
340
341 const double distanceChange = std::abs(revisedDistance - initialDistance);
342
343 if (revisedDistance > initialDistance && distanceChange > 0.01) {
344 foundFinalBoundary = false;
345 break;
346 }
347
348 // Initialise the oscillation checker
349 previousVolume = currentVolume;
350 // As the extrapolation is moving into the next volume, the next volume ->
351 // current volume
352 currentVolume = nextVolume;
353 // Associated layer now needs to be reset
354 // if(!entryLayerFound)
355 associatedLayer = nullptr;
356 } // end while loop
357
358 // catch failures now
359 if (!currentState || (currentVolume != destinationVolume)) {
360 currentState = &multiComponentState;
361 foundFinalBoundary = false;
362 }
363
364 if (!foundFinalBoundary) {
365 Trk::MultiComponentState bailOutState =
366 m_propagator->multiStatePropagate(ctx,
367 *currentState,
368 surface,
371 boundaryCheck,
373
374 emptyRecycleBins(cache);
375 return bailOutState;
376 }
377
378 /*
379 * Extrapolation from volume boundary to surface
380 */
381
382 // extrapolate inside destination volume
383 Trk::MultiComponentState destinationState =
385 cache,
386 *currentState,
387 surface,
388 associatedLayer,
389 *currentVolume,
390 direction,
391 boundaryCheck);
392
393 // FALLBACK POINT: Crisis if extrapolation fails here... As per extrapolation
394 // to volume boundary, in emergency revert to extrapolateDirectly
395
396 // or we failed to reach the target
397 if (!destinationState.empty() &&
398 &((*(destinationState.begin())).params->associatedSurface()) != &surface) {
399 destinationState.clear();
400 }
401
402 if (destinationState.empty()) {
403 destinationState = m_propagator->multiStatePropagate(ctx,
404 *currentState,
405 surface,
408 boundaryCheck,
410 }
411 emptyRecycleBins(cache);
412 return destinationState;
413}
414
415/*
416 * Extrapolate Directly method. Does not use a cache
417 */
420 const EventContext& ctx,
421 const Trk::MultiComponentState& multiComponentState,
422 const Trk::Surface& surface,
424 const Trk::BoundaryCheck& boundaryCheck) const
425{
426 return m_propagator->multiStatePropagate(ctx,
427 multiComponentState,
428 surface,
430 direction,
431 boundaryCheck,
433}
434
435/*
436 * Extrapolate to Volume Boundary!
437 */
438void
440 const EventContext& ctx,
441 Cache& cache,
442 const Trk::MultiComponentState& multiComponentState,
443 const Trk::Layer* layer,
444 const Trk::TrackingVolume& trackingVolume,
446{
447
448 //We 1st point to the input.
449 //As we move on we might change to point to the
450 //last element held by
451 //cache.m_mcsRecycleBin
452 cache.m_stateAtBoundary = &multiComponentState;
453
454 const Trk::TrackParameters* combinedState =
455 cache.m_stateAtBoundary->begin()->params.get();
456 const Trk::Layer* associatedLayer = layer;
457
458 if (!associatedLayer) {
459 // Get entry layer but do not use it as it should have already be hit if it
460 // was desired
461 associatedLayer = trackingVolume.associatedLayer(combinedState->position());
462 associatedLayer = associatedLayer
463 ? associatedLayer
464 : trackingVolume.nextLayer(
465 combinedState->position(),
466 direction * combinedState->momentum().unit(),
467 associatedLayer);
468 }
469 // Only loop over layers if they can be found within the tracking volume
470 else if (trackingVolume.confinedLayers() &&
471 associatedLayer->layerMaterialProperties()) {
472 Trk::MultiComponentState updatedState = m_materialUpdator->postUpdate(
473 cache.m_materialEffectsCaches,
474 *(cache.m_stateAtBoundary),
475 *layer,
476 direction);
477
478 if (!updatedState.empty()) {
479 addMultiComponentToCache(cache,std::move(updatedState));
480 }
481 }
482
483 // If an associated surface can be found, extrapolation within the tracking
484 // volume is mandatory This will take extrapolate to the last layer in the
485 // volume
486 if (associatedLayer) {
488 ctx,
489 cache,
490 *(cache.m_stateAtBoundary),
491 trackingVolume,
492 associatedLayer,
493 nullptr,
494 direction);
495 // if we have a next State update the currentState
496 if (!nextState.empty()) {
497 addMultiComponentToCache(cache,std::move(nextState));
498 }
499 }
500
501 /* =============================================
502 Find the boundary surface using the navigator
503 ============================================= */
504
505 Trk::NavigationCell nextNavigationCell(nullptr, nullptr);
506
507 combinedState = cache.m_stateAtBoundary->begin()->params.get();
508
509 const Trk::TrackingVolume* nextVolume = nullptr;
510 const Trk::TrackParameters* navigationParameters =
511 cache.m_navigationParameters
512 ? cache.m_navigationParameters.get()
513 : combinedState;
514
515 nextNavigationCell = m_navigator->nextTrackingVolume(
516 ctx, *m_propagator, *navigationParameters, direction, trackingVolume);
517
518 nextVolume = nextNavigationCell.nextVolume;
519
520 std::unique_ptr<Trk::TrackParameters> nextNavigationParameters =
521 std::move(nextNavigationCell.parametersOnBoundary);
522
523 if (!nextVolume) {
524 // Reset the layer recall
525 resetRecallInformation(cache);
526 }
527
528 if (useBoundaryMaterialUpdate) {
529 // Check for two things:
530 // 1. If the next volume was found
531 // 2. If there is material associated with the boundary layer.
532 // If so, apply material effects update.
533
534 // Get layer associated with boundary surface.
535 const Trk::MaterialLayer * layerAtBoundary =
536 (nextNavigationCell.parametersOnBoundary)
537 ? (nextNavigationCell.parametersOnBoundary->associatedSurface())
538 .materialLayer()
539 : nullptr;
540 Trk::MultiComponentState matUpdatedState{};
541 if (nextVolume && layerAtBoundary) {
542 if (layerAtBoundary->layerMaterialProperties()) {
543 matUpdatedState = m_materialUpdator->postUpdate(
544 cache.m_materialEffectsCaches,
545 *(cache.m_stateAtBoundary),
546 *layerAtBoundary,
547 direction);
548 }
549 }
550
551 // If state has changed due to boundary material, modify state, parameters
552 // accordingly.
553 if (!matUpdatedState.empty()) {
554 addMultiComponentToCache(cache, std::move(matUpdatedState));
555 nextNavigationParameters =
556 cache.m_stateAtBoundary->begin()->params->uniqueClone();
557 }
558 }
559 // Update the rest of the boundary information in the cache
560 cache.m_navigationParameters = std::move(nextNavigationParameters);
561 cache.m_trackingVolume = nextVolume;
562}
563
564/*
565 * Extrapolate inside volume to destination surface!
566 */
569 const EventContext& ctx,
570 Cache& cache,
571 const Trk::MultiComponentState& multiComponentState,
572 const Trk::Surface& surface,
573 const Trk::Layer* layer,
574 const Trk::TrackingVolume& trackingVolume,
576 const Trk::BoundaryCheck& boundaryCheck) const
577{
578 //curent state is a plainn ptr to keep track
579 const Trk::MultiComponentState* currentState = &multiComponentState;
580
581 // Retrieve the destination layer
582 // 1. Association
583 const Trk::Layer* destinationLayer = surface.associatedLayer();
584
585 // 2. Recall and Global Search
586 if (!destinationLayer) {
587 destinationLayer =
588 (&surface == cache.m_recallSurface)
589 ? cache.m_recallLayer
590 : trackingVolume.associatedLayer(surface.globalReferencePoint());
591 }
592
593 // Retrieve the current layer
594 // Produce a combined state
595 const Trk::TrackParameters* combinedState =
596 currentState->begin()->params.get();
597
598 const Trk::Layer* associatedLayer = layer;
599
600 Trk::MultiComponentState updatedState{};
601 if (!associatedLayer) {
602 // Get entry layer but do not use it as it should have already be hit if it
603 // was desired
604 associatedLayer = trackingVolume.associatedLayer(combinedState->position());
605 associatedLayer =
606 associatedLayer
607 ? associatedLayer
608 : trackingVolume.nextLayer(combinedState->position(),
609 direction * combinedState->momentum().unit(),
610 associatedLayer);
611 }
612
613 else if (associatedLayer != destinationLayer &&
614 trackingVolume.confinedLayers() &&
615 associatedLayer->layerMaterialProperties()) {
616
617 updatedState = m_materialUpdator->postUpdate(cache.m_materialEffectsCaches,
618 *currentState,
619 *associatedLayer,
620 direction);
621
622 if (!updatedState.empty()) {
623 // Refresh the current state pointer
624 currentState = &updatedState;
625 }
626 }
627
628 // Reset combined state target
629 combinedState = nullptr;
631 if (destinationLayer) {
632 // If there are intermediate layers then additional extrapolations need to
633 // be done
634 if (associatedLayer && associatedLayer != destinationLayer) {
636 cache,
637 *currentState,
638 trackingVolume,
639 associatedLayer,
640 destinationLayer,
641 direction);
642
643 // currentState is now the next
644 if (!nextState.empty()) {
645 // Refresh the current state pointer
646 currentState = &nextState;
647 }
648 }
649 // Final extrapolation to destination surface
650 Trk::MultiComponentState returnState =
652 cache,
653 *currentState,
654 surface,
655 *destinationLayer,
656 associatedLayer,
657 direction,
658 boundaryCheck);
659 // Set the information for the current layer, surface, tracking volume
660 setRecallInformation(cache, surface, *destinationLayer, trackingVolume);
661 return returnState;
662 }
663
664 // FALLBACK POINT: If no destination layer is found fall-back and extrapolate
665 // directly
666 Trk::MultiComponentState returnState =
667 m_propagator->multiStatePropagate(ctx,
668 *currentState,
669 surface,
671 direction,
672 boundaryCheck,
674
675 // No destination layer exists so layer recall method cannot be used and
676 // should be reset
677 resetRecallInformation(cache);
678
679 return returnState;
680}
681
682/*
683 * Extrapolate from Layer to Layer
684 */
687 const EventContext& ctx,
688 Cache& cache,
689 const MultiComponentState& multiComponentState,
690 const TrackingVolume& trackingVolume,
691 const Layer* startLayer,
692 const Layer* destinationLayer,
694{
695
696 const Trk::Layer* currentLayer = startLayer;
697 Trk::MultiComponentState currentState{};
698
699 const Trk::TrackParameters* combinedState =
700 multiComponentState.begin()->params.get();
701 Amg::Vector3D currentPosition = combinedState->position();
702 Amg::Vector3D currentDirection = direction * combinedState->momentum().unit();
703
704 // No need to extrapolate to start layer, find the next one
705 const Trk::Layer* nextLayer =
706 currentLayer->nextLayer(currentPosition, currentDirection);
707
708 using LayerSet = boost::container::flat_set<
709 const Trk::Layer*,
710 std::less<const Trk::Layer*>,
711 boost::container::small_vector<const Trk::Layer*, 8>>;
712 LayerSet layersHit;
713
714 layersHit.insert(currentLayer);
715
716 // Begin while loop over all intermediate layers
717 while (nextLayer && nextLayer != destinationLayer) {
718 layersHit.insert(nextLayer);
719 // Only extrapolate to an intermediate layer if it requires material
720 // update. Otherwise step over it
721 if (nextLayer->layerMaterialProperties()) {
722 currentState = extrapolateToIntermediateLayer(
723 ctx,
724 cache,
725 !currentState.empty() ? currentState : multiComponentState,
726 *nextLayer,
727 trackingVolume,
728 direction);
729 }
730
731 if (!currentState.empty()) {
732 combinedState = currentState.begin()->params.get();
733 currentPosition = combinedState->position();
734 currentDirection = direction * combinedState->momentum().unit();
735 }
736
737 // Find the next layer
738 currentLayer = nextLayer;
739 nextLayer = currentLayer->nextLayer(currentPosition, currentDirection);
740 if (layersHit.find(nextLayer) != layersHit.end()) {
741 break;
742 }
743 }
744
745 if (destinationLayer && nextLayer != destinationLayer &&
746 !currentState.empty()) {
747 currentState.clear();
748 }
749
750 return currentState;
751}
752
753/*
754 * Extrapolate to Intermediate Layer
755 */
758 const EventContext& ctx,
759 Cache& cache,
760 const Trk::MultiComponentState& multiComponentState,
761 const Trk::Layer& layer,
762 const Trk::TrackingVolume& trackingVolume,
764{
765 const Trk::MultiComponentState* initialState = &multiComponentState;
766
767 // Propagate over all components
768 Trk::MultiComponentState destinationState =
769 m_propagator->multiStatePropagate(ctx,
770 *initialState,
771 layer.surfaceRepresentation(),
773 direction,
774 true,
776
777 if (destinationState.empty()) {
778 return {};
779 }
780
781 // the layer has been intersected
782 // ------------------------------------------------------------------------
783 // check for radial direction change
784 // ---------------------------------------------------------------------
785 const int rDirection = radialDirection(multiComponentState, direction);
786 const int newrDirection = radialDirection(destinationState, direction);
787 if (newrDirection != rDirection) {
788 // it is unfortunate that the cancelling could invalidate the material
789 // collection
790 // reset the nextParameters if the radial change is not allowed
791 // resetting is ok - since the parameters are in the garbage bin already
792 if (!radialDirectionCheck(ctx,
794 multiComponentState,
795 destinationState,
796 trackingVolume,
798 direction)) {
799 return {};
800 }
801 }
802
803 /* -------------------------------------
804 Material effects
805 ------------------------------------- */
806
807 Trk::MultiComponentState updatedState =
808 m_materialUpdator->update(cache.m_materialEffectsCaches,
809 destinationState,
810 layer,
811 direction);
812
813 if (updatedState.empty()) {
814 return destinationState;
815 }
816
817 return updatedState;
818}
819
820/*
821 Extrapolate to Destination Layer
822*/
825 const EventContext& ctx,
826 Cache& cache,
827 const Trk::MultiComponentState& multiComponentState,
828 const Trk::Surface& surface,
829 const Trk::Layer& layer,
830 const Trk::Layer* startLayer,
832 const Trk::BoundaryCheck& boundaryCheck) const
833{
834
835 const Trk::MultiComponentState* initialState = &multiComponentState;
836 const Trk::TrackParameters* combinedState = nullptr;
837
838 // Propagate over all components
839 Trk::MultiComponentState destinationState =
840 m_propagator->multiStatePropagate(ctx,
841 multiComponentState,
842 surface,
844 direction,
845 boundaryCheck,
847
848 // Require a fall-back if the initial state is close to the destination
849 // surface then a fall-back solution is required
850
851 if (destinationState.empty()) {
852 combinedState = initialState->begin()->params.get();
853 if (surface.isOnSurface(
854 combinedState->position(), true, 0.5 * layer.thickness())) {
855 destinationState = m_propagator->multiStatePropagate(ctx,
856 *initialState,
857 surface,
860 boundaryCheck,
862 }
863 combinedState = nullptr;
864 if (destinationState.empty()) {
865 return {};
866 }
867 }
868
869 /* ----------------------------------------
870 Material effects
871 ---------------------------------------- */
872
873 Trk::MultiComponentState updatedState{};
874 if (startLayer != &layer) {
875 updatedState = m_materialUpdator->preUpdate(cache.m_materialEffectsCaches,
876 destinationState,
877 layer,
878 direction);
879 }
880
881 if (updatedState.empty()) {
882 return destinationState;
883 }
884
885 return updatedState;
886}
887
888/*
889 * Initialise Navigation
890 */
891std::unique_ptr<Trk::TrackParameters>
893 const EventContext& ctx,
894 Cache& cache,
895 const Trk::MultiComponentState& multiComponentState,
896 const Trk::Surface& surface,
897 const Trk::Layer*& currentLayer,
898 const Trk::TrackingVolume*& currentVolume,
899 const Trk::TrackingVolume*& destinationVolume,
901{
902 //Get the highest weight parameters. We will just use those
903 const Trk::TrackParameters* combinedState = multiComponentState.begin()->params.get();
904 /* =============================================
905 Look for current volume
906 ============================================= */
907 // 1. See if the current layer is associated with a tracking volume
908 const Trk::Surface* associatedSurface = &(combinedState->associatedSurface());
909 currentLayer = associatedSurface ? associatedSurface->associatedLayer() : currentLayer;
910 currentVolume = currentLayer ? currentLayer->enclosingTrackingVolume() : currentVolume;
911 // If the association method failed
912 if (!currentVolume) {
913 //Try the recall in case the associatedSurface is the recall one
914 if (associatedSurface == cache.m_recallSurface) {
915 currentVolume = cache.m_recallTrackingVolume;
916 currentLayer = cache.m_recallLayer;
917 }
918 // Global search method if this fails
919 else {
920 // If the recall method fails reset the cache
921 resetRecallInformation(cache);
922 currentVolume = m_navigator->volume(ctx, combinedState->position());
923 currentLayer = currentVolume
924 ? currentVolume->associatedLayer(combinedState->position())
925 : nullptr;
926 }
927 }
928 /* =============================================
929 Determine the resolved direction
930 ============================================= */
931 std::unique_ptr<Trk::TrackParameters> referenceParameters =
932 currentVolume ? m_propagator->propagateParameters(
933 ctx, *combinedState, surface, direction, false,
935 : nullptr;
936 // Find concrete direction based on reference parameters
937 if (direction == Trk::anyDirection && referenceParameters) {
938 const Amg::Vector3D surfaceDirection(referenceParameters->position() -
939 combinedState->position());
940 direction = (surfaceDirection.dot(combinedState->momentum()) > 0.)
943 }
944 /* =============================================
945 Look for destination volume
946 ============================================= */
947 // See if the destination layer is associated with a tracking volume
948 destinationVolume = surface.associatedLayer()
950 : nullptr;
951 // Association failed
952 if (!destinationVolume) {
953 // See if the cached recall surface is the destination one
954 if (&surface == cache.m_recallSurface) {
955 destinationVolume = cache.m_recallTrackingVolume;
956 } else {
957 // Global search of tracking geometry to find the destination volume
958 destinationVolume = m_navigator->volume(
959 ctx, referenceParameters ? referenceParameters->position()
960 : surface.globalReferencePoint());
961 }
962 }
963 return referenceParameters;
964}
965
Scalar mag() const
mag method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
static int layersHit(FPGATrackSimRoad &r)
Abstract base class for convolution of material effects.
static JobState::Enum nextState(JobState::Enum state, Status::Enum status)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
virtual StatusCode initialize() override final
virtual ~GsfExtrapolator() override final
MultiComponentState extrapolateToIntermediateLayer(const EventContext &ctx, Cache &cache, const MultiComponentState &, const Layer &, const TrackingVolume &, PropDirection direction) const
Single extrapolation step to an intermediate layer.
MultiComponentState extrapolateFromLayerToLayer(const EventContext &ctx, Cache &cache, const MultiComponentState &, const TrackingVolume &, const Layer *startLayer, const Layer *destinationLayer, PropDirection direction) const
Layer stepping, stopping at the last layer before destination.
ToolHandle< IPropagator > m_propagator
MultiComponentState extrapolateDirectlyImpl(const EventContext &ctx, const MultiComponentState &, const Surface &, PropDirection direction, const BoundaryCheck &boundaryCheck) const
Implementation of extrapolation without material effects.
std::unique_ptr< Trk::TrackParameters > initialiseNavigation(const EventContext &ctx, Cache &cache, const MultiComponentState &initialState, const Surface &surface, const Layer *&associatedLayer, const TrackingVolume *&currentVolume, const TrackingVolume *&destinationVolume, PropDirection &direction) const
Method to initialise navigation parameters including starting state, layer and volume,...
GsfExtrapolator(const std::string &, const std::string &, const IInterface *)
Constructor with AlgTool parameters.
MultiComponentState extrapolateImpl(const EventContext &ctx, Cache &cache, const MultiComponentState &, const Surface &, PropDirection direction, const BoundaryCheck &boundaryCheck) const
Implementation of main extrapolation method.
void extrapolateToVolumeBoundary(const EventContext &ctx, Cache &cache, const MultiComponentState &, const Layer *, const TrackingVolume &, PropDirection direction) const
Two primary private extrapolation methods.
virtual MultiComponentState extrapolate(const EventContext &ctx, Cache &, const MultiComponentState &, const Surface &, PropDirection direction, const BoundaryCheck &boundaryCheck) const override final
Extrapolation method applying material affects.
ToolHandle< INavigator > m_navigator
BooleanProperty m_fastField
ToolHandle< IMaterialMixtureConvolution > m_materialUpdator
MultiComponentState extrapolateInsideVolume(const EventContext &ctx, Cache &cache, const MultiComponentState &, const Surface &, const Layer *, const TrackingVolume &, PropDirection direction, const BoundaryCheck &boundaryCheck) const
MultiComponentState extrapolateToDestinationLayer(const EventContext &ctx, Cache &cache, const MultiComponentState &, const Surface &, const Layer &, const Layer *, PropDirection direction, const BoundaryCheck &boundaryCheck) const
Final extrapolation step to a destination layer.
virtual MultiComponentState extrapolateDirectly(const EventContext &ctx, const MultiComponentState &, const Surface &, PropDirection direction, const BoundaryCheck &boundaryCheck) const override final
Extrapolation method without material effects.
Trk::MagneticFieldProperties m_fieldProperties
Interface class IPropagators It inherits from IAlgTool.
Definition IPropagator.h:54
Base Class for a Detector Layer in the Tracking realm.
Definition Layer.h:72
const Layer * nextLayer(const Amg::Vector3D &gp, const Amg::Vector3D &udir) const
getting the next/previous Layer if registered - unit for direction vector required
Definition Layer.cxx:161
const LayerMaterialProperties * layerMaterialProperties() const
getting the LayerMaterialProperties including full/pre/post update
const TrackingVolume * enclosingTrackingVolume() const
get the confining TrackingVolume
magnetic field properties to steer the behavior of the extrapolation
A material layer is a simple helper class to attach material information to a boundary surface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
virtual bool isOnSurface(const Amg::Vector3D &glopo, const BoundaryCheck &bchk=true, double tol1=0., double tol2=0.) const
This method returns true if the GlobalPosition is on the Surface for both, within or without check of...
Definition Surface.cxx:123
virtual const Amg::Vector3D & globalReferencePoint() const
Returns a global reference point on the surface, for PlaneSurface, StraightLineSurface,...
const Trk::Layer * associatedLayer() const
return the associated Layer
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
const LayerArray * confinedLayers() const
Return the subLayer array.
const Layer * associatedLayer(const Amg::Vector3D &gp) const
Return the associated Layer.
std::vector< std::shared_ptr< BoundarySurface< TrackingVolume > > > & boundarySurfaces()
Method to return the BoundarySurfaces.
const Layer * nextLayer(const Amg::Vector3D &gp, const Amg::Vector3D &mom, bool asres=true, bool skipNavLayer=false) const
Return the next Layer if existing, NULL if no next layer corresponds.
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
@ anyDirection
std::vector< ComponentParameters > MultiComponentState
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.
@ FastField
call the fast field access method of the FieldSvc
@ FullField
Field is set to be realistic, but within a given Volume.
ParametersBase< TrackParametersDim, Charged > TrackParameters
const IIntersectionCache * cache() const
Retrieve the associated cache block, if it exists.
MultiStateExtrapolator cache class.
useful struct for a single navigation cell
Definition INavigator.h:37
const TrackingVolume * nextVolume
Definition INavigator.h:39
std::unique_ptr< TrackParameters > parametersOnBoundary
Definition INavigator.h:41