19 #include "AthLinks/ElementLink.h"
52 return StatusCode::SUCCESS;
78 ATH_MSG_DEBUG(
"ID TrackParticle container size "<< importedTrackCollection->
size());
81 std::vector<const xAOD::Muon*> theMuonsAfterSelection;
83 unsigned int nCombMuons = 0;
84 unsigned int nSegmentTaggedMuons = 0;
86 for (
const auto *
muon : *importedMuonCollection) {
87 if ( !
muon )
continue;
88 muonDecorator(*
muon) = -1;
90 if (!
muon->inDetTrackParticleLink().isValid())
continue;
91 auto& link =
muon->inDetTrackParticleLink();
93 if ( !muonTrk )
continue;
96 if ( fabs(muonTrk->
pt())<
m_ptCut )
continue;
99 if (
muon->muonType() == xAOD::Muon::SegmentTagged ) ++nSegmentTaggedMuons;
100 theMuonsAfterSelection.push_back(
muon);
102 unsigned int nSelectedMuons = theMuonsAfterSelection.size();
103 ATH_MSG_DEBUG(
"Number of muons after selection: " << nSelectedMuons);
105 ATH_MSG_DEBUG(
"and " << nSegmentTaggedMuons <<
" are segment tagged");
106 if ( (nSelectedMuons < 4) || (nCombMuons < 1) ) {
108 return StatusCode::SUCCESS;
117 std::sort(theMuonsAfterSelection.begin(), theMuonsAfterSelection.end(), [](
const xAOD::Muon *
a,
const xAOD::Muon *
b) {
118 return b->pt() < a->pt();
122 unsigned int muonIndex(0);
123 for (
auto selMuon : theMuonsAfterSelection) {
124 muonDecorator(*selMuon) = muonIndex;
129 std::vector<Combination> quadruplets;
130 std::vector<Combination>
pairs;
132 if (quadruplets.size()==0) {
134 return StatusCode::SUCCESS;
145 std::vector<const xAOD::TrackParticle*> theTracks = (*pairItr).trackParticles(
"pair1");
147 if (pairVxCandidate) {
149 indexDecorator(*pairVxCandidate) = (*pairItr).combinationIndices();
150 chargeDecorator(*pairVxCandidate) = (*pairItr).combinationCharges();
154 std::vector<const xAOD::Muon*> theStoredMuons;
155 theStoredMuons = (*pairItr).muons;
156 helper.setMuons(theStoredMuons,importedMuonCollection.get());
158 pairVxContainer->
push_back(pairVxCandidate);
159 ATH_MSG_DEBUG(
"..... indices: " << (*pairItr).combinationIndices() <<
160 " charges: " << (*pairItr).combinationCharges() <<
171 std::vector<const xAOD::TrackParticle*> theDCTracks; theDCTracks.clear();
172 theDCTracks = (*quadItr).trackParticles(
"DC");
174 if (dcVxCandidate != 0) {
176 indexDecorator(*dcVxCandidate) = (*quadItr).combinationIndices();
177 chargeDecorator(*dcVxCandidate) = (*quadItr).combinationCharges();
183 const std::vector<const xAOD::Muon*> &theStoredMuons = (*quadItr).muons;
184 helper.setMuons(theStoredMuons,importedMuonCollection.get());
186 quadVxContainer->
push_back(dcVxCandidate);
187 ATH_MSG_DEBUG(
"..... indices: " << (*quadItr).combinationIndices() <<
188 " charges: " << (*quadItr).combinationCharges() <<
189 " chi2(DC): " << dcChi2);
196 return StatusCode::SUCCESS;;
213 if(concreteVertexFitter == 0) {
214 ATH_MSG_FATAL(
"The vertex fitter passed is not a V0 Vertex Fitter");
228 return myVxCandidate;
241 std::vector<std::vector<unsigned int> > quadIndices =
mFromN(4,
length);
253 std::vector<std::vector<unsigned int> > allCombinations;
254 std::vector<unsigned int> mainList;
255 std::vector<unsigned int> combination;
256 for (
unsigned int i=0;
i<
N; ++
i) mainList.push_back(
i);
258 return allCombinations;
263 std::vector<unsigned int> &combination,
264 std::vector<unsigned int> &mainList,
265 std::vector<std::vector<unsigned int> > &allCombinations) {
267 allCombinations.push_back(combination);
271 for (
unsigned int i=
offset;
i<=mainList.size()-
k; ++
i) {
272 combination.push_back(mainList[
i]);
274 combination.pop_back();
285 std::vector<std::pair<unsigned int, unsigned int> > uniquePairs;
286 std::vector<std::vector<unsigned int> > doublets =
mFromN(2,
length);
287 for (std::vector<std::vector<unsigned int> >::
iterator it=doublets.begin();
it!=doublets.end(); ++
it) {
288 std::pair<unsigned int, unsigned int> tmpPair = std::make_pair((*it).at(0),(*it).at(1));
289 uniquePairs.push_back(tmpPair);
304 std::vector<Combination> &
pairs,
305 std::vector<Combination> &quadruplets,
306 unsigned int nSelectedMuons) {
308 std::vector<std::vector<unsigned int> > quadrupletIndices =
getQuadIndices(nSelectedMuons);
309 std::vector<std::pair<unsigned int, unsigned int> > pairIndices =
getPairIndices(nSelectedMuons);
312 std::vector<std::vector<unsigned int> >
::iterator quadItr;
313 for (quadItr=quadrupletIndices.begin(); quadItr!=quadrupletIndices.end(); ++quadItr) {
314 const std::vector<unsigned int> &
quad = (*quadItr);
315 std::vector<const xAOD::Muon*> theMuons = {muonsIn[
quad[0]],muonsIn[
quad[1]],muonsIn[
quad[2]],muonsIn[
quad[3]]};
318 tmpQuad.
muons = std::move(theMuons);
320 quadruplets.emplace_back(std::move(tmpQuad));
322 if (quadruplets.size() == 0)
return;
325 std::vector<std::pair<unsigned int, unsigned int> >
::iterator pairItr;
326 for (pairItr=pairIndices.begin(); pairItr!=pairIndices.end(); ++pairItr) {
327 std::pair<unsigned int, unsigned int> pair = (*pairItr);
329 std::vector<const xAOD::Muon*> theMuons = {muonsIn[pair.first],muonsIn[pair.second]};
330 tmpPair.
muons = std::move(theMuons);
332 pairs.emplace_back(std::move(tmpPair));