4#ifndef TRUTHUTILS_ATLASPID_H
5#define TRUTHUTILS_ATLASPID_H
16class DecodedPID:
public std::pair<int,std::vector<int>> {
20 this->second.reserve(10);
22 for(; ap; ap/=10) this->second.push_back( ap%10 );
26 inline const int&
operator()(
const size_t n)
const {
return this->second.at(n);}
27 inline const int&
last()
const {
return this->second.back();}
28 inline const int&
pid()
const {
return this->first;}
29 inline int max_digit(
const int m,
const int n)
const {
return *std::max_element(second.rbegin() + m, second.rbegin() + n);}
30 inline int min_digit(
const int m,
const int n)
const {
return *std::min_element(second.rbegin() + m, second.rbegin() + n);}
31 inline size_t ndigits()
const {
return this->second.size();}
34static const int TABLESIZE = 100;
35static const std::array<int,TABLESIZE> triple_charge = {
36 +0, -1, +2, -1, +2, -1, +2, -1, +2, +0,
37 +0, -3, +0, -3, +0, -3, +0, -3, +0, +0,
38 +0, +0, +0, +0, +3, +0, +0, +0, +0, +0,
39 +0, +0, +0, +0, +3, +0, +0, +3, +6, +0,
40 +0, +0, -1, +0, +0, +0, +0, +0, +0, +0,
41 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
42 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
43 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
44 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
45 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0
50static const std::array<int,TABLESIZE> double_spin = {
51 +0, +1, +1, +1, +1, +1, +1, +1, +1, +0,
52 +0, +1, +1, +1, +1, +1, +1, +1, +1, +0,
53 +2, +2, +2, +2, +2, +0, +0, +0, +0, +0,
54 +0, +0, +2, +2, +2, +0, +0, +0, +0, +4,
55 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
56 +0, +0, +1, +2, +0, +2, +0, +1, +2, +0,
57 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
58 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
59 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0,
60 +0, +0, +0, +0, +0, +0, +0, +0, +0, +0
64static const int DQUARK = 1;
65static const int UQUARK = 2;
66static const int SQUARK = 3;
67static const int CQUARK = 4;
68static const int BQUARK = 5;
69static const int TQUARK = 6;
70static const int BPRIME = 7;
71static const int TPRIME = 8;
72static const int QUARK_LIMIT = BPRIME;
74static const int ELECTRON = 11;
75static const int POSITRON = -ELECTRON;
76static const int NU_E = 12;
77static const int MUON = 13;
78static const int NU_MU = 14;
79static const int TAU = 15;
80static const int NU_TAU = 16;
81static const int LPRIME = 17;
82static const int NUPRIME = 18;
84static const int GLUON = 21;
86static const int COMPOSITEGLUON = 9;
87static const int PHOTON = 22;
88static const int Z0BOSON = 23;
89static const int WPLUSBOSON = 24;
90static const int HIGGSBOSON = 25;
91static const int ZPRIME = 32;
92static const int ZDBLPRIME = 33;
93static const int WPLUSPRIME = 34;
94static const int HIGGS2 = 35;
95static const int HIGGS3 = 36;
96static const int HIGGSPLUS = 37;
97static const int HIGGSPLUSPLUS = 38;
98static const int GRAVITON = 39;
99static const int HIGGS4 = 40;
100static const int LEPTOQUARK = 42;
106static const int DARKPHOTON = 60000;
107static const int MAVTOP = 60001;
109static const int PIPLUS = 211;
110static const int PIMINUS = -PIPLUS;
111static const int PI0 = 111;
112static const int K0L = 130;
114static const int K0S = 310;
115static const int K0 = 311;
116static const int KPLUS = 321;
117static const int DPLUS = 411;
118static const int DSTAR = 413;
119static const int D0 = 421;
120static const int DSPLUS = 431;
121static const int JPSI = 443;
122static const int B0 = 511;
123static const int BCPLUS = 541;
124static const int PROTON = 2212;
125static const int NEUTRON = 2112;
126static const int LAMBDA0 = 3122;
127static const int LAMBDACPLUS = 4122;
128static const int LAMBDAB0 = 5122;
129static const int PSI2S = 20443;
136static const int RH_NU_E = 9900012;
137static const int RH_NU_MU = 9900014;
138static const int RH_NU_TAU = 9900016;
139static const int WBOSON_LRSM = 9900024;
141static const int LEAD = 1000822080;
142static const int OXYGEN = 1000080160;
143static const int NEON = 1000100200;
144static const int HELIUM = 1000020040;
149static const int POMERON = 990;
150static const int ODDERON = 9990;
151static const int REGGEON = 110;
158static const int GEANTINOPLUS = 998;
159static const int GEANTINO0 = 999;
168template<>
inline bool isQuark(
const int& p) {
return p != 0 && (std::abs(p) <= TPRIME || std::abs(p) == MAVTOP);}
173template<>
inline bool isSMQuark(
const int& p) {
return p != 0 && std::abs(p) <= TQUARK;}
177template<>
inline bool isStrange(
const int& p){
return std::abs(p) == SQUARK;}
180template<>
inline bool isCharm(
const int& p){
return std::abs(p) == CQUARK;}
183template<>
inline bool isBottom(
const int& p){
return std::abs(p) == BQUARK;}
185template<
class T>
inline bool isTop(
const T& p){
return isTop(p->pdg_id());}
186template<>
inline bool isTop(
const int& p){
return std::abs(p) == TQUARK;}
190template<>
inline bool isLepton(
const int& p){
auto sp = std::abs(p);
return sp >= ELECTRON && sp <= NUPRIME; }
195template<>
inline bool isSMLepton(
const int& p){
auto sp = std::abs(p);
return sp >= ELECTRON && sp <= NU_TAU; }
200template<>
inline bool isChLepton(
const int& p){
auto sp = std::abs(p);
return sp >= ELECTRON && sp <= LPRIME && sp%2 == 1; }
203template<>
inline bool isElectron(
const int& p){
return std::abs(p) == ELECTRON;}
205template<
class T>
inline bool isMuon(
const T& p){
return isMuon(p->pdg_id());}
206template<>
inline bool isMuon(
const int& p){
return std::abs(p) ==
MUON;}
208template<
class T>
inline bool isTau(
const T& p){
return isTau(p->pdg_id());}
209template<>
inline bool isTau(
const int& p){
return std::abs(p) == TAU;}
213template<>
inline bool isNeutrino(
const int& p){
auto sp = std::abs(p);
return sp == NU_E || sp == NU_MU || sp == NU_TAU || sp == NUPRIME; }
216template<>
inline bool isSMNeutrino(
const int& p){
auto sp = std::abs(p);
return sp == NU_E || sp == NU_MU || sp == NU_TAU; }
221template<>
inline bool isFourthGeneration(
const int& p) {
return std::abs(p) == BPRIME || std::abs(p) == TPRIME || std::abs(p) == LPRIME || std::abs(p) == NUPRIME;}
229 if ( p.ndigits() == 4 && p(0) >= p(1) && p(1) !=0 && p(2) == 0 && (p.last() == 1 || p.last() == 3)
230 && p.max_digit(2,4) < QUARK_LIMIT
246 if (p.ndigits() < 3 )
return false;
247 if (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2))
return false;
248 if (std::abs(p.pid()) == K0S)
return true;
249 if (std::abs(p.pid()) == K0L)
return true;
250 if (std::abs(p.pid()) == K0)
return true;
251 if (p.last() % 2 != 1 )
return false;
252 if (p.max_digit(1,3) >= QUARK_LIMIT )
return false;
253 if (p.min_digit(1,3) == 0 )
return false;
254 if (*(p.second.rbegin() + 2) < *(p.second.rbegin() + 1) )
return false;
255 if (*(p.second.rbegin() + 2) == *(p.second.rbegin() + 1) && p.pid() < 0 )
return false;
256 if (p.ndigits() == 3 )
return true;
257 if (*(p.second.rbegin() + 3) != 0 )
return false;
258 if (p.ndigits() == 5 && p(0) == 1 )
return true;
259 if (p.ndigits() == 5 && p(0) == 2 && p.last() > 1 )
return true;
260 if (p.ndigits() == 5 && p(0) == 3 && p.last() > 1 )
return true;
261 if (p.ndigits() == 6 && p.last() % 2 == 1 )
return true;
262 if (p.ndigits() == 7 && p(0) == 9 && p(1) == 0 )
return true;
276 return (*(p.second.rbegin() + 2) > SQUARK && p.last() > 0 && *(p.second.rbegin() + 1) == *(p.second.rbegin() + 2));
284 if (p.ndigits() < 4 )
return false;
285 if (p.max_digit(1,4) >= QUARK_LIMIT )
return false;
286 if (p.min_digit(1,4) == 0)
return false;
287 if (p.ndigits() == 4 && (p.last() == 2 || p.last() == 4|| p.last() == 6|| p.last() == 8) )
return true;
289 if (p.ndigits() == 5 && p(0) == 1 && (p.last() == 2 || p.last() == 4) )
return true;
290 if (p.ndigits() == 5 && p(0) == 3 && (p.last() == 2 || p.last() == 4) )
return true;
292 if (p.ndigits() == 6 ) {
293 if (p(0) == 1 && p(1) == 0 && p.last() == 2 )
return true;
294 if (p(0) == 1 && p(1) == 0 && p.last() == 4 )
return true;
295 if (p(0) == 1 && p(1) == 0 && p.last() == 6 )
return true;
296 if (p(0) == 1 && p(1) == 1 && p.last() == 2 )
return true;
297 if (p(0) == 1 && p(1) == 2 && p.last() == 4 )
return true;
299 if (p(0) == 2 && p(1) == 0 && p.last() == 2 )
return true;
300 if (p(0) == 2 && p(1) == 0 && p.last() == 4 )
return true;
301 if (p(0) == 2 && p(1) == 0 && p.last() == 6 )
return true;
302 if (p(0) == 2 && p(1) == 0 && p.last() == 8 )
return true;
303 if (p(0) == 2 && p(1) == 1 && p.last() == 2 )
return true;
306 if (p.ndigits() == 5 ) {
307 if (p(0) == 2 && p.last() == 2 )
return true;
308 if (p(0) == 2 && p.last() == 4 )
return true;
309 if (p(0) == 2 && p.last() == 6 )
return true;
310 if (p(0) == 5 && p.last() == 2 )
return true;
311 if (p(0) == 1 && p.last() == 6 )
return true;
312 if (p(0) == 4 && p.last() == 2 )
return true;
327 return (p.ndigits() == 9 && p(0) == 1 && p(5) == 0 &&
328 p.max_digit(1,3) < QUARK_LIMIT && p.min_digit(1,3) > 0 &&
329 p.max_digit(4,6) < QUARK_LIMIT && p.min_digit(4,6) > 0 &&
330 ( p(3) >= p(4) && p(6) >= p(7) ) && ( ( p(3) > p(6) ) || ( p(3) == p(6) && (p(4) >= p(7))))
344 return (p.ndigits() == 9 && p(0) == 1 &&
345 p.max_digit(1,6) < QUARK_LIMIT && p.min_digit(1,6) > 0 &&
346 ( p(3) >= p(4) && p(4) >= p(5) && p(5) >= p(6)) );
360template<>
inline bool isTrajectory(
const int& p){
return std::abs(p) == POMERON || std::abs(p) == ODDERON || std::abs(p) == REGGEON; }
370template<>
inline bool isBoson(
const int& p){
auto sp = std::abs(p);
return sp > 20 && sp < 41; }
374template<>
inline bool isGluon(
const int& p){
return p == GLUON; }
377template<>
inline bool isPhoton(
const int& p){
return p == PHOTON; }
379template<
class T>
inline bool isZ(
const T& p){
return isZ(p->pdg_id());}
380template<>
inline bool isZ(
const int& p){
return p == Z0BOSON; }
382template<
class T>
inline bool isW(
const T& p){
return isW(p->pdg_id());}
383template<>
inline bool isW(
const int& p){
return std::abs(p) == WPLUSBOSON; }
387template<>
inline bool isHeavyBoson(
const int& p){
return p == ZPRIME || p == ZDBLPRIME || std::abs(p) == WPLUSPRIME; }
391template<>
inline bool isHiggs(
const int& p){
return p == HIGGSBOSON; }
395template<>
inline bool isMSSMHiggs(
const int& p){
return p == HIGGS2 || p == HIGGS3 || std::abs(p) == HIGGSPLUS; }
398template<>
inline bool isGraviton(
const int& p){
return p == GRAVITON; }
409template<>
inline bool isLeptoQuark(
const int& p){
return std::abs(p) == LEPTOQUARK; }
421template<>
inline bool isNeutrinoRH(
const int& p){
return (std::abs(p) == RH_NU_E || std::abs(p) == RH_NU_MU|| std::abs(p) == RH_NU_TAU);}
427 int ap = std::abs(p);
428 if (ap >= 81 && ap <= 100)
return true;
429 if (ap >= 901 && ap <= 930)
return true;
430 if (ap >= 998 && ap <= 999)
return true;
431 if (ap >= 1901 && ap <= 1930)
return true;
432 if (ap >= 2901 && ap <= 2930)
return true;
433 if (ap >= 3901 && ap <= 3930)
return true;
438template<>
inline bool isGeantino(
const int& p){
return (std::abs(p) == GEANTINO0 || std::abs(p) == GEANTINOPLUS);}
443 if (p.ndigits() > 4)
return false;
445 ( ( p.ndigits() == 3 && p(0) == COMPOSITEGLUON && p(1) == COMPOSITEGLUON && (p.last() == 1 || p.last() == 5) ) ||
446 ( p.ndigits() == 4 && p(0) == COMPOSITEGLUON && p(1) == COMPOSITEGLUON && p(2) == COMPOSITEGLUON && (p.last() == 3 || p.last() == 7) ) );
460 auto pp = p.shift(1);
return (p.ndigits() == 7 && (p(0) == 1 || p(0) == 2) &&
isSMQuark(pp));
468 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMQuark(pp));
476 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMQuark(pp));
490 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isSMLepton(pp));
498 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 2 &&
isSMLepton(pp));
506 auto pp = p.shift(1);
return (p.ndigits() == 7 && p(0) == 1 &&
isBoson(pp.pid()));
527 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
528 return (p.ndigits() == 7 && p(0) == 3 && (p(1) == 0 || p(1) == 1) &&
539 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
540 return (p.ndigits() == 7 && (p(0) == 4 && p(1) == 0) &&
564 if (p.ndigits() != 7 || p(0) != 1)
return false;
565 auto pp = p.shift(1);
567 ( ( pp.ndigits() == 3 && pp(0) == COMPOSITEGLUON && pp(1) == COMPOSITEGLUON && (pp.last() == 1 || pp.last() == 3) ) ||
568 ( pp.ndigits() == 4 && pp(0) == COMPOSITEGLUON && pp(1) == COMPOSITEGLUON && pp(2) == COMPOSITEGLUON && (pp.last() == 1 || pp.last() == 5) ) );
576 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
577 auto pp = p.shift(1);
580 (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)) ||
582 (pp.ndigits() == 3 && pp.min_digit(1,3) > 0 && pp.max_digit(1,3) < QUARK_LIMIT && pp(1) <= pp(0) && pp.last() == 2)
591 if (!(p.ndigits() == 7 && (p(0) == 1 || p(0) == 2)))
return false;
592 auto pp = p.shift(1);
595 (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)) ||
597 (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))
610template<
class T>
inline bool hasSquark(
const T& p,
const int& q) {
return hasSquark(p->pdg_id(), q); }
612 auto pp = p.shift(1);
return (
623template<
class T>
inline bool isSUSY(
const T& p){
return isSUSY(p->pdg_id());}
635template<
class T>
inline bool isKK(
const T& p){
return isKK(p->pdg_id());}
636template<>
inline bool isKK(
const DecodedPID& p){
return (p.ndigits() == 7 && (p(0) == 5 || p(0) == 6 ) && (p(1) != 9) );}
637template<>
inline bool isKK(
const int& p){
auto value_digits =
DecodedPID(p);
return isKK(value_digits);}
646template<>
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);}
658template<
class T>
inline bool isDM(
const T& p){
return isDM(p->pdg_id());}
659template<>
inline bool isDM(
const int& p){
660 auto sp = std::abs(p);
662 return (sp >= 51 && sp <= 60) || (value_digits.ndigits() == 7 && value_digits(0) == 5 && value_digits(1) == 9) || sp == DARKPHOTON; }
671 const auto& pp = (p.ndigits() == 7) ? p.shift(2) :
DecodedPID(0);
672 return (p.ndigits() == 7 && p(0) == 4 && p(1) == 9 &&
704 if (std::abs(p.pid()) == PROTON)
return true;
705 if (p.ndigits() != 10)
return false;
708 const int A = p(8) + 10*p(7) + 100*p(6);
709 const int Z = p(5) + 10*p(4) + 100*p(3);
710 return (
A >= Z && p(0) == 1 && p(1) == 0 );
715template<
class T>
inline bool hasQuark(
const T& p,
const int& q);
717 if (
isQuark(p.pid())) {
return (std::abs(p.pid()) == q );}
718 if (
isMeson(p)) {
return *(p.second.rbegin() + 1) == q ||*(p.second.rbegin()+2) ==q;}
719 if (
isDiquark(p)) {
auto i = std::find(p.second.rbegin() + 2,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
720 if (
isBaryon(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+4,q);
return (i!=p.second.rbegin()+4);}
721 if (
isTetraquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+5,q);
return (i!=p.second.rbegin()+5);}
722 if (
isPentaquark(p)) {
auto i = std::find(p.second.rbegin() + 1,p.second.rbegin()+6,q);
return (i!=p.second.rbegin()+6);}
723 if (
isNucleus(p) && std::abs(p.pid()) != PROTON) {
return (q == 1 || q == 2 || (q==3 && p(2) > 0));}
725 auto pp = p.shift(1);
726 if ( pp.ndigits() == 1 ) {
return false; }
727 if ( pp.ndigits() == 3 ) {
return (pp(1) == q); }
728 if ( pp.ndigits() == 4 ) {
return (pp(1) == q || pp(2) == q); }
729 if ( pp.ndigits() == 5 ) {
return (pp(1) == q || pp(2) == q || pp(3) == q); }
730 if ( pp.ndigits() > 5 ) { pp = pp.shift(1); }
750 if (
isQuark(p.pid())) {
return (p.pid() > 0) ? 1 : - 1;}
751 if (
isDiquark(p)) {
return (p.pid() > 0) ? 2 : -2; }
755 const int result = 3*p(8) + 30*p(7) + 300*p(6);
759 auto pp = p.shift(1);
761 if (pp(0) == COMPOSITEGLUON) {
762 if (pp(1) == COMPOSITEGLUON) {
return 0; }
763 if ( pp.ndigits() == 4 ) {
return 0; }
764 if ( pp.ndigits() == 5) {
return (p.pid() > 0) ? 3 : -3; }
766 if (pp.ndigits() == 3) {
return 0; }
767 if (pp.ndigits() == 4) {
return (p.pid() > 0) ? 3 : -3; }
784static const std::array<int,10> is_strange = {
785 +0, +0, +0, -1, +0, +0, +0, +0, +0, +0 };
788 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? -p(2) : p(2); }
789 if (
isStrange(p.pid())) {
return (p.pid() > 0) ? -1 : 1; }
791 if (std::abs(p.pid()) == K0) {
return (p.pid() > 0) ? 1 : -1; }
796 bool classified =
false;
797 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
798 if (!classified &&
isDiquark(p)) {
return is_strange.at(p(0))+is_strange.at(p(1)); }
799 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
800 if (!classified &&
isTetraquark(p)){
return is_strange.at(p(3)) + is_strange.at(p(4)) - is_strange.at(p(6)) - is_strange.at(p(7)); }
801 if (!classified &&
isPentaquark(p)){
return is_strange.at(p(3)) + is_strange.at(p(4)) + is_strange.at(p(5)) + is_strange.at(p(6)) - is_strange.at(p(7)); }
802 if (!classified &&
isSUSY(p)) {
804 auto pp = p.shift(1);
806 if (pp(0) == COMPOSITEGLUON) {
807 if (pp(1) == COMPOSITEGLUON) {
return 0; }
808 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
812 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
813 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
815 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
826 if (std::abs(p.pid()) == LAMBDA0) {
return (p.pid() > 0) ? 1 : -1; }
827 if (
isNucleus(p) && p.ndigits() == 10) {
return (p.pid() > 0) ? p(2) : -p(2); }
835 if (std::abs(p.pid()) == PROTON) {
return (p.pid() > 0) ? 1 : -1; }
837 const int result = p(5) + 10*p(4) + 100*p(3);
846template<
class T>
inline bool isBSM(
const T& p){
return isBSM(p->pdg_id());}
848 if (p.pid() == GRAVITON || std::abs(p.pid()) == MAVTOP || p.pid() == DARKPHOTON)
return true;
849 if (std::abs(p.pid()) > 16 && std::abs(p.pid()) < 19)
return true;
850 if (std::abs(p.pid()) > 31 && std::abs(p.pid()) < 39)
return true;
851 if (std::abs(p.pid()) > 39 && std::abs(p.pid()) < 81)
return true;
852 if (std::abs(p.pid()) > 6 && std::abs(p.pid()) < 9)
return true;
853 if (
isSUSY(p))
return true;
858 if (
isKK(p))
return true;
861 if (
isDM(p.pid()))
return true;
864template<>
inline bool isBSM(
const int& p){
865 if (p == GRAVITON || std::abs(p) == MAVTOP || p == DARKPHOTON)
return true;
866 if (std::abs(p) > 16 && std::abs(p) < 19)
return true;
867 if (std::abs(p) > 31 && std::abs(p) < 38)
return true;
868 if (std::abs(p) > 39 && std::abs(p) < 81)
return true;
869 if (std::abs(p) > 6 && std::abs(p) < 9)
return true;
884template<>
inline bool isValid(
const int& p){
if (!p)
return false;
if (std::abs(p) < 42)
return true;
891 if (
isQuark(p.pid())) {
return std::abs(p.pid());}
892 if (
isMeson(p)) {
return p.max_digit(1,3);}
893 if (
isDiquark(p)) {
return p.max_digit(2,4);}
894 if (
isBaryon(p)) {
return p.max_digit(1,4);}
898 auto pp = p.shift(1);
899 if ( pp.ndigits() == 1 ) {
return 0; }
900 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
901 if ( pp.ndigits() > 3 ) { pp = pp.shift(1); }
944 const int pid = std::abs(p);
945 return ( pid == 511 ||
979 const int pid = std::abs(p);
980 return ( pid == 411 ||
997template<
class T>
inline double charge(
const T& p){
1008 auto ap = std::abs(p.pid());
1009 if (ap < TABLESIZE )
return p.pid() > 0 ? triple_charge.at(ap) : -triple_charge.at(ap);
1010 if (ap == K0)
return 0;
1011 if (ap == GEANTINO0)
return 0;
1012 if (ap == GEANTINOPLUS)
return p.pid() > 0 ? 3 : -3;
1013 if (ap == MAVTOP)
return p.pid() > 0 ? 2 : -2;
1018 bool classified =
false;
1019 if (!classified &&
isMeson(p)) { classified =
true; nq = 2;
if ((*(p.second.rbegin()+2)) == 2||(*(p.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1020 if (!classified &&
isDiquark(p)) {
return triple_charge.at(p(0))+triple_charge.at(p(1)); }
1021 if (!classified &&
isBaryon(p)) { classified =
true; nq = 3; }
1022 if (!classified &&
isTetraquark(p)){
return triple_charge.at(p(3)) + triple_charge.at(p(4)) - triple_charge.at(p(6)) - triple_charge.at(p(7)); }
1023 if (!classified &&
isPentaquark(p)){
return triple_charge.at(p(3)) + triple_charge.at(p(4)) + triple_charge.at(p(5)) + triple_charge.at(p(6)) - triple_charge.at(p(7)); }
1025 if (!classified &&
isSUSY(p)) {
1027 auto pp = p.shift(1);
1028 if (pp.ndigits() < 3 ) {
return charge3(pp); }
1029 if (pp(0) == COMPOSITEGLUON) {
1030 if (pp(1) == COMPOSITEGLUON) {
return 0; }
1031 if ( pp.ndigits() == 4 || pp.ndigits() == 5) {
1035 if (pp.ndigits() == 3) { classified =
true; nq = 2;
if (p.last()%2==0) {
sign = -1;} signmult = -1; }
1036 if (pp.ndigits() == 4) { classified =
true; nq = 3; }
1039 auto pp = p.shift(2);
1040 if (!classified &&
isMeson(pp)) { classified =
true; nq = 2;
if ((*(pp.second.rbegin()+2)) == 2||(*(pp.second.rbegin()+2)) == 4 ) {
sign=-1;} signmult =-1; }
1041 if (!classified &&
isDiquark(pp)) {
return triple_charge.at(pp(0))+triple_charge.at(pp(1)); }
1042 if (!classified &&
isBaryon(pp)) { classified =
true; nq = 3; }
1045 if (!classified &&
isKK(p)) {
1046 auto pp = p.shift(2);
1047 auto ap = std::abs(pp.pid());
1048 if (ap < TABLESIZE )
return pp.pid() > 0 ? triple_charge.at(ap) : -triple_charge.at(ap);
1051 if (!classified &&
isDM(p.pid())) {
1052 if (p.ndigits() == 7){
1053 auto pp = p.shift(3);
1054 auto ap = std::abs(pp.pid());
1055 if (ap < TABLESIZE )
return pp.pid() > 0 ? triple_charge.at(ap) : -triple_charge.at(ap);
1056 }
else if (std::abs(p.pid()) < TABLESIZE)
return p.pid() > 0 ? triple_charge.at(ap) : -triple_charge.at(ap);
1061 result = 3*(p(3)*100 + p(4)*10 + p(5));
1062 return ( (p.pid() > 0 && p(2) == 1) || (p.pid() < 0 && p(2) == 2) ) ?
result : -
result;
1065 double abs_charge = 0.0;
1066 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1067 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1068 int abs_threecharge =
static_cast<int>(std::round(abs_charge * 3.));
1069 return p.pid() > 0 ? abs_threecharge : -1 * abs_threecharge;
1071 for (
auto r = p.second.rbegin() + 1;
r != p.second.rbegin() + 1 + nq; ++
r) {
1078 int ap = std::abs(p);
1079 if (ap < TABLESIZE)
return p > 0 ? triple_charge.at(ap):-triple_charge.at(ap);
1085template<
class T>
inline bool isNeutral(
const T& p){
return p->pdg_id() != 0 &&
charge3(p) == 0;}
1092 double abs_charge = 0;
1093 if (p(0) == 1) abs_charge = p(3)*100. + p(4)*10. + p(5)*1 + p(6)*0.1;
1094 if (p(0) == 2) abs_charge = (p(3)*10. + p(4))/(p(5)*10.0 + p(6));
1095 return p.pid() > 0 ? abs_charge : -1 * abs_charge;
1107template<
class T>
inline int spin2(
const T& p) {
return spin2(p->pdg_id()); }
1110 auto pp = p.shift(1);
1111 auto ap = std::abs(pp.pid());
1112 if (ap < TABLESIZE ) {
return std::abs(double_spin.at(ap)-1); }
1116 auto pp = p.shift(2);
1117 if (
isHadron(pp)) {
return pp.last()-1; }
1120 auto pp = p.shift(2);
1121 auto ap = std::abs(pp.pid());
1122 if (ap < TABLESIZE ) {
return double_spin.at(ap); }
1124 if (
isDM(std::abs(p.pid()))) {
1125 if (p.ndigits() == 7) {
1126 auto pp = p.shift(3);
1127 auto ap = std::abs(pp.pid());
1128 if (ap < TABLESIZE) {
return double_spin.at(ap); }
1129 }
else if (std::abs(p.pid()) < TABLESIZE) {
1130 return std::abs(double_spin.at(std::abs(p.pid())));
1133 auto ap = std::abs(p.pid());
1134 if (ap == K0S) {
return 0; }
1135 if (ap == K0L) {
return 0; }
1136 if (ap == MAVTOP) {
return 1; }
1137 if (ap == DARKPHOTON) {
return 2; }
1138 if (ap < TABLESIZE ) {
return double_spin.at(ap); }
1139 if (
isHadron(p)) {
return p.last()-1; }
1143 return p.last() > 0 ? 1 : 0;
1147template<
class T>
inline double spin(
const T& p) {
return spin(p->pdg_id()); }
1149template<>
inline double spin(
const int& p){
auto value_digits =
DecodedPID(p);
return spin(value_digits);}
1156 std::vector<int> quarks;
1157 if (
isQuark(pp.pid())) { quarks.push_back(std::abs(pp.pid())); }
1158 else if (
isDiquark(pp)) { quarks.push_back(pp(0)); quarks.push_back(pp(1)); }
1159 else if (
isMeson(pp)) { quarks.push_back(*(pp.second.rbegin() + 1)); quarks.push_back(*(pp.second.rbegin()+2)); }
1160 else if (
isBaryon(pp)) {
for (
size_t digit = 1; digit < 4; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1161 else if (
isTetraquark(pp)) {
for (
size_t digit = 1; digit < 5; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1162 else if (
isPentaquark(pp)) {
for (
size_t digit = 1; digit < 6; ++digit) { quarks.push_back(*(pp.second.rbegin() + digit)); } }
1164 const int n_uquarks =
A + Z;
const int n_dquarks = 2*
A - Z - L;
const int n_squarks = L;
1165 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); }
1168 if ( pp.ndigits() > 1 ) {
1169 if ( pp.ndigits() == 3 ) { pp =
DecodedPID(pp(1)); }
1170 if ( pp.ndigits() > 3 ) { pp = pp.shift(1); }
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)
int numberOfProtons(const T &p)
bool hasStrange(const T &p)
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 suffici...
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...
bool isChLepton(const T &p)
APID: the fourth generation leptons are leptons.
double baryonNumber(const T &p)
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)
bool isQuarkonium(const T &p)
Is this a heavy-flavour quarkonium meson?
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.
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?
bool isSuperpartner(const T &p)
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)
bool isSquarkLH(const T &p)
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 isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
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)
bool isBBbarMeson(const T &p)
bool isTopHadron(const T &p)
bool isEMInteracting(const T &p)
bool isStrangeBaryon(const T &p)
bool hasCharm(const T &p)
bool isSleptonRH(const T &p)
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...
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.
bool isRMeson(const T &p)
bool isCharmBaryon(const T &p)
bool isSquarkRH(const T &p)
bool isPhoton(const T &p)
bool isHeavyBaryon(const T &p)
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.
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
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...
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 classificationi...
bool isPythia8Specific(const T &p)
bool isNeutral(const T &p)
bool isWeaklyDecayingCHadron(const T &p)
Implementation of classification functions according to PDG2022.
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