4#ifndef TRUTHUTILS_ATLASPID_H
5#define TRUTHUTILS_ATLASPID_H
17constexpr std::array<int, 9>
MIN_DIGIT = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
18constexpr std::array<int, 9>
MAX_DIGIT = {9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999};
19template <
typename... Ns>
21 return ((std::abs(p) >=
MIN_DIGIT[digits - 1] && std::abs(p) <=
MAX_DIGIT[digits - 1]) || ...);
24class DecodedPID:
public std::pair<int,std::vector<int>> {
28 this->second.reserve(10);
30 for(; ap; ap/=10) this->second.push_back( ap%10 );
34 inline const int&
operator()(
const size_t n)
const {
return this->second.at(n);}
35 inline const int&
last()
const {
return this->second.back();}
36 inline const int&
pid()
const {
return this->first;}
37 inline int max_digit(
const int m,
const int n)
const {
return *std::max_element(second.rbegin() + m, second.rbegin() + n);}
38 inline int min_digit(
const int m,
const int n)
const {
return *std::min_element(second.rbegin() + m, second.rbegin() + n);}
39 inline size_t ndigits()
const {
return this->second.size();}
44 +0, -1, +2, -1, +2, -1, +2, -1, +2, +0,
45 +0, -3, +0, -3, +0, -3, +0, -3, +0, +0,
46 +0, +0, +0, +0, +3, +0, +0, +0, +0, +0,
47 +0, +0, +0, +0, +3, +0, +0, +3, +6, +0,
48 +0, +0, -1, +0, +0, +0, +0, +0, +0, +0,
49 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
50 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
51 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
52 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
53 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0
59 +0, +1, +1, +1, +1, +1, +1, +1, +1, +0,
60 +0, +1, +1, +1, +1, +1, +1, +1, +1, +0,
61 +2, +2, +2, +2, +2, +0, +0, +0, +0, +0,
62 +0, +0, +2, +2, +2, +0, +0, +0, +0, +4,
63 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
64 +0, +0, +1, +2, +0, +2, +0, +1, +2, +0,
65 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
66 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
67 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
68 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0
91static const int TAU = 15;
123static const int PI0 = 111;
124static const int K0L = 130;
126static const int K0S = 310;
127static const int K0 = 311;
131static const int D0 = 421;
134static const int B0 = 511;
155static const int LEAD = 1000822080;
161static const int NEON = 1000100200;
188template <>
inline bool isQuark(
const int& p) {
return p != 0 && (std::abs(p) <=
TPRIME || std::abs(p) ==
MAVTOP);}
193template <>
inline bool isSMQuark(
const int& p) {
return p != 0 && std::abs(p) <=
TQUARK;}
200template <>
inline bool isCharm(
const int& p){
return std::abs(p) ==
CQUARK;}
205template <
class T>
inline bool isTop(
const T& p){
return isTop(p->pdg_id());}
206template <>
inline bool isTop(
const int& p){
return std::abs(p) ==
TQUARK;}
225template <
class T>
inline bool isMuon(
const T& p){
return isMuon(p->pdg_id());}
226template <>
inline bool isMuon(
const int& p){
return std::abs(p) ==
MUON;}
228template <
class T>
inline bool isTau(
const T& p){
return isTau(p->pdg_id());}
229template <>
inline bool isTau(
const int& p){
return std::abs(p) ==
TAU;}
249 if ( p.ndigits() == 4 && p(0) >= p(1) && p(1) != 0 && p(2) == 0 && (p.last() == 1 || p.last() == 3)
272 if (p.ndigits() < 3 )
return false;
273 if (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2))
return false;
274 if (std::abs(p.pid()) ==
K0S)
return true;
275 if (std::abs(p.pid()) ==
K0L)
return true;
276 if (std::abs(p.pid()) ==
K0)
return true;
277 if (p.last() % 2 != 1 )
return false;
278 if (p.max_digit(1,3) >=
QUARK_LIMIT )
return false;
279 if (p.min_digit(1,3) == 0 )
return false;
280 if (*(p.second.rbegin() + 2) < *(p.second.rbegin() + 1) )
return false;
281 if (*(p.second.rbegin() + 2) == *(p.second.rbegin() + 1) && p.pid() < 0 )
return false;
282 if (p.ndigits() == 3 )
return true;
283 if (*(p.second.rbegin() + 3) != 0 )
return false;
284 if (p.ndigits() == 5 && p(0) == 1 )
return true;
285 if (p.ndigits() == 5 && p(0) == 2 && p.last() > 1 )
return true;
286 if (p.ndigits() == 5 && p(0) == 3 && p.last() > 1 )
return true;
287 if (p.ndigits() == 6 && p.last() % 2 == 1 )
return true;
288 if (p.ndigits() == 7 && p(0) == 9 && p(1) == 0 )
return true;
298 return (*(p.second.rbegin() + 2) >
SQUARK && p.last() > 0 && *(p.second.rbegin() + 1) == *(p.second.rbegin() + 2));
306 if (p.ndigits() < 4 )
return false;
307 if (p.max_digit(1,4) >=
QUARK_LIMIT )
return false;
308 if (p.min_digit(1,4) == 0)
return false;
309 if (p.ndigits() == 4 && (p.last() == 2 || p.last() == 4|| p.last() == 6|| p.last() == 8) )
return true;
311 if (p.ndigits() == 5 && p(0) == 1 && (p.last() == 2 || p.last() == 4) )
return true;
312 if (p.ndigits() == 5 && p(0) == 3 && (p.last() == 2 || p.last() == 4) )
return true;
314 if (p.ndigits() == 6 ) {
315 if (p(0) == 1 && p(1) == 0 && p.last() == 2 )
return true;
316 if (p(0) == 1 && p(1) == 0 && p.last() == 4 )
return true;
317 if (p(0) == 1 && p(1) == 0 && p.last() == 6 )
return true;
318 if (p(0) == 1 && p(1) == 1 && p.last() == 2 )
return true;
319 if (p(0) == 1 && p(1) == 2 && p.last() == 4 )
return true;
321 if (p(0) == 2 && p(1) == 0 && p.last() == 2 )
return true;
322 if (p(0) == 2 && p(1) == 0 && p.last() == 4 )
return true;
323 if (p(0) == 2 && p(1) == 0 && p.last() == 6 )
return true;
324 if (p(0) == 2 && p(1) == 0 && p.last() == 8 )
return true;
325 if (p(0) == 2 && p(1) == 1 && p.last() == 2 )
return true;
328 if (p.ndigits() == 5 ) {
329 if (p(0) == 2 && p.last() == 2 )
return true;
330 if (p(0) == 2 && p.last() == 4 )
return true;
331 if (p(0) == 2 && p.last() == 6 )
return true;
332 if (p(0) == 5 && p.last() == 2 )
return true;
333 if (p(0) == 1 && p.last() == 6 )
return true;
334 if (p(0) == 4 && p.last() == 2 )
return true;
349 return (p.ndigits() == 9 && p(0) == 1 && p(5) == 0 &&
350 p.max_digit(1,3) <
QUARK_LIMIT && p.min_digit(1,3) > 0 &&
351 p.max_digit(4,6) <
QUARK_LIMIT && p.min_digit(4,6) > 0 &&
352 ( p(3) >= p(4) && p(6) >= p(7) ) && ( ( p(3) > p(6) ) || ( p(3) == p(6) && (p(4) >= p(7))))
366 return (p.ndigits() == 9 && p(0) == 1 &&
367 p.max_digit(1,6) <
QUARK_LIMIT && p.min_digit(1,6) > 0 &&
368 ( p(3) >= p(4) && p(4) >= p(5) && p(5) >= p(6)) );
392template <>
inline bool isBoson(
const int& p){
auto sp = std::abs(p);
return sp > 20 &&
sp < 41; }
401template <
class T>
inline bool isZ(
const T& p){
return isZ(p->pdg_id());}
402template <>
inline bool isZ(
const int& p){
return p ==
Z0BOSON; }
404template <
class T>
inline bool isW(
const T& p){
return isW(p->pdg_id());}
405template <>
inline bool isW(
const int& p){
return std::abs(p) ==
WPLUSBOSON; }
451 int ap = std::abs(p);
452 if (ap >= 81 && ap <= 100)
return true;
453 if (ap >= 901 && ap <= 930)
return true;
454 if (ap >= 998 && ap <= 999)
return true;
455 if (ap >= 1901 && ap <= 1930)
return true;
456 if (ap >= 2901 && ap <= 2930)
return true;
457 if (ap >= 3901 && ap <= 3930)
return true;
470 if (p.ndigits() > 4)
return false;
487 auto pp = p.shift(1);
return (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2) &&
isSMQuark(pp));
495 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMQuark(pp));
503 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMQuark(pp));
517 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMLepton(pp));
525 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMLepton(pp));
533 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isBoson(pp.pid()));
554 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
555 return (p.ndigits() == 7 && p(0) == 3 && (p(1) == 0 || p(1) == 1) &&
566 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
567 return (p.ndigits() == 7 && (p(0) == 4 && p(1) == 0) &&
591 if (p.ndigits() != 7 || p(0) != 1)
return false;
592 auto pp = p.shift(1);
603 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
604 auto pp = p.shift(1);
607 (pp.ndigits() == 4 && p(0) == 1 && pp(0) ==
COMPOSITEGLUON && pp.min_digit(1,3) > 0 && pp.max_digit(1,3) <
QUARK_LIMIT && pp(2) <= pp(1) && (pp.last() == 1 || pp.last() == 3)) ||
609 (pp.ndigits() == 3 && pp.min_digit(1,3) > 0 && pp.max_digit(1,3) <
QUARK_LIMIT && pp(1) <= pp(0) && pp.last() == 2)
618 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
619 auto pp = p.shift(1);
622 (pp.ndigits() == 5 && p(0) == 1 && pp(0) ==
COMPOSITEGLUON && pp.min_digit(1,4) > 0 && pp.max_digit(1,4) <
QUARK_LIMIT && pp(2) <= pp(1) && pp(3) <= pp(2) && (pp.last() == 2 || pp.last() == 4)) ||
624 (pp.ndigits() == 4 && pp.min_digit(1,4) > 0 && pp.max_digit(1,4) <
QUARK_LIMIT && pp(1) <= pp(0) && pp(2) <= pp(1) && (pp.last() == 1 || pp.last() == 3))
637template <
class T>
inline bool hasSquark(
const T& p,
const int& q) {
return hasSquark(p->pdg_id(), q); }
639 auto pp = p.shift(1);
return (
650template <
class T>
inline bool isSUSY(
const T& p){
return isSUSY(p->pdg_id());}
662template <
class T>
inline bool isKK(
const T& p){
return isKK(p->pdg_id());}
663template <>
inline bool isKK(
const DecodedPID& p){
return (p.ndigits() == 7 && (p(0) == 5 || p(0) == 6 ) && (p(1) != 9) );}
673template <>
inline bool isMonopole(
const DecodedPID& p){
return (p.ndigits() == 7 && p(0) == 4 && p(1) == 1 && (p(2) == 1 || p(2) == 2 ) && p(6) == 0);}
685template <
class T>
inline bool isDM(
const T& p){
return isDM(p->pdg_id());}
686template <>
inline bool isDM(
const int& p){
687 auto sp = std::abs(p);
689 return (
sp >= 51 &&
sp <= 60) || (value_digits.ndigits() == 7 && value_digits(0) == 5 && value_digits(1) == 9) ||
sp ==
DARKPHOTON; }
698 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
699 return (p.ndigits() == 7 && p(0) == 4 && p(1) == 9 &&
731 if (std::abs(p.pid()) ==
PROTON)
return true;
732 if (p.ndigits() != 10)
return false;
733 if (p(0) != 1 || p(1) != 0 )
return false;
736 const int A = p(8) + 10*p(7) + 100*p(6);
737 const int Z = p(5) + 10*p(4) + 100*p(3);
743template <
class T>
inline bool hasQuark(
const T& p,
const int& q);
745 if (
isQuark(p.pid())) {
return (std::abs(p.pid()) == q );}
746 if (
isMeson(p)) {
return *(p.second.rbegin() + 1) == q ||*(p.second.rbegin()+2) ==q;}
747 if (
isDiquark(p)) {
auto i = std::find(p.second.rbegin() + 2,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
748 if (
isBaryon(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
749 if (
isTetraquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+5,q);
return (i!=p.second.rbegin()+5);}
750 if (
isPentaquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+6,q);
return (i!=p.second.rbegin()+6);}
751 if (
isNucleus(p) && std::abs(p.pid()) !=
PROTON) {
return (q == 1 || q == 2 || (q==3 && p(2) > 0));}
753 auto pp = p.shift(1);
754 if ( pp.ndigits() == 1 ) {
return false; }
755 if ( pp.ndigits() == 3 ) {
return (pp(1) == q); }
756 if ( pp.ndigits() == 4 ) {
return (pp(1) == q || pp(2) == q); }
757 if ( pp.ndigits() == 5 ) {
return (pp(1) == q || pp(2) == q || pp(3) == q); }
758 if ( pp.ndigits() > 5 ) { pp = pp.shift(1); }
778 if (
isQuark(p.pid())) {
return (p.pid() > 0) ? 1 : - 1;}
779 if (
isDiquark(p)) {
return (p.pid() > 0) ? 2 : -2; }
783 const int result = 3*p(8) + 30*p(7) + 300*p(6);
784 return (p.pid() > 0) ? result : -result;
787 auto pp = p.shift(1);
791 if ( pp.ndigits() == 4 ) {
return 0; }
792 if ( pp.ndigits() == 5) {
return (p.pid() > 0) ? 3 : -3; }
794 if (pp.ndigits() == 3) {
return 0; }
795 if (pp.ndigits() == 4) {
return (p.pid() > 0) ? 3 : -3; }
813 +0, +0, +0, -1, +0, +0, +0, +0, +0, +0 };
816 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? -p(2) : p(2); }
817 if (
isStrange(p.pid())) {
return (p.pid() > 0) ? -1 : 1; }
819 if (std::abs(p.pid()) ==
K0) {
return (p.pid() > 0) ? 1 : -1; }
824 bool classified =
false;
825 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
827 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
830 if (!classified &&
isSUSY(p)) {
832 auto pp = p.shift(1);
836 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
840 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
841 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
843 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
847 return p.pid() > 0 ? result : -result;
854 if (std::abs(p.pid()) ==
LAMBDA0) {
return (p.pid() > 0) ? 1 : -1; }
855 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? p(2) : -p(2); }
863 if (std::abs(p.pid()) ==
PROTON) {
return (p.pid() > 0) ? 1 : -1; }
865 const int result = p(5) + 10*p(4) + 100*p(3);
866 return (p.pid() > 0) ? result : -result;
874template <
class T>
inline bool isBSM(
const T& p){
return isBSM(p->pdg_id());}
877 if (std::abs(p.pid()) > 16 && std::abs(p.pid()) < 19)
return true;
878 if (std::abs(p.pid()) > 31 && std::abs(p.pid()) < 39)
return true;
879 if (std::abs(p.pid()) > 39 && std::abs(p.pid()) < 81)
return true;
880 if (std::abs(p.pid()) > 6 && std::abs(p.pid()) < 9)
return true;
881 if (
isSUSY(p))
return true;
886 if (
isKK(p))
return true;
889 if (
isDM(p.pid()))
return true;
892template <>
inline bool isBSM(
const int& p){
894 if (std::abs(p) > 16 && std::abs(p) < 19)
return true;
895 if (std::abs(p) > 31 && std::abs(p) < 38)
return true;
896 if (std::abs(p) > 39 && std::abs(p) < 81)
return true;
897 if (std::abs(p) > 6 && std::abs(p) < 9)
return true;
912template <>
inline bool isValid(
const int& p){
if (!p)
return false;
if (std::abs(p) < 42)
return true;
919 if (
isQuark(p.pid())) {
return std::abs(p.pid());}
920 if (
isMeson(p)) {
return p.max_digit(1,3);}
921 if (
isDiquark(p)) {
return p.max_digit(2,4);}
922 if (
isBaryon(p)) {
return p.max_digit(1,4);}
926 auto pp = p.shift(1);
927 if ( pp.ndigits() == 1 ) {
return 0; }
928 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
929 if ( pp.ndigits() > 3 ) { pp = pp.shift(1); }
972 const int pid = std::abs(p);
973 return ( pid == 511 ||
1007 const int pid = std::abs(p);
1008 return ( pid == 411 ||
1025template <
class T>
inline double charge(
const T& p){
1036 auto ap = std::abs(p.pid());
1038 if (ap ==
K0)
return 0;
1041 if (ap ==
MAVTOP)
return p.pid() > 0 ? 2 : -2;
1046 bool classified =
false;
1047 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1049 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
1053 if (!classified &&
isSUSY(p)) {
1055 auto pp = p.shift(1);
1056 if (pp.ndigits() < 3 ) {
return charge3(pp); }
1059 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
1063 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
1064 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
1067 auto pp = p.shift(2);
1068 if (!classified &&
isMeson(pp)) { classified =
true; nq = 2;
if ((*(pp.second.rbegin()+2)) == 2||(*(pp.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1070 if (!classified &&
isBaryon(pp)) { classified =
true; nq = 3; }
1073 auto pp = p.shift(2);
1074 auto ap = std::abs(pp.pid());
1077 if (!classified &&
isKK(p)) {
1078 auto pp = p.shift(2);
1079 auto ap = std::abs(pp.pid());
1083 if (!classified &&
isDM(p.pid())) {
1084 if (p.ndigits() == 7){
1085 auto pp = p.shift(3);
1086 auto ap = std::abs(pp.pid());
1093 result = 3*(p(3)*100 + p(4)*10 + p(5));
1094 return ( (p.pid() > 0 && p(2) == 1) || (p.pid() < 0 && p(2) == 2) ) ? result : -result;
1097 double abs_charge = 0.0;
1098 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1099 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1100 int abs_threecharge =
static_cast<int>(std::round(abs_charge * 3.));
1101 return p.pid() > 0 ? abs_threecharge : -1 * abs_threecharge;
1103 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
1107 return p.pid() > 0 ? result : -result;
1110 int ap = std::abs(p);
1117template <
class T>
inline bool isNeutral(
const T& p){
return p->pdg_id() != 0 &&
charge3(p) == 0;}
1124 double abs_charge = 0;
1125 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1126 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1127 return p.pid() > 0 ? abs_charge : -1 * abs_charge;
1139template <
class T>
inline int spin2(
const T& p) {
return spin2(p->pdg_id()); }
1142 auto pp = p.shift(1);
1143 auto ap = std::abs(pp.pid());
1148 auto pp = p.shift(2);
1149 if (
isHadron(pp)) {
return pp.last()-1; }
1152 auto pp = p.shift(2);
1153 auto ap = std::abs(pp.pid());
1156 if (
isDM(std::abs(p.pid()))) {
1157 if (p.ndigits() == 7) {
1158 auto pp = p.shift(3);
1159 auto ap = std::abs(pp.pid());
1161 }
else if (std::abs(p.pid()) <
TABLESIZE) {
1162 return std::abs(
double_spin.at(std::abs(p.pid())));
1165 auto ap = std::abs(p.pid());
1166 if (ap ==
K0S) {
return 0; }
1167 if (ap ==
K0L) {
return 0; }
1168 if (ap ==
MAVTOP) {
return 1; }
1171 if (
isHadron(p)) {
return p.last()-1; }
1175 return p.last() > 0 ? 1 : 0;
1179template <
class T>
inline double spin(
const T& p) {
return spin(p->pdg_id()); }
1181template <>
inline double spin(
const int& p){
auto value_digits =
DecodedPID(p);
return spin(value_digits);}
1188 std::vector<int> quarks;
1189 if (
isQuark(pp.pid())) { quarks.push_back(std::abs(pp.pid())); }
1190 else if (
isDiquark(pp)) { quarks.push_back(pp(0)); quarks.push_back(pp(1)); }
1191 else if (
isMeson(pp)) { quarks.push_back(*(pp.second.rbegin() + 1)); quarks.push_back(*(pp.second.rbegin()+2)); }
1192 else if (
isBaryon(pp)) {
for (
size_t digit = 1; digit < 4; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1193 else if (
isTetraquark(pp)) {
for (
size_t digit = 1; digit < 5; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1194 else if (
isPentaquark(pp)) {
for (
size_t digit = 1; digit < 6; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1196 const int n_uquarks =
A + Z;
const int n_dquarks = 2*
A - Z - L;
const int n_squarks = L;
1197 quarks.reserve(3*
A); quarks.insert(quarks.end(), n_dquarks, 1); quarks.insert(quarks.end(), n_uquarks, 2); quarks.insert(quarks.end(), n_squarks, 3); }
1200 if ( pp.ndigits() > 1 ) {
1201 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
1202 if ( pp.ndigits() > 3 ) { pp = pp.shift(1); }
bool isValid() const
Test to see if the link can be dereferenced.
bool isGraviton(const T &p)
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
bool isWeaklyDecayingBHadron(const T &p)
static const int GRAVITON
static const int HIGGSBOSON
static const int ZDBLPRIME
int numberOfProtons(const T &p)
bool hasStrange(const T &p)
static const int TABLESIZE
bool isBottomBaryon(const T &p)
bool isBottomMeson(const T &p)
bool isRGlueball(const T &p)
PDG rule 11g: Within several scenarios of new physics, it is possible to have colored particles suffi...
bool isElectron(const T &p)
bool isBoson(const T &p)
PDG rule 9: Two-digit numbers in the range 21–30 are provided for the Standard Model gauge and Higgs ...
bool isBottom(const T &p)
bool isStrange(const T &p)
bool isExcited(const T &p)
PDG rule 11f Excited (composite) quarks and leptons are identified by setting n= 4 and nr= 0.
bool isRBaryon(const T &p)
bool isSleptonLH(const T &p)
bool isSlepton(const T &p)
int strangeness(const T &p)
bool isTransportable(const T &p)
bool isPentaquark(const T &p)
PDG rule 15 The 9-digit penta-quark codes are ±1nrnLnq1nq2nq3nq4nq5nJ, sorted such that nq1≥nq2≥nq3≥n...
static const std::array< int, 10 > is_strange
static const std::array< int, TABLESIZE > triple_charge
bool isChLepton(const T &p)
APID: the fourth generation leptons are leptons.
double baryonNumber(const T &p)
static const int RH_NU_MU
static const int ELECTRON
static const int HIGGSPLUS
bool isStrangeHadron(const T &p)
double fractionalCharge(const T &p)
static const int DQUARK
PDG Rule 1: Particles are given positive numbers, antiparticles negative numbers.
bool isLepton(const T &p)
APID: the fourth generation leptons are leptons.
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
int numberOfLambdas(const T &p)
bool isLightBaryon(const T &p)
static const int POMERON
PDG rule 8: The pomeron and odderon trajectories and a generic reggeon trajectory of states in QCD ar...
bool isQuarkonium(const T &p)
APID: states with s,sbar are not considered quarkonium.
bool isTopMeson(const T &p)
bool hasQuark(const T &p, const int &q)
bool isGaugino(const T &p)
bool isHeavyBoson(const T &p)
APID: Additional "Heavy"/"prime" versions of W and Z bosons (Used in MCTruthClassifier).
bool isTetraquark(const T &p)
PDG rule 14 The 9-digit tetra-quark codes are ±1nrnLnq1nq20nq3nq4nJ.
static const int WBOSON_LRSM
bool isCharged(const T &p)
bool isMonopole(const T &p)
PDG rule 11i Magnetic monopoles and dyons are assumed to have one unit of Dirac monopole charge and a...
bool isHeavyMeson(const T &p)
bool isSMQuark(const T &p)
bool isFourthGeneration(const T &p)
Is this a 4th generation fermion?
static const int QUARK_LIMIT
bool isSuperpartner(const T &p)
static const int POSITRON
bool isHiddenValley(const T &p)
PDG rule 11k Hidden Valley particles have n = 4 and n_r = 9, and trailing numbers in agreement with t...
bool hasBottom(const T &p)
constexpr std::array< int, 9 > MAX_DIGIT
static const int BPRIME
PDG Rule 11a: The standard fourth generation of fermions is included by analogy with the first three.
bool isSquarkLH(const T &p)
static const int LEPTOQUARK
bool isGlueball(const T &p)
PDG rule 7: The gluon, when considered as a gauge boson, has official number 21.
bool isLightHadron(const T &p)
bool isTechnicolor(const T &p)
PDG rule 11e Technicolor states have n = 3, with technifermions treated like ordinary fermions.
double charge(const T &p)
bool isResonance(const T &p)
bool isStrongInteracting(const T &p)
bool isParton(const T &p)
bool isCCbarMeson(const T &p)
int baryonNumber3(const T &p)
static const int MAGNESIUM
constexpr bool hasAllowedNumberOfDigits(int p, Ns... digits)
bool isBBbarMeson(const T &p)
bool isTopHadron(const T &p)
bool isEMInteracting(const T &p)
bool isStrangeBaryon(const T &p)
static const int RH_NU_E
PDG Rule 12: Occasionally program authors add their own states.
bool hasCharm(const T &p)
bool isSleptonRH(const T &p)
static const int LAMBDAB0
bool isBottomHadron(const T &p)
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
std::vector< int > containedQuarks(const T &p)
bool isMeson(const T &p)
Table 43.1 PDG rule 5a: The numbers specifying the meson’s quark content conform to the convention nq...
static const int GEANTINOPLUS
PDG rule 10: Codes 81–100 are reserved for generator-specific pseudoparticles and concepts.
bool isGeantino(const T &p)
bool isDiquark(const T &p)
PDG rule 4 Diquarks have 4-digit numbers with nq1 >= nq2 and nq3 = 0 APID: states with top quarks are...
bool isGenericMultichargedParticle(const T &p)
In addition, there is a need to identify ”Q-ball” and similar very exotic (multi-charged) particles w...
bool isNeutrino(const T &p)
APID: the fourth generation neutrinos are neutrinos.
static const int WPLUSPRIME
bool isRMeson(const T &p)
static const int GEANTINO0
static const int COMPOSITEGLUON
bool isCharmBaryon(const T &p)
bool isSquarkRH(const T &p)
bool isPhoton(const T &p)
bool isHeavyBaryon(const T &p)
static const int RH_NU_TAU
double threeCharge(const T &p)
bool isKK(const T &p)
PDG rule 11h A black hole in models with extra dimensions has code 5000040.
bool isCharmMeson(const T &p)
bool isNeutrinoRH(const T &p)
PDG rule 12: Occasionally program authors add their own states.
bool isBaryon(const T &p)
Table 43.2 APID: states with fourth generation quarks are not baryons.
bool hasSquark(const T &p, const int &q)
int leadingQuark(const T &p)
bool isLeptoQuark(const T &p)
PDG rule 11c: “One-of-a-kind” exotic particles are assigned numbers in the range 41–80.
constexpr std::array< int, 9 > MIN_DIGIT
Implementation of classification functions according to PDG2022.
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
static const int LAMBDACPLUS
bool isSMNeutrino(const T &p)
bool isMSSMHiggs(const T &p)
APID: Additional Higgs bosons for MSSM (Used in MCTruthClassifier).
bool isSquark(const T &p)
PDG rule 11d Fundamental supersymmetric particles are identified by adding a nonzero n to the particl...
bool isTopBaryon(const T &p)
bool isTrajectory(const T &p)
PDG rule 8: The pomeron and odderon trajectories and a generic reggeon trajectory of states in QCD ar...
static const int WPLUSBOSON
static const int HIGGSPLUSPLUS
static const int DARKPHOTON
PDG Ids for Mavtop madgraph UFO model found under DarkX.
bool isCharmHadron(const T &p)
bool isRHadron(const T &p)
bool isHadron(const T &p)
bool isLightMeson(const T &p)
bool isStrangeMeson(const T &p)
bool isHeavyHadron(const T &p)
bool isGenSpecific(const T &p)
Main Table for MC internal use 81–100,901–930,998-999,1901–1930,2901–2930, and 3901–3930.
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
bool isDM(const T &p)
PDG rule 11j: The nature of Dark Matter (DM) is not known, and therefore a definitive classification ...
bool isPythia8Specific(const T &p)
bool isNeutral(const T &p)
static const std::array< int, TABLESIZE > double_spin
bool isWeaklyDecayingCHadron(const T &p)
int min_digit(const int m, const int n) const
DecodedPID shift(const size_t n) const
int max_digit(const int m, const int n) const
const int & operator()(const size_t n) const
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
hold the test vectors and ease the comparison