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) {
194 ATH_MSG_WARNING(
"You have no primary vertices: " << pvContainer.cptr()->size());
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) {
238 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
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) {
283 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
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){
433 double chi2DOF = theResult->chiSquared()/theResult->numberDoF();
437 for(
size_t i=0;
i<theResult->trackParticleLinks().size();
i++) {
440 tpLinkVector.push_back( mylink );
442 theResult->clearTracks();
443 theResult->setTrackParticleLinks( tpLinkVector );
447 psi1_helper.setRefTrks();
452 tpLinkVector_psi1.push_back( mylink );
459 psi2_helper.setRefTrks();
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;