12 #include "boost/graph/bron_kerbosch_all_cliques.hpp"
40 std::vector<xAOD::Vertex*>
43 const TLorentzVector& jetDir,
48 const double probVrtMergeLimit = 0.01;
52 inpNPart = xAODwrk->
InpTrk.size();
56 ATH_MSG_DEBUG(
"InDet getVrtSecMulti() called with NPart=" << inpNPart );
58 std::vector<xAOD::Vertex*> finalVertices(0);
65 const EventContext & ctx = Gaudi::Hive::currentContext();
67 if (eventInfo.isValid()) {
68 if(eventInfo->hasBeamSpotWeight()) evtWgt *= eventInfo->beamSpotWeight();
73 TLorentzVector momentumJet;
90 ATH_MSG_DEBUG(
"Number of selected tracks inside jet= " << nTracks);
94 h.m_hb_jmom->Fill(momentumJet.Perp(), evtWgt);
95 h.m_hb_ntrkjet->Fill(
static_cast<double>(nTracks), evtWgt);
106 std::vector<double> inpMass(nTracks,
m_massPi);
107 double vrt2TrackNumber = 0;
129 ATH_MSG_DEBUG(
" Found different tracks in pairs=" << vrt2TrackNumber);
141 std::unique_ptr<std::vector<WrkVrt>> wrkVrtSet = std::make_unique<std::vector<WrkVrt>>();
149 std::vector<std::vector<int>> allCliques;
150 bron_kerbosch_all_cliques(compatibilityGraph,
clique_visitor(allCliques));
152 for (
const auto& clique : allCliques) {
154 newvrt.selTrk.clear();
157 for (
int i_trk : clique){
158 newvrt.selTrk.push_back(i_trk);
163 if (
sc.isFailure() ||
174 double jetVrtDir = jetDir.Px() * vDist.x() + jetDir.Py() * vDist.y() +
175 jetDir.Pz() * vDist.z();
177 if (jetVrtDir > 0.) {
188 sc = StatusCode::FAILURE;
201 if (
sc.isFailure())
continue;
203 if (clique.size() == 2 && newvrt.chi2 > 10.)
continue;
205 if (newvrt.chi2PerTrk.size() == 2){
206 newvrt.chi2PerTrk[0] = newvrt.chi2PerTrk[1] = newvrt.chi2 / 2.;
209 newvrt.nCloseVrt = 0;
210 newvrt.dCloseVrt = 1000000.;
211 newvrt.projectedVrt =
213 wrkVrtSet->push_back(newvrt);
219 bool disassembled =
false;
222 disassembled =
false;
223 int NSoluI = (*wrkVrtSet).size();
224 for (
int iv = 0; iv < NSoluI; iv++) {
225 WrkVrt vrt = (*wrkVrtSet)[iv];
226 if (!vrt.
Good || vrt.
selTrk.size() == 2)
continue;
227 if (TMath::Prob(vrt.
chi2, 2 * vrt.
selTrk.size() - 3) < 1.e-3) {
232 }
while(disassembled);
235 while( (*wrkVrtSet).size()>1 ){
236 int tmpN = (*wrkVrtSet).size();
239 for(; iv<tmpN-1; iv++){
240 WrkVrt vert_i = (*wrkVrtSet)[iv];
241 if(!vert_i.
Good )
continue;
242 int ntrk_i = (*wrkVrtSet)[iv].
selTrk.size();
245 for(; jv<tmpN; jv++){
246 WrkVrt vert_j = (*wrkVrtSet)[jv];
247 if(!vert_j.
Good )
continue;
248 int ntrk_j = (*wrkVrtSet)[jv].
selTrk.size();
250 int nTCom =
nTrkCommon(wrkVrtSet.get(), iv, jv);
252 (*wrkVrtSet).erase((*wrkVrtSet).begin()+iv);
255 else if(nTCom==ntrk_j){
256 (*wrkVrtSet).erase((*wrkVrtSet).begin()+jv);
263 if(iv==tmpN-1)
break;
270 std::multimap<int,std::pair<int,int>> vrtWithCommonTrk;
271 std::multimap<int,std::pair<int,int>>::reverse_iterator icvrt;
273 int NSoluI = (*wrkVrtSet).size();
274 vrtWithCommonTrk.clear();
275 for(
int iv = 0; iv<NSoluI-1; iv++ ){
276 for(
int jv = iv+1; jv<NSoluI; jv++){
277 if(!(*wrkVrtSet)[iv].Good || !(*wrkVrtSet)[jv].Good)
continue;
278 int nTCom=
nTrkCommon(wrkVrtSet.get(), iv, jv);
280 vrtWithCommonTrk.emplace(nTCom,std::make_pair(iv,jv));
284 for(icvrt = vrtWithCommonTrk.rbegin(); icvrt!=vrtWithCommonTrk.rend(); ++icvrt){
285 int nTCom = (*icvrt).first;
286 int iv = (*icvrt).second.first;
287 int jv = (*icvrt).second.second;
288 int nTrkI = (*wrkVrtSet)[iv].selTrk.size();
289 int nTrkJ = (*wrkVrtSet)[jv].selTrk.size();
295 if(probV<probVrtMergeLimit){
296 if(nTrkI==2 || nTrkJ==2 || nTCom<2) {
299 if(nTCom>nTrkI-nTCom || nTCom>nTrkJ-nTCom){
308 (*wrkVrtSet).push_back(newvrt);
309 (*wrkVrtSet)[iv].Good =
false;
310 (*wrkVrtSet)[jv].Good =
false;
314 }
while( icvrt != vrtWithCommonTrk.rend() );
319 for(
const auto& vrt : (*wrkVrtSet)){
320 if(vrt.Good) cvgood++;
323 h.m_hb_rawVrtN->Fill(
static_cast<float>(cvgood), evtWgt);
327 for(
auto &tmpV : (*wrkVrtSet) ) {
328 if(tmpV.vertex.perp()>
m_rLayer3+10.) tmpV.Good =
false;
329 TLorentzVector SVPV(tmpV.vertex.x()-primVrt.
x(),
330 tmpV.vertex.y()-primVrt.
y(),
331 tmpV.vertex.z()-primVrt.
z(), 1.);
335 unsigned int tmpV = 0;
336 while( tmpV<(*wrkVrtSet).size() ){
337 if( !(*wrkVrtSet)[tmpV].Good ) (*wrkVrtSet).erase((*wrkVrtSet).begin()+tmpV);
341 if((*wrkVrtSet).empty()){
342 return finalVertices;
345 std::vector< std::vector<float> > trkScore(0);
350 for(
auto &tmpV : (*wrkVrtSet) ) tmpV.projectedVrt=
jetProjDist(tmpV.vertex, primVrt, jetDir);
357 std::unique_ptr<std::vector< std::deque<long int> > > trkInVrt = std::make_unique<std::vector<std::deque<long int>>>(nTracks);
361 long int selectedTrack, selectedVertex;
362 int foundV1, foundV2;
365 while( ( foundMaxT =
MaxOfShared(wrkVrtSet.get(), trkInVrt.get(), selectedTrack, selectedVertex) ) > 0) {
367 double foundMinVrtDst = 1000000.;
372 &&
nTrkCommon(wrkVrtSet.get(), foundV1, foundV2) ){
374 bool vrtMerged=
false;
376 if(foundV1<foundV2)
std::swap(foundV1, foundV2);
383 double tstDst =
jetProjDist(newvrt.vertex, primVrt, jetDir);
386 std::swap((*wrkVrtSet)[foundV1], newvrt);
387 (*wrkVrtSet)[foundV1].projectedVrt = tstDst;
388 (*wrkVrtSet)[foundV2].Good =
false;
389 (*wrkVrtSet)[foundV2].selTrk.clear();
394 (*wrkVrtSet)[foundV1].nCloseVrt = -1;
395 (*wrkVrtSet)[foundV1].dCloseVrt = 1000000.;
396 (*wrkVrtSet)[foundV2].nCloseVrt = -1;
397 (*wrkVrtSet)[foundV2].dCloseVrt = 1000000.;
403 trkInVrt->resize(nTracks);
412 sc = StatusCode::FAILURE;
415 (*wrkVrtSet)[selectedVertex].projectedVrt =
jetProjDist((*wrkVrtSet)[selectedVertex].
vertex, primVrt, jetDir);
417 if(
sc.isFailure() ) (*wrkVrtSet)[selectedVertex].Good =
false;
418 if( (*wrkVrtSet)[selectedVertex].projectedVrt<0.
419 && (*wrkVrtSet)[selectedVertex].selTrk.size()==2 ){
420 (*wrkVrtSet)[selectedVertex].Good =
false;
429 double minDistVV =
minVrtVrtDist( wrkVrtSet.get(), foundV1, foundV2);
431 if(foundV1<foundV2)
std::swap(foundV1, foundV2);
438 double tstDst =
jetProjDist(newvrt.vertex, primVrt, jetDir);
442 (*wrkVrtSet)[foundV1].projectedVrt = tstDst;
443 (*wrkVrtSet)[foundV2].Good =
false;
444 (*wrkVrtSet)[foundV2].selTrk.clear();
448 (*wrkVrtSet)[foundV1].nCloseVrt = -1;
449 (*wrkVrtSet)[foundV1].dCloseVrt = 1000000.;
450 (*wrkVrtSet)[foundV2].nCloseVrt = -1;
451 (*wrkVrtSet)[foundV2].dCloseVrt = 1000000.;
457 for(
unsigned int iv=0; iv<wrkVrtSet->size(); iv++) {
458 WrkVrt vert_i = (*wrkVrtSet)[iv];
459 if(!vert_i.
Good)
continue;
460 if( vert_i.
selTrk.size()<3 )
continue;
462 double tmpProb = TMath::Prob( vert_i.
chi2, 2*vert_i.
selTrk.size()-3 );
465 if(tmpProb<0.001) vert_i.
Good =
false;
475 for(
auto &ntrVrt : (*wrkVrtSet)){
476 if(!ntrVrt.Good || ntrVrt.selTrk.size()<=1)
continue;
478 for(
auto &onetVrt : (*wrkVrtSet)){
479 if(!onetVrt.Good || onetVrt.selTrk.size()!=1)
continue;
481 if(ntrVrt.detachedTrack==onetVrt.selTrk[0]){
483 newV.
selTrk.push_back(ntrVrt.detachedTrack);
486 if(vProb>probVrtMergeLimit){
497 for(
auto &iVrt : (*wrkVrtSet)){
498 if(!iVrt.Good || iVrt.selTrk.size()!=1)
continue;
500 for(
auto &jVrt : (*wrkVrtSet)){
501 if(!jVrt.Good || jVrt.selTrk.size()!=1)
continue;
503 if(iVrt.detachedTrack==jVrt.selTrk[0]){
505 newV.
selTrk.push_back(iVrt.detachedTrack);
508 if(vProb>probVrtMergeLimit){
520 for(
auto &ntrVrt : (*wrkVrtSet)){
521 if(!ntrVrt.Good || ntrVrt.selTrk.size()<=1)
continue;
523 for(
auto tr : ntrVrt.selTrk){
524 for(
auto &onetVrt : (*wrkVrtSet)){
525 if(!onetVrt.Good || onetVrt.selTrk.size()!=1)
continue;
527 if(onetVrt.detachedTrack==tr){
529 newV.
selTrk.push_back(onetVrt.selTrk[0]);
532 if(vProb>probVrtMergeLimit){
533 onetVrt.Good =
false;
544 for(
auto & curVrt : (*wrkVrtSet) ) {
545 if(!curVrt.Good )
continue;
546 if( std::abs(curVrt.vertex.z())>650. ){
550 if(curVrt.selTrk.size() != 1)
continue;
556 double Signif3D = 0.;
557 vrtVrtDist(primVrt,curVrt.vertex, curVrt.vertexCov, Signif3D);
558 double tmpProb = TMath::Prob(curVrt.chi2, 1);
560 bool trkGood =
false;
563 if(trkGood && tmpProb>0.01){
565 std::vector<double> Impact,ImpactError;
566 double Signif3DP = 0;
571 h.m_hb_diffPS->Fill(Signif3DP, evtWgt);
582 for(
auto& curVrt : (*wrkVrtSet)){
583 if(!curVrt.Good )
continue;
584 int nth = curVrt.selTrk.size();
587 double Signif3D = 0.;
588 vrtVrtDist(primVrt,curVrt.vertex, curVrt.vertexCov, Signif3D);
591 for(
int i = 0;
i < nth;
i++) {
596 if(nth <= 1)
continue;
597 if(curVrt.projectedVrt<0.)
continue;
599 if(TMath::Prob( curVrt.chi2, 2*nth-3)<0.001)
continue;
601 if(nth==2 && xAODwrk){
612 if(std::abs(ihitR-jhitR)>25.)
continue;
613 if(curVrt.vertex.perp()-
std::min(ihitR,jhitR) > 2.*vrErr)
continue;
621 h.m_hb_r2d->Fill(curVrt.vertex.perp(), evtWgt);
625 double xvt = curVrt.vertex.x();
626 double yvt = curVrt.vertex.y();
627 double zvt = curVrt.vertex.z();
628 double Rvt = std::hypot(xvt,yvt);
635 h.m_hb_r2d->Fill(curVrt.vertex.perp(), evtWgt);
639 if(nth==2 && curVrt.vertexCharge==0 && curVrt.detachedTrack<0){
640 double mass_PiPi = curVrt.vertexMom.M();
645 h.m_hb_massPiPi->Fill(mass_PiPi, evtWgt);
646 h.m_hb_massPPi ->Fill(mass_PPi, evtWgt);
647 if(curVrt.vertex.perp()>20.)
h.m_hb_massEE->Fill(mass_EE, evtWgt);
650 if(std::abs(mass_PiPi-
m_massK0) < 22.)
continue;
651 if(std::abs(mass_PPi-
m_massLam) < 8.)
continue;
652 if(mass_EE < 60. && curVrt.vertex.perp() > 20.)
continue;
657 h.m_hb_sig3DTot->Fill(Signif3D, evtWgt);
671 int ngoodVertices = 0;
672 std::vector<WrkVrt> goodVertices(0);
674 for(
auto & iv : (*wrkVrtSet)) {
675 int nth = iv.selTrk.size();
676 if(nth == 0)
continue;
680 goodVertices.emplace_back(iv);
681 if(nth==2) n2trVrt++;
682 if(nth>=3) nNtrVrt++;
686 if(ngoodVertices == 0 || (n2trVrt+nNtrVrt)==0){
687 return finalVertices;
692 bool swapDone =
false;
693 for(
unsigned int iv = 0; iv<goodVertices.size()-1; iv++) {
694 if(goodVertices[iv].
vertex.perp() > goodVertices[iv+1].vertex.perp()){
695 std::swap( goodVertices[iv], goodVertices[iv+1] );
703 bool swapDone =
false;
704 for(
unsigned int iv = 0; iv<goodVertices.size()-1; iv++) {
705 if(goodVertices[iv+1].
vertex.perp() > 400.)
continue;
706 if(goodVertices[iv].projectedVrt > goodVertices[iv+1].projectedVrt){
707 std::swap( goodVertices[iv], goodVertices[iv+1] );
715 if( goodVertices[1].vertexMom.M()-goodVertices[0].vertexMom.M() > 5000.){
716 std::swap( goodVertices[0], goodVertices[1] );
722 h.m_hb_distVV->Fill(
minVrtVrtDist(wrkVrtSet.get(), foundV1, foundV2), evtWgt);
731 std::vector<int> nonusedTrk(0);
732 for(
int trk=0; trk<nTracks; trk++){
733 bool present =
false;
735 for(
const auto& iv : (*wrkVrtSet)){
737 for(
auto t_in_V : iv.selTrk){
747 if(!present) nonusedTrk.push_back(trk);
750 struct MatchedSV{
int indVrt;
double Signif3D;};
751 std::vector<MatchedSV> matchSV(0);
753 for(
const auto& i_trk : nonusedTrk){
754 MatchedSV tmpV = {0, 1.e9};
756 for(
unsigned int iv = 0; iv<goodVertices.size(); iv++){
758 if(!goodVertices[iv].Good)
continue;
759 if(goodVertices[iv].selTrk.size()<2)
continue;
760 if(
vrtVrtDist(primVrt, goodVertices[iv].
vertex, goodVertices[iv].vertexCov, jetDir) < 10.)
continue;
763 std::vector<double> Impact, ImpactError;
765 if(Signif<tmpV.Signif3D){
766 tmpV.Signif3D = Signif;
771 matchSV.push_back(tmpV);
774 for(
int iv = 0; iv<static_cast<int>(goodVertices.size()); iv++){
775 WrkVrt newV(goodVertices[iv]);
777 std::map<double,int> addTrk;
779 for(
unsigned int it = 0;
it<nonusedTrk.size();
it++){
780 if(matchSV[
it].indVrt==iv) addTrk[matchSV[
it].Signif3D]=
it;
786 newV.
selTrk.push_back(nonusedTrk[atrk->second]);
794 newV.
selTrk.push_back(nonusedTrk[atrk->second]);
801 if(vProb>0.01) goodVertices[iv] = newV;
803 std::vector<WrkVrt> TestVertices(1,newV);
805 if(vProb>0.01) goodVertices[iv] = TestVertices[0];
815 int ngoodVertices_final = 0;
817 TLorentzVector vertexMom;
818 bool isPrimaryVertex =
true;
820 for(
auto& vrt : goodVertices){
821 int nth = vrt.selTrk.size();
824 for(
int i = 0;
i < nth;
i++) {
825 int j = vrt.selTrk[
i];
831 if(nth==1)
h.m_hb_r1dc->Fill(vrt.vertex.perp(), evtWgt);
832 if(nth==2)
h.m_hb_r2dc->Fill(vrt.vertex.perp(), evtWgt);
833 if(nth==3)
h.m_hb_r3dc->Fill(vrt.vertex.perp(), evtWgt);
834 if(nth> 3)
h.m_hb_rNdc->Fill(vrt.vertex.perp(), evtWgt);
835 double Signif3D =
vrtVrtDist(primVrt, vrt.vertex, vrt.vertexCov, jetDir);
838 if(vrt.vertexCharge==0)
h.m_hb_totmass2T1->Fill(vrt.vertexMom.M(), evtWgt);
839 else h.m_hb_totmass2T2->Fill(vrt.vertexMom.M(), evtWgt);
840 h.m_hb_sig3D2tr->Fill(Signif3D , evtWgt);
844 else if(vrt.vertexMom.M()>6000.)
h.m_hb_sig3D1tr->Fill(Signif3D, evtWgt);
845 else h.m_hb_sig3DNtr->Fill(Signif3D, evtWgt);
851 return finalVertices;
856 std::vector<float> floatErrMtx;
857 floatErrMtx.resize(6);
858 for(
int i = 0;
i<6;
i++) floatErrMtx[
i] = vrt.vertexCov[
i];
863 std::vector<Trk::VxTrackAtVertex> & tmpVTAV = tmpVertex->
vxTrackAtVertex();
866 for(
int ii = 0; ii<nth; ii++) {
868 CovMtxP.setIdentity();
874 std::move(CovMtxP) );
875 tmpVTAV.emplace_back( 1., tmpMeasPer );
886 finalVertices.push_back(tmpVertex);
887 ngoodVertices_final++;
888 if(nth==1) n1trVrt++;
891 isPrimaryVertex =
false;
895 vertexMom += vrt.vertexMom;
901 h.m_hb_goodvrtN->Fill(ngoodVertices_final+0.1, evtWgt);
902 h.m_curTup->ewgt = evtWgt;
903 if(n1trVrt)
h.m_hb_goodvrtN->Fill(n1trVrt+15., evtWgt);
907 if(ngoodVertices_final==0){
908 return finalVertices;
915 double totMass = vertexMom.M();
917 double eRatio = vertexMom.E()/momentumJet.E();
918 results.push_back(eRatio<1. ? eRatio : 1.);
919 results.push_back(vrt2TrackNumber);
923 results.push_back(momentumJet.E());
927 h.m_hb_ratio->Fill(
results[1], evtWgt);
928 h.m_hb_totmass->Fill(
results[0], evtWgt);
929 h.m_hb_nvrt2->Fill(
results[2], evtWgt);
930 h.m_hb_mom->Fill( momentumJet.Perp(), evtWgt);
933 return finalVertices;
946 template <
class Particle>
948 std::vector<const Particle*> AllTracks,
954 std::vector<const Particle*> ListBaseTracks;
955 int NTrk = (*wrkVrtSet)[iv].selTrk.size();
964 (*wrkVrtSet)[iv].Good =
false;
970 for(
int i = 0;
i<NTrk;
i++){
971 if((*wrkVrtSet)[iv].chi2PerTrk[
i]>Chi2Max) {
972 Chi2Max = (*wrkVrtSet)[iv].chi2PerTrk[
i];
977 unsigned int NVrtCur = wrkVrtSet->size();
978 for(
int i = 0;
i<NTrk;
i++){
979 if(
i==SelT)
continue;
980 ListBaseTracks.clear();
981 ListBaseTracks.push_back( AllTracks[(*wrkVrtSet)[iv].selTrk[
i]] );
982 ListBaseTracks.push_back( AllTracks[(*wrkVrtSet)[iv].selTrk[SelT]] );
984 newvrt.
selTrk[0] = (*wrkVrtSet)[iv].selTrk[
i];
985 newvrt.
selTrk[1] = (*wrkVrtSet)[iv].selTrk[SelT];
988 if(
sc.isFailure() )
continue;
1001 if(
sc.isFailure() )
continue;
1002 if(newvrt.
chi2>10.)
continue;
1009 if(wrkVrtSet->size()==NVrtCur){
1010 wrkVrtSet->push_back(newvrt);
1014 if( (*wrkVrtSet).at(NVrtCur).chi2<newvrt.
chi2 )
continue;
1016 wrkVrtSet->pop_back();
1017 wrkVrtSet->push_back(newvrt);
1020 (*wrkVrtSet)[iv].selTrk.erase( (*wrkVrtSet)[iv].selTrk.begin() + SelT );
1022 if(
sc.isFailure() ) (*wrkVrtSet)[iv].Good =
false;
1028 std::vector<int> countVT(wrkVrtSet->size(),0);
1029 std::vector<int> linkedVrt(wrkVrtSet->size(),0);
1032 for(
unsigned int i1tv = 0; i1tv<wrkVrtSet->size(); i1tv++) {
1033 WrkVrt vrt1 = (*wrkVrtSet)[i1tv];
1034 if( vrt1.
selTrk.size()!=1)
continue;
1035 if(!vrt1.
Good)
continue;
1038 int foundInGoodVrt = 0;
1039 for(
unsigned int mtv=0; mtv<wrkVrtSet->size(); mtv++) {
1040 WrkVrt vrtm = (*wrkVrtSet)[mtv];
1041 if( vrtm.
selTrk.size()<2)
continue;
1042 if(!vrtm.
Good)
continue;
1047 linkedVrt[i1tv] = mtv;
1051 if(!foundInGoodVrt) vrt1.
Good=
false;
1055 for(
int mtv = 0; mtv<static_cast<int>(wrkVrtSet->size()); mtv++) {
1056 WrkVrt vrtm = (*wrkVrtSet)[mtv];
1057 if(vrtm.
selTrk.size()<2)
continue;
1058 if(!vrtm.
Good)
continue;
1059 if(countVT[mtv] < 1)
continue;
1061 double distM = 1.e9;
1063 for(
unsigned int i1tv = 0; i1tv<wrkVrtSet->size(); i1tv++) {
1064 WrkVrt vrt1 = (*wrkVrtSet)[i1tv];
1065 if(vrt1.
selTrk.size()!=1)
continue;
1066 if(!vrt1.
Good)
continue;
1067 if(linkedVrt[i1tv]!=mtv)
continue;
1077 if(best1TVrt>-1 && distM<
c_vrtBCMassLimit) (*wrkVrtSet)[best1TVrt].Good=
true;
1083 std::vector< std::deque<long int> > *TrkInVrt)
1086 int NSet = wrkVrtSet->size();
1087 for(
int iv = 0; iv<NSet; iv++) {
1088 if(!(*wrkVrtSet)[iv].Good)
continue;
1089 int NTrkAtVrt = (*wrkVrtSet)[iv].selTrk.size();
1090 if(NTrkAtVrt<2)
continue;
1092 for(
int jt = 0; jt<NTrkAtVrt; jt++){
1093 int tracknum = (*wrkVrtSet)[iv].selTrk[jt];
1094 (*TrkInVrt).at(tracknum).push_back(iv);
1101 std::vector< std::deque<long int> > *TrkInVrt,
1102 long int & selectedTrack,
1103 long int & selectedVertex)
1106 long int NTrack = TrkInVrt->size();
1107 double MaxOf = -999999999, SelectedProb = -1.;
1109 for(
const auto& trk : (*TrkInVrt)){
1110 int NVrt = trk.size();
1111 if(NVrt > NShareMax) NShareMax=NVrt;
1113 if(NShareMax<=1)
return MaxOf;
1115 for(
int it = 0;
it<NTrack;
it++) {
1116 int NVrt = (*TrkInVrt)[
it].size();
1117 if( NVrt <= 1 )
continue;
1118 if( NVrt < NShareMax )
continue;
1121 for(
auto &vrtn : (*TrkInVrt)[
it] ){
1122 if((*wrkVrtSet).at(vrtn).selTrk.size()==2) N2trVrt++;
1125 for(
const auto& VertexNumber : (*TrkInVrt)[
it]){
1126 WrkVrt vrt = (*wrkVrtSet).at(VertexNumber);
1127 if(!vrt.
Good)
continue;
1128 int NTrkInVrt = vrt.
selTrk.size();
1129 if( NTrkInVrt <= 1)
continue;
1130 if(N2trVrt>0 && N2trVrt<NShareMax && NTrkInVrt>2)
continue;
1132 for(
int itmp = 0; itmp<NTrkInVrt; itmp++){
1136 Chi2Red = vrt.
chi2/2.;
1140 double prob_vrt = TMath::Prob(vrt.
chi2, 2*vrt.
selTrk.size()-3);
1141 if( MaxOf < Chi2Red ){
1142 if(MaxOf>0 && prob_vrt>0.01 && SelectedProb<0.01)
continue;
1145 selectedVertex = VertexNumber;
1146 SelectedProb = prob_vrt;
1156 if( (*TrkInVrt)[selectedTrack].
size() == 2){
1157 int v1 = (*TrkInVrt)[selectedTrack][0];
1158 int v2 = (*TrkInVrt)[selectedTrack][1];
1159 WrkVrt vrt1 = (*wrkVrtSet)[v1];
1161 double prb1 = TMath::Prob(vrt1.
chi2, 2*vrt1.
selTrk.size()-3);
1162 double prb2 = TMath::Prob(vrt2.
chi2, 2*vrt2.
selTrk.size()-3);
1166 if(prb1>0.05 && prb2>0.05){
1168 if (selectedVertex==v1 && dst2<dst1) selectedVertex =
v2;
1169 else if(selectedVertex==
v2 && dst1<dst2) selectedVertex = v1;
1178 if( vrt1.
selTrk.size()==2 && dst1>dst2) selectedVertex =
v2;
1179 if( vrt2.
selTrk.size()==2 && dst2>dst1) selectedVertex = v1;
1189 std::vector< std::deque<long int> > *TrkInVrt,
1190 long int & selectedTrack,
1191 long int & selectedVertex)
1194 int posInVrtFit = 0;
1196 WrkVrt vrt = (*wrkVrtSet)[selectedVertex];
1197 std::deque<long int> trk = (*TrkInVrt).at(selectedTrack);
1200 if( (*
it) == selectedTrack ) {
1206 for(
it = trk.begin();
it!=trk.end(); ++
it) {
1207 if( (*
it) == selectedVertex ) {
1208 trk.erase(
it);
break;
1215 if( vrt.
selTrk.size() == 1){
1216 long int LeftTrack = vrt.
selTrk[0];
1217 for(
it = (*TrkInVrt).at(LeftTrack).begin();
it!=(*TrkInVrt)[LeftTrack].end(); ++
it) {
1218 if( (*
it) == selectedVertex ) {
1219 (*TrkInVrt)[LeftTrack].erase(
it);
break;
1223 if( TMath::Prob(vrt.
chi2, 1) < 0.05 ) vrt.
Good =
false;
1227 if(posInVrtFit==0) ipos = 1;
1229 if(!(*TrkInVrt)[LeftTrack].
empty()) vrt.
Good =
false;
1242 WrkVrt vrt1 = (*wrkVrtSet).at(V1);
1243 WrkVrt vrt2 = (*wrkVrtSet).at(V2);
1244 int NTrk_V1 = vrt1.
selTrk.size();
if( NTrk_V1< 2)
return 0;
1245 int NTrk_V2 = vrt2.
selTrk.size();
if( NTrk_V2< 2)
return 0;
1248 if(NTrk_V1 < NTrk_V2){
1249 for(
const auto& trk : vrt1.
selTrk){
1253 for(
const auto& trk : vrt2.
selTrk){
1267 for(
auto& vrt : (*wrkVrtSet)){
1268 vrt.dCloseVrt = 1000000.;
1271 double foundMinVrtDst = 1000000.;
1273 for(
unsigned int iv = 0; iv<wrkVrtSet->size()-1; iv++) {
1274 WrkVrt vrt_i = (*wrkVrtSet)[iv];
1275 if( vrt_i.
selTrk.size()< 2)
continue;
1276 if(!vrt_i.
Good )
continue;
1278 for(
unsigned int jv = iv+1; jv<wrkVrtSet->size(); jv++) {
1279 WrkVrt vrt_j = (*wrkVrtSet)[jv];
1280 if( vrt_j.
selTrk.size()< 2)
continue;
1281 if(!vrt_j.
Good )
continue;
1285 if(
tmp>20.)
continue;
1289 if(tmpDst < foundMinVrtDst){
1290 foundMinVrtDst = tmpDst;
1306 return foundMinVrtDst;
1315 double foundMinVrtDst = 1000000.;
1317 for(
unsigned int iv = 0; iv<wrkVrtSet->size()-1; iv++) {
1318 WrkVrt vrt_i = (*wrkVrtSet)[iv];
1319 if(vrt_i.
selTrk.size()< 2)
continue;
1324 if((*wrkVrtSet)[vtmp].nCloseVrt==-1)
continue;
1331 return foundMinVrtDst;
1337 template <
class Particle>
1339 std::vector<const Particle*> & AllTrackList,
1343 WrkVrt vrt1 = (*wrkVrtSet)[V1];
1344 WrkVrt vrt2 = (*wrkVrtSet)[V2];
1345 if(!vrt1.
Good)
return -1.;
1346 if(!vrt2.
Good)
return -1.;
1349 int NTrk_V1 = vrt1.
selTrk.size();
1350 int NTrk_V2 = vrt2.
selTrk.size();
1351 newvrt.
selTrk.resize(NTrk_V1+NTrk_V2);
1357 TransfEnd = unique( newvrt.
selTrk.begin(), newvrt.
selTrk.end() );
1360 std::vector<const Particle*> fitTrackList(0);
1361 for(
const auto& trk : newvrt.
selTrk) fitTrackList.push_back( AllTrackList[trk] );
1378 if(
sc.isFailure() )
return -1.;
1379 if( newvrt.
chi2>500. )
return -1.;
1381 return TMath::Prob(newvrt.
chi2, 2*newvrt.
selTrk.size()-3);
1386 template <
class Particle>
1388 std::vector<const Particle*> & AllTrackList,
1391 WrkVrt vrt1 = (*wrkVrtSet)[V1];
1392 WrkVrt vrt2 = (*wrkVrtSet)[V2];
1393 if(!vrt1.
Good)
return;
1394 if(!vrt2.
Good)
return;
1398 if(
nTrkCommon( wrkVrtSet, V1, V2)<2 )
return;
1409 std::vector<int> noncommonTrk(0);
1415 std::vector<const Particle*> fitTrackList(0);
1416 std::vector<int> detachedTrk(0);
1419 bool foundMerged =
false;
1421 for(
auto nct : noncommonTrk){
1422 fitTrackList.clear();
1423 for(
const auto& trk : newvrt.
selTrk) fitTrackList.push_back( AllTrackList[trk] );
1424 fitTrackList.push_back( AllTrackList.at(nct) );
1431 if(
sc.isFailure() || TMath::Prob(newvrt.
chi2, 2*newvrt.
selTrk.size()+2-3)<0.001 ) {
1432 detachedTrk.push_back(nct);
1436 newvrt.
selTrk.push_back(nct);
1441 if(foundMerged) vrt1=bestVrt;
1445 if(detachedTrk.size()>1){
1447 fitTrackList.clear();
1450 for(
auto nct : detachedTrk){
1451 fitTrackList.push_back( AllTrackList[nct] );
1452 nVrt.
selTrk.push_back(nct);
1460 if(
sc.isSuccess()) (*wrkVrtSet).push_back(nVrt);
1462 }
else if( detachedTrk.size()==1 ){
1463 bool tFound =
false;
1464 for(
auto &vrt : (*wrkVrtSet) ){
1465 if( !vrt.Good || vrt.selTrk.size()<2 )
continue;
1466 if(
std::find(vrt.selTrk.begin(), vrt.selTrk.end(), detachedTrk[0]) != vrt.selTrk.end() ) {
1472 double Chi2min = 1.e9;
1473 int selectedTrk = -1;
1475 fitTrackList.resize(2);
1476 fitTrackList[0]= AllTrackList[detachedTrk[0]];
1478 for(
auto trk : vrt2.
selTrk){
1479 if(trk==detachedTrk[0])
continue;
1482 fitTrackList[1] = AllTrackList[trk];
1488 if(
sc.isSuccess() && nVrt.
chi2<Chi2min) {
1489 Chi2min = nVrt.
chi2;
1496 saveVrt.
selTrk.resize(1);
1497 saveVrt.
selTrk[0] = detachedTrk[0];
1500 (*wrkVrtSet).push_back(saveVrt);
1511 template <
class Particle>
1517 WrkVrt vrt = (*wrkVrtSet)[V];
1518 int NTrk = vrt.
selTrk.size();
1519 if( NTrk<2 )
return 0.;
1521 double Prob=TMath::Prob(vrt.
chi2, 2*NTrk-3);
1524 NTrk = vrt.
selTrk.size();
1525 if(NTrk==2)
return Prob;
1528 double Chi2Max = 0.;
1529 for(
int i = 0;
i<NTrk;
i++){
1537 if (SelT<0)
return 0;
1541 if(
sc.isFailure())
return 0.;
1543 Prob = TMath::Prob(vrt.
chi2, 2*(NTrk-1)-3);
1549 template <
class Particle>
1552 std::vector<const Particle*> & selectedTracks,
1556 WrkVrt vrt = (*wrkVrtSet)[selectedVertex];
1557 int nth = vrt.
selTrk.size();
1558 if(nth<2)
return StatusCode::SUCCESS;
1560 double vProb =
refitVertex(vrt, selectedTracks, istate, ifCovV0);
1561 if(vProb<0)
return StatusCode::FAILURE;
1562 else return StatusCode::SUCCESS;
1566 template <
class Particle>
1568 std::vector<const Particle*> & selectedTracks,
1572 int nth = Vrt.
selTrk.size();
1573 if(nth<2)
return -1.;
1575 std::vector<const Particle*> ListTracks(0);
1576 for(
const auto& j : Vrt.
selTrk) ListTracks.push_back( selectedTracks[j] );
1586 if(
SC.isSuccess()) Vrt.
Good =
true;
1593 return TMath::Prob(Vrt.
chi2, 2*nth-1);
1599 for(trk =
test.begin(); trk!=
test.end(); ++trk){
1608 return (
vv.x()*jetDir.X()+
vv.y()*jetDir.Y()+
vv.z()*jetDir.Z() )/ jetDir.P();