344 {
346 assert(cascadeinfoContainer!=nullptr && cascadeinfoContainer_noConstr!=nullptr);
347
348
351
352 std::vector<const xAOD::TrackParticle*> tracksJpsi;
353 std::vector<const xAOD::TrackParticle*> tracksDiTrk;
354 std::vector<const xAOD::TrackParticle*> tracksPsi;
355 std::vector<const xAOD::TrackParticle*> tracksJpsi2;
356 std::vector<double> massesPsi;
362
363
366
367
370
371
372 std::vector<const xAOD::Vertex*> selectedJpsiCandidates;
373 for(auto vxcItr=jpsiContainer.cptr()->cbegin(); vxcItr!=jpsiContainer.cptr()->cend(); ++vxcItr) {
374
379 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
381 }
382 }
384
385
386 double mass_jpsi2 =
m_V0Tools->invariantMass(*vxcItr, massesJpsi2);
387 if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 >
m_jpsi2MassUpper)
continue;
388
389 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
391
392 selectedJpsiCandidates.push_back(*vxcItr);
393 }
394 if(selectedJpsiCandidates.size()==0) return StatusCode::SUCCESS;
395
396
397 std::vector<const xAOD::Vertex*> selectedPsiCandidates;
398 for(auto vxcItr=psiContainer.cptr()->cbegin(); vxcItr!=psiContainer.cptr()->cend(); ++vxcItr) {
399
404 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
406 }
407 }
409
410
411 double mass_psi =
m_V0Tools->invariantMass(*vxcItr,massesPsi);
412 if(mass_psi < m_psiMassLower || mass_psi >
m_psiMassUpper)
continue;
413
414
415 TLorentzVector p4_mu1, p4_mu2;
416 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
417 (*vxcItr)->trackParticle(0)->eta(),
419 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
420 (*vxcItr)->trackParticle(1)->eta(),
422 double mass_jpsi = (p4_mu1 + p4_mu2).M();
423 if (mass_jpsi < m_jpsiMassLower || mass_jpsi >
m_jpsiMassUpper)
continue;
424
426 TLorentzVector p4_trk1, p4_trk2;
427 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
428 (*vxcItr)->trackParticle(2)->eta(),
430 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
431 (*vxcItr)->trackParticle(3)->eta(),
433 double mass_diTrk = (p4_trk1 + p4_trk2).M();
435 }
436
437 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
439
440 selectedPsiCandidates.push_back(*vxcItr);
441 }
442 if(selectedPsiCandidates.size()==0) return StatusCode::SUCCESS;
443
444 std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
445 for(auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
446 tracksJpsi2.clear();
447 for(
size_t i=0;
i<(*jpsiItr)->nTrackParticles();
i++) tracksJpsi2.push_back((*jpsiItr)->trackParticle(i));
448 for(auto psiItr=selectedPsiCandidates.cbegin(); psiItr!=selectedPsiCandidates.cend(); ++psiItr) {
450 for(
size_t j=0;
j<(*psiItr)->nTrackParticles();
j++) {
451 if(std::find(tracksJpsi2.cbegin(), tracksJpsi2.cend(), (*psiItr)->trackParticle(j)) != tracksJpsi2.cend()) {
skip =
true;
break; }
452 }
454 candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*jpsiItr,*psiItr));
455 }
456 }
457
458 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(); } );
460 candidatePairs.erase(candidatePairs.begin()+
m_maxCandidates, candidatePairs.end());
461 }
462
463 for(
size_t ic=0;
ic<candidatePairs.size();
ic++) {
466
467 tracksJpsi2.clear();
469 if (tracksJpsi2.size() != 2 || massesJpsi2.size() != 2) {
470 ATH_MSG_ERROR(
"Problems with Jpsi input: number of tracks or track mass inputs is not 2!");
471 }
472 tracksPsi.clear();
474 if (tracksPsi.size() != massesPsi.size()) {
475 ATH_MSG_ERROR(
"Problems with Psi input: number of tracks or track mass inputs is not correct!");
476 }
477
478 tracksJpsi.clear();
481 tracksDiTrk.clear();
485 }
486
487 TLorentzVector p4_moth;
492 }
496 }
498
499
500 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState(ctx);
501
502 int robustness = 0;
504
505
506 std::vector<Trk::VertexID> vrtList;
507
509
512 } else {
514 }
515 vrtList.push_back(vID1);
516
520 } else {
522 }
523 vrtList.push_back(vID2);
524
525 std::vector<const xAOD::TrackParticle*> tp; tp.clear();
526 std::vector<double> tp_masses; tp_masses.clear();
529 std::vector<Trk::VertexID> cnstV; cnstV.clear();
532 }
533 }
535 std::vector<Trk::VertexID> cnstV; cnstV.clear();
538 }
539 }
540
542
543 bool pass = false;
544 if (result != nullptr) {
545 for(
auto v :
result->vertices()) {
546 if(
v->nTrackParticles()==0) {
547 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
548 v->setTrackParticleLinks(nullLinkVector);
549 }
550 }
551
553
554
555 result->setSVOwnership(
true);
556
557
560
561 if(chi2CutPassed) {
562 cascadeinfoContainer->push_back(
result.release());
563 pass = true;
564 }
565 }
566
567
568 if(pass) {
570 std::unique_ptr<Trk::IVKalState> state (
m_iVertexFitter->makeState(ctx));
572 std::vector<Trk::VertexID> vrtList_nc;
573
575 vrtList_nc.push_back(vID1_nc);
577 vrtList_nc.push_back(vID2_nc);
578
579 std::vector<const xAOD::TrackParticle*> tp; tp.clear();
580 std::vector<double> tp_masses; tp_masses.clear();
582
583 std::unique_ptr<Trk::VxCascadeInfo> result_nc(
m_iVertexFitter->fitCascade(*state));
584
585 if (result_nc != nullptr) {
586 for(auto v : result_nc->vertices()) {
587 if(
v->nTrackParticles()==0) {
588 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
589 v->setTrackParticleLinks(nullLinkVector);
590 }
591 }
592
594
595
596 result_nc->setSVOwnership(true);
597 cascadeinfoContainer_noConstr->push_back(result_nc.release());
598 }
599 else cascadeinfoContainer_noConstr->push_back(0);
600 }
601 else cascadeinfoContainer_noConstr->push_back(0);
602 }
603 }
604
605 return StatusCode::SUCCESS;
606 }
#define ATH_MSG_DEBUG(x,...)
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
SG::Accessor< T, ALLOC > Accessor
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.