extrapolates a muon track to the muon entry record and returns a new track expressed at the destination.
254 {
256
258 if (isSL) {
259 MagField::AtlasFieldCache fieldCache;
260
262 const AtlasFieldCacheCondObj *fieldCondObj{*readHandle};
263
264 if (!fieldCondObj) {
266 return nullptr;
267 }
269 if (fieldCache.
toroidOn()) {
return nullptr; }
270 }
271
273 if (!pp) return nullptr;
274
276 if (!firstPars) {
278 return nullptr;
279 }
280
281
285
286 bool atIP = false;
287 if (!exPars) {
288 ATH_MSG_DEBUG(
"failed to extrapolate parameters to muon entry, trying perigee ");
289
290
293 atIP = true;
294 }
295 }
296 if (!exPars) {
297
298 if (firstPars->
momentum().mag() < 7000.)
299 ATH_MSG_DEBUG(
"lower energy muon lost during extrapolation ");
300 else
301 ATH_MSG_WARNING(
"failed to extrapolate parameters to muon entry and perigee ");
302 return nullptr;
303 }
304
305
308 const Trk::TrackingVolume *msEntrance =
getVolume(
"Calo::Container", ctx);
309
311 ATH_MSG_DEBUG(
"extrapolate parameters at perigee inside muon entry volume " <<
m_printer->print(*exPars));
312 }
313 }
314
317
318 std::shared_ptr<Trk::Perigee> perigee = std::dynamic_pointer_cast<Trk::Perigee>(exPars);
319
320 if (!perigee) {
322 }
323
324 if (!perigee) {
326 return nullptr;
327 }
328
329
331
332
333
334 std::shared_ptr< Trk::Perigee>secondPerigee;
337
339 if (secondEntryCrossing) {
341
342
344 if (secondExPars) {
345
346 double distance = (secondExPars->position() - perigee->position()).dot(perDir);
347 ATH_MSG_DEBUG(
" second crossing: " <<
m_printer->print(*secondExPars) <<
" distance to first " << distance);
348 if (std::abs(distance) < 1.) {
350 } else {
351
352 secondPerigee = std::dynamic_pointer_cast<Trk::Perigee>(secondExPars);
353 if (!secondPerigee) {
355 }
356 }
357 } else {
358 ATH_MSG_DEBUG(
" Extrapolation to muon entry failed for second crossing ");
359 }
360 }
361 }
362
364
365
366 bool perigeeWasInserted = false;
367 bool secondPerigeeWasInserted = false;
368
369
370 bool perigeePointsToIP = perigee->position().dot(perDir) < 0.;
371 bool secondPerigeePointsToIP = false;
372 if (secondPerigee) {
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 ");
377 }
378 }
379
380
382 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
383 unsigned int newSize = oldTSOT->
size();
384 trackStateOnSurfaces->reserve(newSize + 11);
385
389 for (;
tit != tit_end; ++
tit) {
390
391 if ((*tit)->trackParameters() == pp) {
395 Trk::StraightLineSurface slSurf(ptrans);
399 }
400 continue;
401 }
403 if (!pars) {
404
405 trackStateOnSurfaces->push_back((*tit)->clone());
406 continue;
407 }
408
409 double distanceOfPerigeeToCurrent = (
pars->position() - perigee->position()).dot(perDir);
410
412
413 if (!perigeeWasInserted && distanceOfPerigeeToCurrent > 0.) {
415 << distanceOfPerigeeToCurrent);
416
417
418
419 if (!atIP) {
421
422
423 if (perigeePointsToIP) {
424
425
426 ATH_MSG_VERBOSE(
" perigee points towards IP, inserting material first ");
427
428
429 if (tit_prev != tit) {
430 const Trk::MeasurementBase *meas = (*tit_prev)->measurementOnTrack();
431 if (meas) {
432 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
433
434
435 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
437 if (matvec && !matvec->empty()) {
439
440 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
441 } else {
443 }
444 delete matvec;
445 }
446 } else {
448 }
449 } else {
450
451
453
454
456 perigeeWasInserted = true;
457
458
459
460
461
462
463 const Trk::MeasurementBase *meas = (*tit)->measurementOnTrack();
464 if (meas) {
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()) {
470
471 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
472 } else {
474 }
475 delete matvec;
476 }
477 }
478 }
479
480
481 if (!perigeeWasInserted) {
483 perigeeWasInserted = true;
485 }
486 }
487 if (secondPerigee) {
488 double distanceOfSecondPerigeeToCurrent =
489 (
pars->position() - secondPerigee->position()).dot(secondPerigee->momentum().unit());
490 if (!secondPerigeeWasInserted && distanceOfSecondPerigeeToCurrent > 0.) {
491
492
494 << distanceOfSecondPerigeeToCurrent);
495
496
497 if (secondPerigeePointsToIP) {
498
499
500 ATH_MSG_VERBOSE(
" perigee points towards IP, inserting material first ");
501
502
503 if (tit_prev != tit) {
504 const Trk::MeasurementBase *meas = (*tit_prev)->measurementOnTrack();
505 if (meas) {
506 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
507
508
509 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
511 if (matvec && !matvec->empty()) {
513
514 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
515 } else {
517 }
518 delete matvec;
519 }
520 }
521 } else {
522
523
525
526
528 secondPerigeeWasInserted = true;
529
530
531
532
533
534 const Trk::MeasurementBase *meas = (*tit)->measurementOnTrack();
535 if (meas) {
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()) {
541
542 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
543 } else {
545 }
546 delete matvec;
547 }
548 }
549
550
551 if (!secondPerigeeWasInserted) {
553 secondPerigeeWasInserted = true;
555 }
556 }
557 }
558
559
560 trackStateOnSurfaces->push_back((*tit)->clone());
561
562
564 }
565
566 if (!perigeeWasInserted) {
567
568 if (tit_prev != tit_end) {
569 const Trk::MeasurementBase *meas = (*tit_prev)->measurementOnTrack();
570 if (meas) {
571 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
572
573
574 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
576 if (matvec && !matvec->empty()) {
578
579 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
580 } else {
582 }
583 delete matvec;
584 }
585 }
588 }
589 if (secondPerigee && !secondPerigeeWasInserted) {
590
591 if (tit_prev != tit_end) {
592 const Trk::MeasurementBase *meas = (*tit_prev)->measurementOnTrack();
593 if (meas) {
594 ATH_MSG_VERBOSE(
" trying to adding material layers extrapolating to previous measurement ");
595
596
597 const std::vector<const Trk::TrackStateOnSurface *> *matvec =
m_muonExtrapolator->extrapolateM(
599 if (matvec && !matvec->empty()) {
601
602 trackStateOnSurfaces->insert(trackStateOnSurfaces->end(), matvec->begin(), matvec->end());
603 } else {
605 }
606 delete matvec;
607 }
608 }
611 }
612
613
614 return std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
615 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
616 }
#define ATH_MSG_VERBOSE(x)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
DataModel_detail::const_iterator< DataVector > const_iterator
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.
static std::unique_ptr< Trk::TrackStateOnSurface > createPerigeeTSOS(std::unique_ptr< Trk::TrackParameters > perigee)
create a perigee TSOS, takes ownership of the Perigee
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
virtual const S & associatedSurface() const override final
Access to the Surface method.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
bool inside(const Amg::Vector3D &gp, double tol=0.) const
Inside() method for checks.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
constexpr double tolerance