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
87static const int TAU = 15;
119static const int PI0 = 111;
120static const int K0L = 130;
122static const int K0S = 310;
123static const int K0 = 311;
127static const int D0 = 421;
130static const int B0 = 511;
149static const int LEAD = 1000822080;
155static const int NEON = 1000100200;
182template <>
inline bool isQuark(
const int& p) {
return p != 0 && (std::abs(p) <=
TPRIME || std::abs(p) ==
MAVTOP);}
187template <>
inline bool isSMQuark(
const int& p) {
return p != 0 && std::abs(p) <=
TQUARK;}
194template <>
inline bool isCharm(
const int& p){
return std::abs(p) ==
CQUARK;}
199template <
class T>
inline bool isTop(
const T& p){
return isTop(p->pdg_id());}
200template <>
inline bool isTop(
const int& p){
return std::abs(p) ==
TQUARK;}
219template <
class T>
inline bool isMuon(
const T& p){
return isMuon(p->pdg_id());}
220template <>
inline bool isMuon(
const int& p){
return std::abs(p) ==
MUON;}
222template <
class T>
inline bool isTau(
const T& p){
return isTau(p->pdg_id());}
223template <>
inline bool isTau(
const int& p){
return std::abs(p) ==
TAU;}
243 if ( p.ndigits() == 4 && p(0) >= p(1) && p(1) != 0 && p(2) == 0 && (p.last() == 1 || p.last() == 3)
260 if (p.ndigits() < 3 )
return false;
261 if (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2))
return false;
262 if (std::abs(p.pid()) ==
K0S)
return true;
263 if (std::abs(p.pid()) ==
K0L)
return true;
264 if (std::abs(p.pid()) ==
K0)
return true;
265 if (p.last() % 2 != 1 )
return false;
266 if (p.max_digit(1,3) >=
QUARK_LIMIT )
return false;
267 if (p.min_digit(1,3) == 0 )
return false;
268 if (*(p.second.rbegin() + 2) < *(p.second.rbegin() + 1) )
return false;
269 if (*(p.second.rbegin() + 2) == *(p.second.rbegin() + 1) && p.pid() < 0 )
return false;
270 if (p.ndigits() == 3 )
return true;
271 if (*(p.second.rbegin() + 3) != 0 )
return false;
272 if (p.ndigits() == 5 && p(0) == 1 )
return true;
273 if (p.ndigits() == 5 && p(0) == 2 && p.last() > 1 )
return true;
274 if (p.ndigits() == 5 && p(0) == 3 && p.last() > 1 )
return true;
275 if (p.ndigits() == 6 && p.last() % 2 == 1 )
return true;
276 if (p.ndigits() == 7 && p(0) == 9 && p(1) == 0 )
return true;
286 return (*(p.second.rbegin() + 2) >
SQUARK && p.last() > 0 && *(p.second.rbegin() + 1) == *(p.second.rbegin() + 2));
294 if (p.ndigits() < 4 )
return false;
295 if (p.max_digit(1,4) >=
QUARK_LIMIT )
return false;
296 if (p.min_digit(1,4) == 0)
return false;
297 if (p.ndigits() == 4 && (p.last() == 2 || p.last() == 4|| p.last() == 6|| p.last() == 8) )
return true;
299 if (p.ndigits() == 5 && p(0) == 1 && (p.last() == 2 || p.last() == 4) )
return true;
300 if (p.ndigits() == 5 && p(0) == 3 && (p.last() == 2 || p.last() == 4) )
return true;
302 if (p.ndigits() == 6 ) {
303 if (p(0) == 1 && p(1) == 0 && p.last() == 2 )
return true;
304 if (p(0) == 1 && p(1) == 0 && p.last() == 4 )
return true;
305 if (p(0) == 1 && p(1) == 0 && p.last() == 6 )
return true;
306 if (p(0) == 1 && p(1) == 1 && p.last() == 2 )
return true;
307 if (p(0) == 1 && p(1) == 2 && p.last() == 4 )
return true;
309 if (p(0) == 2 && p(1) == 0 && p.last() == 2 )
return true;
310 if (p(0) == 2 && p(1) == 0 && p.last() == 4 )
return true;
311 if (p(0) == 2 && p(1) == 0 && p.last() == 6 )
return true;
312 if (p(0) == 2 && p(1) == 0 && p.last() == 8 )
return true;
313 if (p(0) == 2 && p(1) == 1 && p.last() == 2 )
return true;
316 if (p.ndigits() == 5 ) {
317 if (p(0) == 2 && p.last() == 2 )
return true;
318 if (p(0) == 2 && p.last() == 4 )
return true;
319 if (p(0) == 2 && p.last() == 6 )
return true;
320 if (p(0) == 5 && p.last() == 2 )
return true;
321 if (p(0) == 1 && p.last() == 6 )
return true;
322 if (p(0) == 4 && p.last() == 2 )
return true;
337 return (p.ndigits() == 9 && p(0) == 1 && p(5) == 0 &&
338 p.max_digit(1,3) <
QUARK_LIMIT && p.min_digit(1,3) > 0 &&
339 p.max_digit(4,6) <
QUARK_LIMIT && p.min_digit(4,6) > 0 &&
340 ( p(3) >= p(4) && p(6) >= p(7) ) && ( ( p(3) > p(6) ) || ( p(3) == p(6) && (p(4) >= p(7))))
354 return (p.ndigits() == 9 && p(0) == 1 &&
355 p.max_digit(1,6) <
QUARK_LIMIT && p.min_digit(1,6) > 0 &&
356 ( p(3) >= p(4) && p(4) >= p(5) && p(5) >= p(6)) );
380template <>
inline bool isBoson(
const int& p){
auto sp = std::abs(p);
return sp > 20 &&
sp < 41; }
389template <
class T>
inline bool isZ(
const T& p){
return isZ(p->pdg_id());}
390template <>
inline bool isZ(
const int& p){
return p ==
Z0BOSON; }
392template <
class T>
inline bool isW(
const T& p){
return isW(p->pdg_id());}
393template <>
inline bool isW(
const int& p){
return std::abs(p) ==
WPLUSBOSON; }
437 int ap = std::abs(p);
438 if (ap >= 81 && ap <= 100)
return true;
439 if (ap >= 901 && ap <= 930)
return true;
440 if (ap >= 998 && ap <= 999)
return true;
441 if (ap >= 1901 && ap <= 1930)
return true;
442 if (ap >= 2901 && ap <= 2930)
return true;
443 if (ap >= 3901 && ap <= 3930)
return true;
453 if (p.ndigits() > 4)
return false;
470 auto pp = p.shift(1);
return (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2) &&
isSMQuark(pp));
478 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMQuark(pp));
486 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMQuark(pp));
500 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMLepton(pp));
508 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMLepton(pp));
516 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isBoson(pp.pid()));
537 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
538 return (p.ndigits() == 7 && p(0) == 3 && (p(1) == 0 || p(1) == 1) &&
549 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
550 return (p.ndigits() == 7 && (p(0) == 4 && p(1) == 0) &&
574 if (p.ndigits() != 7 || p(0) != 1)
return false;
575 auto pp = p.shift(1);
586 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
587 auto pp = p.shift(1);
590 (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)) ||
592 (pp.ndigits() == 3 && pp.min_digit(1,3) > 0 && pp.max_digit(1,3) <
QUARK_LIMIT && pp(1) <= pp(0) && pp.last() == 2)
601 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
602 auto pp = p.shift(1);
605 (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)) ||
607 (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))
620template <
class T>
inline bool hasSquark(
const T& p,
const int& q) {
return hasSquark(p->pdg_id(), q); }
622 auto pp = p.shift(1);
return (
633template <
class T>
inline bool isSUSY(
const T& p){
return isSUSY(p->pdg_id());}
645template <
class T>
inline bool isKK(
const T& p){
return isKK(p->pdg_id());}
646template <>
inline bool isKK(
const DecodedPID& p){
return (p.ndigits() == 7 && (p(0) == 5 || p(0) == 6 ) && (p(1) != 9) );}
656template <>
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);}
668template <
class T>
inline bool isDM(
const T& p){
return isDM(p->pdg_id());}
669template <>
inline bool isDM(
const int& p){
670 auto sp = std::abs(p);
672 return (
sp >= 51 &&
sp <= 60) || (value_digits.ndigits() == 7 && value_digits(0) == 5 && value_digits(1) == 9) ||
sp ==
DARKPHOTON; }
681 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
682 return (p.ndigits() == 7 && p(0) == 4 && p(1) == 9 &&
714 if (std::abs(p.pid()) ==
PROTON)
return true;
715 if (p.ndigits() != 10)
return false;
716 if (p(0) != 1 || p(1) != 0 )
return false;
719 const int A = p(8) + 10*p(7) + 100*p(6);
720 const int Z = p(5) + 10*p(4) + 100*p(3);
726template <
class T>
inline bool hasQuark(
const T& p,
const int& q);
728 if (
isQuark(p.pid())) {
return (std::abs(p.pid()) == q );}
729 if (
isMeson(p)) {
return *(p.second.rbegin() + 1) == q ||*(p.second.rbegin()+2) ==q;}
730 if (
isDiquark(p)) {
auto i = std::find(p.second.rbegin() + 2,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
731 if (
isBaryon(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
732 if (
isTetraquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+5,q);
return (i!=p.second.rbegin()+5);}
733 if (
isPentaquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+6,q);
return (i!=p.second.rbegin()+6);}
734 if (
isNucleus(p) && std::abs(p.pid()) !=
PROTON) {
return (q == 1 || q == 2 || (q==3 && p(2) > 0));}
736 auto pp = p.shift(1);
737 if ( pp.ndigits() == 1 ) {
return false; }
738 if ( pp.ndigits() == 3 ) {
return (pp(1) == q); }
739 if ( pp.ndigits() == 4 ) {
return (pp(1) == q || pp(2) == q); }
740 if ( pp.ndigits() == 5 ) {
return (pp(1) == q || pp(2) == q || pp(3) == q); }
741 if ( pp.ndigits() > 5 ) { pp = pp.shift(1); }
761 if (
isQuark(p.pid())) {
return (p.pid() > 0) ? 1 : - 1;}
762 if (
isDiquark(p)) {
return (p.pid() > 0) ? 2 : -2; }
766 const int result = 3*p(8) + 30*p(7) + 300*p(6);
767 return (p.pid() > 0) ? result : -result;
770 auto pp = p.shift(1);
774 if ( pp.ndigits() == 4 ) {
return 0; }
775 if ( pp.ndigits() == 5) {
return (p.pid() > 0) ? 3 : -3; }
777 if (pp.ndigits() == 3) {
return 0; }
778 if (pp.ndigits() == 4) {
return (p.pid() > 0) ? 3 : -3; }
796 +0, +0, +0, -1, +0, +0, +0, +0, +0, +0 };
799 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? -p(2) : p(2); }
800 if (
isStrange(p.pid())) {
return (p.pid() > 0) ? -1 : 1; }
802 if (std::abs(p.pid()) ==
K0) {
return (p.pid() > 0) ? 1 : -1; }
807 bool classified =
false;
808 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
810 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
813 if (!classified &&
isSUSY(p)) {
815 auto pp = p.shift(1);
819 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
823 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
824 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
826 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
830 return p.pid() > 0 ? result : -result;
837 if (std::abs(p.pid()) ==
LAMBDA0) {
return (p.pid() > 0) ? 1 : -1; }
838 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? p(2) : -p(2); }
846 if (std::abs(p.pid()) ==
PROTON) {
return (p.pid() > 0) ? 1 : -1; }
848 const int result = p(5) + 10*p(4) + 100*p(3);
849 return (p.pid() > 0) ? result : -result;
857template <
class T>
inline bool isBSM(
const T& p){
return isBSM(p->pdg_id());}
860 if (std::abs(p.pid()) > 16 && std::abs(p.pid()) < 19)
return true;
861 if (std::abs(p.pid()) > 31 && std::abs(p.pid()) < 39)
return true;
862 if (std::abs(p.pid()) > 39 && std::abs(p.pid()) < 81)
return true;
863 if (std::abs(p.pid()) > 6 && std::abs(p.pid()) < 9)
return true;
864 if (
isSUSY(p))
return true;
869 if (
isKK(p))
return true;
872 if (
isDM(p.pid()))
return true;
875template <>
inline bool isBSM(
const int& p){
877 if (std::abs(p) > 16 && std::abs(p) < 19)
return true;
878 if (std::abs(p) > 31 && std::abs(p) < 38)
return true;
879 if (std::abs(p) > 39 && std::abs(p) < 81)
return true;
880 if (std::abs(p) > 6 && std::abs(p) < 9)
return true;
895template <>
inline bool isValid(
const int& p){
if (!p)
return false;
if (std::abs(p) < 42)
return true;
902 if (
isQuark(p.pid())) {
return std::abs(p.pid());}
903 if (
isMeson(p)) {
return p.max_digit(1,3);}
904 if (
isDiquark(p)) {
return p.max_digit(2,4);}
905 if (
isBaryon(p)) {
return p.max_digit(1,4);}
909 auto pp = p.shift(1);
910 if ( pp.ndigits() == 1 ) {
return 0; }
911 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
912 if ( pp.ndigits() > 3 ) { pp = pp.shift(1); }
955 const int pid = std::abs(p);
956 return ( pid == 511 ||
990 const int pid = std::abs(p);
991 return ( pid == 411 ||
1008template <
class T>
inline double charge(
const T& p){
1019 auto ap = std::abs(p.pid());
1021 if (ap ==
K0)
return 0;
1024 if (ap ==
MAVTOP)
return p.pid() > 0 ? 2 : -2;
1029 bool classified =
false;
1030 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1032 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
1036 if (!classified &&
isSUSY(p)) {
1038 auto pp = p.shift(1);
1039 if (pp.ndigits() < 3 ) {
return charge3(pp); }
1042 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
1046 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
1047 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
1050 auto pp = p.shift(2);
1051 if (!classified &&
isMeson(pp)) { classified =
true; nq = 2;
if ((*(pp.second.rbegin()+2)) == 2||(*(pp.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1053 if (!classified &&
isBaryon(pp)) { classified =
true; nq = 3; }
1056 auto pp = p.shift(2);
1057 auto ap = std::abs(pp.pid());
1060 if (!classified &&
isKK(p)) {
1061 auto pp = p.shift(2);
1062 auto ap = std::abs(pp.pid());
1066 if (!classified &&
isDM(p.pid())) {
1067 if (p.ndigits() == 7){
1068 auto pp = p.shift(3);
1069 auto ap = std::abs(pp.pid());
1076 result = 3*(p(3)*100 + p(4)*10 + p(5));
1077 return ( (p.pid() > 0 && p(2) == 1) || (p.pid() < 0 && p(2) == 2) ) ? result : -result;
1080 double abs_charge = 0.0;
1081 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1082 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1083 int abs_threecharge =
static_cast<int>(std::round(abs_charge * 3.));
1084 return p.pid() > 0 ? abs_threecharge : -1 * abs_threecharge;
1086 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
1090 return p.pid() > 0 ? result : -result;
1093 int ap = std::abs(p);
1100template <
class T>
inline bool isNeutral(
const T& p){
return p->pdg_id() != 0 &&
charge3(p) == 0;}
1107 double abs_charge = 0;
1108 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1109 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1110 return p.pid() > 0 ? abs_charge : -1 * abs_charge;
1122template <
class T>
inline int spin2(
const T& p) {
return spin2(p->pdg_id()); }
1125 auto pp = p.shift(1);
1126 auto ap = std::abs(pp.pid());
1131 auto pp = p.shift(2);
1132 if (
isHadron(pp)) {
return pp.last()-1; }
1135 auto pp = p.shift(2);
1136 auto ap = std::abs(pp.pid());
1139 if (
isDM(std::abs(p.pid()))) {
1140 if (p.ndigits() == 7) {
1141 auto pp = p.shift(3);
1142 auto ap = std::abs(pp.pid());
1144 }
else if (std::abs(p.pid()) <
TABLESIZE) {
1145 return std::abs(
double_spin.at(std::abs(p.pid())));
1148 auto ap = std::abs(p.pid());
1149 if (ap ==
K0S) {
return 0; }
1150 if (ap ==
K0L) {
return 0; }
1151 if (ap ==
MAVTOP) {
return 1; }
1154 if (
isHadron(p)) {
return p.last()-1; }
1158 return p.last() > 0 ? 1 : 0;
1162template <
class T>
inline double spin(
const T& p) {
return spin(p->pdg_id()); }
1164template <>
inline double spin(
const int& p){
auto value_digits =
DecodedPID(p);
return spin(value_digits);}
1171 std::vector<int> quarks;
1172 if (
isQuark(pp.pid())) { quarks.push_back(std::abs(pp.pid())); }
1173 else if (
isDiquark(pp)) { quarks.push_back(pp(0)); quarks.push_back(pp(1)); }
1174 else if (
isMeson(pp)) { quarks.push_back(*(pp.second.rbegin() + 1)); quarks.push_back(*(pp.second.rbegin()+2)); }
1175 else if (
isBaryon(pp)) {
for (
size_t digit = 1; digit < 4; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1176 else if (
isTetraquark(pp)) {
for (
size_t digit = 1; digit < 5; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1177 else if (
isPentaquark(pp)) {
for (
size_t digit = 1; digit < 6; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1179 const int n_uquarks =
A + Z;
const int n_dquarks = 2*
A - Z - L;
const int n_squarks = L;
1180 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); }
1183 if ( pp.ndigits() > 1 ) {
1184 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
1185 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)
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
bool isSquarkLH(const T &p)
static const int LEPTOQUARK
bool isGlueball(const T &p)
APID: Definition of Glueballs: SM glueballs 99X (X=1,5), 999Y (Y=3,7).
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: Generator defined PDG ID values for right handed neutrinos and corresponding W+ boson fr...
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: APID: Helper function for right-handed neutrino states These are generator defined PDG I...
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