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)
122 << norm *
static_cast<double>(
m_countBeamAxis) <<
"% with beamAxis constraint" <<
endmsg <<
" " << std::setw(4)
123 << std::setprecision(2) << norm *
static_cast<double>(
m_countVertexRegion) <<
"% with vertexRegion constraint"
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 =
182 (surface->
globalReferencePoint() - innerTSOS->materialEffectsOnTrack()->associatedSurface().globalReferencePoint()).mag();
184 if (surfaceOffset > 1. * Gaudi::Units::mm) {
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;
220 if (msgLevel(MSG::DEBUG))
countAEOTs(*muonTrack,
" muonTrack track before fit ");
226 bool haveMS {
false}, perigeeOutside{
false};
229 if (msgLevel(MSG::DEBUG))
countAEOTs(*combinedTrack,
" combinedTrack track after fit ");
231 <<
m_printer->printStations(*combinedTrack));
233 auto rit = combinedTrack->trackStateOnSurfaces()->rbegin();
234 auto ritEnd = combinedTrack->trackStateOnSurfaces()->rend();
235 for (; rit != ritEnd; ++rit) {
236 if (!(**rit).measurementOnTrack() || !(**rit).trackParameters())
continue;
243 ATH_MSG_DEBUG(
"combinedFit:: fail with MS removed by cleaner");
246 if (!combinedTrack->perigeeParameters() || !
m_indetVolume->inside(combinedTrack->perigeeParameters()->position())) {
247 if (!combinedTrack->perigeeParameters()) {
250 ATH_MSG_DEBUG(
" position: r " << combinedTrack->perigeeParameters()->position().perp() <<
" z "
251 << combinedTrack->perigeeParameters()->position().z());
255 perigeeOutside =
true;
259 if (!combinedTrack || !combinedTrack->fitQuality() || !haveMS || perigeeOutside) {
260 bool hasFitQ = combinedTrack ? (combinedTrack->fitQuality() !=
nullptr) :
false;
261 ATH_MSG_DEBUG(
"combinedTrack fails with bad fit" << combinedTrack.get() <<
" " << hasFitQ <<
" " << haveMS <<
" "
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 "
283 << combinedEnergyParameters->
momentum().perp() / Gaudi::Units::GeV <<
" GeV");
285 ATH_MSG_DEBUG(
" iterate combined fit to recollect calorimeter material");
288 const Trk::TrackStates* combinedTSOS = combinedTrack->trackStateOnSurfaces();
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);
302 combinedTrack.swap(refittedTrack);
305 muonTrack.swap(oldTrack);
306 caloEnergy =
caloEnergyParameters(combinedTrack.get(), muonTrack.get(), combinedEnergyParameters, muonEnergyParameters);
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;
335 combinedEnergyParameters->
position().eta(),
336 combinedEnergyParameters->
position().phi());
344 << energyBalance / Gaudi::Units::GeV <<
" signif " << energyBalance / caloEnergy->
sigmaMinusDeltaE()
345 <<
" indet max E " << indetMaxE / Gaudi::Units::GeV << std::endl
346 <<
" param CaloEnergy: " << paramEnergy->deltaE() / Gaudi::Units::GeV <<
" + "
347 << paramEnergy->sigmaPlusDeltaE() / Gaudi::Units::GeV <<
" for P "
348 << combinedEnergyParameters->
momentum().mag() / Gaudi::Units::GeV <<
" eta "
349 << combinedEnergyParameters->
position().eta() <<
" phi " << combinedEnergyParameters->
position().phi()
350 <<
endmsg <<
" tail-param energy diff "
351 << (caloEnergy->
deltaE() - paramEnergy->deltaE()) / Gaudi::Units::GeV);
353 ATH_MSG_VERBOSE(
"Calling createMuonTrack from " << __func__ <<
" at line " << __LINE__);
355 createMuonTrack(ctx, extrapolatedTrack,
nullptr, std::move(paramEnergy), muonTrack->trackStateOnSurfaces());
359 if (refittedTrack) { combinedTrack.swap(refittedTrack); }
365 if (!combinedTrack) {
379 std::unique_ptr<Trk::Track> newTrack =
addIDMSerrors(combinedTrack.get());
384 if (msgLevel(MSG::DEBUG))
countAEOTs(*newTrack,
" combinedTrack after addIDMSerrors ");
386 dumpCaloEloss(newTrack.get(),
"CB input TSOS after refine IDMS ");
387 std::unique_ptr<Trk::Track> refittedTrack{
fit(ctx, *newTrack,
false,
Trk::muon)};
389 if (msgLevel(MSG::DEBUG))
countAEOTs(*refittedTrack,
" CB fit after refit ");
390 dumpCaloEloss(refittedTrack.get(),
"CB refit after refine IDMS ");
392 if (
checkTrack(
"combinedFit", refittedTrack.get())) {
394 combinedTrack.swap(refittedTrack);
400 if (!
checkTrack(
"addIDMS failed", combinedTrack.get())) {
401 ATH_MSG_DEBUG(
"addIDMS errors failed and original track does not pass checkTrack");
407 return combinedTrack;
412 std::unique_ptr<Trk::TrackParameters> innerParameters,
413 std::unique_ptr<Trk::TrackParameters> middleParameters,
414 std::unique_ptr<Trk::TrackParameters> outerParameters)
const {
415 if (msgLvl(MSG::VERBOSE)) {
416 msg(MSG::VERBOSE) <<
endmsg <<
"indetExtension fit:: " << std::setiosflags(std::ios::fixed);
418 if (innerParameters || middleParameters || outerParameters) {
419 msg(MSG::VERBOSE) <<
" parameters at R,Z ";
421 if (innerParameters) {
422 msg(MSG::VERBOSE) <<
"I:" << std::setw(5) << std::setprecision(0) << innerParameters->position().perp() <<
","
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) {
432 msg(MSG::VERBOSE) <<
"O:" << std::setw(6) << std::setprecision(0) << outerParameters->position().perp() <<
","
433 << std::setw(5) << std::setprecision(0) << outerParameters->position().z();
436 msg(MSG::VERBOSE) <<
" with P ";
438 if (innerParameters) {
439 msg(MSG::VERBOSE) << std::setw(9) << std::setprecision(3) << innerParameters->momentum().mag() / Gaudi::Units::GeV;
442 if (middleParameters) {
443 msg(MSG::VERBOSE) << std::setw(9) << std::setprecision(3) << middleParameters->momentum().mag() / Gaudi::Units::GeV;
446 if (outerParameters) {
447 msg(MSG::VERBOSE) << std::setw(9) << std::setprecision(3) << outerParameters->momentum().mag() / Gaudi::Units::GeV;
452 msg(MSG::VERBOSE) <<
" without parameters" <<
endmsg;
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()) {
480 frontParameters = innerParameters->uniqueClone();
483 frontParameters = propagator->
propagate(ctx, *innerParameters, spectrometerMeasurements.front()->associatedSurface(),
486 }
else if (middleParameters) {
487 if (middleParameters->associatedSurface() == spectrometerMeasurements.front()->associatedSurface()) {
488 frontParameters = middleParameters->uniqueClone();
491 frontParameters = propagator->
propagate(ctx, *middleParameters, spectrometerMeasurements.front()->associatedSurface(),
496 if (outerParameters) {
497 if (outerParameters->associatedSurface() == spectrometerMeasurements.back()->associatedSurface()) {
498 backParameters = outerParameters->uniqueClone();
501 backParameters = propagator->
propagate(ctx, *outerParameters, spectrometerMeasurements.back()->associatedSurface(),
504 }
else if (middleParameters) {
505 if (middleParameters->associatedSurface() == spectrometerMeasurements.back()->associatedSurface()) {
506 backParameters = middleParameters->uniqueClone();
509 backParameters = propagator->
propagate(ctx, *middleParameters, spectrometerMeasurements.back()->associatedSurface(),
515 std::unique_ptr<Trk::TrackParameters> midParameters;
518 if (middleParameters && innerParameters && outerParameters) {
519 Amg::Vector3D direction = (outerParameters->position() - innerParameters->position()).unit();
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());
526 if (distance < midDistance) {
527 previousDistance = distance;
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(
573 if (msgLevel(MSG::DEBUG))
countAEOTs(muonTrack,
" in detExtension muonTrack ");
575 ATH_MSG_VERBOSE(
"Calling combinedFit from " << __func__ <<
" at line " << __LINE__);
576 std::unique_ptr<Trk::Track> combinedTrack{
combinedFit(ctx, indetTrack, muonTrack, muonTrack)};
577 return combinedTrack;
587 if (
m_trackQuery->isLineFit(inputSpectrometerTrack) && !fieldCache.
toroidOn()) {
return nullptr; }
589 ATH_MSG_DEBUG(
" standaloneFit beam position bs_x " << origin <<
" inputVertex "
592 if (msgLvl(MSG::VERBOSE)) {
593 msg(MSG::VERBOSE) <<
endmsg <<
"==== Start of standaloneFit:: " << std::setiosflags(std::ios::fixed);
595 if (
m_trackQuery->isExtrapolated(inputSpectrometerTrack, ctx)) {
597 msg(MSG::VERBOSE) <<
"extrapolated has lineFit";
599 msg(MSG::VERBOSE) <<
"extrapolated momentum " << std::setprecision(1)
603 msg(MSG::VERBOSE) <<
" at eta " << std::setw(6) << std::setprecision(3)
607 }
else if (!
m_trackQuery->isProjective(inputSpectrometerTrack)) {
608 msg(MSG::VERBOSE) <<
"spectrometer track does not project";
611 msg(MSG::VERBOSE) <<
"spectrometer has lineFit";
613 msg(MSG::VERBOSE) <<
"spectrometer momentum " << std::setprecision(1)
617 msg(MSG::VERBOSE) <<
" at eta " << std::setw(6) << std::setprecision(3)
622 msg(MSG::VERBOSE) <<
" hasCov";
624 msg(MSG::VERBOSE) <<
" noCov ";
627 msg(MSG::VERBOSE) <<
" spectrometer track without PerigeeParameters";
631 msg(MSG::VERBOSE) <<
" fit: chi2 /DoF " << std::setprecision(2) <<
normalizedChi2(inputSpectrometerTrack) <<
" /"
635 if (
m_trackQuery->numberPseudoMeasurements(inputSpectrometerTrack)) {
636 msg(MSG::VERBOSE) <<
" pseudo " <<
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 ");
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");
732 parameters = std::make_unique<Trk::Perigee>(*spectrometerTrack.
perigeeParameters());
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);
757 parameters =
extrapolatedParameters(ctx, badlyDeterminedCurvature, spectrometerTrack, mvertex.get(), mperigeeSurface.get());
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();
806 if (msgLvl(MSG::DEBUG)) {
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)
812 << measuredPerigee->
momentum().mag() / Gaudi::Units::GeV <<
" (GeV), zFirst "
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__);
838 prefit =
createExtrapolatedTrack(ctx, spectrometerTrack, *parameters, particleHypothesis,
false, spectrometerTSOS, vertexInFit,
839 mbeamAxis.get(), mperigeeSurface.get());
842 if (!prefit || !prefit->fitQuality() || !prefit->perigeeParameters()) {
849 bool hasCov = prefit->perigeeParameters() ? (prefit->perigeeParameters()->covariance() !=
nullptr) :
false;
852 if (prefit->perigeeParameters()) { prefitResult.reset(prefit->perigeeParameters()->clone()); }
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());
868 if (ms_entrance && ms_entrance != prefit->trackStateOnSurfaces()->front() && ms_entrance->
trackParameters()) {
870 caloParameters = parameters.get();
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>();
946 trackStateOnSurfaces->reserve(badfit->trackStateOnSurfaces()->size() + 1);
948 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
type{};
950 std::unique_ptr<Trk::PseudoMeasurementOnTrack> vertexInFit =
951 vertexOnTrack(*badfit->perigeeParameters(), mvertex.get(), mbeamAxis.get());
956 std::move(vertexInFit), badfit->perigeeParameters()->uniqueClone(),
nullptr,
type));
959 s != badfit->trackStateOnSurfaces()->end(); ++s) {
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();
981 for (; s != prefit->trackStateOnSurfaces()->end(); ++s) { spectrometerTSOS.emplace_back((**s).clone()); }
983 ATH_MSG_VERBOSE(
"Calling createExtrapolatedTrack from " << __func__ <<
" at line " << __LINE__);
986 vertexInFit, mbeamAxis.get(), mperigeeSurface.get(), prefitResult.get());
987 returnAfterCleaner =
true;
1006 double momentum = parameters->momentum().mag();
1008 bool allowRefit = !badlyDeterminedCurvature;
1012 if (returnAfterCleaner) {
1018 auto s =
extrapolated->trackStateOnSurfaces()->begin();
1019 while (!(**s).trackParameters() ||
m_calorimeterVolume->inside((**s).trackParameters()->position())) {
1026 pRatio = momentum / parameters->momentum().mag();
1035 std::unique_ptr<Trk::Track> track;
1038 if (msgLvl(MSG::VERBOSE)) {
1039 double sinTheta = params_pRat->
momentum().perp() / params_pRat->
momentum().mag();
1042 << pRatio <<
", pT before " << momentum * sinTheta / Gaudi::Units::GeV <<
", after "
1043 << params_pRat->
momentum().perp() / Gaudi::Units::GeV <<
" GeV");
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;
1078 std::unique_ptr<Trk::Track> refinedTrack(
fit(ctx, *track,
false,
Trk::muon));
1079 if (
checkTrack(
"refineFit", refinedTrack.get())) {
1081 track.swap(refinedTrack);
1084 ++improvementsFailed;
1091 std::unique_ptr<Trk::Track> newTrack =
addIDMSerrors(track.get());
1095 if (msgLevel(MSG::DEBUG))
countAEOTs(*newTrack,
" SA track after addIDMSerrors ");
1096 dumpCaloEloss(newTrack.get(),
"SA input TSOS after refine IDMS ");
1099 std::unique_ptr<Trk::Track> refittedTrack(
fit(ctx, *newTrack,
false,
Trk::muon));
1100 if (msgLevel(MSG::DEBUG) && refittedTrack) {
countAEOTs(*refittedTrack,
" SA track after refit "); }
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");
1140 if (msgLevel(MSG::DEBUG))
countAEOTs(combinedTrack,
" in standalone Refit input combinedTrack ");
1152 ATH_MSG_DEBUG(
" StandaloneRefit beam position bs_x " << origin);
1159 const Trk::Perigee* measuredPerigee = combinedTrack.perigeeParameters();
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;
1179 unsigned spectrometerPhiQuality =
m_trackQuery->spectrometerPhiQuality(combinedTrack, ctx);
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;
1221 if (materialEffects && parameters &&
m_calorimeterVolume->inside(parameters->position())) {
1225 innerTSOS.reset(cmb_inner_tsos->
clone());
1239 if (s != cmb_end_itr) {
1243 middleParameters = parameters;
1247 materialEffects =
nullptr;
1248 parameters =
nullptr;
1264 double energyDeposit{0.};
1266 std::unique_ptr<Trk::TrackStateOnSurface> middleTSOS;
1268 if (materialEffects && parameters &&
m_calorimeterVolume->inside(parameters->position())) {
1270 middleTSOS.reset(cmb_middle_tsos->
clone());
1277 if (s != cmb_end_itr) {
1282 materialEffects =
nullptr;
1283 parameters =
nullptr;
1298 std::unique_ptr<Trk::TrackStateOnSurface> outerTSOS;
1300 double pInner{0.}, pOuter{0.};
1301 if (materialEffects && parameters &&
m_calorimeterVolume->inside(parameters->position())) {
1303 pOuter = parameters->momentum().mag();
1305 outerTSOS.reset(cmb_outer_tsos->
clone());
1321 if (outerScattering && middleTSOS) {
1322 parameters = middleTSOS->trackParameters();
1325 param_owner =
m_propagator->propagate(ctx, *parameters, middleTSOS->trackParameters()->associatedSurface(),
1327 parameters = param_owner.get();
1332 if (!param_owner) param_owner = parameters->uniqueClone();
1335 pInner = pOuter + energyDeposit;
1338 parameters = param_owner.get();
1347 if (!innerTSOS || !middleTSOS || !outerTSOS || !parameters) {
return nullptr; }
1349 parameters =
nullptr;
1358 std::unique_ptr<Trk::TrackParameters> perigee_owner;
1367 if (!perigee_owner) { perigee_owner = combinedTrack.perigeeParameters()->uniqueClone(); }
1385 param_owner =
m_propagator->propagate(ctx, *param_owner, outerTSOS->trackParameters()->associatedSurface(),
1390 if (!param_owner) {
return nullptr; }
1396 const double deltaTheta = outerTSOS->trackParameters()->momentum().theta() - param_owner->momentum().theta();
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)) {
1540 if (msgLevel(MSG::DEBUG))
countAEOTs(*refittedTrack,
" standaloneRefit final refittedTrack ");
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;
1707 if (!combinedTrack || !muonTrack)
return nullptr;
1719 muonEnergyParameters = (**s).trackParameters();
1722 s = combinedTrack->trackStateOnSurfaces()->begin();
1724 if (++s == combinedTrack->trackStateOnSurfaces()->end()) {
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,
1745 ATH_MSG_DEBUG(
" createExtrapolatedTrack() - " << __LINE__ <<
": pt " << parameters.momentum().perp() <<
" r "
1746 << parameters.position().perp() <<
" z " << parameters.position().z() <<
" cov "
1747 << parameters.covariance() <<
" muonfit " << (particleHypothesis ==
Trk::muon));
1749 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> caloTSOS, leadingTSOS;
1751 std::unique_ptr<const Trk::TrackParameters> track_param_owner;
1755 if (vertex &&
m_indetVolume->inside(parameters.position())) { perigee =
dynamic_cast<const Trk::Perigee*
>(¶meters); }
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; }
1782 Amg::VectorX parameterVector = parameters.parameters();
1784 constexpr double Emax = 50000.;
1789 if (std::abs(parameterVector[
Trk::qOverP]) * Emax < 1) {
1790 parameterVector[
Trk::qOverP] = parameters.charge() / Emax;
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__);
1818 if (msgLevel(MSG::DEBUG)) {
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;
1868 std::unique_ptr<const Trk::TrackStateOnSurface> tsos =
m_caloTSOS->innerTSOS(ctx, parameters);
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();
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) {
1911 <<
" pt " << trackParameters->
momentum().perp());
1917 ATH_MSG_DEBUG(
" back extrapolation problem: retry with tracking out from vertex ");
1922 const Amg::Vector3D momentum = parameters.position().unit() * Gaudi::Units::TeV;
1924 track_param_owner = std::make_unique<Trk::Perigee>(vertex->position(), momentum, 1., *mperigeeSurface);
1925 trackParameters = track_param_owner.get();
1929 ATH_MSG_VERBOSE(
" Retrieving 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()) {
2028 if (msgLevel(MSG::DEBUG))
countAEOTs(*track,
" createExtrapolatedTrack before fit ");
2037 ATH_MSG_VERBOSE(
" fit SA track with " << track->trackStateOnSurfaces()->size() <<
" TSOS"
2039 :
"usig interacting hypothesis"));
2041 std::unique_ptr<Trk::Track> fittedTrack{
fit(ctx, *track, runOutlier, particleHypothesis)};
2043 if (msgLevel(MSG::DEBUG))
countAEOTs(*fittedTrack,
" createExtrapolatedTrack after fit");
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);
2100 size_t size = tsos->
size();
2102 if (msgLevel(MSG::DEBUG))
countAEOTs(muonTrack,
" createMuonTrack ");
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;
2132 if (!lastIDtp) { lastIDtp = parameters; }
2133 ATH_MSG_VERBOSE(
" Retrieving Calorimeter TSOS from " << __func__ <<
" at line " << __LINE__);
2136 caloTSOS =
m_caloTSOS->caloTSOS(ctx, *parameters);
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());
2207 double distance = (entranceTSOS->trackParameters()->position() - (**s).trackParameters()->position()).mag();
2209 if (distance > 2000) {
2211 <<
" r " << entranceTSOS->trackParameters()->position().perp() <<
" z "
2212 << entranceTSOS->trackParameters()->position().z() <<
" track pars r "
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<<
2247 m_printer->print(newMuonTrack->measurementsOnTrack()->stdcont()) );
2256 return newMuonTrack;
2261 auto parameters =
m_trackQuery->spectrometerParameters(track, ctx);
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),
2269 parameters->associatedSurface());
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()) {
2330 if (msgLvl(MSG::VERBOSE)) {
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());
2394 if (trapezoid && deltaZ < 1. * Gaudi::Units::mm) {
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;
2421 if (!parameters)
return nullptr;
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()) {
2453 auto parameters =
m_trackQuery->spectrometerParameters(spectrometerTrack, ctx);
2454 if (!parameters || !parameters->covariance()) {
2463 std::unique_ptr<Trk::TrackParameters> correctedParameters{};
2464 Amg::VectorX parameterVector = parameters->parameters();
2465 double trackEnergy = 1. / std::abs(parameterVector[
Trk::qOverP]);
2470 parameterVector[
Trk::qOverP] = parameters->charge() / trackEnergy;
2472 parameters = parameters->associatedSurface().createUniqueTrackParameters(
2479 bool curvatureOK =
false;
2488 }
else if (std::abs(parameters->position().z()) <
m_zECToroid &&
2496 std::unique_ptr<CaloEnergy> caloEnergy{
2497 m_caloEnergyParam->energyLoss(ctx, trackEnergy, parameters->position().eta(), parameters->position().phi())};
2499 if (trackEnergy + caloEnergy->deltaE() <
m_minEnergy) {
2504 parameterVector[
Trk::qOverP] = parameters->charge() / (trackEnergy + caloEnergy->deltaE());
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 "
2527 << std::abs(spectrometerEnergyLoss / Gaudi::Units::GeV) <<
" GeV"
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(
2604 parameterVector[
Trk::qOverP] = parameters->charge() / trackEnergy;
2605 correctedParameters = parameters->associatedSurface().createUniqueTrackParameters(
2609 parameters = std::move(correctedParameters);
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;
2626 Amg::Vector3D momentum = parameters->position().unit() * Gaudi::Units::TeV;
2628 std::unique_ptr<const Trk::TrackParameters> trigParameters{
m_trackQuery->triggerStationParameters(spectrometerTrack, ctx)};
2630 if (trigParameters) { momentum = trigParameters->position().unit() * Gaudi::Units::TeV; }
2632 if (msgLvl(MSG::VERBOSE)) {
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");
2662 if (msgLevel(MSG::DEBUG))
countAEOTs(*track,
" finalTrackBuilt input ");
2669 std::unique_ptr<Trk::Track> recoveredTrack{
m_muonHoleRecovery->recover(*track, ctx)};
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);
2734 countAEOTs(*track,
" before optimize ") == 0) {
2736 std::unique_ptr<Trk::Track> optimizedTrack =
m_muonErrorOptimizer->optimiseErrors(*track, ctx);
2737 if (
checkTrack(
"finalTrackBuild2", optimizedTrack.get())) {
2738 track.swap(optimizedTrack);
2739 if (msgLevel(MSG::DEBUG))
countAEOTs(*track,
" finalTrackBuilt alignment errors Track ");
2747 bool directionUpdate,
double deltaPhi,
double deltaTheta)
const {
2748 if (!parameters)
return;
2750 std::unique_ptr<Trk::TrackParameters> updatedParameters;
2755 if (directionUpdate) {
2756 double cosDeltaPhi = 0.;
2757 double sinDeltaPhi = std::sin(
deltaPhi);
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();
2782 double charge = parameters->charge();
2785 parameters->covariance() ? std::optional<AmgSymMatrix(5)>(*(parameters->covariance())) : std::nullopt;
2786 const Trk::Surface* surface = &(parameters->associatedSurface());
2789 if (updatedParameters) {
2790 parameters = std::move(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) {
2845 if (spectrometerFit) { spectrometerFit->info().addPatternReco(spectrometerTrack.
info()); }
2847 Trk::MeasurementSet::iterator m = spectrometerMeasurements.begin();
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();
2861 const Trk::Perigee* measuredPerigee = track->perigeeParameters();
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");
2872 qOverP = (**r).trackParameters()->parameters()[
Trk::qOverP];
2874 qOverP = (**r).trackParameters()->parameters()[
Trk::qOverP] +
2877 ATH_MSG_DEBUG(
" limit momentum to " << 1. / std::abs(qOverP * Gaudi::Units::GeV) <<
" from original value "
2878 << momentum / Gaudi::Units::GeV);
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();
2927 if (limitMomentum) { parameterVector[
Trk::qOverP] = qOverP; }
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()); }
2990 track = std::make_unique<Trk::Track>(
trackInfo, std::move(trackStateOnSurfaces), std::move(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();
3015 const Amg::MatrixX& cov = vertex->covariancePosition();
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;
3026 const Amg::MatrixX& cov = vertex->covariancePosition();
3027 covarianceMatrix = cov.similarity(jacobian);
3030 return std::make_unique<Trk::PseudoMeasurementOnTrack>(std::move(localParameters),
3031 std::move(covarianceMatrix),
3037 if (!track || !msgLevel(MSG::DEBUG))
return;
3038 if (!
m_trackQuery->isCaloAssociated(*track, Gaudi::Hive::currentContext())) {
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;
3137 ATH_MSG_DEBUG(txt <<
" eta " <<
eta <<
" pstart " << pstart / Gaudi::Units::GeV <<
" Eloss on TSOS idEloss " << idEloss
3138 <<
" caloEloss " << caloEloss <<
" msEloss " << msEloss <<
" Total " << Eloss <<
" pstart - pMuonEntry "
3139 << pstart - pMuonEntry);
3151 return handle.
cptr()->trackingVolume(vol_name);
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());
Scalar eta() const
pseudorapidity method
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
#define AmgSymMatrix(dim)
Wrapper to avoid constant divisions when using units.
class extending the basic Trk::EnergyLoss to describe the measured or parameterised muon energy loss ...
CaloEnergy::EnergyLossType energyLossType(void) const
Accessor methods.
DataModel_detail::const_iterator< DataVector > const_iterator
value_type push_back(value_type pElem)
Add an element to the end of the collection.
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.
std::reverse_iterator< const_iterator > const_reverse_iterator
size_type size() const noexcept
Returns the number of elements in the collection.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOS(std::unique_ptr< Trk::MeasurementBase > meas, std::unique_ptr< Trk::TrackParameters > pars, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
create a TSOS with a measurement, takes ownership of the pointers
static std::unique_ptr< Trk::TrackStateOnSurface > createPerigeeTSOS(std::unique_ptr< Trk::TrackParameters > perigee)
create a perigee TSOS, takes ownership of the Perigee
void removeSpectrometerMaterial(std::unique_ptr< Trk::Track > &track) const
virtual StatusCode finalize() override
ToolHandle< Trk::IMaterialAllocator > m_materialAllocator
std::unique_ptr< Trk::Track > createMuonTrack(const EventContext &ctx, const Trk::Track &muonTrack, const Trk::TrackParameters *parameters, std::unique_ptr< CaloEnergy > caloEnergy, const Trk::TrackStates *tsos) const
Summarizes the available information about the ID track, the deposited calorimeter energies and the t...
ToolHandle< Trk::IPropagator > m_propagator
ToolHandle< Muon::IMuonHoleRecoveryTool > m_muonHoleRecovery
static std::unique_ptr< Trk::PseudoMeasurementOnTrack > vertexOnTrack(const Trk::TrackParameters ¶meters, const Trk::RecVertex *vertex, const Trk::RecVertex *mbeamAxis)
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_cscRotCreator
Gaudi::Property< bool > m_addElossID
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
Gaudi::Property< double > m_lineMomentum
ToolHandle< Trk::IPropagator > m_propagatorSL
std::atomic_uint m_countBeamAxis
void appendSelectedTSOS(Trk::TrackStates &trackStateOnSurfaces, Trk::TrackStates::const_iterator begin, Trk::TrackStates::const_iterator end) const
Gaudi::Property< double > m_largeImpact
ToolHandle< Trk::IExtrapolator > m_extrapolator
virtual StatusCode initialize() override
PublicToolHandle< Muon::IMuonAlignmentUncertTool > m_alignUncertTool_theta
ToolHandles to retrieve the uncertainties for theta and phi for the scattering uncertainties.
virtual std::unique_ptr< Trk::Track > standaloneFit(const EventContext &ctx, const Trk::Track &spectrometerTrack, const Amg::Vector3D &bs, const Trk::Vertex *vertex) const override
ICombinedMuonTrackBuilder interface: propagate to perigee adding calo energy-loss and material to MS ...
Gaudi::Property< bool > m_useRefitTrackError
Gaudi::Property< bool > m_refineELossStandAloneTrackFit
Gaudi::Property< double > m_vertex3DSigmaZ
Gaudi::Property< bool > m_perigeeAtSpectrometerEntrance
std::unique_ptr< Trk::TrackStateOnSurface > createPhiPseudoMeasurement(const EventContext &ctx, const Trk::Track &track) const
Gaudi::Property< bool > m_reallocateMaterial
std::unique_ptr< Trk::TrackStateOnSurface > entrancePerigee(const EventContext &ctx, const Trk::TrackParameters *parameters) const
std::vector< std::unique_ptr< const Trk::TrackStateOnSurface > > createSpectrometerTSOS(const EventContext &ctx, const Trk::Track &spectrometerTrack) const
virtual std::unique_ptr< Trk::Track > combinedFit(const EventContext &ctx, const Trk::Track &indetTrack, const Trk::Track &extrapolatedTrack, const Trk::Track &spectrometerTrack) const override
ICombinedMuonTrackBuilder interface: build and fit combined ID/Calo/MS track.
virtual ~CombinedMuonTrackBuilder()
ToolHandle< Rec::IMuidCaloEnergy > m_caloEnergyParam
PublicToolHandle< Muon::IMuonAlignmentUncertTool > m_alignUncertTool_phi
std::unique_ptr< Trk::Track > createIndetTrack(const Trk::TrackInfo &info, const Trk::TrackStates *tsos) const
void dumpCaloEloss(const Trk::Track *track, const std::string &txt) const
std::atomic_uint m_countDegradedStandaloneFit
const Trk::TrackingVolume * getVolume(const EventContext &ctx, const std::string &&vol_name) const
Gaudi::Property< bool > m_refineELossCombinedTrackFit
std::unique_ptr< Trk::Track > reallocateMaterial(const EventContext &ctx, const Trk::Track &spectrometerTrack) const
Gaudi::Property< bool > m_iterateCombinedTrackFit
Gaudi::Property< bool > m_cleanStandalone
const CaloEnergy * caloEnergyParameters(const Trk::Track *combinedTrack, const Trk::Track *muonTrack, const Trk::TrackParameters *&combinedEnergyParameters, const Trk::TrackParameters *&muonEnergyParameters) const
SG::ReadCondHandleKey< Trk::TrackingGeometry > m_trackingGeometryReadKey
std::unique_ptr< Trk::Track > addIDMSerrors(const Trk::Track *track) const
ToolHandle< Muon::IMdtDriftCircleOnTrackCreator > m_mdtRotCreator
std::vector< std::unique_ptr< const Trk::TrackStateOnSurface > > getCaloTSOSfromMatProvider(const Trk::TrackParameters &track_params, const Trk::Track &me_track) const
Helper method to retrieve the CaloTSO from the Material provider in a memory safe way.
Gaudi::Property< bool > m_addIDMSerrors
std::unique_ptr< const Trk::RecVertex > m_beamAxis
Gaudi::Property< double > m_largeMomentumChange
std::unique_ptr< const Trk::RecVertex > m_vertex
Gaudi::Property< double > m_vertex2DSigmaZ
Gaudi::Property< double > m_largeMomentumError
std::atomic_uint m_countVertexRegion
std::unique_ptr< const Trk::PerigeeSurface > m_perigeeSurface
std::unique_ptr< Trk::Track > createExtrapolatedTrack(const EventContext &ctx, const Trk::Track &spectrometerTrack, const Trk::TrackParameters ¶meters, Trk::ParticleHypothesis particleHypothesis, Trk::RunOutlierRemoval runOutlier, const std::vector< std::unique_ptr< const Trk::TrackStateOnSurface > > &trackStateOnSurfaces, const Trk::RecVertex *vertex, const Trk::RecVertex *mbeamAxis, const Trk::PerigeeSurface *mperigeeSurface, const Trk::Perigee *seedParameter=nullptr) const
Gaudi::Property< double > m_largePhiError
Trk::MagneticFieldProperties m_magFieldProperties
Gaudi::Property< double > m_lowMomentum
Gaudi::Property< double > m_vertex3DSigmaRPhi
virtual std::unique_ptr< Trk::Track > standaloneRefit(const EventContext &ctx, const Trk::Track &combinedTrack, const Amg::Vector3D &vec) const override
ICombinedMuonTrackBuilder interface: refit a track removing any indet measurements with optional addi...
virtual std::unique_ptr< Trk::Track > indetExtension(const EventContext &ctx, const Trk::Track &indetTrack, const Trk::MeasurementSet &spectrometerMeas, std::unique_ptr< Trk::TrackParameters > innerParameters, std::unique_ptr< Trk::TrackParameters > middleParameters, std::unique_ptr< Trk::TrackParameters > outerParameters) const override
ICombinedMuonTrackBuilder interface: build and fit indet track extended to include MS Measurement set...
void momentumUpdate(std::unique_ptr< Trk::TrackParameters > ¶meters, double updatedP, bool directionUpdate=false, double deltaPhi=0., double deltaTheta=0.) const
void finalTrackBuild(const EventContext &ctx, std::unique_ptr< Trk::Track > &track) const
CombinedMuonTrackBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< double > m_minEnergy
Gaudi::Property< bool > m_cleanCombined
Gaudi::Property< double > m_numberSigmaFSR
std::unique_ptr< Trk::TrackParameters > extrapolatedParameters(const EventContext &ctx, bool &badlyDeterminedCurvature, const Trk::Track &spectrometerTrack, const Trk::RecVertex *mvertex, const Trk::PerigeeSurface *mperigeeSurface) const
std::atomic_uint m_countAcceptedStandaloneFit
Gaudi::Property< double > m_vertex2DSigmaRPhi
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_muClusterRotCreator
ToolHandle< Muon::IMuonErrorOptimisationTool > m_muonErrorOptimizer
ToolHandle< Trk::ITrkMaterialProviderTool > m_materialUpdator
Gaudi::Property< bool > m_useCaloTG
Gaudi::Property< double > m_badFitChi2
Gaudi::Property< double > m_zECToroid
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
virtual StatusCode initialize() override
std::unique_ptr< MessageHelper > m_messageHelper
ToolHandle< Trk::ITrackSummaryTool > m_trackSummary
ToolHandle< Rec::IMuidCaloTrackStateOnSurface > m_caloTSOS
virtual std::unique_ptr< Trk::Track > fit(const EventContext &ctx, const Trk::Track &track, const Trk::RunOutlierRemoval runOutlier, const Trk::ParticleHypothesis particleHypothesis) const override
double normalizedChi2(const Trk::Track &track) const
unsigned int countAEOTs(const Trk::Track &track, const std::string &txt) const
std::unique_ptr< const Trk::Volume > m_calorimeterVolume
bool checkTrack(std::string_view txt, const Trk::Track *newTrack) const
virtual StatusCode finalize() override
bool loadMagneticField(const EventContext &ctx, MagField::AtlasFieldCache &field_cache) const
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
Gaudi::Property< bool > m_updateWithCaloTG
std::unique_ptr< const Trk::Volume > m_indetVolume
ToolHandle< Rec::IMuonTrackQuery > m_trackQuery
const_pointer_type cptr()
This class describes energy loss material effects in the ATLAS tracking EDM.
double sigmaMinusDeltaE() const
returns the negative side
double sigmaDeltaE() const
returns the symmatric error
double deltaE() const
returns the
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
std::vector< std::unique_ptr< const TrackStateOnSurface > > Garbage_t
Interface class IPropagators It inherits from IAlgTool.
virtual std::unique_ptr< NeutralParameters > propagate(const NeutralParameters ¶meters, const Surface &sf, PropDirection dir, const BoundaryCheck &bcheck, bool returnCurv=false) const =0
Main propagation method for NeutralParameters.
base class to integrate material effects on Trk::Track in a flexible way.
@ ScatteringEffects
contains material effects due to multiple scattering
@ EnergyLossEffects
contains energy loss corrections
double thicknessInX0() const
returns the actually traversed material .
represents the full description of deflection and e-loss of a track in material.
const EnergyLoss * energyLoss() const
returns the energy loss object.
const ScatteringAngles * scatteringAngles() const
returns the MCS-angles object.
This class is the pure abstract base class for all fittable tracking measurements.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual constexpr SurfaceType surfaceType() const override=0
Returns the Surface Type enum for the surface used to define the derived class.
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy
const Amg::Vector3D & position() const
Access method for the position.
double charge() const
Returns the charge.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
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...
Class describing the Line to which the Perigee refers to.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Class to handle pseudo-measurements in fitters and on track objects.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
Trk::RecVertex inherits from Trk::Vertex.
Bounds for a rotated trapezoidal, planar Surface.
represents a deflection of the track caused through multiple scattering in material.
double sigmaDeltaPhi() const
returns the
double deltaPhi() const
returns the
double sigmaDeltaTheta() const
returns the
double deltaTheta() const
returns the
Abstract Base Class for tracking surfaces.
virtual ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theat, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const =0
Use the Surface as a ParametersBase constructor, from local parameters - charged.
virtual const Amg::Vector3D & globalReferencePoint() const
Returns a global reference point on the surface, for PlaneSurface, StraightLineSurface,...
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Contains information about the 'fitter' of this track.
@ Unknown
Track fitter not defined.
@ StraightTrack
A straight track.
@ MuidStandaloneRefit
Standalone muon that was obtained by refitting a combined muon using the calorimeter information of t...
represents the track state (measurement, material, fit parameters and quality) at a surface.
virtual TrackStateOnSurface * clone() const
Pseudo-constructor: needed to avoid excessive RTTI.
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
std::string dumpType() const
returns a string with the expanded type of the object (i.e.
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Parameter
This TSOS contains a Trk::ParameterBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
@ Hole
A hole on the track - this is defined in the following way.
@ CaloDeposit
This TSOS contains a CaloEnergy object.
const MaterialEffectsBase * materialEffectsOnTrack() const
return material effects const overload
const AlignmentEffectsOnTrack * alignmentEffectsOnTrack() const
return the the alignment effects const overload
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const Perigee * perigeeParameters() const
return Perigee.
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
Bounds for a trapezoidal, planar Surface.
This class is a simplest representation of a vertex candidate.
const Amg::Vector3D & position() const
return position of vertex
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
bool hasPositiveDiagElems(const AmgSymMatrix(N) &mat)
Returns true if all diagonal elements of the covariance matrix are finite aka sane in the above defin...
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
bool RunOutlierRemoval
switch to toggle quality processing after fit
@ loc2
generic first and second local coordinate
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[