28 declareInterface<IMuonTrackExtrapolationTool>(
this);
40 ATH_MSG_ERROR(
"Could not retrieve a valid tracking geometry");
46 return StatusCode::SUCCESS;
65 std::unique_ptr<Trk::TrackParameters> entryPars =
71 if (!entryPars)
ATH_MSG_VERBOSE(
" failed to extrapolate along momentum for the second trial");
86 double dirPosProduct = (
pars.position() - refPos).
dot(
pars.momentum());
90 <<
pars.momentum().unit()
96 std::unique_ptr<Trk::TrackParameters> entryPars =
104 if (!entryPars)
ATH_MSG_VERBOSE(
" failed to extrapolate to IP in opposite direction");
119 if (!pp)
return nullptr;
131 double minDistance = 1e9;
132 double minMeasDistance = 1e9;
134 ATH_MSG_DEBUG(
" Cosmic model, starting for measurement closest to muon entry record ");
138 if (!
pars) {
continue; }
141 if (!surf->measurementOnTrack())
continue;
151 closestMeasPars =
pars;
155 << std::setw(6) << (
int)
pars->position().z() << (
pars->covariance() ?
" measured" :
"")
159 }
else if (
perp < 1000. && std::abs(
z) < 1000.) {
160 ATH_MSG_VERBOSE(
" track at IP, starting from closest measurement in muon spectrometer ");
164 if (!
pars) {
continue; }
168 if (!meas) {
continue; }
171 if (pseudo) {
continue; }
183 if (closestMeasPars) {
185 return closestMeasPars;
195 if (!msEntrance)
return 0;
200 double minDistance = 1e9;
203 for (
size_t ib =0 ; !boundarySurfs.empty();++
ib) {
204 const Trk::Surface &surf = boundarySurfs[
ib]->surfaceRepresentation();
214 double dirPosProduct = firstCrossing.
position().dot(firstCrossing.
momentum());
215 double sign = dirPosProduct < 0. ? 1. : -1.;
220 double minDistance = 1e9;
221 double minMeasDistance = 1e9;
234 if (!surf->measurementOnTrack())
continue;
236 double distanceOfPerigeeToCurrent = (
pars->position() - firstCrossing.
position()).
dot(perDir);
238 if (
sign * distanceOfPerigeeToCurrent > 0.) {
239 double distance = std::abs(distanceOfPerigeeToCurrent);
246 closestMeasPars =
pars;
251 return closestMeasPars ? closestMeasPars : closestPars;
268 fieldCondObj->getInitializedCache(fieldCache);
269 if (fieldCache.
toroidOn()) {
return nullptr; }
273 if (!pp)
return nullptr;
288 ATH_MSG_DEBUG(
"failed to extrapolate parameters to muon entry, trying perigee ");
298 if (firstPars->
momentum().mag() < 7000.)
299 ATH_MSG_DEBUG(
"lower energy muon lost during extrapolation ");
301 ATH_MSG_WARNING(
"failed to extrapolate parameters to muon entry and perigee ");
311 ATH_MSG_DEBUG(
"extrapolate parameters at perigee inside muon entry volume " <<
m_printer->print(*exPars));
318 std::shared_ptr<Trk::Perigee> perigee = std::dynamic_pointer_cast<Trk::Perigee>(exPars);
334 std::shared_ptr< Trk::Perigee>secondPerigee;
339 if (secondEntryCrossing) {
352 secondPerigee = std::dynamic_pointer_cast<Trk::Perigee>(secondExPars);
353 if (!secondPerigee) {
358 ATH_MSG_DEBUG(
" Extrapolation to muon entry failed for second crossing ");
366 bool perigeeWasInserted =
false;
367 bool secondPerigeeWasInserted =
false;
370 bool perigeePointsToIP = perigee->position().dot(perDir) < 0.;
371 bool secondPerigeePointsToIP =
false;
374 secondPerigeePointsToIP = secondPerigee->position().dot(secondPerigee->momentum()) < 0.;
375 if (perigeePointsToIP == secondPerigeePointsToIP) {
376 ATH_MSG_DEBUG(
" Track has two perigee's with the same orientation with respect to the IP ");
382 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
383 unsigned int newSize = oldTSOT->
size();
384 trackStateOnSurfaces->reserve(newSize + 11);
389 for (;
tit != tit_end; ++
tit) {
391 if ((*tit)->trackParameters() == pp) {
405 trackStateOnSurfaces->push_back((*tit)->clone());
409 double distanceOfPerigeeToCurrent = (
pars->position() - perigee->position()).
dot(perDir);
413 if (!perigeeWasInserted && distanceOfPerigeeToCurrent > 0.) {
415 << distanceOfPerigeeToCurrent);
423 if (perigeePointsToIP) {
426 ATH_MSG_VERBOSE(
" perigee points towards IP, inserting material first ");
429 if (tit_prev !=
tit) {
432 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
435 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
437 if (matvec && !matvec->empty()) {
440 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
456 perigeeWasInserted =
true;
465 ATH_MSG_VERBOSE(
" trying to add material layers extrapolating to next measurement ");
466 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
468 if (matvec && !matvec->empty()) {
471 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
481 if (!perigeeWasInserted) {
483 perigeeWasInserted =
true;
488 double distanceOfSecondPerigeeToCurrent =
489 (
pars->position() - secondPerigee->position()).
dot(secondPerigee->momentum().unit());
490 if (!secondPerigeeWasInserted && distanceOfSecondPerigeeToCurrent > 0.) {
494 << distanceOfSecondPerigeeToCurrent);
497 if (secondPerigeePointsToIP) {
500 ATH_MSG_VERBOSE(
" perigee points towards IP, inserting material first ");
503 if (tit_prev !=
tit) {
506 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
509 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
511 if (matvec && !matvec->empty()) {
514 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
528 secondPerigeeWasInserted =
true;
536 ATH_MSG_VERBOSE(
" trying to add material layers extrapolating to next measurement ");
537 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
539 if (matvec && !matvec->empty()) {
542 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
551 if (!secondPerigeeWasInserted) {
553 secondPerigeeWasInserted =
true;
560 trackStateOnSurfaces->push_back((*tit)->clone());
566 if (!perigeeWasInserted) {
568 if (tit_prev != tit_end) {
571 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
574 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
576 if (matvec && !matvec->empty()) {
579 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
589 if (secondPerigee && !secondPerigeeWasInserted) {
591 if (tit_prev != tit_end) {
594 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
597 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
599 if (matvec && !matvec->empty()) {
602 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
614 return std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
615 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
619 std::unique_ptr<TrackCollection> extrapolateTracks = std::make_unique<TrackCollection>();
624 std::unique_ptr<Trk::Track> extrapolateTrack =
extrapolate(*
tit, ctx);
625 if (!extrapolateTrack) {
continue; }
627 extrapolateTracks->
push_back(std::move(extrapolateTrack));
629 return extrapolateTracks;
635 std::shared_ptr<Trk::TrackParameters> exPars {
637 std::shared_ptr<Trk::Perigee> pp = std::dynamic_pointer_cast<Trk::Perigee>(exPars);
639 ATH_MSG_WARNING(
" Extrapolation to Perigee surface did not return a perigee!! ");