53 const double s_sigmaPhiSector =
std::tan(0.125 *
M_PI / std::sqrt(12.));
60 declareInterface<ICombinedMuonTrackBuilder>(
this);
95 beamAxisCovariance.setZero();
99 m_beamAxis = std::make_unique<Trk::RecVertex>(origin, beamAxisCovariance);
102 vertexRegionCovariance.setZero();
106 m_vertex = std::make_unique<Trk::RecVertex>(origin, vertexRegionCovariance);
114 return StatusCode::SUCCESS;
121 <<
endmsg <<
" " << std::setiosflags(std::ios::fixed) << std::setw(4) << std::setprecision(2)
132 if (msgLevel(
MSG::DEBUG))
countAEOTs(extrapolatedTrack,
" extrapolatedTrack start combinedFit ");
144 if (
m_trackQuery->isCaloAssociated(extrapolatedTrack, ctx)) {
146 if (!
it->materialEffectsOnTrack())
continue;
148 const Amg::Vector3D& position =
it->materialEffectsOnTrack()->associatedSurface().globalReferencePoint();
153 surface = &
it->materialEffectsOnTrack()->associatedSurface();
165 std::unique_ptr<const Trk::TrackStateOnSurface> innerTSOS;
167 ATH_MSG_VERBOSE(
" Retrieving Calorimeter TSOS from " << __func__ <<
" at line " << __LINE__);
168 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> caloTSOS =
170 if (!caloTSOS.empty()) { innerTSOS.swap(caloTSOS.front()); }
176 ATH_MSG_DEBUG(
" indet track fails to intersect the calorimeter ");
181 double surfaceOffset =
185 ATH_MSG_DEBUG(
" different inner-calo-surface obtained from indet extrapolation, "
187 <<
"mm. Re-evaluate the caloTSOS ");
193 std::unique_ptr<Trk::Track> muonTrack;
195 ATH_MSG_VERBOSE(
" SL MS track: Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
202 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
205 }
else if (
m_trackQuery->numberPseudoMeasurements(extrapolatedTrack) > 1) {
206 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
210 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
218 if (!muonTrack)
return nullptr;
226 bool haveMS {
false}, perigeeOutside{
false};
235 for (; rit != ritEnd; ++rit) {
236 if (!(**rit).measurementOnTrack() || !(**rit).trackParameters())
continue;
243 ATH_MSG_DEBUG(
"combinedFit:: fail with MS removed by cleaner");
255 perigeeOutside =
true;
278 double pRatio = muonEnergyParameters->momentum().mag() / combinedEnergyParameters->momentum().mag();
281 ATH_MSG_DEBUG(
" iterate combined fit to recollect calorimeter material as significant momentum change after fit "
282 << pRatio <<
", pT before " << muonEnergyParameters->momentum().perp() /
Gaudi::Units::GeV <<
", after "
285 ATH_MSG_DEBUG(
" iterate combined fit to recollect calorimeter material");
292 std::unique_ptr<Trk::Track> oldTrack(std::move(muonTrack));
294 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
295 muonTrack =
createMuonTrack(ctx, extrapolatedTrack, combinedEnergyParameters,
nullptr, combinedTSOS);
297 if (indetNewTrack && muonTrack) {
299 caloEnergy =
caloEnergyParameters(refittedTrack.get(), muonTrack.get(), combinedEnergyParameters, muonEnergyParameters);
305 muonTrack.swap(oldTrack);
316 if (!indetPerigee->covariance()) {
317 ATH_MSG_WARNING(
" indetPerigee has no covariance tolerance left as zero. ");
323 double energyBalance = combinedEnergyParameters->momentum().mag() + caloEnergy->deltaE() - indetMaxE;
326 std::unique_ptr<CaloEnergy> paramEnergy;
327 if (indetMaxE > 0. && energyBalance >
m_numberSigmaFSR * caloEnergy->sigmaMinusDeltaE()) {
334 paramEnergy =
m_caloEnergyParam->energyLoss(ctx, combinedEnergyParameters->momentum().mag(),
335 combinedEnergyParameters->position().eta(),
336 combinedEnergyParameters->position().phi());
344 << energyBalance /
Gaudi::Units::GeV <<
" signif " << energyBalance / caloEnergy->sigmaMinusDeltaE()
349 << combinedEnergyParameters->position().eta() <<
" phi " << combinedEnergyParameters->position().phi()
350 <<
endmsg <<
" tail-param energy diff "
353 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
386 dumpCaloEloss(newTrack.get(),
"CB input TSOS after refine IDMS ");
387 std::unique_ptr<Trk::Track> refittedTrack{
fit(ctx, *newTrack,
false,
Trk::muon)};
390 dumpCaloEloss(refittedTrack.get(),
"CB refit after refine IDMS ");
392 if (
checkTrack(
"combinedFit", refittedTrack.get())) {
401 ATH_MSG_DEBUG(
"addIDMS errors failed and original track does not pass checkTrack");
412 std::unique_ptr<Trk::TrackParameters> innerParameters,
413 std::unique_ptr<Trk::TrackParameters> middleParameters,
414 std::unique_ptr<Trk::TrackParameters> outerParameters)
const {
418 if (innerParameters || middleParameters || outerParameters) {
421 if (innerParameters) {
423 << std::setw(5) << std::setprecision(0) << innerParameters->
position().z() <<
" ";
426 if (middleParameters) {
427 msg(
MSG::VERBOSE) <<
"M:" << std::setw(5) << std::setprecision(0) << middleParameters->
position().perp() <<
","
428 << std::setw(5) << std::setprecision(0) << middleParameters->
position().z() <<
" ";
431 if (outerParameters) {
433 << std::setw(5) << std::setprecision(0) << outerParameters->
position().z();
438 if (innerParameters) {
442 if (middleParameters) {
446 if (outerParameters) {
467 ATH_MSG_VERBOSE(
"indetExtension: method switched off when solenoid 'off' / toroid 'on'");
476 std::unique_ptr<Trk::TrackParameters> frontParameters, backParameters;
478 if (innerParameters) {
479 if (innerParameters->
associatedSurface() == spectrometerMeasurements.front()->associatedSurface()) {
486 }
else if (middleParameters) {
487 if (middleParameters->
associatedSurface() == spectrometerMeasurements.front()->associatedSurface()) {
496 if (outerParameters) {
497 if (outerParameters->
associatedSurface() == spectrometerMeasurements.back()->associatedSurface()) {
504 }
else if (middleParameters) {
505 if (middleParameters->
associatedSurface() == spectrometerMeasurements.back()->associatedSurface()) {
515 std::unique_ptr<Trk::TrackParameters> midParameters;
518 if (middleParameters && innerParameters && outerParameters) {
520 double midDistance = 0.5 * direction.dot(outerParameters->
position() - innerParameters->
position());
521 double previousDistance = 0.;
523 Trk::MeasurementSet::const_iterator
m = spectrometerMeasurements.begin();
524 for (++
m;
m != spectrometerMeasurements.end(); ++
m) {
525 double distance = direction.dot((**m).globalPosition() - innerParameters->
position());
529 if (midDistance - previousDistance <
distance - midDistance) --
m;
534 if (midParameters) midMeasurement = *
m;
541 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typeM;
543 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typeP;
547 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
549 trackStateOnSurfaces->reserve(spectrometerMeasurements.size());
555 if (frontParameters) {
556 trackStateOnSurfaces->push_back(
558 }
else if (in_meas == midMeasurement) {
559 trackStateOnSurfaces->push_back(
561 }
else if (backParameters && in_meas == spectrometerMeasurements.back()) {
562 trackStateOnSurfaces->push_back(
565 trackStateOnSurfaces->push_back(
575 ATH_MSG_VERBOSE(
"Calling combinedFit from " << __func__ <<
" at line " << __LINE__);
587 if (
m_trackQuery->isLineFit(inputSpectrometerTrack) && !fieldCache.
toroidOn()) {
return nullptr; }
589 ATH_MSG_DEBUG(
" standaloneFit beam position bs_x " << origin <<
" inputVertex "
593 msg(
MSG::VERBOSE) <<
endmsg <<
"==== Start of standaloneFit:: " << std::setiosflags(std::ios::fixed);
595 if (
m_trackQuery->isExtrapolated(inputSpectrometerTrack, ctx)) {
603 msg(
MSG::VERBOSE) <<
" at eta " << std::setw(6) << std::setprecision(3)
604 << inputSpectrometerTrack.
perigeeParameters()->momentum().eta() <<
" phi " << std::setw(6)
605 << std::setprecision(3) << inputSpectrometerTrack.
perigeeParameters()->momentum().phi();
607 }
else if (!
m_trackQuery->isProjective(inputSpectrometerTrack)) {
617 msg(
MSG::VERBOSE) <<
" at eta " << std::setw(6) << std::setprecision(3)
618 << inputSpectrometerTrack.
perigeeParameters()->position().eta() <<
" phi " << std::setw(6)
619 << std::setprecision(3) << inputSpectrometerTrack.
perigeeParameters()->position().phi();
635 if (
m_trackQuery->numberPseudoMeasurements(inputSpectrometerTrack)) {
644 if (inputVertex && !
vertex) {
657 int measurements = 0;
662 if (measurements < 4) {
669 if (
fitQuality && measurements < fitQuality->numberDoF() + 4) {
677 const bool is_extrapolated =
m_trackQuery->isExtrapolated(inputSpectrometerTrack, ctx);
678 if (!is_extrapolated && !
m_trackQuery->isProjective(inputSpectrometerTrack)) {
684 double spectrometerFitChi2 =
normalizedChi2(inputSpectrometerTrack);
685 std::unique_ptr<Trk::Track> spectrometerFit = std::make_unique<Trk::Track>(inputSpectrometerTrack);
688 if (!spectrometerFit) {
694 const Trk::Track& spectrometerTrack = *spectrometerFit;
699 if (!measuredPerigee || !measuredPerigee->covariance()) {
708 bool badlyDeterminedCurvature =
false;
711 ATH_MSG_WARNING(
"standaloneFit: measuredPerigee has non-positive-definite covariance ");
717 double errorP = std::sqrt(measuredPerigee->momentum().mag2() * (*measuredPerigee->covariance())(
Trk::qOverP,
Trk::qOverP));
719 std::unique_ptr<Trk::RecVertex> mvertex = std::make_unique<Trk::RecVertex>(*
m_vertex);
720 std::unique_ptr<Trk::RecVertex> mbeamAxis = std::make_unique<Trk::RecVertex>(*
m_beamAxis);
721 std::unique_ptr<Trk::PerigeeSurface> mperigeeSurface = std::make_unique<Trk::PerigeeSurface>(*
m_perigeeSurface);
723 std::unique_ptr<const Trk::TrackParameters>
parameters;
728 ATH_MSG_VERBOSE(
"standaloneFit: vertex fit not attempted as curvature badly measured");
737 if ((origin - mvertex->
position()).mag() > 0.001) {
740 mperigeeSurface = std::make_unique<Trk::PerigeeSurface>(origin);
743 beamAxisCovariance.setZero();
747 mbeamAxis = std::make_unique<Trk::RecVertex>(origin, beamAxisCovariance);
750 vertexRegionCovariance.setZero();
754 mvertex = std::make_unique<Trk::RecVertex>(origin, vertexRegionCovariance);
766 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> spectrometerTSOS =
createSpectrometerTSOS(ctx, spectrometerTrack);
768 if (spectrometerTSOS.empty()) {
776 bool haveFitWithVertex =
false;
777 bool performPrefit =
false;
781 if (
s->measurementOnTrack() && !
s->trackParameters()) {
782 performPrefit =
true;
789 std::unique_ptr<Trk::Track> prefit;
796 bool inCSCregion = std::abs(measuredPerigee->momentum().eta()) > 2.0;
800 if (inCSCregion ||
m_trackQuery->numberPseudoMeasurements(spectrometerTrack) ||
803 performPrefit =
true;
804 vertexInFit = (badlyDeterminedCurvature || inCSCregion) ? mvertex.get() : mbeamAxis.get();
807 unsigned numberPseudo =
m_trackQuery->numberPseudoMeasurements(spectrometerTrack);
808 if (errorPhi > s_sigmaPhiSector) { ++numberPseudo; }
810 if (badlyDeterminedCurvature) {
811 ATH_MSG_DEBUG(
" prefit with vertex: " << std::setiosflags(std::ios::fixed) <<
" momentum " << std::setprecision(1)
813 << std::setprecision(1) << std::abs(
parameters->position().z())
814 <<
", phiError " << std::setprecision(2) << errorPhi <<
", momentumError "
815 << std::setprecision(2) << errorP <<
", numberPseudo " << numberPseudo);
818 << std::setiosflags(std::ios::fixed) <<
" momentum " << std::setprecision(1)
819 << measuredPerigee->momentum().mag() /
Gaudi::Units::GeV <<
" (GeV), zFirst " << std::setprecision(1)
820 << std::abs(
parameters->position().z()) <<
", phiError " << std::setprecision(2) << errorPhi
821 <<
", momentumError " << std::setprecision(2) << errorP <<
", numberPseudo " << numberPseudo);
827 std::unique_ptr<const Trk::Perigee> prefitResult;
833 if (vertexInFit) { haveFitWithVertex =
true; }
837 ATH_MSG_VERBOSE(
"Calling createExtrapolatedTrack from " << __func__ <<
" at line " << __LINE__);
839 mbeamAxis.get(), mperigeeSurface.get());
856 if (!
s->trackParameters() || !
s->trackParameters()->covariance()) {
continue; }
861 ATH_MSG_DEBUG(
"Found first parameters in MS " <<
s->trackParameters()->position().perp() <<
" z "
862 <<
s->trackParameters()->position().z());
878 spectrometerTSOS.clear();
891 return (tsos->trackParameters() && !m_calorimeterVolume->inside(tsos->trackParameters()->position())) ||
892 tsos->type(Trk::TrackStateOnSurface::Perigee);
897 for (;
s != prefit_tsos->
end(); ++
s) { spectrometerTSOS.emplace_back((*s)->clone()); }
902 for (std::unique_ptr<const Trk::TrackStateOnSurface>&
t : spectrometerTSOS) {
903 if (!
t->measurementOnTrack() || !
t->trackParameters()) {
continue; }
912 std::unique_ptr<Trk::RIO_OnTrack> updatedRot;
930 bool returnAfterCleaner = !fieldCache.
toroidOn();
932 ATH_MSG_VERBOSE(
"Calling createExtrapolatedTrack from " << __func__ <<
" at line " << __LINE__);
935 mperigeeSurface.get(), prefitResult.get()));
941 if (
extrapolated && !haveFitWithVertex && !vertexInFit) {
943 std::unique_ptr<Trk::Track> badfit(std::move(
extrapolated));
945 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
948 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
type{};
950 std::unique_ptr<Trk::PseudoMeasurementOnTrack> vertexInFit =
960 trackStateOnSurfaces->push_back((**s).clone());
963 std::unique_ptr<Trk::Track>
track =
964 std::make_unique<Trk::Track>(spectrometerTrack.
info(), std::move(trackStateOnSurfaces),
nullptr);
970 if (prefit && prefit->
fitQuality() && caloParameters) {
971 ATH_MSG_DEBUG(
" restarting from prefit as back extrapolation fit failed");
972 spectrometerTSOS.clear();
983 ATH_MSG_VERBOSE(
"Calling createExtrapolatedTrack from " << __func__ <<
" at line " << __LINE__);
986 vertexInFit, mbeamAxis.get(), mperigeeSurface.get(), prefitResult.get());
987 returnAfterCleaner =
true;
1008 bool allowRefit = !badlyDeterminedCurvature;
1012 if (returnAfterCleaner) {
1019 while (!(**s).trackParameters() ||
m_calorimeterVolume->inside((**s).trackParameters()->position())) {
1035 std::unique_ptr<Trk::Track>
track;
1039 double sinTheta = params_pRat->
momentum().perp() / params_pRat->
momentum().mag();
1046 spectrometerTSOS.clear();
1051 ATH_MSG_VERBOSE(
"Calling createExtrapolatedTrack from " << __func__ <<
" at line " << __LINE__);
1054 vertexInFit, mbeamAxis.get(), mperigeeSurface.get(),
extrapolated->perigeeParameters());
1071 int improvementsFailed = 0;
1079 if (
checkTrack(
"refineFit", refinedTrack.get())) {
1081 track.swap(refinedTrack);
1084 ++improvementsFailed;
1096 dumpCaloEloss(newTrack.get(),
"SA input TSOS after refine IDMS ");
1099 std::unique_ptr<Trk::Track> refittedTrack(
fit(ctx, *newTrack,
false,
Trk::muon));
1101 dumpCaloEloss(refittedTrack.get(),
" SA refit after refine IDMS ");
1102 if (
checkTrack(
"standaloneFit", refittedTrack.get())) {
1104 track.swap(refittedTrack);
1106 ++improvementsFailed;
1109 ++improvementsFailed;
1120 if (fitChi2 >
m_badFitChi2 && fitChi2 > spectrometerFitChi2 + 0.5) {
1121 ATH_MSG_DEBUG(
"standaloneFit: fit quality degraded wrt spectrometer alone. "
1122 <<
" Chi2/DoF= " << fitChi2);
1125 if (improvementsFailed >= 2) {
1126 ATH_MSG_DEBUG(
"reject track, quality degraded and improvements failed");
1152 ATH_MSG_DEBUG(
" StandaloneRefit beam position bs_x " << origin);
1164 ATH_MSG_DEBUG(
" StandaloneRefit new vertex d0 error " << std::sqrt(error2d0) <<
" new vertex z0 error "
1165 << std::sqrt(error2z0));
1168 (vertexRegionCovariance)(0, 0) = error2d0;
1169 (vertexRegionCovariance)(1, 1) = error2d0;
1170 (vertexRegionCovariance)(2, 2) = error2z0;
1172 std::unique_ptr<Trk::RecVertex>
vertex = std::make_unique<Trk::RecVertex>(origin, vertexRegionCovariance);
1174 ATH_MSG_DEBUG(
" StandaloneRefit new vertex position x " <<
vertex->position().x() <<
" y " <<
vertex->position().y() <<
" z "
1175 <<
vertex->position().z());
1177 bool addPhiPseudo =
false;
1180 if (spectrometerPhiQuality > 1) { addPhiPseudo =
true; }
1182 ATH_MSG_VERBOSE(
"standaloneRefit: using vertex region constraint with "
1183 <<
"spectrometerPhiQuality " << spectrometerPhiQuality);
1186 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1189 unsigned size =
combinedTrack.trackStateOnSurfaces()->size() + 3 + addPhiPseudo;
1191 trackStateOnSurfaces->reserve(
size);
1194 bool haveCaloDeposit =
false;
1200 if (
s == cmb_end_itr) {
1206 haveCaloDeposit =
true;
1209 }
while (!haveCaloDeposit);
1215 std::unique_ptr<Trk::TrackStateOnSurface> innerTSOS;
1220 std::unique_ptr<Trk::TrackParameters> param_owner;
1225 innerTSOS.reset(cmb_inner_tsos->
clone());
1239 if (
s != cmb_end_itr) {
1247 materialEffects =
nullptr;
1266 std::unique_ptr<Trk::TrackStateOnSurface> middleTSOS;
1270 middleTSOS.reset(cmb_middle_tsos->
clone());
1277 if (
s != cmb_end_itr) {
1282 materialEffects =
nullptr;
1298 std::unique_ptr<Trk::TrackStateOnSurface> outerTSOS;
1300 double pInner{0.}, pOuter{0.};
1305 outerTSOS.reset(cmb_outer_tsos->
clone());
1321 if (outerScattering && middleTSOS) {
1332 if (!param_owner) param_owner =
parameters->uniqueClone();
1347 if (!innerTSOS || !middleTSOS || !outerTSOS || !
parameters) {
return nullptr; }
1358 std::unique_ptr<Trk::TrackParameters> perigee_owner;
1367 if (!perigee_owner) { perigee_owner =
combinedTrack.perigeeParameters()->uniqueClone(); }
1390 if (!param_owner) {
return nullptr; }
1400 std::unique_ptr<Trk::RecVertex> mbeamAxis = std::make_unique<Trk::RecVertex>(*
m_beamAxis);
1402 std::unique_ptr<Trk::PseudoMeasurementOnTrack> vertexInFit{
vertexOnTrack(*perigee_owner,
vertex.get(), mbeamAxis.get())};
1413 double Eloss{0.}, sigmaEloss{0.}, X0tot{0.}, sigmaDeltaPhitot2{0.}, sigmaDeltaThetatot2{0.};
1415 std::vector<const Trk::TrackStateOnSurface*> scatter_tsos;
1416 scatter_tsos.reserve(
combinedTrack.trackStateOnSurfaces()->size());
1419 if (!comb_tsos->trackParameters())
continue;
1420 if (!
m_indetVolume->inside(comb_tsos->trackParameters()->position()))
break;
1421 if (!comb_tsos->materialEffectsOnTrack()) {
continue; }
1422 const double X0 = comb_tsos->materialEffectsOnTrack()->thicknessInX0();
1427 if (!meot) {
continue; }
1429 if (!energyLoss) {
continue; }
1430 Eloss += energyLoss->
deltaE();
1433 ATH_MSG_DEBUG(
"CombinedMuonFit ID Eloss found r " << (comb_tsos->trackParameters())->position().perp() <<
" z "
1434 << (comb_tsos->trackParameters())->position().z() <<
" value "
1435 << energyLoss->
deltaE() <<
" Eloss " << Eloss <<
" sigma Eloss "
1442 sigmaDeltaPhitot2 += sigmaDeltaPhi * sigmaDeltaPhi;
1443 sigmaDeltaThetatot2 += sigmaDeltaTheta * sigmaDeltaTheta;
1444 scatter_tsos.push_back(comb_tsos);
1448 ATH_MSG_DEBUG(
"standaloneRefit Total ID Eloss " << Eloss <<
" sigma Eloss " << sigmaEloss <<
" X0 " << X0tot
1449 <<
" sigma scat phi " << std::sqrt(sigmaDeltaPhitot2) <<
" sigma scat theta "
1450 << std::sqrt(sigmaDeltaThetatot2));
1451 if (!scatter_tsos.empty()) {
1452 const int itsosMiddle = scatter_tsos.size() / 2;
1455 std::unique_ptr<Trk::EnergyLoss> energyLossNew = std::make_unique<Trk::EnergyLoss>(Eloss, sigmaEloss, sigmaEloss, sigmaEloss);
1458 Trk::ScatteringAngles scatNew{0., 0., std::sqrt(sigmaDeltaPhitot2), std::sqrt(sigmaDeltaThetatot2)};
1460 std::bitset<Trk::MaterialEffectsBase::NumberOfMaterialEffectsTypes> meotPattern(0);
1464 ATH_MSG_DEBUG(
" itsosMiddle " << itsosMiddle <<
" tsosnr size " << scatter_tsos.size());
1466 std::unique_ptr<Trk::MaterialEffectsOnTrack> meotNew = std::make_unique<Trk::MaterialEffectsOnTrack>(X0tot, scatNew, std::move(energyLossNew), surfNew, meotPattern);
1469 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePatternScat(0);
1472 std::unique_ptr<Trk::TrackStateOnSurface> newTSOS =
1473 std::make_unique<Trk::TrackStateOnSurface>(
nullptr, std::move(parsNew), std::move(meotNew), typePatternScat);
1475 trackStateOnSurfaces->push_back(std::move(newTSOS));
1482 trackStateOnSurfaces->push_back(std::move(innerTSOS));
1483 trackStateOnSurfaces->push_back(std::move(middleTSOS));
1484 trackStateOnSurfaces->push_back(std::move(outerTSOS));
1488 std::unique_ptr<Trk::TrackStateOnSurface> entranceTSOS =
entrancePerigee(ctx, outerTSOSParam);
1489 if (entranceTSOS) trackStateOnSurfaces->push_back(std::move(entranceTSOS));
1493 bool haveLeadingMaterial =
false;
1496 for (; mat_it != cmb_end_itr; ++mat_it) {
1498 haveLeadingMaterial =
true;
1502 if (mat_it == cmb_end_itr) {
1512 if (tsos) trackStateOnSurfaces->push_back(std::move(tsos));
1519 std::unique_ptr<Trk::Track> standaloneTrack =
1520 std::make_unique<Trk::Track>(
combinedTrack.info(), std::move(trackStateOnSurfaces),
nullptr);
1522 if (
m_trackQuery->isCombined(*standaloneTrack, ctx)) {
ATH_MSG_WARNING(
" This should not happen standalone Track has ID hits "); }
1524 if (msgLevel(
MSG::DEBUG))
countAEOTs(*standaloneTrack,
" in standalone Refit standaloneTrack track before fit ");
1526 std::unique_ptr<Trk::Track> refittedTrack{
fit(ctx, *standaloneTrack,
false,
Trk::muon)};
1527 if (!
checkTrack(
"standaloneRefit", refittedTrack.get())) {
return nullptr; }
1531 if (refittedTrack) {
1532 if (!refittedTrack->fitQuality()) {
return nullptr; }
1534 if (!
m_trackQuery->isCaloAssociated(*refittedTrack, ctx)) {
1545 countAEOTs(*refittedTrack,
" before optimize ") == 0) {
1546 ATH_MSG_VERBOSE(
" perform spectrometer error optimization after cleaning ");
1547 std::unique_ptr<Trk::Track> optimizedTrack =
m_muonErrorOptimizer->optimiseErrors(*refittedTrack, ctx);
1549 if (
checkTrack(
"standaloneRefitOpt", optimizedTrack.get())) {
1550 refittedTrack.swap(optimizedTrack);
1551 if (msgLevel(
MSG::DEBUG))
countAEOTs(*refittedTrack,
" standaloneRefit alignment errors Track ");
1557 return refittedTrack;
1569 ATH_MSG_DEBUG(
" CombinedMuonTrackBuilder addIDMSerrors to track ");
1579 if (!calo_entrance || !calo_exit || !ms_entrance) {
1584 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1585 trackStateOnSurfaces->reserve(
track->trackStateOnSurfaces()->size());
1588 if (calo_entrance == trk_srf || calo_entrance == trk_srf) {
1589 if (!trk_srf->materialEffectsOnTrack()) {
1596 ATH_MSG_WARNING(
" This should not happen: no MaterialEffectsOnTrack for scatterer ");
1601 ATH_MSG_WARNING(
" This should not happen: no Scattering Angles for scatterer ");
1607 float X0 = trk_srf->materialEffectsOnTrack()->thicknessInX0();
1609 auto energyLossNew = std::make_unique<Trk::EnergyLoss>(0., 0., 0., 0.);
1612 const Trk::Surface& surfNew = trk_srf->trackParameters()->associatedSurface();
1614 std::bitset<Trk::MaterialEffectsBase::NumberOfMaterialEffectsTypes> meotPattern(0);
1618 auto meotNew = std::make_unique<Trk::MaterialEffectsOnTrack>(
1621 std::move(energyLossNew),
1624 auto parsNew = trk_srf->trackParameters()->uniqueClone();
1626 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePatternScat(0);
1631 trackStateOnSurfaces->push_back(newTSOS);
1636 ATH_MSG_DEBUG(
" new Calo scatterer made with sigmaDeltaPhi mrad " << sigmaDeltaPhi * 1000 <<
" sigmaDeltaTheta mrad "
1637 << sigmaDeltaTheta * 1000);
1641 if (trk_srf->alignmentEffectsOnTrack()) {
1642 ATH_MSG_DEBUG(
" addIDMSerrors alignmentEffectsOnTrack() found on track ");
1645 trackStateOnSurfaces->push_back(trk_srf->clone());
1648 ATH_MSG_DEBUG(
" trackStateOnSurfaces on input track " <<
track->trackStateOnSurfaces()->size() <<
" trackStateOnSurfaces found "
1649 << trackStateOnSurfaces->size());
1651 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track->info(), std::move(trackStateOnSurfaces),
nullptr);
1658 std::vector<const Trk::Surface*> measurementSurfaces;
1659 measurementSurfaces.reserve(trackStateOnSurfaces.
size());
1663 for (;
s !=
end; ++
s) {
1671 ATH_MSG_VERBOSE(
"appendSelectedTSOS:: skip a perigee without material and measuremet "<<tsos);
1685 if (previousSurface &&
1686 std::find(measurementSurfaces.begin(), measurementSurfaces.end(), surface) != measurementSurfaces.end()) {
1692 measurementSurfaces.push_back(surface);
1693 previousSurface = surface;
1703 combinedEnergyParameters =
nullptr;
1704 muonEnergyParameters =
nullptr;
1719 muonEnergyParameters = (**s).trackParameters();
1731 combinedEnergyParameters = (**s).trackParameters();
1732 if (muonEnergyParameters && combinedEnergyParameters) {
1733 ATH_MSG_DEBUG(
"muon and combined EnergyParameters: " << muonEnergyParameters->
momentum().mag() <<
" "
1734 << combinedEnergyParameters->
momentum().mag());
1743 const std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>>& spectrometerTSOS,
const Trk::RecVertex*
vertex,
1749 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> caloTSOS, leadingTSOS;
1751 std::unique_ptr<const Trk::TrackParameters> track_param_owner;
1758 trackParameters = perigee;
1765 bool haveMaterial{
false}, haveLeadingMaterial{
false}, firstMSHit{
false};
1767 for (
const std::unique_ptr<const Trk::TrackStateOnSurface>&
s : spectrometerTSOS) {
1768 if (
s->materialEffectsOnTrack()) {
1769 haveMaterial =
true;
1770 if (!firstMSHit) haveLeadingMaterial =
true;
1773 if (
s->measurementOnTrack() && !firstMSHit) { firstMSHit =
true; }
1775 if (haveMaterial && firstMSHit) {
break; }
1784 constexpr
double Emax = 50000.;
1793 std::unique_ptr<Trk::TrackParameters> correctedParameters{
parameters.associatedSurface().createUniqueTrackParameters(
1798 std::unique_ptr<std::vector<const Trk::TrackStateOnSurface*>> lead_tsos_from_alloc{
1800 if (lead_tsos_from_alloc) {
1803 if (!leadingTSOS.empty() && leadingTSOS.front()->trackParameters()) {
1804 leadingParameters = leadingTSOS.front()->trackParameters();
1810 bool caloAssociated =
false;
1813 ATH_MSG_VERBOSE(
" Retrieving Calorimeter TSOS from " << __func__ <<
" at line " << __LINE__);
1819 for (std::unique_ptr<const Trk::TrackStateOnSurface>&
m : caloTSOS) {
1820 if (!
m->materialEffectsOnTrack())
continue;
1823 double pcalo{0.}, deltaP{0.};
1824 if (!meot)
continue;
1830 if (!scatAngles) {
continue; }
1831 pcalo =
m->trackParameters()->momentum().mag();
1837 <<
" deltaTheta " << scatAngles->
deltaTheta() <<
" pull "
1841 if (!energyLoss)
continue;
1843 if (
m->trackParameters()) {
1844 ATH_MSG_DEBUG(
"Eloss found r " << (
m->trackParameters())->position().perp() <<
" z "
1845 << (
m->trackParameters())->position().z() <<
" deltaE "
1846 << energyLoss->
deltaE());
1850 double caloEloss = std::abs(energyLoss->
deltaE());
1851 if (
m->trackParameters()) { deltaP =
m->trackParameters()->momentum().mag() - pcalo; }
1853 ATH_MSG_DEBUG(
" Calorimeter Deposit " << caloEloss <<
" pcalo Entrance " << pcalo <<
" deltaP " << deltaP);
1858 caloTSOS =
m_caloTSOS->caloTSOS(ctx, *leadingParameters);
1861 if (caloTSOS.size() > 2) {
1862 caloAssociated =
true;
1870 caloTSOS.push_back(std::move(tsos));
1871 tsos =
m_caloTSOS->outerTSOS(ctx, *caloTSOS.back()->trackParameters());
1873 caloAssociated =
true;
1874 caloTSOS.push_back(std::move(tsos));
1877 ATH_MSG_VERBOSE(
"Special non-muon case for calo: " << caloAssociated);
1881 if (caloAssociated) {
1890 if(not oldParameters->covariance()) {
ATH_MSG_VERBOSE(
" createExtrapolatedTrack: no cov (0)"); }
1899 trackParameters = track_param_owner.get();
1902 if (trackParameters && !
m_indetVolume->inside(trackParameters->position())) {
1903 ATH_MSG_DEBUG(
" back extrapolation problem: probably outside indet volume ");
1904 caloAssociated =
false;
1907 if (trackParameters && !trackParameters->covariance()) {
ATH_MSG_VERBOSE(
" createExtrapolatedTrack: no cov (1)"); }
1909 if (trackParameters) {
1910 ATH_MSG_VERBOSE(
" Seed parameter: r " << trackParameters->position().perp() <<
" z " << trackParameters->position().z()
1911 <<
" pt " << trackParameters->momentum().perp());
1917 ATH_MSG_DEBUG(
" back extrapolation problem: retry with tracking out from vertex ");
1924 track_param_owner = std::make_unique<Trk::Perigee>(
vertex->position(),
momentum, 1., *mperigeeSurface);
1925 trackParameters = track_param_owner.get();
1929 ATH_MSG_VERBOSE(
" Retriving Calorimeter TSOS from " << __func__ <<
" at line " << __LINE__);
1934 std::unique_ptr<const Trk::TrackStateOnSurface> tsos =
m_caloTSOS->innerTSOS(ctx, *trackParameters);
1936 caloTSOS.push_back(std::move(tsos));
1937 tsos =
m_caloTSOS->outerTSOS(ctx, *trackParameters);
1939 caloTSOS.push_back(std::move(tsos));
1941 track_param_owner.reset();
1945 trackParameters = track_param_owner.get();
1949 if (!trackParameters || caloTSOS.empty()) {
1956 if (seedParameters) { trackParameters = seedParameters; }
1960 const unsigned int size = spectrometerTSOS.size() + 3 + caloTSOS.size() + leadingTSOS.size();
1962 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1963 trackStateOnSurfaces->reserve(
size);
1967 if (trackParameters && !trackParameters->covariance()) {
ATH_MSG_VERBOSE(
" createExtrapolatedTrack: no cov (2)"); }
1969 if (trackParameters) {
1971 ATH_MSG_DEBUG(
"createExtrapolatedTrack() - Track parameters are not perigee " << (*trackParameters));
1977 if (
vertex && trackParameters) {
1978 std::unique_ptr<Trk::PseudoMeasurementOnTrack> vertexInFit =
vertexOnTrack(*trackParameters,
vertex, mbeamAxis);
1986 for (std::unique_ptr<const Trk::TrackStateOnSurface>& c_tsos : caloTSOS) { trackStateOnSurfaces->push_back(std::move(c_tsos)); }
1991 const Trk::TrackParameters* mstrackParameters = trackStateOnSurfaces->back()->trackParameters();
1993 if (!mstrackParameters) { mstrackParameters = spectrometerTSOS.front()->trackParameters(); }
1995 if (mstrackParameters) {
1996 std::unique_ptr<Trk::TrackStateOnSurface> entranceTSOS =
entrancePerigee(ctx, mstrackParameters);
1997 if (entranceTSOS) { trackStateOnSurfaces->push_back(std::move(entranceTSOS)); }
2002 for (std::unique_ptr<const Trk::TrackStateOnSurface>& c_tsos : leadingTSOS) {
2003 if (c_tsos->materialEffectsOnTrack()) { trackStateOnSurfaces->push_back(std::move(c_tsos)); }
2005 leadingTSOS.clear();
2008 for (
const auto&
s : spectrometerTSOS) {
2011 trackStateOnSurfaces->push_back(
s->clone());
2020 std::unique_ptr<Trk::Track>
track =
2021 std::make_unique<Trk::Track>(spectrometerTrack.
info(), std::move(trackStateOnSurfaces),
nullptr);
2023 if (!
track->perigeeParameters()) {
2039 :
"usig interacting hypothesis"));
2041 std::unique_ptr<Trk::Track> fittedTrack{
fit(ctx, *
track, runOutlier, particleHypothesis)};
2046 if (fittedTrack->perigeeParameters() && !
m_indetVolume->inside(fittedTrack->perigeeParameters()->position())) {
2047 ATH_MSG_DEBUG(
" back extrapolation problem: fitted perigee outside indet volume ");
2067 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
2077 std::unique_ptr<Trk::TrackStateOnSurface> perigeeTSOS {(**s).clone()};
2080 for (;
s !=
end; ++
s) {
2082 if (!
m_indetVolume->inside((**s).trackParameters()->position())) {
break; }
2086 trackStateOnSurfaces->reserve(
size);
2087 trackStateOnSurfaces->push_back(std::move(perigeeTSOS));
2092 return std::make_unique<Trk::Track>(
info, std::move(trackStateOnSurfaces),
nullptr);
2107 while ((**s).trackParameters() &&
2109 if (
m_indetVolume->inside((**s).trackParameters()->position())) { lastIDtp = (**s).trackParameters(); }
2115 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
2118 bool redoCaloAssoc =
false;
2120 redoCaloAssoc =
true;
2123 while ((**s).trackParameters() &&
2130 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> caloTSOS;
2133 ATH_MSG_VERBOSE(
" Retriving Calorimeter TSOS from " << __func__ <<
" at line " << __LINE__);
2139 if (caloTSOS.size() < 3) {
2140 ATH_MSG_DEBUG(
" muonTrack: parameters fail to fully intersect the calorimeter");
2144 size += caloTSOS.size();
2145 trackStateOnSurfaces->reserve(
size + 1);
2148 for (std::unique_ptr<const Trk::TrackStateOnSurface>& c_tsos : caloTSOS) { trackStateOnSurfaces->push_back(std::move(c_tsos)); }
2151 trackStateOnSurfaces->reserve(
size + 1);
2156 if (caloEnergy && (**s).trackParameters() &&
m_calorimeterVolume->inside((**s).trackParameters()->position())) {
2158 trackStateOnSurfaces->push_back(TSOS);
2162 if ((**s).trackParameters() &&
m_calorimeterVolume->inside((**s).trackParameters()->position())) {
2163 std::bitset<Trk::MaterialEffectsBase::NumberOfMaterialEffectsTypes> typePattern;
2166 std::unique_ptr<Trk::MaterialEffectsOnTrack> materialEffects =
2167 std::make_unique<Trk::MaterialEffectsOnTrack>(0., std::move(caloEnergy), (**s).trackParameters()->associatedSurface(), typePattern);
2171 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
type;
2175 trackStateOnSurfaces->push_back(TSOS);
2184 bool hasAlreadyPerigee =
false;
2187 while ((**s).trackParameters() &&
m_calorimeterVolume->inside((**s).trackParameters()->position())) {
2190 trackStateOnSurfaces->push_back(TSOS);
2196 std::unique_ptr<Trk::TrackStateOnSurface> entranceTSOS;
2200 if (!hasAlreadyPerigee) {
2201 if ((**s).trackParameters()) {
2204 entranceTSOS =
entrancePerigee(ctx, trackStateOnSurfaces->back()->trackParameters());
2213 << (**s).trackParameters()->position().perp() <<
" z " << (**s).trackParameters()->position().z());
2215 trackStateOnSurfaces->push_back(std::move(entranceTSOS));
2216 hasAlreadyPerigee =
true;
2225 if (!hasAlreadyPerigee && std::find_if(trackStateOnSurfaces->begin(), trackStateOnSurfaces->end(),
2227 return tsos->type(Trk::TrackStateOnSurface::Perigee);
2231 std::stable_sort(trackStateOnSurfaces->begin(),trackStateOnSurfaces->end(),
2233 return a->type(Trk::TrackStateOnSurface::Perigee) > b->type(Trk::TrackStateOnSurface::Perigee);
2235 ATH_MSG_DEBUG(__FILE__<<
":"<<__LINE__<<
" No track perigee parameters were added. Copy the existing ones from the muon track");
2237 std::unique_ptr<Trk::Track> newMuonTrack = std::make_unique<Trk::Track>(muonTrack.
info(), std::move(trackStateOnSurfaces),
nullptr);
2238 unsigned int num_ms{0}, num_precMS{0};
2245 if (num_precMS < 3 || num_ms < 5) {
2246 ATH_MSG_VERBOSE(__FILE__
":"<<__LINE__<<
" MS track with too few meausrements constructed "<<std::endl<<
2256 return newMuonTrack;
2263 covarianceMatrix.setZero();
2264 covarianceMatrix(0, 0) = s_sigmaPhiSector * s_sigmaPhiSector *
parameters->position().perp2();
2266 std::unique_ptr<Trk::PseudoMeasurementOnTrack> pseudo = std::make_unique<Trk::PseudoMeasurementOnTrack>(
2268 std::move(covarianceMatrix),
2277 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> spectrometerTSOS;
2281 if (!measuredPerigee)
2283 else if (!measuredPerigee->covariance())
2286 ATH_MSG_DEBUG(
"createSpectrometerTSOS::perigee covariance not valid");
2287 return spectrometerTSOS;
2296 unsigned numberPseudo =
m_trackQuery->numberPseudoMeasurements(spectrometerTrack);
2297 if (errorPhi > s_sigmaPhiSector) { ++numberPseudo; }
2299 if (numberPseudo > 1 && !
m_trackQuery->isSectorOverlap(spectrometerTrack)) {
2303 if (tsos) { spectrometerTSOS.emplace_back(std::move(tsos)); }
2308 bool haveMeasurement =
false;
2310 std::vector<const Trk::Surface*> measurementSurfaces;
2313 unsigned numberMaterial{0}, numberParameters{0};
2316 std::unique_ptr<const Trk::TrackStateOnSurface> previousTSOS;
2320 if (!haveMeasurement) {
2321 if (
s->measurementOnTrack()) {
2322 haveMeasurement =
true;
2323 }
else if (
s->materialEffectsOnTrack()) {
2331 if (
s->materialEffectsOnTrack()) ++numberMaterial;
2332 if (trackParameters) ++numberParameters;
2336 if (!
s->measurementOnTrack() && !
s->materialEffectsOnTrack()) {
2343 if (
s->trackParameters()) {
2344 ATH_MSG_DEBUG(
"createSpectrometerTSOS:: skip unrecognized TSOS " <<
s->dumpType() <<
" r "
2345 <<
s->trackParameters()->position().perp() <<
" z "
2346 <<
s->trackParameters()->position().z());
2355 bool trapezoid =
false;
2356 bool rotatedTrap =
false;
2357 if (
s->measurementOnTrack()) {
2364 const Trk::Surface* surface = &
s->measurementOnTrack()->associatedSurface();
2366 if (previousSurface) {
deltaZ = std::abs(previousSurface->
center().z() - surface->
center().z()); }
2377 if (previousSurface &&
2378 std::find(measurementSurfaces.begin(), measurementSurfaces.end(), surface) != measurementSurfaces.end()) {
2383 measurementSurfaces.push_back(surface);
2384 previousSurface = surface;
2386 }
else if (previousTSOS) {
2387 spectrometerTSOS.emplace_back(std::move(previousTSOS));
2391 std::unique_ptr<const Trk::TrackStateOnSurface> TSOS(
s->clone());
2395 spectrometerTSOS.emplace_back(std::move(TSOS));
2396 TSOS = std::move(previousTSOS);
2398 spectrometerTSOS.emplace_back(std::move(previousTSOS));
2403 previousTSOS.swap(TSOS);
2407 spectrometerTSOS.emplace_back(std::move(TSOS));
2410 if (previousTSOS) spectrometerTSOS.emplace_back(std::move(previousTSOS));
2413 << numberMaterial <<
" have MaterialEffects and " << numberParameters
2414 <<
" have TrackParameters");
2416 return spectrometerTSOS;
2423 if (!spectrometerEntrance)
return nullptr;
2425 std::unique_ptr<Trk::TrackParameters> entranceParameters{
2428 if (!entranceParameters)
return nullptr;
2431 std::unique_ptr<Trk::TrackParameters> trackParameters{
m_extrapolator->extrapolateDirectly(ctx, *entranceParameters, surface)};
2433 if (!trackParameters)
return nullptr;
2435 std::unique_ptr<Trk::Perigee> perigee =
2436 std::make_unique<Trk::Perigee>(trackParameters->position(), trackParameters->momentum(), trackParameters->charge(), std::move(surface));
2441 const EventContext& ctx,
bool& badlyDeterminedCurvature,
const Trk::Track& spectrometerTrack,
const Trk::RecVertex* mvertex,
2443 badlyDeterminedCurvature =
false;
2446 if (!measuredPerigee || !measuredPerigee->covariance()) {
2460 double errorP = std::sqrt(measuredPerigee->momentum().mag2() * (*measuredPerigee->covariance())(
Trk::qOverP,
Trk::qOverP));
2463 std::unique_ptr<Trk::TrackParameters> correctedParameters{};
2465 double trackEnergy = 1. / std::abs(parameterVector[
Trk::qOverP]);
2479 bool curvatureOK =
false;
2496 std::unique_ptr<CaloEnergy> caloEnergy{
2499 if (trackEnergy + caloEnergy->deltaE() <
m_minEnergy) {
2505 correctedParameters =
parameters->associatedSurface().createUniqueTrackParameters(
2512 double spectrometerEnergyLoss = 0.;
2516 for (;
s != sEnd; ++
s) {
2517 if (!(**s).materialEffectsOnTrack()) {
continue; }
2524 if (std::abs(spectrometerEnergyLoss) > 1.5 * std::abs(caloEnergy->deltaE())) {
2525 curvatureOK =
false;
2526 ATH_MSG_DEBUG(
"standaloneFit: excessive energy loss in spectrometer "
2528 <<
" in calo " << std::abs(caloEnergy->deltaE() /
Gaudi::Units::GeV) <<
" GeV");
2535 std::unique_ptr<Trk::TrackParameters> perigee{propagator->
propagate(
2539 ATH_MSG_DEBUG(
"standaloneFit: failed back extrapolation to perigee");
2545 ATH_MSG_DEBUG(
"Track d0 perigee: " << std::abs(perigee->parameters()[
Trk::d0]) <<
" which is smaller than "
2551 double deltaR = (position - perigee->position()).
perp();
2568 correctedParameters =
parameters->associatedSurface().createUniqueTrackParameters(
2577 deltaR = (position - perigee->position()).
perp();
2583 ATH_MSG_VERBOSE(
"standaloneFit: corrected perigee impact " << perigee->parameters()[
Trk::d0] <<
" deltaR, deltaPhi "
2592 correctedParameters =
parameters->associatedSurface().createUniqueTrackParameters(
2605 correctedParameters =
parameters->associatedSurface().createUniqueTrackParameters(
2613 if (!perigee || !
m_indetVolume->inside(perigee->position())) {
2614 if (perigee && perigee->position().z() * perigee->momentum().z() < 0. && perigee->momentum().eta() > 2.0) {
2615 ATH_MSG_DEBUG(
"standaloneFit: halo candidate, perigee at R " << perigee->position().perp() <<
" Z "
2616 << perigee->position().z());
2618 ATH_MSG_DEBUG(
"standaloneFit: perigee outside indet volume");
2625 badlyDeterminedCurvature =
true;
2628 std::unique_ptr<const Trk::TrackParameters> trigParameters{
m_trackQuery->triggerStationParameters(spectrometerTrack, ctx)};
2633 if (trigParameters) {
2635 <<
" start with line from origin to 1st trigger station ");
2638 <<
" start with line from origin to 1st measurement ");
2642 std::unique_ptr<Trk::TrackParameters> perigee =
2643 std::make_unique<Trk::Perigee>(mvertex->
position(),
momentum, 1., *mperigeeSurface);
2649 ATH_MSG_DEBUG(
"standaloneFit: failed back extrapolation to perigee");
2678 if (
checkTrack(
"finalTrackBuild1", recoveredTrack.get())) {
2680 if (chi2After <
m_badFitChi2 || chi2After < chi2Before + 0.1) {
2681 track.swap(recoveredTrack);
2683 ATH_MSG_VERBOSE(
" track rejected by recovery as chi2 " << chi2After <<
" compared to " << chi2Before);
2737 if (
checkTrack(
"finalTrackBuild2", optimizedTrack.get())) {
2738 track.swap(optimizedTrack);
2747 bool directionUpdate,
double deltaPhi,
double deltaTheta)
const {
2750 std::unique_ptr<Trk::TrackParameters> updatedParameters;
2755 if (directionUpdate) {
2756 double cosDeltaPhi = 0.;
2759 if (std::abs(sinDeltaPhi) < 1.) { cosDeltaPhi = std::sqrt(1. - sinDeltaPhi * sinDeltaPhi); }
2761 double cosDeltaTheta = 0.;
2762 double sinDeltaTheta =
std::sin(deltaTheta);
2764 if (std::abs(sinDeltaTheta) < 1.) { cosDeltaTheta = std::sqrt(1. - sinDeltaTheta * sinDeltaTheta); }
2766 double cosTheta = direction.z() * cosDeltaTheta - direction.perp() * sinDeltaTheta;
2767 if (std::abs(cosTheta) < 1.) {
2768 direction =
Amg::Vector3D(direction.x() * cosDeltaPhi - direction.y() * sinDeltaPhi,
2769 direction.y() * cosDeltaPhi + direction.x() * sinDeltaPhi,
2770 direction.perp() * cosTheta / std::sqrt(1. - cosTheta * cosTheta));
2775 direction = direction.unit();
2785 parameters->covariance() ? std::optional<AmgSymMatrix(5)>(*(
parameters->covariance())) : std::nullopt;
2789 if (updatedParameters) {
2800 double perigeeDistance = 0.;
2806 for (;
s != sEnd; ++
s) {
2812 spectrometerMeasurements.push_back((**s).measurementOnTrack()->clone());
2813 if (!(**s).trackParameters() || (perigeeStartValue && (**s).trackParameters()->
position().mag() > perigeeDistance)) {
2817 perigeeDistance = (**s).trackParameters()->position().mag();
2818 perigeeStartValue = (**s).trackParameters();
2823 if (!perigeeStartValue) {
2831 std::unique_ptr<Trk::Track> spectrometerFit =
fit(ctx, spectrometerMeasurements, *perigeeStartValue,
true,
Trk::muon);
2832 if (!spectrometerFit) {
2833 spectrometerFit =
fit(ctx, spectrometerMeasurements, *perigeeStartValue,
false,
Trk::muon);
2835 if (!spectrometerFit) {
2838 if (!spectrometerFit) {
2848 auto mEnd = spectrometerMeasurements.end();
2849 for (;
m != mEnd; ++
m) {
delete *
m; }
2851 return spectrometerFit;
2856 bool limitMomentum =
false;
2857 double momentum =
track->perigeeParameters()->momentum().mag();
2863 if (measuredPerigee) {
2866 while (!(**r).trackParameters()) { --
r; }
2868 limitMomentum =
true;
2870 if (!measuredPerigee->covariance()) {
2871 ATH_MSG_DEBUG(
"measuredPerigee has no covariance, qOverP not set");
2884 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> defaultType;
2885 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
type = defaultType;
2886 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
2888 trackStateOnSurfaces->reserve(
track->trackStateOnSurfaces()->size());
2889 bool is_first{
true};
2892 if (tsos->trackParameters()) {
2893 if (limitMomentum && is_first && tsos->trackParameters()->covariance() &&
2895 Amg::VectorX parameterVector = tsos->trackParameters()->parameters();
2899 std::unique_ptr<Trk::TrackParameters>
parameters =
2900 tsos->trackParameters()->associatedSurface().createUniqueTrackParameters(
2902 parameterVector[
Trk::qOverP], *tsos->trackParameters()->covariance());
2907 std::unique_ptr<Trk::MeasurementBase> measurementBase;
2908 if (tsos->measurementOnTrack()) {
2909 measurementBase = tsos->measurementOnTrack()->
uniqueClone();
2912 trackStateOnSurfaces->push_back(
2915 trackStateOnSurfaces->push_back(tsos->clone());
2923 if (tsos->materialEffectsOnTrack() &&
2924 !
m_calorimeterVolume->inside(tsos->materialEffectsOnTrack()->associatedSurface().globalReferencePoint())) {
2925 if (tsos->measurementOnTrack()) {
2926 Amg::VectorX parameterVector = tsos->trackParameters()->parameters();
2928 std::unique_ptr<Trk::TrackParameters> trackParameters =
2929 tsos->trackParameters()->associatedSurface().createUniqueTrackParameters(
2932 tsos->trackParameters()->covariance() ? std::optional<
AmgSymMatrix(5)>(*tsos->trackParameters()->covariance())
2939 std::unique_ptr<Trk::MeasurementBase> measurementBase;
2940 measurementBase = tsos->measurementOnTrack()->
uniqueClone();
2941 trackStateOnSurfaces->push_back(
2945 }
else if (!tsos->measurementOnTrack() && tsos->trackParameters() &&
2950 if (limitMomentum && tsos->trackParameters()) {
2951 Amg::VectorX parameterVector = tsos->trackParameters()->parameters();
2953 std::unique_ptr<Trk::TrackParameters> trackParameters =
2954 tsos->trackParameters()->associatedSurface().createUniqueTrackParameters(
2957 tsos->trackParameters()->covariance() ? std::optional<
AmgSymMatrix(5)>(*tsos->trackParameters()->covariance())
2962 std::unique_ptr<Trk::MeasurementBase> measurementBase;
2963 if (tsos->measurementOnTrack()) {
2968 measurementBase = tsos->measurementOnTrack()->
uniqueClone();
2971 std::unique_ptr<Trk::MaterialEffectsBase> materialEffects;
2972 if (tsos->materialEffectsOnTrack()) {
2976 materialEffects = tsos->materialEffectsOnTrack()->
uniqueClone();
2978 trackStateOnSurfaces->push_back(
new Trk::TrackStateOnSurface(std::move(measurementBase), std::move(trackParameters),
2979 std::move(materialEffects),
type));
2981 trackStateOnSurfaces->push_back(tsos->clone());
2987 std::unique_ptr<Trk::FitQuality>
fitQuality =
nullptr;
2988 if (
track->fitQuality()) {
fitQuality = std::make_unique<Trk::FitQuality>(*
track->fitQuality()); }
3000 covarianceMatrix.setZero();
3004 double ptInv = 1. /
parameters.momentum().perp();
3006 if (
vertex == mbeamAxis) {
3012 jacobian(0, 0) = -ptInv *
parameters.momentum().y();
3013 jacobian(0, 1) = ptInv *
parameters.momentum().x();
3016 covarianceMatrix =
cov.similarity(jacobian);
3022 jacobian(0, 0) = -ptInv *
parameters.momentum().y();
3023 jacobian(0, 1) = ptInv *
parameters.momentum().x();
3024 jacobian(1, 2) = 1.0;
3027 covarianceMatrix =
cov.similarity(jacobian);
3030 return std::make_unique<Trk::PseudoMeasurementOnTrack>(std::move(localParameters),
3031 std::move(covarianceMatrix),
3054 double idEloss = 0.;
3055 double caloEloss = 0.;
3056 double msEloss = 0.;
3061 double pMuonEntry = 0.;
3063 for (
const auto*
m : *trackTSOS) {
3066 if (
m->trackParameters()) { pMuonEntry =
m->trackParameters()->momentum().mag(); }
3070 if (
id.is_valid()) {
3076 if (pstart == 0 &&
m->trackParameters()) {
3077 pstart =
m->trackParameters()->momentum().mag();
3078 eta =
m->trackParameters()->momentum().eta();
3080 ATH_MSG_DEBUG(
"Start pars found eta " << eta <<
" r " << (
m->trackParameters())->position().perp() <<
" z "
3081 << (
m->trackParameters())->position().z() <<
" pstart " << pstart);
3084 if (
m->materialEffectsOnTrack()) {
3094 pcalo =
m->trackParameters()->momentum().mag();
3100 << pullPhi <<
" deltaTheta (mrad) " << 1000 * scatAngles->
deltaTheta() <<
" sigma "
3107 if (
m->trackParameters()) {
3108 ATH_MSG_DEBUG(
"Eloss found r " << (
m->trackParameters())->position().perp() <<
" z "
3109 << (
m->trackParameters())->position().z() <<
" value " << energyLoss->
deltaE()
3110 <<
" Eloss " << Eloss);
3115 caloEloss = std::abs(energyLoss->
deltaE());
3118 if (
m->trackParameters()) { deltaP =
m->trackParameters()->momentum().mag() - pcalo; }
3123 ATH_MSG_DEBUG(txt <<
" Calorimeter delta p " << deltaP <<
" deltaE " << caloEloss
3124 <<
" delta pID = pcaloEntry-pstart " << pcalo - pstart);
3127 Eloss += std::abs(energyLoss->
deltaE());
3135 Eloss = idEloss + caloEloss + msEloss;
3138 <<
" caloEloss " << caloEloss <<
" msEloss " << msEloss <<
" Total " << Eloss <<
" pstart - pMuonEntry "
3139 << pstart - pMuonEntry);
3155 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> to_ret;
3156 std::unique_ptr<std::vector<const Trk::TrackStateOnSurface*>> tsos_vec{
m_materialUpdator->getCaloTSOS(track_params, me_track)};
3158 to_ret.reserve(tsos_vec->size());