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
77 std::vector<const xAOD::Muon*> candidateSAmuons;
79 bool isSA = (
muon->muonType() == xAOD::Muon::MuonStandAlone);
80 bool isCalo = (
muon->muonType() == xAOD::Muon::CaloTagged);
81 bool isSegment = (
muon->muonType() == xAOD::Muon::SegmentTagged);
82 bool isSiForward = (
muon->muonType() == xAOD::Muon::SiliconAssociatedForwardMuon);
90 if (isCalo || isSegment || isSiForward) {
91 ATH_MSG_VERBOSE(
"Skipping non-SA, non-Combined muon type in validation mode!");
104 if (MuSAMSTP->
pt() > 13000000) {
105 ATH_MSG_DEBUG(
"Skipping SA muon with pT " << (MuSAMSTP->
pt() / 1000.) <<
" GeV!");
113 ATH_MSG_DEBUG(
"Skipping SA muon with spectrometerFieldIntegral " <<
muon->spectrometerFieldIntegral <<
" T*m!");
117 candidateSAmuons.push_back(
muon);
121 if (candidateSAmuons.size() < 2) {
123 return StatusCode::SUCCESS;
127 std::vector<std::unique_ptr<xAOD::TrackParticle>> extrapolatedMuSATracks;
128 std::map<const xAOD::TrackParticle*, const xAOD::Muon*> muonToExtrapolatedTrackMap;
129 for (
const auto muon : candidateSAmuons) {
131 auto extrapolatedMuSATrack =
extrapolateMuSA(*MuSAMSTP, eventInfo, ctx);
132 if (extrapolatedMuSATrack->definingParameters()[
Trk::d0] > 8000) {
133 ATH_MSG_DEBUG(
"Failed to extrapolate MuSA track, skipping!");
136 extrapolatedMuSATracks.push_back(std::move(extrapolatedMuSATrack));
137 muonToExtrapolatedTrackMap[extrapolatedMuSATracks.back().get()] =
muon;
138 ATH_MSG_VERBOSE(
"Extrapolated MuSA track! Total extrapolated so far: " << extrapolatedMuSATracks.size());
141 if (extrapolatedMuSATracks.size() < 2) {
143 return StatusCode::SUCCESS;
146 std::unique_ptr<Trk::IVKalState> state =
m_vertexFitter->makeState(ctx);
148 for (
unsigned int i = 0;
i < extrapolatedMuSATracks.size();
i++) {
149 for (
unsigned int j =
i+1; j < extrapolatedMuSATracks.size(); j++) {
151 std::vector<const xAOD::TrackParticle*> tracksToFit = {
152 extrapolatedMuSATracks[
i].get(),
153 extrapolatedMuSATracks[j].get()
155 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
157 MuSACandidate.
pos, MuSACandidate.
mom,
160 MuSACandidate.
chi2, *state);
161 if (
res.isSuccess()) {
165 auto sharedTrack1 = std::make_shared<const xAOD::TrackParticle>(*extrapolatedMuSATracks[
i]);
166 auto sharedTrack2 = std::make_shared<const xAOD::TrackParticle>(*extrapolatedMuSATracks[j]);
170 muonToExtrapolatedTrackMap[tracksToFit[0]],
171 muonToExtrapolatedTrackMap[tracksToFit[1]]
173 MuSACandidate.
minOpAng = muonToExtrapolatedTrackMap[tracksToFit[0]]->p4().DeltaR(
174 muonToExtrapolatedTrackMap[tracksToFit[1]]->p4());
175 workVerticesContainer.emplace_back(MuSACandidate);
183 return StatusCode::SUCCESS;
189 for (
auto& workVertex : workVerticesContainer) {
191 ATH_MSG_DEBUG(
"SA vertex chi2 too high, removing from consideration");
192 workVertex.isGood =
false;
197 workVerticesContainer.erase(std::remove_if(workVerticesContainer.begin(), workVerticesContainer.end(),
200 return StatusCode::SUCCESS;
212 if (workVerticesContainer.size() < 2) {
214 return StatusCode::SUCCESS;
219 ATH_MSG_VERBOSE(
"Sorted vertices by chi2! Lowest chi2: " << workVerticesContainer.front().chi2 <<
" Highest chi2: " << workVerticesContainer.back().chi2);
222 for (
unsigned int i = 0;
i < workVerticesContainer.size();
i++) {
223 auto&
vertex = workVerticesContainer.at(
i);
227 for (
unsigned int j =
i+1; j < workVerticesContainer.size(); j++) {
228 auto& otherVertex = workVerticesContainer.at(j);
229 for (
const auto&
muon :
vertex.muonCandidates) {
230 if (
std::find(otherVertex.muonCandidates.begin(), otherVertex.muonCandidates.end(),
muon) != otherVertex.muonCandidates.end()) {
232 ATH_MSG_VERBOSE(
"Found a vertex re-using a muon with chi2: " << otherVertex.chi2 <<
" removing from consideration!");
233 otherVertex.isGood =
false;
240 workVerticesContainer.erase(std::remove_if(workVerticesContainer.begin(), workVerticesContainer.end(),
243 return StatusCode::SUCCESS;