341 {
343 assert(cascadeinfoContainer!=nullptr && cascadeinfoContainer_noConstr!=nullptr);
344
345
348
349 std::vector<const xAOD::TrackParticle*> tracksJpsi;
350 std::vector<const xAOD::TrackParticle*> tracksDiTrk;
351 std::vector<const xAOD::TrackParticle*> tracksPsi;
352 std::vector<const xAOD::TrackParticle*> tracksJpsi2;
353 std::vector<double> massesPsi;
359
360
363
364
367
368
369 std::vector<const xAOD::Vertex*> selectedJpsiCandidates;
370 for(auto vxcItr=jpsiContainer.cptr()->cbegin(); vxcItr!=jpsiContainer.cptr()->cend(); ++vxcItr) {
371
376 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
378 }
379 }
381
382
383 double mass_jpsi2 =
m_V0Tools->invariantMass(*vxcItr, massesJpsi2);
384 if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 >
m_jpsi2MassUpper)
continue;
385
386 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
388
389 selectedJpsiCandidates.push_back(*vxcItr);
390 }
391 if(selectedJpsiCandidates.size()==0) return StatusCode::SUCCESS;
392
393
394 std::vector<const xAOD::Vertex*> selectedPsiCandidates;
395 for(auto vxcItr=psiContainer.cptr()->cbegin(); vxcItr!=psiContainer.cptr()->cend(); ++vxcItr) {
396
401 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
403 }
404 }
406
407
408 double mass_psi =
m_V0Tools->invariantMass(*vxcItr,massesPsi);
409 if(mass_psi < m_psiMassLower || mass_psi >
m_psiMassUpper)
continue;
410
411
412 TLorentzVector p4_mu1, p4_mu2;
413 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
414 (*vxcItr)->trackParticle(0)->eta(),
416 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
417 (*vxcItr)->trackParticle(1)->eta(),
419 double mass_jpsi = (p4_mu1 + p4_mu2).M();
420 if (mass_jpsi < m_jpsiMassLower || mass_jpsi >
m_jpsiMassUpper)
continue;
421
423 TLorentzVector p4_trk1, p4_trk2;
424 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
425 (*vxcItr)->trackParticle(2)->eta(),
427 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
428 (*vxcItr)->trackParticle(3)->eta(),
430 double mass_diTrk = (p4_trk1 + p4_trk2).M();
432 }
433
434 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
436
437 selectedPsiCandidates.push_back(*vxcItr);
438 }
439 if(selectedPsiCandidates.size()==0) return StatusCode::SUCCESS;
440
441 std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
442 for(auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
443 tracksJpsi2.clear();
444 for(
size_t i=0;
i<(*jpsiItr)->nTrackParticles();
i++) tracksJpsi2.push_back((*jpsiItr)->trackParticle(i));
445 for(auto psiItr=selectedPsiCandidates.cbegin(); psiItr!=selectedPsiCandidates.cend(); ++psiItr) {
447 for(size_t j=0; j<(*psiItr)->nTrackParticles(); j++) {
448 if(std::find(tracksJpsi2.cbegin(), tracksJpsi2.cend(), (*psiItr)->trackParticle(j)) != tracksJpsi2.cend()) {
skip =
true;
break; }
449 }
451 candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*jpsiItr,*psiItr));
452 }
453 }
454
455 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(); } );
457 candidatePairs.erase(candidatePairs.begin()+
m_maxCandidates, candidatePairs.end());
458 }
459
460 for(
size_t ic=0;
ic<candidatePairs.size();
ic++) {
463
464 tracksJpsi2.clear();
466 if (tracksJpsi2.size() != 2 || massesJpsi2.size() != 2) {
467 ATH_MSG_ERROR(
"Problems with Jpsi input: number of tracks or track mass inputs is not 2!");
468 }
469 tracksPsi.clear();
471 if (tracksPsi.size() != massesPsi.size()) {
472 ATH_MSG_ERROR(
"Problems with Psi input: number of tracks or track mass inputs is not correct!");
473 }
474
475 tracksJpsi.clear();
478 tracksDiTrk.clear();
482 }
483
484 TLorentzVector p4_moth;
489 }
493 }
495
496
498
499 int robustness = 0;
501
502
503 std::vector<Trk::VertexID> vrtList;
504
506
509 } else {
511 }
512 vrtList.push_back(vID1);
513
517 } else {
519 }
520 vrtList.push_back(vID2);
521
522 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
523 std::vector<double> tp_masses; tp_masses.clear();
526 std::vector<Trk::VertexID> cnstV; cnstV.clear();
529 }
530 }
532 std::vector<Trk::VertexID> cnstV; cnstV.clear();
535 }
536 }
537
539
540 bool pass = false;
541 if (result != nullptr) {
542 for(
auto v :
result->vertices()) {
543 if(
v->nTrackParticles()==0) {
544 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
545 v->setTrackParticleLinks(nullLinkVector);
546 }
547 }
548
550
551
552 result->setSVOwnership(
true);
553
554
557
558 if(chi2CutPassed) {
559 cascadeinfoContainer->push_back(
result.release());
560 pass = true;
561 }
562 }
563
564
565 if(pass) {
569 std::vector<Trk::VertexID> vrtList_nc;
570
572 vrtList_nc.push_back(vID1_nc);
574 vrtList_nc.push_back(vID2_nc);
575
576 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
577 std::vector<double> tp_masses; tp_masses.clear();
579
580 std::unique_ptr<Trk::VxCascadeInfo> result_nc(
m_iVertexFitter->fitCascade(*state));
581
582 if (result_nc != nullptr) {
583 for(auto v : result_nc->vertices()) {
584 if(
v->nTrackParticles()==0) {
585 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
586 v->setTrackParticleLinks(nullLinkVector);
587 }
588 }
589
591
592
593 result_nc->setSVOwnership(true);
594 cascadeinfoContainer_noConstr->push_back(result_nc.release());
595 }
596 else cascadeinfoContainer_noConstr->push_back(0);
597 }
598 else cascadeinfoContainer_noConstr->push_back(0);
599 }
600 }
601
602 return StatusCode::SUCCESS;
603 }
SG::Accessor< T, ALLOC > Accessor
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.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.