18 #include "Math/Vector4D.h"
25 typedef std::vector<const xAOD::TrackParticle*>
TrackBag;
27 typedef ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >
GenVecFourMom_t;
31 std::array<const xAOD::TrackParticle*, N>
tracks;
41 for(
size_t i =1;
i<
N;
i++) total+= vectors[
i];
46 m_trkSelector(
"InDet::TrackSelectorTool"),
47 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
48 m_V0Tools(
"Trk::V0Tools"),
49 m_CascadeTools(
"DerivationFramework::CascadeTools"),
50 m_pvRefitter(
"Analysis::PrimaryVertexRefitter"),
51 m_cascadeOutputsKeys{
"CascadeVtx1",
"CascadeVtx2" }
53 declareProperty(
"V0Tools", m_V0Tools);
54 declareProperty(
"TrackMassHyp", m_trackMasses);
55 declareProperty(
"CascadeVertexCollections", m_cascadeOutputsKeys);
56 declareProperty(
"TwoTrackMassMin", m_2trackmassMin);
57 declareProperty(
"TwoTrackMassMax", m_2trackmassMax);
58 declareProperty(
"ThreeTrackMassMin", m_3trackmassMin);
59 declareProperty(
"ThreeTrackMassMax", m_3trackmassMax);
60 declareProperty(
"FourTrackMassMin", m_4trackmassMin);
61 declareProperty(
"FourTrackMassMax", m_4trackmassMax);
62 declareProperty(
"TwoTracksMass", m_2tracksMass);
63 declareProperty(
"ThreeTracksMass", m_3tracksMass);
64 declareProperty(
"FourTracksMass", m_4tracksMass);
65 declareProperty(
"TrackSelectorTool",m_trkSelector);
66 declareProperty(
"CascadeTools", m_CascadeTools);
67 declareProperty(
"MinNTracksInPV", m_PV_minNTracks = 0);
68 declareProperty(
"HypothesisName", m_hypoName =
"Bs");
69 declareProperty(
"Track3Name", m_3TrackName =
"Ds");
70 declareProperty(
"MaxnPV", m_PV_max = 999);
71 declareProperty(
"DoVertexType", m_DoVertexType = 7);
72 declareProperty(
"RefitPV", m_refitPV =
true);
73 declareProperty(
"RefPVContainerName", m_refPVContainerName =
"RefittedPrimaryVertices");
74 declareProperty(
"PVRefitter", m_pvRefitter);
75 declareProperty(
"TrkVertexFitterTool", m_iVertexFitter);
76 declareProperty(
"PVContainerName", m_VxPrimaryCandidateName);
77 declareProperty(
"ThreeTrackMassConstraint", m_3TrackMassConstraint);
78 declareProperty(
"TwoTrackMassConstraint", m_2TrackMassConstraint);
79 declareProperty(
"Chi2NDFCut", m_Chi2NDFCut);
81 declareProperty(
"FourTrackMassFinalMin", m_4trackmassFinalMin);
82 declareProperty(
"FourTrackMassFinalMax", m_4trackmassFinalMax);
83 declareProperty(
"FourTrackTauCut", m_tauCut);
84 declareProperty(
"UseMuonsForTracks", m_requireMuonsOnTrack);
85 declareProperty(
"ThreeVertexOutputContainer", m_3TrackVertexOutput);
86 declareProperty(
"VertexEstimator", m_vertexEstimator);
87 declareProperty(
"ThreeTrackChi2NDF", m_3TrackChi2NDFCut);
88 declareProperty(
"EliminateBad3Tracksfrom4Track", m_eliminateBad3Tracksfrom4Track);
89 declareProperty(
"CopyAllVertices", m_copyAllVertices);
90 declareProperty(
"PTCutPerTrack", m_ptCutPerTrack);
91 m_ptCutPerVertex.fill(0);
92 declareProperty(
"PTCutVertex1", m_ptCutPerVertex[0]);
93 declareProperty(
"PTCutVertex2", m_ptCutPerVertex[1]);
94 declareProperty(
"PTCutVertex3", m_ptCutPerVertex[2]);
100 return StatusCode::FAILURE;
104 return StatusCode::FAILURE;
118 return StatusCode::FAILURE;
123 return StatusCode::FAILURE;
127 return StatusCode::FAILURE;
133 return StatusCode::FAILURE;
143 return StatusCode::FAILURE;
147 return StatusCode::SUCCESS;
157 if(ptCut <=0.0)
return tracks;
159 for(
auto ptr : tracks){
160 if(
ptr->pt() > ptCut) cuttracks.push_back(
ptr);
184 refPvContainer->setStore(refPvAuxContainer);
190 std::array<xAOD::VertexContainer*, s_topoN> Vtxwritehandles;
191 std::array<xAOD::VertexAuxContainer*, s_topoN> Vtxwritehandlesaux;
196 Vtxwritehandles[
i]->setStore(Vtxwritehandlesaux[
i]);
204 v3container->setStore(vcontaineraux);
216 if (pvContainer->
size()==0) {
218 return StatusCode::RECOVERABLE;
220 primaryVertex = (*pvContainer)[0];
225 TrackBag theIDTracksAfterAdditionalSelection;
226 for(
auto x : *trackContainer) {
227 if (
m_trkSelector->decision(*
x,
nullptr) ) theIDTracksAfterSelection.push_back(
x);
229 ATH_MSG_DEBUG(
"Found good tracks N="<<theIDTracksAfterSelection.size());
234 for(
auto muon : *importedMuonCollection) {
235 if(
muon->muonType() == xAOD::Muon::SiliconAssociatedForwardMuon)
continue;
236 auto ptr =
muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
237 if(
ptr) theMuonsAfterSelection.push_back(
ptr);
241 std::vector<Candidate<2>> Initialcandidates;
243 const TrackBag &Tracksfor2Vertex =
ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 0);
244 for(
auto track1itr = Tracksfor2Vertex.cbegin(); track1itr != Tracksfor2Vertex.cend(); ++track1itr) {
246 std::array<GenVecFourMom_t, 2> vectors;
247 cand.
tracks[0] = *track1itr;
249 for(
auto track2itr = track1itr+1; track2itr != Tracksfor2Vertex.cend(); ++track2itr) {
250 cand.
tracks[1] = *track2itr;
251 if(cand.
tracks[0]->qOverP() * cand.
tracks[1]->qOverP() >= 0.)
continue;
257 Initialcandidates.push_back(cand);
262 ATH_MSG_DEBUG(
"2 Track candidates found: " << Initialcandidates.size());
263 if(Initialcandidates.empty()) {
265 return StatusCode::SUCCESS;
267 std::vector<Candidate<3>> Candidates3;
270 const TrackBag &Tracksfor3Vertex =
ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 2);
271 for(
auto &
c : Initialcandidates) {
273 std::copy(
c.tracks.begin(),
c.tracks.end(),
c3.tracks.begin());
274 std::array<GenVecFourMom_t, 3> vectors;
275 vectors[0].SetCoordinates(
c.tracks[0]->pt(),
c.tracks[0]->eta(),
c.tracks[0]->phi(),
m_trackMasses[0]);
276 vectors[1].SetCoordinates(
c.tracks[1]->pt(),
c.tracks[1]->eta(),
c.tracks[1]->phi(),
m_trackMasses[1]);
277 for(
auto track3itr = Tracksfor3Vertex.cbegin(); track3itr != Tracksfor3Vertex.cend(); ++track3itr) {
278 if(
std::find(
c3.tracks.begin(),
c3.tracks.end(), *track3itr) !=
c3.tracks.end())
continue;
279 c3.tracks[2] = *track3itr;
280 vectors[2].SetCoordinates(
c3.tracks[2]->pt(),
c3.tracks[2]->eta(),
c3.tracks[2]->phi(),
m_trackMasses[2]);
285 Candidates3.push_back(
c3);
290 Initialcandidates.clear();
291 Initialcandidates.shrink_to_fit();
293 ATH_MSG_DEBUG(
"3 Track candidates found: " << Candidates3.size());
294 std::map<const std::array<const xAOD::TrackParticle*, 3>,
xAOD::Vertex* > threeVertexMap;
300 helper.SetMinNTracksInPV(0);
302 std::vector<const xAOD::TrackParticle*> tracksforfit;
303 std::vector<Candidate<3>> Candidates3PassCuts;
305 for(
const auto &
c3 : Candidates3) {
306 tracksforfit.assign(
c3.tracks.begin(),
c3.tracks.end());
317 threeVertexMap[
c3.tracks] =
v.get();
323 if(v3container->
size() >0)
ATH_CHECK(
helper.FillCandExistingVertices(v3container, pvContainer, 1));
326 ATH_MSG_DEBUG(
"Swapping container to N = "<< Candidates3PassCuts.size() <<
" from " << Candidates3.size());
327 Candidates3PassCuts.swap(Candidates3);
331 std::vector<VertexCand> Candidates4;
333 const TrackBag &Tracksfor4Vertex =
ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 3);
334 for(
auto &
c : Candidates3) {
337 std::array<GenVecFourMom_t, 4> vectors;
338 vectors[0].SetCoordinates(
c.tracks[0]->pt(),
c.tracks[0]->eta(),
c.tracks[0]->phi(),
m_trackMasses[0]);
339 vectors[1].SetCoordinates(
c.tracks[1]->pt(),
c.tracks[1]->eta(),
c.tracks[1]->phi(),
m_trackMasses[1]);
340 vectors[2].SetCoordinates(
c.tracks[2]->pt(),
c.tracks[2]->eta(),
c.tracks[2]->phi(),
m_trackMasses[2]);
341 for(
auto track4itr = Tracksfor4Vertex.cbegin(); track4itr != Tracksfor4Vertex.cend(); ++track4itr) {
343 c4.
tracks[3] = *track4itr;
344 if(c4.
tracks[2]->qOverP() * c4.
tracks[3]->qOverP() >= 0.)
continue;
350 Candidates4.push_back(std::move(c4));
356 Candidates3.shrink_to_fit();
358 ATH_MSG_DEBUG(
"4 Track candidates found: " << Candidates4.size() <<
" running cascade");
359 for(
auto &
c : Candidates4) {
361 if(
c.cascVertex!=
nullptr) {
362 c.cascVertex->setSVOwnership(
true);
392 for(
auto &
c : Candidates4) {
393 if(
c.cascVertex==
nullptr) {
397 auto x =
c.cascVertex.get();
398 const std::vector<xAOD::Vertex*> &cascadeVertices =
x->vertices();
399 if(cascadeVertices.size()!=
s_topoN) {
403 if(cascadeVertices[0] ==
nullptr || cascadeVertices[1] ==
nullptr) {
411 const std::vector< std::vector<TLorentzVector> > &moms =
x->getParticleMoms();
415 double tau =
m_CascadeTools->tau(moms[1],cascadeVertices[1],primaryVertex);
419 for(
int i =0;
i<
s_topoN;
i++) Vtxwritehandles[
i]->push_back(cascadeVertices[
i]);
420 x->setSVOwnership(
false);
421 const auto mainVertex = cascadeVertices[1];
424 std::vector<const xAOD::Vertex*> verticestoLink;
425 verticestoLink.push_back(cascadeVertices[0]);
447 PtErr_decor(*mainVertex) =
m_CascadeTools->pTError(moms[1],
x->getCovariance()[1]);
449 chi2_decor(*mainVertex) =
x->fitChi2();
450 ndof_decor(*mainVertex) =
x->nDoF();
455 Mass_svdecor(*mainVertex) =
m_CascadeTools->invariantMass(moms[0]);
456 MassErr_svdecor(*mainVertex) =
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0]);
458 PtErr_svdecor(*mainVertex) =
m_CascadeTools->pTError(moms[0],
x->getCovariance()[0]);
459 Lxy_svdecor(*mainVertex) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
460 LxyErr_svdecor(*mainVertex) =
m_CascadeTools->lxyError(moms[0],
x->getCovariance()[0], cascadeVertices[0],cascadeVertices[1]);
461 Tau_svdecor(*mainVertex) =
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1]);
462 TauErr_svdecor(*mainVertex) =
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0], cascadeVertices[0],cascadeVertices[1]);
463 if(!threeVertexMap.empty()) {
464 std::array<const xAOD::TrackParticle*, 3> lookuparray;
465 std::copy(
c.tracks.begin(),
c.tracks.begin()+3, lookuparray.begin());
466 auto ptr = threeVertexMap[lookuparray];
473 ATH_MSG_DEBUG(
"Found " << Vtxwritehandles[0]->
size() <<
" candidates " << totalnotnull <<
" were null");
475 return StatusCode::SUCCESS;
480 std::vector<const xAOD::TrackParticle*> tracksDs(
Track.begin(),
Track.begin()+3);
481 std::vector<const xAOD::TrackParticle*> tracksBs(1,
Track[3]);
492 std::vector<Trk::VertexID> vrtList;
495 std::vector<Trk::VertexID> cnstV;
499 vrtList.push_back(vID);
503 auto x = std::unique_ptr<Trk::VxCascadeInfo> (
m_iVertexFitter->fitCascade(*state));
515 if (errorcode != 0) {
516 startingPoint(0) = 0.0;
517 startingPoint(1) = 0.0;
518 startingPoint(2) = 0.0;