22 declareInterface<MuSAVtxFitterTool>(
this);
39 return StatusCode::SUCCESS;
49 auto newTrack = std::make_unique<xAOD::TrackParticle>();
50 newTrack->makePrivateStore();
58 newTrack->setDefiningParameters(1.e19, 1.e19, 1.e19, 1.e19, 0);
63 newTrack->setDefiningParametersCovMatrix(*entryPars->covariance());
72 const EventContext& ctx)
const
78 std::vector<const xAOD::Muon*> candidateSAmuons;
80 bool isSA = (muon->muonType() == xAOD::Muon::MuonStandAlone);
81 bool isCalo = (muon->muonType() == xAOD::Muon::CaloTagged);
82 bool isSegment = (muon->muonType() == xAOD::Muon::SegmentTagged);
83 bool isSiForward = (muon->muonType() == xAOD::Muon::SiliconAssociatedForwardMuon);
84 bool isCombined = (muon->muonType() == xAOD::Muon::Combined);
85 bool isStaco = (muon->author() == xAOD::Muon::STACO);
88 bool isStacoRecovery =
false;
90 const xAOD::TrackParticle* msTrk = muon->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
91 const xAOD::TrackParticle* idTrk = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
93 double dEta = std::abs(msTrk->
eta() - idTrk->
eta());
94 double dPhi = std::abs(msTrk->
phi() - idTrk->
phi());
95 if (dPhi >
M_PI) dPhi = 2.0 *
M_PI - dPhi;
97 ATH_MSG_DEBUG(
"Recovering Staco Combined muon with dEta=" << dEta <<
" dPhi=" << dPhi);
98 isStacoRecovery =
true;
107 const xAOD::TrackParticle* MuSAMSTP = muon->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
109 if (isCalo || isSegment || isSiForward) {
110 ATH_MSG_VERBOSE(
"Skipping non-SA, non-Combined muon type in validation mode!");
123 if (MuSAMSTP->
pt() > 13000000) {
124 ATH_MSG_DEBUG(
"Skipping SA muon with pT " << (MuSAMSTP->
pt() / 1000.) <<
" GeV!");
129 float spectrometerFieldIntegral = 0.0;
130 muon->parameter(spectrometerFieldIntegral, xAOD::Muon::spectrometerFieldIntegral);
131 if (spectrometerFieldIntegral < 0.1) {
132 ATH_MSG_DEBUG(
"Skipping SA muon with spectrometerFieldIntegral " << muon->spectrometerFieldIntegral <<
" T*m!");
136 candidateSAmuons.push_back(muon);
140 if (candidateSAmuons.size() < 2) {
142 return StatusCode::SUCCESS;
146 std::vector<std::shared_ptr<xAOD::TrackParticle>> extrapolatedMuSATracks;
147 std::map<const xAOD::TrackParticle*, const xAOD::Muon*> muonToExtrapolatedTrackMap;
148 for (
const auto muon : candidateSAmuons) {
149 const xAOD::TrackParticle* MuSAMSTP = muon->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
150 auto extrapolatedMuSATrack =
extrapolateMuSA(*MuSAMSTP, eventInfo, ctx);
151 if (extrapolatedMuSATrack->definingParameters()[
Trk::d0] > 8000) {
152 ATH_MSG_DEBUG(
"Failed to extrapolate MuSA track, skipping!");
156 extrapolatedMuSATracks.emplace_back(extrapolatedMuSATrack.release());
157 muonToExtrapolatedTrackMap[extrapolatedMuSATracks.back().get()] = muon;
158 ATH_MSG_VERBOSE(
"Extrapolated MuSA track! Total extrapolated so far: " << extrapolatedMuSATracks.size());
161 if (extrapolatedMuSATracks.size() < 2) {
163 return StatusCode::SUCCESS;
166 std::unique_ptr<Trk::IVKalState> state =
m_vertexFitter->makeState(ctx);
167 std::vector<const xAOD::TrackParticle*> tracksToFit(2);
168 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
170 for (
unsigned int i = 0; i < extrapolatedMuSATracks.size(); i++) {
171 for (
unsigned int j = i+1; j < extrapolatedMuSATracks.size(); j++) {
173 tracksToFit[0] = extrapolatedMuSATracks[i].get();
174 tracksToFit[1] = extrapolatedMuSATracks[j].get();
176 MuSACandidate.
pos, MuSACandidate.
mom,
179 MuSACandidate.
chi2, *state);
180 if (
res.isSuccess()) {
185 muonToExtrapolatedTrackMap[tracksToFit[0]],
186 muonToExtrapolatedTrackMap[tracksToFit[1]]
188 MuSACandidate.
minOpAng = muonToExtrapolatedTrackMap[tracksToFit[0]]->p4().DeltaR(
189 muonToExtrapolatedTrackMap[tracksToFit[1]]->p4());
190 workVerticesContainer.emplace_back(std::move(MuSACandidate));
198 return StatusCode::SUCCESS;
204 for (
auto& workVertex : workVerticesContainer) {
206 ATH_MSG_DEBUG(
"SA vertex chi2 too high, removing from consideration");
207 workVertex.isGood =
false;
212 workVerticesContainer.erase(
std::remove_if(workVerticesContainer.begin(), workVerticesContainer.end(),
215 return StatusCode::SUCCESS;
227 if (workVerticesContainer.size() < 2) {
229 return StatusCode::SUCCESS;
234 ATH_MSG_VERBOSE(
"Sorted vertices by chi2! Lowest chi2: " << workVerticesContainer.front().chi2 <<
" Highest chi2: " << workVerticesContainer.back().chi2);
237 for (
unsigned int i = 0; i < workVerticesContainer.size(); i++) {
238 auto& vertex = workVerticesContainer.at(i);
239 if (!vertex.isGood) {
242 for (
unsigned int j = i+1; j < workVerticesContainer.size(); j++) {
243 auto& otherVertex = workVerticesContainer.at(j);
244 for (
const auto& muon : vertex.muonCandidates) {
245 if (std::find(otherVertex.muonCandidates.begin(), otherVertex.muonCandidates.end(), muon) != otherVertex.muonCandidates.end()) {
247 ATH_MSG_VERBOSE(
"Found a vertex re-using a muon with chi2: " << otherVertex.chi2 <<
" removing from consideration!");
248 otherVertex.isGood =
false;
255 workVerticesContainer.erase(
std::remove_if(workVerticesContainer.begin(), workVerticesContainer.end(),
258 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
std::pair< std::vector< unsigned int >, bool > res
xAOD::MuonContainer * muonContainer
Class describing the Line to which the Perigee refers to.
float beamPosX() const
X coordinate of the beam spot position.
float beamPosZ() const
Z coordinate of the beam spot position.
float beamPosY() const
Y coordinate of the beam spot position.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
EventInfo_v1 EventInfo
Definition of the latest event info version.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".