15 #include "HepPDT/ParticleDataTable.hh"
26 m_vertexPsi1ContainerKey(
""),
27 m_vertexPsi2ContainerKey(
""),
28 m_outputsKeys({
"Psi1Vtx",
"Psi2Vtx",
"MainVtx"}),
29 m_VxPrimaryCandidateName(
"PrimaryVertices"),
30 m_trackContainerName(
"InDetTrackParticles"),
31 m_eventInfo_key(
"EventInfo"),
32 m_jpsi1MassLower(0.0),
33 m_jpsi1MassUpper(20000.0),
34 m_diTrack1MassLower(-1.0),
35 m_diTrack1MassUpper(-1.0),
37 m_psi1MassUpper(25000.0),
38 m_jpsi2MassLower(0.0),
39 m_jpsi2MassUpper(20000.0),
40 m_diTrack2MassLower(-1.0),
41 m_diTrack2MassUpper(-1.0),
43 m_psi2MassUpper(25000.0),
47 m_vtx1Daug1MassHypo(-1),
48 m_vtx1Daug2MassHypo(-1),
49 m_vtx1Daug3MassHypo(-1),
50 m_vtx1Daug4MassHypo(-1),
52 m_vtx2Daug1MassHypo(-1),
53 m_vtx2Daug2MassHypo(-1),
54 m_vtx2Daug3MassHypo(-1),
55 m_vtx2Daug4MassHypo(-1),
64 m_constrDiTrk1(
false),
67 m_constrDiTrk2(
false),
70 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
71 m_pvRefitter(
"Analysis::PrimaryVertexRefitter",
this),
72 m_V0Tools(
"Trk::V0Tools")
74 declareProperty(
"Psi1Vertices", m_vertexPsi1ContainerKey);
75 declareProperty(
"Psi2Vertices", m_vertexPsi2ContainerKey);
76 declareProperty(
"Psi1VtxHypoNames", m_vertexPsi1HypoNames);
77 declareProperty(
"Psi2VtxHypoNames", m_vertexPsi2HypoNames);
78 declareProperty(
"VxPrimaryCandidateName", m_VxPrimaryCandidateName);
79 declareProperty(
"TrackContainerName", m_trackContainerName);
80 declareProperty(
"RefPVContainerName", m_refPVContainerName =
"RefittedPrimaryVertices");
81 declareProperty(
"Jpsi1MassLowerCut", m_jpsi1MassLower);
82 declareProperty(
"Jpsi1MassUpperCut", m_jpsi1MassUpper);
83 declareProperty(
"DiTrack1MassLower", m_diTrack1MassLower);
84 declareProperty(
"DiTrack1MassUpper", m_diTrack1MassUpper);
85 declareProperty(
"Psi1MassLowerCut", m_psi1MassLower);
86 declareProperty(
"Psi1MassUpperCut", m_psi1MassUpper);
87 declareProperty(
"Jpsi2MassLowerCut", m_jpsi2MassLower);
88 declareProperty(
"Jpsi2MassUpperCut", m_jpsi2MassUpper);
89 declareProperty(
"DiTrack2MassLower", m_diTrack2MassLower);
90 declareProperty(
"DiTrack2MassUpper", m_diTrack2MassUpper);
91 declareProperty(
"Psi2MassLowerCut", m_psi2MassLower);
92 declareProperty(
"Psi2MassUpperCut", m_psi2MassUpper);
93 declareProperty(
"MassLowerCut", m_MassLower);
94 declareProperty(
"MassUpperCut", m_MassUpper);
95 declareProperty(
"HypothesisName", m_hypoName =
"TQ");
96 declareProperty(
"NumberOfPsi1Daughters", m_vtx1Daug_num);
97 declareProperty(
"Vtx1Daug1MassHypo", m_vtx1Daug1MassHypo);
98 declareProperty(
"Vtx1Daug2MassHypo", m_vtx1Daug2MassHypo);
99 declareProperty(
"Vtx1Daug3MassHypo", m_vtx1Daug3MassHypo);
100 declareProperty(
"Vtx1Daug4MassHypo", m_vtx1Daug4MassHypo);
101 declareProperty(
"NumberOfPsi2Daughters", m_vtx2Daug_num);
102 declareProperty(
"Vtx2Daug1MassHypo", m_vtx2Daug1MassHypo);
103 declareProperty(
"Vtx2Daug2MassHypo", m_vtx2Daug2MassHypo);
104 declareProperty(
"Vtx2Daug3MassHypo", m_vtx2Daug3MassHypo);
105 declareProperty(
"Vtx2Daug4MassHypo", m_vtx2Daug4MassHypo);
106 declareProperty(
"MaxCandidates", m_maxCandidates);
107 declareProperty(
"Jpsi1Mass", m_mass_jpsi1);
108 declareProperty(
"DiTrack1Mass", m_mass_diTrk1);
109 declareProperty(
"Psi1Mass", m_mass_psi1);
110 declareProperty(
"Jpsi2Mass", m_mass_jpsi2);
111 declareProperty(
"DiTrack2Mass", m_mass_diTrk2);
112 declareProperty(
"Psi2Mass", m_mass_psi2);
113 declareProperty(
"ApplyJpsi1MassConstraint", m_constrJpsi1);
114 declareProperty(
"ApplyDiTrk1MassConstraint", m_constrDiTrk1);
115 declareProperty(
"ApplyPsi1MassConstraint", m_constrPsi1);
116 declareProperty(
"ApplyJpsi2MassConstraint", m_constrJpsi2);
117 declareProperty(
"ApplyDiTrk2MassConstraint", m_constrDiTrk2);
118 declareProperty(
"ApplyPsi2MassConstraint", m_constrPsi2);
119 declareProperty(
"Chi2Cut", m_chi2cut);
120 declareProperty(
"RefitPV", m_refitPV =
true);
121 declareProperty(
"MaxnPV", m_PV_max = 1000);
122 declareProperty(
"MinNTracksInPV", m_PV_minNTracks = 0);
123 declareProperty(
"DoVertexType", m_DoVertexType = 7);
124 declareProperty(
"TrkVertexFitterTool", m_iVertexFitter);
125 declareProperty(
"PVRefitter", m_pvRefitter);
126 declareProperty(
"V0Tools", m_V0Tools);
127 declareProperty(
"OutputVertexCollections", m_outputsKeys);
167 return StatusCode::SUCCESS;
171 if (m_vtx1Daug_num < 2 || m_vtx1Daug_num > 4 || m_vtx2Daug_num < 2 || m_vtx2Daug_num > 4) {
173 return StatusCode::FAILURE;
176 constexpr
int topoN = 3;
179 return StatusCode::FAILURE;
181 std::array<SG::WriteHandle<xAOD::VertexContainer>, topoN> VtxWriteHandles;
int ikey(0);
184 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
193 if (pvContainer.
cptr()->
size()==0) {
195 return StatusCode::RECOVERABLE;
202 std::vector<const xAOD::TrackParticle*> tracksJpsi1;
203 std::vector<const xAOD::TrackParticle*> tracksDiTrk1;
204 std::vector<const xAOD::TrackParticle*> tracksPsi1;
205 std::vector<const xAOD::TrackParticle*> tracksJpsi2;
206 std::vector<const xAOD::TrackParticle*> tracksDiTrk2;
207 std::vector<const xAOD::TrackParticle*> tracksPsi2;
208 std::vector<const xAOD::TrackParticle*>
inputTracks;
209 std::vector<double> massesPsi1;
214 std::vector<double> massesPsi2;
219 std::vector<double> massesInputTracks;
220 massesInputTracks.reserve(massesPsi1.size() + massesPsi2.size());
221 for(
auto mass : massesPsi1) massesInputTracks.push_back(
mass);
222 for(
auto mass : massesPsi2) massesInputTracks.push_back(
mass);
231 std::vector<const xAOD::Vertex*> selectedPsi1Candidates;
232 for(
auto vxcItr=psi1Container->
cbegin(); vxcItr!=psi1Container->
cend(); ++vxcItr) {
246 double mass_psi1 =
m_V0Tools->invariantMass(*vxcItr, massesPsi1);
247 if (mass_psi1 < m_psi1MassLower || mass_psi1 >
m_psi1MassUpper)
continue;
250 TLorentzVector p4_mu1, p4_mu2;
251 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
252 (*vxcItr)->trackParticle(0)->eta(),
254 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
255 (*vxcItr)->trackParticle(1)->eta(),
257 double mass_jpsi1 = (p4_mu1 + p4_mu2).M();
258 if (mass_jpsi1 < m_jpsi1MassLower || mass_jpsi1 >
m_jpsi1MassUpper)
continue;
261 TLorentzVector p4_trk1, p4_trk2;
262 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
263 (*vxcItr)->trackParticle(2)->eta(),
265 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
266 (*vxcItr)->trackParticle(3)->eta(),
268 double mass_diTrk1 = (p4_trk1 + p4_trk2).M();
272 selectedPsi1Candidates.push_back(*vxcItr);
276 std::vector<const xAOD::Vertex*> selectedPsi2Candidates;
277 for(
auto vxcItr=psi2Container->
cbegin(); vxcItr!=psi2Container->
cend(); ++vxcItr) {
291 double mass_psi2 =
m_V0Tools->invariantMass(*vxcItr,massesPsi2);
292 if(mass_psi2 < m_psi2MassLower || mass_psi2 >
m_psi2MassUpper)
continue;
295 TLorentzVector p4_mu1, p4_mu2;
296 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
297 (*vxcItr)->trackParticle(0)->eta(),
299 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
300 (*vxcItr)->trackParticle(1)->eta(),
302 double mass_jpsi2 = (p4_mu1 + p4_mu2).M();
303 if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 >
m_jpsi2MassUpper)
continue;
306 TLorentzVector p4_trk1, p4_trk2;
307 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
308 (*vxcItr)->trackParticle(2)->eta(),
310 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
311 (*vxcItr)->trackParticle(3)->eta(),
313 double mass_diTrk2 = (p4_trk1 + p4_trk2).M();
316 selectedPsi2Candidates.push_back(*vxcItr);
319 std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
320 for(
auto psi1Itr=selectedPsi1Candidates.cbegin(); psi1Itr!=selectedPsi1Candidates.cend(); ++psi1Itr) {
322 tracksPsi1.reserve((*psi1Itr)->nTrackParticles());
323 for(
size_t i=0;
i<(*psi1Itr)->nTrackParticles();
i++) tracksPsi1.push_back((*psi1Itr)->trackParticle(
i));
324 for(
auto psi2Itr=selectedPsi2Candidates.cbegin(); psi2Itr!=selectedPsi2Candidates.cend(); ++psi2Itr) {
326 for(
size_t j=0; j<(*psi2Itr)->nTrackParticles(); j++) {
327 if(
std::find(tracksPsi1.cbegin(), tracksPsi1.cend(), (*psi2Itr)->trackParticle(j)) != tracksPsi1.cend()) {
skip =
true;
break; }
331 for(
size_t ic=0;
ic<candidatePairs.size();
ic++) {
334 if((psi1Vertex == *psi1Itr && psi2Vertex == *psi2Itr) || (psi1Vertex == *psi2Itr && psi2Vertex == *psi1Itr)) {
skip =
true;
break; }
338 candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*psi1Itr,*psi2Itr));
342 std::sort( candidatePairs.begin(), candidatePairs.end(), [](std::pair<const xAOD::Vertex*, const xAOD::Vertex*>
a, std::pair<const xAOD::Vertex*, const xAOD::Vertex*>
b) { return a.first->chiSquared()/a.first->numberDoF()+a.second->chiSquared()/a.second->numberDoF() < b.first->chiSquared()/b.first->numberDoF()+b.second->chiSquared()/b.second->numberDoF(); } );
344 candidatePairs.erase(candidatePairs.begin()+
m_maxCandidates, candidatePairs.end());
347 for(
size_t ic=0;
ic<candidatePairs.size();
ic++) {
354 if (tracksPsi1.size() != massesPsi1.size()) {
355 ATH_MSG_ERROR(
"Problems with Psi1 input: number of tracks or track mass inputs is not correct!");
360 if (tracksPsi2.size() != massesPsi2.size()) {
361 ATH_MSG_ERROR(
"Problems with Psi2 input: number of tracks or track mass inputs is not correct!");
367 tracksDiTrk1.clear();
375 tracksDiTrk2.clear();
381 TLorentzVector p4_moth;
426 Amg::Vector3D startingPoint((psi1Vertex->
x()+psi2Vertex->
x())/2,(psi1Vertex->
y()+psi2Vertex->
y())/2,(psi1Vertex->
z()+psi2Vertex->
z())/2);
431 if(theResult !=
nullptr){
440 tpLinkVector.push_back( mylink );
452 tpLinkVector_psi1.push_back( mylink );
464 tpLinkVector_psi2.push_back( mylink );
469 VtxWriteHandles[0].ptr()->push_back(psi1Vertex_);
470 VtxWriteHandles[1].ptr()->push_back(psi2Vertex_);
477 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
481 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
484 PrecedingLinksDecor(*theResult.get()) = precedingVertexLinks;
490 VtxWriteHandles[2].ptr()->push_back(theResult.release());
502 ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
504 if(VtxWriteHandles[2]->
size()>0) {
505 for(
int i=0;
i<topoN;
i++) {
508 ATH_MSG_FATAL(
"FillCandwithRefittedVertices failed - check the vertices you passed");
515 if(VtxWriteHandles[2]->
size()>0) {
516 for(
int i=0;
i<topoN;
i++) {
519 ATH_MSG_FATAL(
"FillCandExistingVertices failed - check the vertices you passed");
526 return StatusCode::SUCCESS;