170 return StatusCode::FAILURE;
173 constexpr int topoN = 3;
176 return StatusCode::FAILURE;
178 std::array<SG::WriteHandle<xAOD::VertexContainer>, topoN> VtxWriteHandles;
int ikey(0);
181 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
190 if (pvContainer.
cptr()->size()==0) {
192 return StatusCode::RECOVERABLE;
199 std::vector<const xAOD::TrackParticle*> tracksJpsi1;
200 std::vector<const xAOD::TrackParticle*> tracksDiTrk1;
201 std::vector<const xAOD::TrackParticle*> tracksPsi1;
202 std::vector<const xAOD::TrackParticle*> tracksJpsi2;
203 std::vector<const xAOD::TrackParticle*> tracksDiTrk2;
204 std::vector<const xAOD::TrackParticle*> tracksPsi2;
205 std::vector<const xAOD::TrackParticle*> inputTracks;
206 std::vector<double> massesPsi1;
211 std::vector<double> massesPsi2;
216 std::vector<double> massesInputTracks;
217 massesInputTracks.reserve(massesPsi1.size() + massesPsi2.size());
218 for(
auto mass : massesPsi1) massesInputTracks.push_back(mass);
219 for(
auto mass : massesPsi2) massesInputTracks.push_back(mass);
228 std::vector<const xAOD::Vertex*> selectedPsi1Candidates;
229 for(
auto vxcItr=psi1Container->cbegin(); vxcItr!=psi1Container->cend(); ++vxcItr) {
235 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
243 double mass_psi1 =
m_V0Tools->invariantMass(*vxcItr, massesPsi1);
244 if (mass_psi1 < m_psi1MassLower || mass_psi1 >
m_psi1MassUpper)
continue;
247 TLorentzVector p4_mu1, p4_mu2;
248 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
249 (*vxcItr)->trackParticle(0)->eta(),
251 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
252 (*vxcItr)->trackParticle(1)->eta(),
254 double mass_jpsi1 = (p4_mu1 + p4_mu2).M();
255 if (mass_jpsi1 < m_jpsi1MassLower || mass_jpsi1 >
m_jpsi1MassUpper)
continue;
258 TLorentzVector p4_trk1, p4_trk2;
259 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
260 (*vxcItr)->trackParticle(2)->eta(),
262 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
263 (*vxcItr)->trackParticle(3)->eta(),
265 double mass_diTrk1 = (p4_trk1 + p4_trk2).M();
269 selectedPsi1Candidates.push_back(*vxcItr);
273 std::vector<const xAOD::Vertex*> selectedPsi2Candidates;
274 for(
auto vxcItr=psi2Container->cbegin(); vxcItr!=psi2Container->cend(); ++vxcItr) {
280 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
288 double mass_psi2 =
m_V0Tools->invariantMass(*vxcItr,massesPsi2);
289 if(mass_psi2 < m_psi2MassLower || mass_psi2 >
m_psi2MassUpper)
continue;
292 TLorentzVector p4_mu1, p4_mu2;
293 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
294 (*vxcItr)->trackParticle(0)->eta(),
296 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
297 (*vxcItr)->trackParticle(1)->eta(),
299 double mass_jpsi2 = (p4_mu1 + p4_mu2).M();
300 if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 >
m_jpsi2MassUpper)
continue;
303 TLorentzVector p4_trk1, p4_trk2;
304 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
305 (*vxcItr)->trackParticle(2)->eta(),
307 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
308 (*vxcItr)->trackParticle(3)->eta(),
310 double mass_diTrk2 = (p4_trk1 + p4_trk2).M();
313 selectedPsi2Candidates.push_back(*vxcItr);
316 std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
317 for(
auto psi1Itr=selectedPsi1Candidates.cbegin(); psi1Itr!=selectedPsi1Candidates.cend(); ++psi1Itr) {
319 tracksPsi1.reserve((*psi1Itr)->nTrackParticles());
320 for(
size_t i=0; i<(*psi1Itr)->nTrackParticles(); i++) tracksPsi1.push_back((*psi1Itr)->trackParticle(i));
321 for(
auto psi2Itr=selectedPsi2Candidates.cbegin(); psi2Itr!=selectedPsi2Candidates.cend(); ++psi2Itr) {
323 for(
size_t j=0; j<(*psi2Itr)->nTrackParticles(); j++) {
324 if(std::find(tracksPsi1.cbegin(), tracksPsi1.cend(), (*psi2Itr)->trackParticle(j)) != tracksPsi1.cend()) {
skip =
true;
break; }
328 for(
size_t ic=0; ic<candidatePairs.size(); ic++) {
329 const xAOD::Vertex* psi1Vertex = candidatePairs[ic].first;
330 const xAOD::Vertex* psi2Vertex = candidatePairs[ic].second;
331 if((psi1Vertex == *psi1Itr && psi2Vertex == *psi2Itr) || (psi1Vertex == *psi2Itr && psi2Vertex == *psi1Itr)) {
skip =
true;
break; }
335 candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*psi1Itr,*psi2Itr));
339 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(); } );
341 candidatePairs.erase(candidatePairs.begin()+
m_maxCandidates, candidatePairs.end());
344 for(
size_t ic=0; ic<candidatePairs.size(); ic++) {
345 const xAOD::Vertex* psi1Vertex = candidatePairs[ic].first;
346 const xAOD::Vertex* psi2Vertex = candidatePairs[ic].second;
351 if (tracksPsi1.size() != massesPsi1.size()) {
352 ATH_MSG_ERROR(
"Problems with Psi1 input: number of tracks or track mass inputs is not correct!");
357 if (tracksPsi2.size() != massesPsi2.size()) {
358 ATH_MSG_ERROR(
"Problems with Psi2 input: number of tracks or track mass inputs is not correct!");
364 tracksDiTrk1.clear();
372 tracksDiTrk2.clear();
378 TLorentzVector p4_moth;
401 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState(ctx);
423 Amg::Vector3D startingPoint((psi1Vertex->
x()+psi2Vertex->
x())/2,(psi1Vertex->
y()+psi2Vertex->
y())/2,(psi1Vertex->
z()+psi2Vertex->
z())/2);
426 std::unique_ptr<xAOD::Vertex> theResult(
m_iVertexFitter->fit(inputTracks, startingPoint, *state) );
428 if(theResult !=
nullptr){
430 double chi2DOF = theResult->chiSquared()/theResult->numberDoF();
434 for(
size_t i=0; i<theResult->trackParticleLinks().
size(); i++) {
437 tpLinkVector.push_back( mylink );
439 theResult->clearTracks();
440 theResult->setTrackParticleLinks( tpLinkVector );
449 tpLinkVector_psi1.push_back( mylink );
461 tpLinkVector_psi2.push_back( mylink );
466 VtxWriteHandles[0].ptr()->push_back(psi1Vertex_);
467 VtxWriteHandles[1].ptr()->push_back(psi2Vertex_);
474 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
478 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
480 SG::AuxElement::Decorator<VertexLinkVector> PrecedingLinksDecor(
"PrecedingVertexLinks");
481 PrecedingLinksDecor(*theResult.get()) = precedingVertexLinks;
487 VtxWriteHandles[2].ptr()->push_back(theResult.release());
499 ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
501 if(VtxWriteHandles[2]->
size()>0) {
502 for(
int i=0; i<topoN; i++) {
505 ATH_MSG_FATAL(
"FillCandwithRefittedVertices failed - check the vertices you passed");
512 if(VtxWriteHandles[2]->
size()>0) {
513 for(
int i=0; i<topoN; i++) {
514 StatusCode SC = helper.FillCandExistingVertices(VtxWriteHandles[i].ptr(), pvContainer.
cptr(),
m_DoVertexType);
516 ATH_MSG_FATAL(
"FillCandExistingVertices failed - check the vertices you passed");
523 return StatusCode::SUCCESS;