check fitterData, add fake phi hits if needed.
513 {
514
515
517
518
519 if (nphiConstraints >= 2) {
520 if (fitterData.firstEntry->stations().size() == 1 && fitterData.firstEntry->containsStation(StIndex::EI) &&
521 (fitterData.firstEntry->phiHits().empty() || (fitterData.firstEntry->containsChamber(ChIndex::CSS) ||
522 fitterData.firstEntry->containsChamber(ChIndex::CSL)))) {
523 ATH_MSG_VERBOSE(
" Special treatment of the forward region: adding fake at ip ");
524 }
525 return true;
526 }
527
528
529
530 std::unique_ptr<Amg::Vector3D> overlapPos;
531 std::unique_ptr<const Amg::Vector3D> phiPos;
532 if (fitterData.numberOfSLOverlaps() > 0 || (fitterData.numberOfSmallChambers() > 0 && fitterData.numberOfLargeChambers() > 0)) {
533
534
535
536 overlapPos = std::make_unique<Amg::Vector3D>(1., 1., 1.);
537 double phi = fitterData.avePhi;
538 double theta = fitterData.secondEntry->etaHits().front()->globalPosition().theta();
540 if (fitterData.firstEntry->hasSLOverlap()) {
541 theta = fitterData.firstEntry->entryPars().momentum().theta();
542 phi = fitterData.firstEntry->entryPars().momentum().phi();
543 } else {
544 theta = fitterData.secondEntry->entryPars().momentum().theta();
545 phi = fitterData.secondEntry->entryPars().momentum().phi();
546 }
547 }
549
550 if (fitterData.startPars) {
551 phiPos = std::make_unique<Amg::Vector3D>(fitterData.startPars->momentum());
552 } else {
553 phiPos = std::make_unique<Amg::Vector3D>(*overlapPos);
554 }
555
556 if (
msgLvl(MSG::VERBOSE)) {
557 if (fitterData.numberOfSLOverlaps() > 0) {
558 if (fitterData.stations.size() == 1)
559 msg(MSG::VERBOSE) <<
" one station fit with SL overlap, using overlapPos " << *overlapPos <<
endmsg;
560 else
561 msg(MSG::VERBOSE) <<
" multi station fit with SL overlap, using overlapPos " << *overlapPos <<
endmsg;
562 } else if (fitterData.numberOfSmallChambers() > 0 && fitterData.numberOfLargeChambers() > 0) {
563 msg(MSG::VERBOSE) <<
" multi station fit, SL overlap not in same station, using overlapPos " << *overlapPos <<
endmsg;
564 } else
566 }
567 }
568
569 if (fitterData.phiHits.empty()) {
570 const MuPatSegment* segInfo1 = dynamic_cast<const MuPatSegment*>(fitterData.firstEntry);
571 const MuPatSegment* segInfo2 = dynamic_cast<const MuPatSegment*>(fitterData.secondEntry);
572 if (segInfo1 && segInfo2 && fitterData.stations.size() == 1 && fitterData.numberOfSLOverlaps() == 1) {
573
576
577 ATH_MSG_VERBOSE(
" Special treatment for tracks with one station, a SL overlap and no phi hits ");
578
579 IMuonSegmentInOverlapResolvingTool::SegmentMatchResult
result =
581
582 if (!
result.goodMatch()) {
584 return false;
585 }
586
587 double locx1 =
result.segmentResult1.positionInTube1;
588 double locy1 =
589 segInfo1->segment->localParameters().contains(
Trk::locY) ? segInfo1->segment->localParameters()[
Trk::locY] : 0.;
590 Trk::AtaPlane segPars1(locx1, locy1,
result.phiResult.segmentDirection1.phi(),
result.phiResult.segmentDirection1.theta(),
591 0., segInfo1->segment->associatedSurface());
592
593 std::unique_ptr<Trk::TrackParameters> exPars1 =
m_propagator->propagate(ctx,
594 segPars1, fitterData.measurements.front()->associatedSurface(),
Trk::anyDirection,
596 if (exPars1) {
598 std::unique_ptr<Trk::MeasurementBase> fake =
600 if (fake) {
601 fitterData.phiHits.push_back(fake.get());
602 fitterData.measurements.insert(fitterData.measurements.begin(), fake.get());
603 fitterData.firstLastMeasurements.insert(fitterData.firstLastMeasurements.begin(), fake.get());
604 fitterData.garbage.push_back(std::move(fake));
605 }
606 } else {
608 return false;
609 }
610 double locx2 =
result.segmentResult2.positionInTube1;
611 double locy2 =
612 segInfo2->segment->localParameters().contains(
Trk::locY) ? segInfo2->segment->localParameters()[
Trk::locY] : 0.;
613 Trk::AtaPlane segPars2(locx2, locy2,
result.phiResult.segmentDirection2.phi(),
result.phiResult.segmentDirection2.theta(),
614 0., segInfo2->segment->associatedSurface());
615
617 segPars2, fitterData.measurements.back()->associatedSurface(),
Trk::anyDirection,
619 if (exPars2) {
621 std::unique_ptr<Trk::MeasurementBase> fake =
623 if (fake) {
624 fitterData.phiHits.push_back(fake.get());
625 fitterData.measurements.push_back(fake.get());
626 fitterData.firstLastMeasurements.push_back(fake.get());
627 fitterData.garbage.push_back(std::move(fake));
628 }
629 } else {
631 return false;
632 }
633 } else if (nphiConstraints == 0 || (fitterData.stations.size() == 1) ||
634 (nphiConstraints == 1 && fitterData.numberOfSLOverlaps() == 0 && fitterData.numberOfSmallChambers() > 0 &&
635 fitterData.numberOfLargeChambers() > 0)) {
636 {
638 overlapPos.get(), phiPos.get(), 100.);
639 if (fake) {
640 fitterData.phiHits.push_back(fake.get());
641 fitterData.measurements.insert(fitterData.measurements.begin(), fake.get());
642 fitterData.firstLastMeasurements.insert(fitterData.firstLastMeasurements.begin(), fake.get());
643 fitterData.garbage.push_back(std::move(fake));
644 }
645
646 }
647 {
649 overlapPos.get(), phiPos.get(), 100.);
650 if (fake) {
651 fitterData.phiHits.push_back(fake.get());
652 fitterData.measurements.push_back(fake.get());
653 fitterData.firstLastMeasurements.push_back(fake.get());
654 fitterData.garbage.push_back(std::move(fake));
655 }
656 }
657
658 } else if (fitterData.numberOfSLOverlaps() == 1) {
659
660 ATH_MSG_VERBOSE(
" Special treatment for tracks with one SL overlap and no phi hits ");
661
662 StIndex overlapStation = StIndex::StUnknown;
663 SLStationMap::iterator
it = fitterData.smallLargeChambersPerStation.begin();
664 SLStationMap::iterator it_end = fitterData.smallLargeChambersPerStation.end();
665 for (;
it != it_end; ++
it) {
666 if (
it->second.first &&
it->second.second) {
667 overlapStation =
it->first;
668 break;
669 }
670 }
671 if (overlapStation == StIndex::StUnknown) {
673 return false;
674 }
675
676 Identifier firstId =
m_edmHelperSvc->getIdentifier(*fitterData.measurements.front());
678 ATH_MSG_WARNING(
" unexpected condition, first measurement has no identifier ");
679 return false;
680 }
682 if (overlapStation == firstSt) {
684
685
687 overlapPos.get(), phiPos.get(), 100.);
688 if (fake) {
689 fitterData.phiHits.push_back(fake.get());
690 fitterData.measurements.push_back(fake.get());
691 fitterData.firstLastMeasurements.push_back(fake.get());
692 fitterData.garbage.push_back(std::move(fake));
693 }
694 } else {
696
698 overlapPos.get(), phiPos.get(), 100.);
699 if (fake) {
700 fitterData.phiHits.push_back(fake.get());
701 fitterData.measurements.insert(fitterData.measurements.begin(), fake.get());
702 fitterData.firstLastMeasurements.insert(fitterData.firstLastMeasurements.begin(), fake.get());
703 fitterData.garbage.push_back(std::move(fake));
704 }
705 }
706
707 } else {
709 return false;
710 }
711 } else {
712
713 double distFirstEtaPhi =
714 (fitterData.measurements.front()->globalPosition() - fitterData.phiHits.front()->globalPosition()).mag();
715 double distLastEtaPhi = (fitterData.measurements.back()->globalPosition() - fitterData.phiHits.back()->globalPosition()).mag();
716
717
719 phiPos = std::make_unique<Amg::Vector3D>(fitterData.phiHits.back()->globalPosition());
720 ATH_MSG_VERBOSE(
" using pointing constraint to calculate fake phi hit ");
721 }
722
723
724 const Trk::Surface *firstmdtsurf = nullptr, *lastmdtsurf = nullptr;
726 int indexfirst = 0, indexlast = (
int)fitterData.measurements.size();
728 for (; hitit != fitterData.hitList.end(); hitit++) {
729 if ((**hitit).info().measuresPhi) break;
731 firstmdtsurf = &(**hitit).measurement().associatedSurface();
732 break;
733 }
734 indexfirst++;
735 }
736 hitit = fitterData.hitList.end();
737 hitit--;
738 for (; hitit != fitterData.hitList.begin(); hitit--) {
739 if ((**hitit).info().measuresPhi) break;
741 lastmdtsurf = &(**hitit).measurement().associatedSurface();
742 lastmdtpar = &(**hitit).parameters();
743 break;
744 }
745 indexlast--;
746 }
749 indexlast = std::max(indexlast, 0);
750 bool phifromextrapolation = false;
751 if (!fitterData.secondEntry->phiHits().empty() || !fitterData.firstEntry->phiHits().empty()) phifromextrapolation = true;
752
753 const Trk::Surface *firstphisurf = nullptr, *lastphisurf = nullptr;
754 Amg::Vector3D firstphinormal{Amg::Vector3D::Zero()}, lastphinormal{Amg::Vector3D::Zero()};
755 if (!fitterData.phiHits.empty()) {
756 firstphisurf = &fitterData.phiHits.front()->associatedSurface();
757 lastphisurf = &fitterData.phiHits.back()->associatedSurface();
758 firstphinormal = firstphisurf->
normal();
759 lastphinormal = lastphisurf->normal();
760 if (firstphinormal.dot(startpar.momentum()) < 0) firstphinormal = -firstphinormal;
761 if (lastphinormal.dot(startpar.momentum()) < 0) lastphinormal = -lastphinormal;
762 }
763 if (lastmdtsurf && (!firstphisurf || (lastmdtsurf->center() - lastphisurf->center()).dot(lastphinormal) > 1000)) {
764 ATH_MSG_VERBOSE(
" Adding fake at last hit: dist first phi/first eta " << distFirstEtaPhi <<
" dist last phi/last eta "
765 << distLastEtaPhi);
766 std::unique_ptr<Trk::MeasurementBase> fake{};
767 if (fitterData.secondEntry->hasSLOverlap() || phifromextrapolation) {
768
769 std::unique_ptr<Trk::TrackParameters> mdtpar{};
770 if (fitterData.secondEntry->hasSLOverlap()){
772 } else {
773 mdtpar =
m_propagator->propagateParameters(ctx, startpar, *lastmdtsurf,
775 }
776 if (mdtpar) {
779 fake = std::make_unique<Trk::PseudoMeasurementOnTrack>(
781 std::move(cov),
782 mdtpar->associatedSurface());
783
784 }
785 } else {
787 }
788 if (fake) {
789 fitterData.phiHits.push_back(fake.get());
790 fitterData.measurements.insert(fitterData.measurements.begin() + indexlast, fake.get());
791 fitterData.firstLastMeasurements.push_back(fake.get());
792 fitterData.garbage.push_back(std::move(fake));
793 }
794 }
795
796 if (firstmdtsurf && (!firstphisurf || (firstmdtsurf->
center() - firstphisurf->
center()).dot(firstphinormal) < -1000)) {
797 ATH_MSG_VERBOSE(
" Adding fake at first hit: dist first phi/first eta " << distFirstEtaPhi <<
" dist last phi/last eta "
798 << distLastEtaPhi);
799 std::unique_ptr<Trk::MeasurementBase> fake{};
800 if (phifromextrapolation) {
801
802 auto mdtpar =
m_propagator->propagateParameters(ctx, startpar,
804 if (mdtpar) {
807 fake = std::make_unique<Trk::PseudoMeasurementOnTrack>(
809 std::move(cov),
810 mdtpar->associatedSurface());
811 }
812 } else{
814 }
815 if (fake) {
816 fitterData.phiHits.insert(fitterData.phiHits.begin(), fake.get());
817 fitterData.measurements.insert(fitterData.measurements.begin() + indexfirst, fake.get());
818 fitterData.firstLastMeasurements.insert(fitterData.firstLastMeasurements.begin(), fake.get());
819 fitterData.garbage.push_back(std::move(fake));
820 }
821 }
822 }
823 return true;
824 }
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool msgLvl(const MSG::Level lvl) const
bool is_valid() const
Check if id is in a valid state.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Trk::MagneticFieldProperties m_magFieldProperties
magnetic field properties
ToolHandle< IMuonSegmentInOverlapResolvingTool > m_overlapResolver
std::unique_ptr< Trk::MeasurementBase > createFakePhiForMeasurement(const Trk::MeasurementBase &measurement, const Amg::Vector3D *overlapPos, const Amg::Vector3D *phiPos, double error) const
create fake phi hit on the surface of the give measurement
Gaudi::Property< bool > m_seedWithAvePhi
Gaudi::Property< bool > m_cosmics
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
multi purpose helper tool
unsigned int hasPhiConstrain(FitterData &inputData) const
check whether data has sufficient phi constraints
ToolHandle< Trk::IPropagator > m_propagator
propagator
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
void setThetaPhi(Amg::Vector3D &v, double theta, double phi)
sets the theta and phi angle of a vector without changing the magnitude
StIndex
enum to classify the different station layers in the muon spectrometer
MuPatHitList::const_iterator MuPatHitCit
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParametersBase< TrackParametersDim, Charged > TrackParameters
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane