@@ -59,6 +59,8 @@ struct RecoDecay {
5959 static constexpr int PdgBosonMax{37 }; // largest boson (gauge or H) PDG code; o2-linter: disable=pdg/explicit-code (H+ does not have a named constant.)
6060 static constexpr int PdgDivisorMeson{100 }; // order of magnitude of the meson PDG codes
6161 static constexpr int PdgDivisorBaryon{1000 }; // order of magnitude of the baryon PDG codes
62+ static constexpr int PdgDiquarkSpin0Code{1 }; // last digits of a spin-0 diquark PDG code
63+ static constexpr int PdgDiquarkSpin1Code{3 }; // last digits of a spin-1 diquark PDG code
6264
6365 // Auxiliary functions
6466
@@ -1179,6 +1181,31 @@ struct RecoDecay {
11791181 return OriginType::None;
11801182 }
11811183
1184+ // / Check whether the PDG code corresponds to a diquark state (e.g. 4101, 4201, 5101).
1185+ // / Diquarks are constituents used by the generators during the hadronisation and are not
1186+ // / hadrons. A diquark carrying a charm or beauty quark has a PDG code that satisfies the
1187+ // / pdg / 1000 == 4 or 5 condition used to identify charm and beauty baryons in
1188+ // / getParticleOrigin, so such a state would be misidentified as a heavy-flavour baryon there.
1189+ // / This check therefore validates the diquark structure: two quark flavours in
1190+ // / PDG_t::kDown..kTop (any quark pair, not only a heavy-flavour one), the first flavour not
1191+ // / smaller than the second, and a spin-0 or spin-1 code.
1192+ // / \param pdgCode PDG code of the particle
1193+ // / \return true if the PDG code belongs to a diquark state
1194+ static bool isDiquark (const int pdgCode)
1195+ {
1196+ // a diquark PDG code is composed as pdgQuark1 * PdgDivisorBaryon + pdgQuark2 * PdgDivisorMeson
1197+ // + spinCode, with pdgQuark1 >= pdgQuark2 the quark flavours and spinCode either
1198+ // PdgDiquarkSpin0Code or PdgDiquarkSpin1Code
1199+ const int absPdgCode = std::abs (pdgCode);
1200+ const int spinCode = absPdgCode % PdgDivisorMeson;
1201+ if (spinCode != PdgDiquarkSpin0Code && spinCode != PdgDiquarkSpin1Code) {
1202+ return false ;
1203+ }
1204+ const int pdgQuark1 = absPdgCode / PdgDivisorBaryon;
1205+ const int pdgQuark2 = (absPdgCode % PdgDivisorBaryon) / PdgDivisorMeson;
1206+ return pdgQuark1 >= PDG_t::kDown && pdgQuark1 <= PDG_t::kTop && pdgQuark2 >= PDG_t::kDown && pdgQuark2 <= PDG_t::kTop && pdgQuark1 >= pdgQuark2;
1207+ }
1208+
11821209 // / based on getCharmHardronOrigin in order to extend general particle
11831210 // / Finding the origin (from charm hadronisation or beauty-hadron decay) of paritcle (b, c and others)
11841211 // / \param particlesMC table with MC particles
@@ -1221,6 +1248,17 @@ struct RecoDecay {
12211248 // Check status code
12221249 // auto motherStatusCode = std::abs(mother.getGenStatusCode());
12231250 auto pdgParticleIMother = std::abs (mother.pdgCode ()); // PDG code of the mother
1251+ // in the hadron-level mode, stop the walk when a parton or a diquark is reached: no
1252+ // heavy-flavour hadron can be found above the partonic level, and a diquark is not a
1253+ // hadron although its PDG code (e.g. 4101, 4201, 5101) satisfies pdg / 1000 == 4 or 5
1254+ // and would be misidentified as a charm/beauty baryon below. In the parton-level mode
1255+ // the walk has to continue through diquarks, since a charm or beauty quark can still be
1256+ // found above them.
1257+ if (!searchUpToQuark &&
1258+ (isDiquark (pdgParticleIMother) || pdgParticleIMother <= PdgQuarkMax ||
1259+ (pdgParticleIMother >= PdgBosonMin && pdgParticleIMother <= PdgBosonMax))) {
1260+ break ;
1261+ }
12241262 // Check mother's PDG code.
12251263 // printf("getMother: ");
12261264 // for (int i = stage; i < 0; i++) // Indent to make the tree look nice.
0 commit comments