@@ -298,6 +298,12 @@ void SVertexer::updateTimeDependentParams()
298298
299299 m3bodyHyps[Hyp3body::H3L3body].set (PID::HyperTriton, PID::Proton, PID::Pion, PID::Deuteron, mSVParams ->pidCutsH3L3body , bz);
300300 m3bodyHyps[Hyp3body::AntiH3L3body].set (PID::HyperTriton, PID::Pion, PID::Proton, PID::Deuteron, mSVParams ->pidCutsH3L3body , bz);
301+ m3bodyHyps[Hyp3body::H4L3body].set (PID::Hyperhydrog4, PID::Proton, PID::Pion, PID::Triton, mSVParams ->pidCutsH4L3body , bz);
302+ m3bodyHyps[Hyp3body::AntiH4L3body].set (PID::Hyperhydrog4, PID::Pion, PID::Proton, PID::Triton, mSVParams ->pidCutsH4L3body , bz);
303+ m3bodyHyps[Hyp3body::He4L3body].set (PID::HyperHelium4, PID::Proton, PID::Pion, PID::Helium3, mSVParams ->pidCutsHe4L3body , bz);
304+ m3bodyHyps[Hyp3body::AntiHe4L3body].set (PID::HyperHelium4, PID::Pion, PID::Proton, PID::Helium3, mSVParams ->pidCutsHe4L3body , bz);
305+ m3bodyHyps[Hyp3body::He5L3body].set (PID::HyperHelium5, PID::Proton, PID::Pion, PID::Alpha, mSVParams ->pidCutsHe5L3body , bz);
306+ m3bodyHyps[Hyp3body::AntiHe5L3body].set (PID::HyperHelium5, PID::Pion, PID::Proton, PID::Alpha, mSVParams ->pidCutsHe5L3body , bz);
301307
302308 for (auto & ft : mFitterV0 ) {
303309 ft.setBz (bz);
@@ -1090,60 +1096,68 @@ int SVertexer::check3bodyDecays(const V0Index& v0Idx, const V0& v0, float rv0, s
10901096 tr0.getPxPyPzGlo (p0);
10911097 tr1.getPxPyPzGlo (p1);
10921098 tr2.getPxPyPzGlo (p2);
1093- std::array<float , 3 > p3B = {p0[0 ] + p1[0 ] + p2[0 ], p0[1 ] + p1[1 ] + p2[1 ], p0[2 ] + p1[2 ] + p2[2 ]};
10941099
1095- float pt2candidate = p3B[0 ] * p3B[0 ] + p3B[1 ] * p3B[1 ], p2candidate = pt2candidate + p3B[2 ] * p3B[2 ];
1096- if (pt2candidate < mMinPt23Body ) { // pt cut
1097- continue ;
1098- }
1099- if (p3B[2 ] * p3B[2 ] / pt2candidate > mMaxTgl23Body ) { // tgLambda cut
1100- continue ;
1101- }
1102-
1103- // compute primary vertex and cosPA of the 3-body decay
1104- auto bestCosPA = mSVParams ->minCosPA3body ;
1100+ bool goodHyp = false ;
1101+ o2::track::PID pidHyp = o2::track::PID::Electron; // Update if goodHyp is true
11051102 auto decay3bodyVtxID = -1 ;
1103+ auto vtxCosPA = -1 ;
1104+
1105+ std::array<float , 3 > pbach = {0 , 0 , 0 }, p3B = {0 , 0 , 0 }; // Update during the check of invariant mass
1106+ for (int ipid = 0 ; ipid < NHyp3body; ipid++) {
1107+ // check mass based on hypothesis of charge of bachelor (pos and neg expected to be proton/pion)
1108+ float bachChargeFactor = m3bodyHyps[ipid].getChargeBachProng () / tr2.getAbsCharge ();
1109+ pbach = {bachChargeFactor * p2[0 ], bachChargeFactor * p2[1 ], bachChargeFactor * p2[2 ]};
1110+ p3B = {p0[0 ] + p1[0 ] + pbach[0 ], p0[1 ] + p1[1 ] + pbach[1 ], p0[2 ] + p1[2 ] + pbach[2 ]};
1111+ float sqP0 = p0[0 ] * p0[0 ] + p0[1 ] * p0[1 ] + p0[2 ] * p0[2 ], sqP1 = p1[0 ] * p1[0 ] + p1[1 ] * p1[1 ] + p1[2 ] * p1[2 ], sqPBach = pbach[0 ] * pbach[0 ] + pbach[1 ] * pbach[1 ] + pbach[2 ] * pbach[2 ];
1112+ float pt2Candidate = p3B[0 ] * p3B[0 ] + p3B[1 ] * p3B[1 ], p2Candidate = pt2Candidate + p3B[2 ] * p3B[2 ];
1113+ float ptCandidate = std::sqrt (pt2Candidate);
1114+ if (m3bodyHyps[ipid].check (sqP0, sqP1, sqPBach, p2Candidate, ptCandidate)) {
1115+ if (pt2Candidate < mMinPt23Body ) { // pt cut
1116+ continue ;
1117+ }
1118+ if (p3B[2 ] * p3B[2 ] > pt2Candidate * mMaxTgl23Body ) { // tgLambda cut
1119+ continue ;
1120+ }
11061121
1107- for (int iv = decay3bodyVlist.getMin (); iv <= decay3bodyVlist.getMax (); iv++) {
1108- const auto & pv = mPVertices [iv];
1109- // check cos of pointing angle
1110- float dx = vertexXYZ[0 ] - pv.getX (), dy = vertexXYZ[1 ] - pv.getY (), dz = vertexXYZ[2 ] - pv.getZ (), prodXYZ3body = dx * p3B[0 ] + dy * p3B[1 ] + dz * p3B[2 ];
1111- float cosPA = prodXYZ3body / std::sqrt ((dx * dx + dy * dy + dz * dz) * p2candidate);
1112- if (cosPA < bestCosPA) {
1113- LOG (debug) << " Rej. cosPA: " << cosPA;
1114- continue ;
1115- }
1116- decay3bodyVtxID = iv;
1117- bestCosPA = cosPA;
1118- }
1119- if (decay3bodyVtxID == -1 ) {
1120- LOG (debug) << " 3-body decay not compatible with any vertex" ;
1121- continue ;
1122- }
1123-
1124- const auto & decay3bodyPv = mPVertices [decay3bodyVtxID];
1125- float sqP0 = p0[0 ] * p0[0 ] + p0[1 ] * p0[1 ] + p0[2 ] * p0[2 ], sqP1 = p1[0 ] * p1[0 ] + p1[1 ] * p1[1 ] + p1[2 ] * p1[2 ], sqP2 = p2[0 ] * p2[0 ] + p2[1 ] * p2[1 ] + p2[2 ] * p2[2 ];
1126- float pt3B = std::sqrt (pt2candidate);
1122+ // compute primary vertex and cosPA of the 3-body decay
1123+ auto bestCosPA = mSVParams ->minCosPA3body ;
1124+ for (int iv = decay3bodyVlist.getMin (); iv <= decay3bodyVlist.getMax (); iv++) {
1125+ const auto & pv = mPVertices [iv];
1126+ // check cos of pointing angle
1127+ float dx = vertexXYZ[0 ] - pv.getX (), dy = vertexXYZ[1 ] - pv.getY (), dz = vertexXYZ[2 ] - pv.getZ (), prodXYZ3body = dx * p3B[0 ] + dy * p3B[1 ] + dz * p3B[2 ];
1128+ float cosPA = prodXYZ3body / std::sqrt ((dx * dx + dy * dy + dz * dz) * p2Candidate);
1129+ if (cosPA < bestCosPA) {
1130+ LOG (debug) << " Rej. cosPA: " << cosPA;
1131+ continue ;
1132+ }
1133+ decay3bodyVtxID = iv;
1134+ bestCosPA = cosPA;
1135+ }
1136+ if (decay3bodyVtxID == -1 ) {
1137+ LOG (debug) << " 3-body decay not compatible with any vertex" ;
1138+ continue ;
1139+ }
11271140
1128- bool goodHyp = false ;
1129- for (int ipid = 0 ; ipid < 2 ; ipid++) { // TODO: expand this loop to cover all the 3body cases if (m3bodyHyps[ipid].check(sqP0, sqP1, sqP2, sqPtot, pt3B))
1130- if (m3bodyHyps[ipid].check (sqP0, sqP1, sqP2, p2candidate, pt3B)) {
11311141 goodHyp = true ;
1142+ pidHyp = m3bodyHyps[ipid].getPIDHyp ();
1143+ vtxCosPA = bestCosPA;
11321144 break ;
11331145 }
11341146 }
11351147 if (!goodHyp) {
11361148 continue ;
11371149 }
1138- Decay3Body candidate3B (PID::HyperTriton, vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat (cand3B), tr0, tr1, tr2);
1150+
1151+ const auto & decay3bodyPv = mPVertices [decay3bodyVtxID];
1152+ Decay3Body candidate3B (vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat (cand3B), tr0, tr1, tr2, pidHyp);
11391153 o2::track::TrackParCov trc = candidate3B;
11401154 o2::dataformats::DCA dca;
11411155 if (!trc.propagateToDCA (decay3bodyPv, fitter3body.getBz (), &dca, 5 .) ||
11421156 std::abs (dca.getY ()) > mSVParams ->maxDCAXY3Body || std::abs (dca.getZ ()) > mSVParams ->maxDCAZ3Body ) {
11431157 continue ;
11441158 }
11451159 if (mSVParams ->createFull3Bodies ) {
1146- candidate3B.setCosPA (bestCosPA );
1160+ candidate3B.setCosPA (vtxCosPA );
11471161 candidate3B.setDCA (fitter3body.getChi2AtPCACandidate ());
11481162 m3bodyTmp[ithread].push_back (candidate3B);
11491163 }
0 commit comments