File indexing completed on 2025-09-16 09:07:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef RIVET_PARTICLEIDUTILS_HH
0010 #define RIVET_PARTICLEIDUTILS_HH
0011
0012
0013
0014
0015 #include "Rivet/Tools/ParticleName.hh"
0016 #include "Rivet/Math/MathUtils.hh"
0017 #include <cassert>
0018
0019 namespace Rivet {
0020 namespace PID {
0021
0022
0023
0024
0025
0026
0027
0028 inline int abspid(int pid) {
0029 return abs(pid);
0030 }
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 inline size_t _pow10(unsigned int power) {
0045
0046 assert(power < 16 && "_pow10 only defined for powers < 16");
0047 static const size_t POWS10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000};
0048 return POWS10[power];
0049 }
0050
0051
0052
0053
0054
0055
0056
0057
0058 enum Location { nj=1, nq3, nq2, nq1, nl, nr, n, n8, n9, n10 };
0059
0060
0061
0062
0063
0064
0065 inline unsigned short _digit(Location loc, int pid) {
0066 const int div = _pow10(loc-1);
0067 return (abs(pid)/div) % 10;
0068 }
0069
0070
0071 inline int _extraBits(int pid) {
0072 return abs(pid)/10000000;
0073 }
0074
0075
0076
0077 inline int _fundamentalID(int pid) {
0078 if (_extraBits(pid) > 0) return 0;
0079 if (_digit(nq2,pid) == 0 && _digit(nq1,pid) == 0) {
0080 return abs(pid) % 10000;
0081 } else if (abs(pid) <= 100) {
0082 return abs(pid);
0083 } else {
0084 return 0;
0085 }
0086 }
0087
0088
0089
0090
0091
0092 inline bool isBSM(int pid);
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 inline bool isNucleus(int pid) {
0107
0108 if (abs(pid) == 2212) return true;
0109
0110 if (_digit(n10,pid) == 1 && _digit(n9,pid) == 0) {
0111
0112
0113 if ((abs(pid)/10) % 1000 >= (abs(pid)/10000) % 1000) return true;
0114 }
0115 return false;
0116 }
0117
0118
0119
0120 inline int nuclZ(int pid) {
0121
0122 if (abs(pid) == 2212) {
0123 return 1;
0124 }
0125 if (isNucleus(pid)) return (abs(pid)/10000) % 1000;
0126 return 0;
0127 }
0128
0129 inline int Z(int pid) {
0130 return nuclZ(pid);
0131 }
0132
0133
0134
0135 inline int nuclA(int pid) {
0136
0137 if (abs(pid) == 2212) {
0138 return 1;
0139 }
0140 if (isNucleus(pid)) return (abs(pid)/10) % 1000;
0141 return 0;
0142 }
0143
0144 inline int A(int pid) {
0145 return nuclA(pid);
0146 }
0147
0148
0149
0150 inline int nuclNlambda(int pid) {
0151
0152 if (abs(pid) == 2212) {
0153 return 0;
0154 }
0155 if (isNucleus(pid)) return _digit(n8,pid);
0156 return 0;
0157 }
0158
0159 inline int lambda(int pid) {
0160 return nuclNlambda(pid);
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170 inline bool isQuark(int pid) {
0171 return in_closed_range(abs(pid), 1, 8);
0172 }
0173
0174
0175 inline bool isGluon(int pid) {
0176 return pid == GLUON;
0177 }
0178
0179
0180 inline bool isParton(int pid) {
0181 return isGluon(pid) || isQuark(pid);
0182 }
0183
0184
0185
0186 inline bool isPhoton(int pid) {
0187 return pid == PHOTON;
0188 }
0189
0190
0191 inline bool isElectron(int pid) {
0192 return abs(pid) == ELECTRON;
0193 }
0194
0195
0196 inline bool isMuon(int pid) {
0197 return abs(pid) == MUON;
0198 }
0199
0200
0201 inline bool isTau(int pid) {
0202 return abs(pid) == TAU;
0203 }
0204
0205
0206 inline bool isChargedLepton(int pid) {
0207 const long apid = abs(pid);
0208 return apid == 11 || apid == 13 || apid == 15 || apid == 17;
0209 }
0210
0211
0212 inline bool isChLepton(int pid) {
0213 return isChargedLepton(pid);
0214 }
0215
0216
0217 inline bool isNeutrino(int pid) {
0218 const long apid = abs(pid);
0219 return apid == 12 || apid == 14 || apid == 16 || apid == 18;
0220 }
0221
0222
0223
0224 inline bool isWplus(int pid) {
0225 return pid == WPLUSBOSON;
0226 }
0227
0228
0229 inline bool isWminus(int pid) {
0230 return pid == WMINUSBOSON;
0231 }
0232
0233
0234 inline bool isW(int pid) {
0235 return abs(pid) == WPLUSBOSON;
0236 }
0237
0238
0239 inline bool isZ(int pid) {
0240 return pid == Z0BOSON;
0241 }
0242
0243
0244 inline bool isHiggs(int pid) {
0245 return pid == HIGGSBOSON || pid == 26;
0246 }
0247
0248
0249
0250
0251
0252 inline bool isGraviton(int pid) {
0253 return pid == GRAVITON;
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 inline bool isStrange(int pid) {
0265 return abs(pid) == SQUARK;
0266 }
0267
0268
0269 inline bool isCharm(int pid) {
0270 return abs(pid) == CQUARK;
0271 }
0272
0273
0274 inline bool isBottom(int pid) {
0275 return abs(pid) == BQUARK;
0276 }
0277
0278
0279 inline bool isTop(int pid) {
0280 return abs(pid) == TQUARK;
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290 inline bool isReggeon(int pid) {
0291 return pid == 110 || pid == 990 || pid == 9990;
0292 }
0293
0294
0295 inline bool isMeson(int pid) {
0296 if (_extraBits(pid) > 0) return false;
0297 if (isBSM(pid)) return false;
0298 const int aid = abs(pid);
0299 if (aid == 130 || aid == 310 || aid == 210) return true;
0300 if (aid <= 100) return false;
0301 if (_digit(nq1,pid) != 0) return false;
0302 if (_digit(nq2,pid) == 0) return false;
0303 if (_digit(nq3,pid) == 0) return false;
0304 if (_digit(nq2,pid) < _digit(nq3,pid)) return false;
0305
0306
0307 if (aid == 150 || aid == 350 || aid == 510 || aid == 530) return true;
0308
0309 if (isReggeon(pid)) return false;
0310
0311 if (_digit(nj,pid) > 0 && _digit(nq3,pid) > 0 && _digit(nq2,pid) > 0 && _digit(nq1,pid) == 0) {
0312 return !(_digit(nq3,pid) == _digit(nq2,pid) && pid < 0);
0313 }
0314 return false;
0315 }
0316
0317
0318 inline bool isBaryon(int pid) {
0319 if (_extraBits(pid) > 0) return false;
0320 if (isBSM(pid)) return false;
0321 if (abs(pid) <= 100) return false;
0322 if (_fundamentalID(pid) <= 100 && _fundamentalID(pid) > 0) return false;
0323 if (abs(pid) == 2110 || abs(pid) == 2210) return true;
0324 if (_digit(nj,pid) == 0) return false;
0325 if (_digit(nq1,pid) == 0 || _digit(nq2,pid) == 0 || _digit(nq3,pid) == 0) return false;
0326 return true;
0327
0328
0329
0330
0331
0332
0333 }
0334
0335
0336 inline bool isDiquark(int pid) {
0337 if (_extraBits(pid) > 0) return false;
0338 if (isBSM(pid)) return false;
0339 if (abs(pid) <= 100) return false;
0340 if (_fundamentalID(pid) <= 100 && _fundamentalID(pid) > 0) return false;
0341 if (_digit(nq1,pid) == 0) return false;
0342 if (_digit(nq2,pid) == 0) return false;
0343 if (_digit(nq3,pid) != 0) return false;
0344 if (_digit(nq1,pid) < _digit(nq2,pid)) return false;
0345 if (_digit(nj,pid) > 0 && _digit(nq3,pid) == 0 && _digit(nq2,pid) > 0 && _digit(nq1,pid) > 0) return true;
0346
0347
0348
0349
0350
0351
0352 return false;
0353 }
0354
0355 inline bool isDiQuark(int pid) {
0356 return isDiquark(pid);
0357 }
0358
0359
0360 inline bool isPentaquark(int pid) {
0361
0362
0363 if (_extraBits(pid) > 0) return false;
0364 if (isBSM(pid)) return false;
0365 if (_digit(n,pid) != 9) return false;
0366 if (_digit(nr,pid) == 9 || _digit(nr,pid) == 0) return false;
0367 if (_digit(nj,pid) == 9 || _digit(nl,pid) == 0) return false;
0368 if (_digit(nq1,pid) == 0) return false;
0369 if (_digit(nq2,pid) == 0) return false;
0370 if (_digit(nq3,pid) == 0) return false;
0371 if (_digit(nj,pid) == 0) return false;
0372
0373 if (_digit(nq2,pid) > _digit(nq1,pid)) return false;
0374 if (_digit(nq1,pid) > _digit(nl,pid)) return false;
0375 if (_digit(nl,pid) > _digit(nr,pid)) return false;
0376 return true;
0377 }
0378
0379
0380
0381
0382
0383
0384 inline bool isQuarkonium(int pid) {
0385 if (!isMeson(pid)) return false;
0386 if (_digit(nq1, pid) != 0) return false;
0387 const int fq = _digit(nq2, pid);
0388 return (fq > 3 && _digit(nj, pid) > 0 && _digit(nq3, pid) == fq);
0389 }
0390
0391
0392
0393
0394 inline bool isHadron(int pid) {
0395 if (_extraBits(pid) > 0) return false;
0396 if (isBSM(pid) > 0) return false;
0397 if (isMeson(pid)) return true;
0398 if (isBaryon(pid)) return true;
0399 if (isPentaquark(pid)) return true;
0400 return false;
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 inline bool isLepton(int pid) {
0413 if (_extraBits(pid) > 0) return false;
0414 if (isBSM(pid) > 0) return false;
0415 if (_fundamentalID(pid) >= 11 && _fundamentalID(pid) <= 18) return true;
0416 return false;
0417 }
0418
0419
0420 inline bool isBSMBoson(int pid) {
0421 return in_closed_range(abs(pid), 32, 37);
0422 }
0423
0424
0425 inline bool isSMFundamental(int pid) {
0426 return isQuark(pid) || isLepton(pid) ||
0427 isGluon(pid) || isPhoton(pid) || isW(pid) || isZ(pid) || isHiggs(pid) ||
0428 isBSMBoson(pid) || isGraviton(pid);
0429 }
0430
0431
0432
0433
0434 inline bool isSUSY(int pid) {
0435
0436 if (_extraBits(pid) > 0) return false;
0437 if (_digit(n,pid) != 1 && _digit(n,pid) != 2) return false;
0438 if (_digit(nr,pid) != 0) return false;
0439
0440 const int fundId = _fundamentalID(pid);
0441 if (fundId == 0) return false;
0442 if (_digit(n,pid) == 1) {
0443 return isSMFundamental(fundId);
0444 } else if (_digit(n,pid) == 2) {
0445 return isQuark(fundId) || isChargedLepton(fundId);
0446 }
0447 return true;
0448 }
0449
0450
0451 inline bool isRHadron(int pid) {
0452
0453
0454 if (_extraBits(pid) > 0) return false;
0455 if (_digit(n,pid) != 1) return false;
0456 if (_digit(nr,pid) != 0) return false;
0457
0458 if (isSUSY(pid)) return false;
0459
0460 if (_digit(nq2,pid) == 0) return false;
0461 if (_digit(nq3,pid) == 0) return false;
0462 if (_digit(nj,pid) == 0) return false;
0463 return true;
0464 }
0465
0466 inline bool isRhadron(int pid) {
0467 return isRHadron(pid);
0468 }
0469
0470
0471 inline bool isTechnicolor(int pid) {
0472 if (_extraBits(pid) > 0) return false;
0473 return _digit(n,pid) == 3;
0474 }
0475
0476
0477 inline bool isExcited(int pid) {
0478 if (_extraBits(pid) > 0) return false;
0479 return _digit(n,pid) == 4 && _digit(nr,pid) == 0;
0480 }
0481
0482
0483 inline bool isKK(int pid) {
0484 if (_extraBits(pid) > 0) return false;
0485 const int ndigit = _digit(n,pid);
0486 return ndigit == 5 || ndigit == 6;
0487 }
0488
0489
0490 inline bool isLeptoQuark(int pid) {
0491
0492 return abs(pid) == 42;
0493 }
0494
0495
0496
0497
0498
0499 inline bool isDarkMatter(int pid) {
0500 const int ndigit = _digit(n,pid);
0501 const int nrdigit = _digit(nr,pid);
0502 if ((ndigit == 0 && nrdigit == 0) || (ndigit == 5 && nrdigit == 9))
0503 return in_closed_range(abs(_fundamentalID(pid)),50,60);
0504 return false;
0505 }
0506
0507 inline bool isDM(int pid) {
0508 return isDarkMatter(pid);
0509 }
0510
0511
0512 inline bool isHiddenValley(int pid) {
0513 return (_digit(n,pid) == 4 && _digit(nr,pid) == 9);
0514 }
0515
0516
0517 inline bool isExotic(int pid) {
0518
0519
0520
0521 return in_closed_range(abs(pid),40,80);
0522 }
0523
0524
0525 inline bool isFourthGen(int pid) {
0526 return abs(pid) == BPRIME || abs(pid) == TPRIME || abs(pid) == LPRIME || abs(pid) == NUPRIME;
0527 }
0528
0529
0530 inline bool isMagMonopole(int pid) {
0531 if (_digit(n,pid) != 4) return false;
0532 if (_digit(nr,pid) != 1) return false;
0533 if (_digit(nl,pid) != 1 && _digit(nl,pid) != 2) return false;
0534
0535
0536
0537
0538 if (_digit(nj,pid) != 0) return false;
0539 return true;
0540 }
0541
0542 inline bool isDyon(int pid) {
0543 return isMagMonopole(pid);
0544 }
0545
0546
0547
0548 inline bool isQBall(int pid) {
0549 if (_extraBits(pid) != 1) return false;
0550 if (_digit(n,pid) != 0) return false;
0551 if (_digit(nr,pid) != 0) return false;
0552
0553 if ((abs(pid)/10) % 10000 == 0) return false;
0554
0555 if (_digit(nj,pid) != 0) return false;
0556 return true;
0557 }
0558
0559 inline bool isQball(int pid) {
0560 return isQBall(pid);
0561 }
0562
0563
0564 inline bool isExcitedLepton(int pid) {
0565 if (!isExcited(pid)) return false;
0566 return isLepton( _fundamentalID(pid) );
0567 }
0568
0569
0570 inline bool isBlackHole(int pid) {
0571 if (_digit(n,pid) != 5 && _digit(n,pid) != 6) return false;
0572 if (_digit(nl,pid) != 0) return false;
0573 return _fundamentalID(pid)==40;
0574 }
0575
0576
0577 inline bool isAECO(int pid) {
0578 if (_digit( n,pid) != 1) return false;
0579 if (_digit(nr,pid) != 0) return false;
0580 if (_digit(nl,pid) != 0) return false;
0581 if (_digit(nj,pid) != 0) return false;
0582 return true;
0583 }
0584
0585
0586 inline bool isBSM(int pid) {
0587 return isSUSY(pid) || isRHadron(pid) || isTechnicolor(pid) ||
0588 isExcited(pid) || isKK(pid) || isGraviton(pid) ||
0589 isBSMBoson(pid) || isLeptoQuark(pid) || isDM(pid) || isHiddenValley(pid) ||
0590 isExotic(pid) || isFourthGen(pid) || isBlackHole(pid) ||
0591 isDyon(pid) || isQball(pid) || isAECO(pid);
0592 }
0593
0594
0595 inline bool _isValid(int pid) {
0596
0597 if (_digit(n, pid) == 9 && _digit(nr, pid) == 9) return true;
0598
0599 if (_extraBits(pid) > 0) return (isNucleus(pid) || isQball(pid));
0600
0601 if (isBSM(pid)) return true;
0602 if (isHadron(pid)) return true;
0603 if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return false;
0604 if (isDiquark(pid)) return true;
0605 if (isPentaquark(pid)) return true;
0606 if (isReggeon(pid)) return true;
0607
0608
0609
0610
0611 return (_fundamentalID(pid) > 0);
0612 }
0613 inline bool isValid(int pid) {
0614 return _isValid(pid);
0615 }
0616
0617
0618
0619
0620
0621
0622
0623 inline bool _hasQ(int pid, int q) {
0624 if (abs(pid) == q) return true;
0625 if (!_isValid(pid)) return false;
0626
0627
0628 if (isMagMonopole(pid)) return false;
0629 if (isRHadron(pid)) {
0630 int iz = 7;
0631 for (int i = 6; i > 1; --i) {
0632 if (_digit(Location(i), pid) == 0) {
0633 iz = i;
0634 } else if ( i == iz-1 ) {
0635
0636 } else {
0637 if (_digit(Location(i),pid) == q) return true;
0638 }
0639 }
0640 return false;
0641 }
0642 if (_digit(nq3,pid) == q || _digit(nq2,pid) == q || _digit(nq1,pid) == q ) return true;
0643 if (isPentaquark(pid)) {
0644 if (_digit(nl,pid) == q || _digit(nr,pid) == q) return true;
0645 }
0646 return false;
0647 }
0648
0649
0650 inline bool hasDown(int pid) {
0651 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 1);
0652 }
0653
0654 inline bool hasUp(int pid) {
0655 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 2);
0656 }
0657
0658 inline bool hasStrange(int pid) {
0659 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 3);
0660 }
0661
0662 inline bool hasCharm(int pid) {
0663 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 4);
0664 }
0665
0666 inline bool hasBottom(int pid) {
0667 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 5);
0668 }
0669
0670 inline bool hasTop(int pid) {
0671 return (isHadron(pid) || isQuark(pid)) && _hasQ(pid, 6);
0672 }
0673
0674
0675
0676
0677
0678
0679
0680
0681 inline bool isHeavyFlavor(int pid) {
0682 if (!isHadron(pid) && !isQuark(pid)) return false;
0683 return hasCharm(pid) || hasBottom(pid) || hasTop(pid);
0684 }
0685
0686 inline bool isHeavyFlavour(int pid) {
0687 return isHeavyFlavor(pid);
0688 }
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698 inline bool isHeavyParton(int pid) {
0699 return isParton(pid) && isHeavyFlavor(pid);
0700 }
0701
0702
0703 inline bool isLightParton(int pid) {
0704 return isParton(pid) && !isHeavyFlavor(pid);
0705 }
0706
0707
0708
0709 inline bool isHeavyMeson(int pid) {
0710 return isMeson(pid) && isHeavyFlavor(pid);
0711 }
0712
0713
0714 inline bool isHeavyBaryon(int pid) {
0715 return isBaryon(pid) && isHeavyFlavor(pid);
0716 }
0717
0718
0719 inline bool isHeavyHadron(int pid) {
0720 return isHadron(pid) && isHeavyFlavor(pid);
0721 }
0722
0723
0724 inline bool isLightMeson(int pid) {
0725 return isMeson(pid) && !isHeavyFlavor(pid);
0726 }
0727
0728
0729 inline bool isLightBaryon(int pid) {
0730 return isBaryon(pid) && !isHeavyFlavor(pid);
0731 }
0732
0733
0734 inline bool isLightHadron(int pid) {
0735 return isHadron(pid) && !isHeavyFlavor(pid);
0736 }
0737
0738
0739
0740 inline bool isBottomMeson(int pid) {
0741 return hasBottom(pid) && isMeson(pid);
0742 }
0743
0744
0745 inline bool isBottomBaryon(int pid) {
0746 return hasBottom(pid) && isBaryon(pid);
0747 }
0748
0749
0750 inline bool isBottomHadron(int pid) {
0751 return hasBottom(pid) && isHadron(pid);
0752 }
0753
0754
0755
0756
0757
0758
0759 inline bool isCharmMeson(int pid) {
0760 return isMeson(pid) && hasCharm(pid) &&
0761 !hasBottom(pid);
0762 }
0763
0764
0765
0766
0767
0768
0769 inline bool isCharmBaryon(int pid) {
0770 return isBaryon(pid) && hasCharm(pid) &&
0771 !hasBottom(pid);
0772 }
0773
0774
0775
0776
0777
0778
0779 inline bool isCharmHadron(int pid) {
0780 return isHadron(pid) && hasCharm(pid) &&
0781 !hasBottom(pid);
0782 }
0783
0784
0785
0786
0787
0788
0789 inline bool isStrangeMeson(int pid) {
0790 return isMeson(pid) && hasStrange(pid) &&
0791 !(hasBottom(pid) || hasCharm(pid));
0792 }
0793
0794
0795
0796
0797
0798 inline bool isStrangeBaryon(int pid) {
0799 return isBaryon(pid) && hasStrange(pid) &&
0800 !(hasBottom(pid) || hasCharm(pid));
0801 }
0802
0803
0804
0805
0806
0807 inline bool isStrangeHadron(int pid) {
0808 return isHadron(pid) && hasStrange(pid) &&
0809 !(hasBottom(pid) || hasCharm(pid));
0810 }
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 inline int jSpin(int pid) {
0821 const int fund = _fundamentalID(pid);
0822 if (fund > 0) {
0823
0824 if (fund > 0 && fund < 7) return 2;
0825 if (fund == 9) return 3;
0826 if (fund > 10 && fund < 17) return 2;
0827 if (fund > 20 && fund < 25) return 3;
0828 return 0;
0829 } else if (_extraBits(pid) > 0) {
0830 return 0;
0831 }
0832 return abs(pid) % 10;
0833 }
0834
0835
0836 inline int sSpin(int pid) {
0837
0838 if (!isMeson(pid)) return 0;
0839 if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return 0;
0840
0841 const int fund = _fundamentalID(pid);
0842 if (fund == 51 || fund == 54) return 1;
0843 if (fund == 52) return 2;
0844 if (fund == 53 || fund == 55) return 3;
0845
0846 const int inl = _digit(nl,pid);
0847 const int js = _digit(nj,pid);
0848 if (inl == 0 && js >= 3) return 1;
0849 else if (inl == 0 && js == 1) return 0;
0850 else if (inl == 1 && js >= 3) return 0;
0851 else if (inl == 2 && js >= 3) return 1;
0852 else if (inl == 1 && js == 1) return 1;
0853 else if (inl == 3 && js >= 3) return 1;
0854
0855 return 0;
0856 }
0857
0858
0859 inline int lSpin(int pid) {
0860
0861 if (!isMeson(pid)) return 0;
0862 if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return 0;
0863
0864 const int inl = _digit(nl,pid);
0865 const int js = _digit(nj,pid);
0866 if (inl == 0 && js == 3) return 0;
0867 else if (inl == 0 && js == 5) return 1;
0868 else if (inl == 0 && js == 7) return 2;
0869 else if (inl == 0 && js == 9) return 3;
0870 else if (inl == 0 && js == 1) return 0;
0871 else if (inl == 1 && js == 3) return 1;
0872 else if (inl == 1 && js == 5) return 2;
0873 else if (inl == 1 && js == 7) return 3;
0874 else if (inl == 1 && js == 9) return 4;
0875 else if (inl == 2 && js == 3) return 1;
0876 else if (inl == 2 && js == 5) return 2;
0877 else if (inl == 2 && js == 7) return 3;
0878 else if (inl == 2 && js == 9) return 4;
0879 else if (inl == 1 && js == 1) return 1;
0880 else if (inl == 3 && js == 3) return 2;
0881 else if (inl == 3 && js == 5) return 3;
0882 else if (inl == 3 && js == 7) return 4;
0883 else if (inl == 3 && js == 9) return 5;
0884
0885 return 0;
0886 }
0887
0888
0889
0890
0891
0892
0893
0894
0895 inline int charge3(int pid) {
0896 static int ch100[100] = { -1, 2, -1, 2, -1, 2, -1, 2, 0, 0,
0897 -3, 0, -3, 0, -3, 0, -3, 0, 0, 0,
0898 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
0899 0, 0, 0, 3, 0, 0, 3, 0, 0, 0,
0900 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
0901 0, 6, 3, 6, 0, 0, 0, 0, 0, 0,
0902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0903 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0906 };
0907 const int ida = abs(pid);
0908
0909 if (pid == 21 || pid == 22) return 0;
0910 if (ida == 211) return std::signbit(pid) ? -3 : 3;
0911 if (pid == 111) return 0;
0912
0913
0914
0915
0916
0917 const unsigned short q1 = _digit(nq1,pid);
0918 const unsigned short q2 = _digit(nq2,pid);
0919 const unsigned short q3 = _digit(nq3,pid);
0920 const unsigned short ql = _digit(nl,pid);
0921 const int sid = _fundamentalID(pid);
0922 int ch3 = 0;
0923 if (ida == 0 || _extraBits(pid) > 0) {
0924 return 0;
0925 } else if (sid > 0 && sid <= 100) {
0926 if (ida == 1000017 || ida == 1000018 || ida == 1000034) ch3 = 0;
0927 else if (ida > 1000050 && ida <= 1000060) ch3 = 0;
0928 else if (ida > 50 && ida <= 60) ch3 = 0;
0929 else if (ida == 5100061 || ida == 5100062) ch3 = 6;
0930 else ch3 = ch100[sid-1];
0931 } else if (_digit(nj,pid) == 0) {
0932 return 0;
0933 } else if (isMeson(pid)) {
0934 ch3 = ((q2 == 3 || q2 == 5) ? -1 : 1) * (ch100[q2-1] - ch100[q3-1]);
0935 } else if (isBaryon(pid)) {
0936 ch3 = ch100[q3-1] + ch100[q2-1] + ch100[q1-1];
0937 } else if (isQBall(pid) ) {
0938 ch3 = 3*( (ida/10) % 10000);
0939 } else if (isHiddenValley(pid) ) {
0940 return 0;
0941 } else if (isDyon(pid) ) {
0942 ch3 = 3*( (ida/10) % 1000) * (ql == 2 ? -1 : 1);
0943 } else if (isRHadron(pid) ) {
0944
0945 if (q1 == 0 || q1 == 9) {
0946 if (q2 == 3 || q2 == 5) {
0947 ch3 = ch100[q3-1] - ch100[q2-1];
0948 } else {
0949 ch3 = ch100[q2-1] - ch100[q3-1];
0950 }
0951 } else if (ql == 0) {
0952 ch3 = ch100[q3-1] + ch100[q2-1] + ch100[q1-1];
0953 } else if (_digit(nr,pid) == 0) {
0954 ch3 = ch100[q3-1] + ch100[q2-1] + ch100[q1-1] + ch100[ql-1];
0955 }
0956 } else if (isDiQuark(pid)) {
0957 ch3 = ch100[q2-1] + ch100[q1-1];
0958 } else {
0959 return 0;
0960 }
0961 if (pid < 0) ch3 *= -1;
0962 return ch3;
0963 }
0964
0965
0966
0967 inline int threeCharge(int pid) {
0968 return charge3(pid);
0969 }
0970
0971
0972 inline int abscharge3(int pid) {
0973 return std::abs(charge3(pid));
0974 }
0975
0976
0977 inline double charge(int pid) {
0978 return charge3(pid)/3.0;
0979 }
0980
0981
0982 inline double abscharge(int pid) {
0983 return std::abs(charge(pid));
0984 }
0985
0986
0987
0988
0989
0990
0991
0992
0993 inline bool isCharged(int pid) {
0994 return charge3(pid) != 0;
0995 }
0996
0997
0998 inline bool isNeutral(int pid) {
0999 return charge3(pid) == 0;
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009 inline bool isStrongInteracting(int pid) {
1010 return isParton(pid) || isHadron(pid);
1011 }
1012
1013
1014 inline bool isEMInteracting(int pid) {
1015 return isCharged(pid) || isPhoton(pid);
1016 }
1017
1018
1019
1020
1021
1022 inline bool isWeakInteracting(int pid) {
1023 return !isGluon(pid) && !isGraviton(pid);
1024 }
1025
1026
1027
1028
1029
1030
1031
1032
1033 inline bool isGenSpecific(int pid) {
1034 return in_range(pid, 80, 101);
1035 }
1036
1037
1038
1039
1040 inline bool isResonance(int pid) {
1041 return isW(pid) || isZ(pid) || isHiggs(pid) || isTop(pid);
1042 }
1043
1044
1045
1046
1047
1048 inline bool isTransportable(int pid) {
1049
1050 return isPhoton(pid) || isHadron(pid) || isLepton(pid);
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 inline bool isSameSign(PdgId a, PdgId b) { return a*b >= 0; }
1063 inline bool isOppSign(PdgId a, PdgId b) { return !isSameSign(a, b); }
1064 inline bool isSameFlav(PdgId a, PdgId b) { return abs(a) == abs(b); }
1065 inline bool isOppFlav(PdgId a, PdgId b) { return !isSameFlav(a, b); }
1066
1067 inline bool isOSSF(PdgId a, PdgId b) { return isOppSign(a, b) && isSameFlav(a, b); }
1068 inline bool isSSSF(PdgId a, PdgId b) { return isSameSign(a, b) && isSameFlav(a, b); }
1069 inline bool isOSOF(PdgId a, PdgId b) { return isOppSign(a, b) && isOppFlav(a, b); }
1070 inline bool isSSOF(PdgId a, PdgId b) { return isSameSign(a, b) && isOppFlav(a, b); }
1071
1072
1073
1074
1075 }
1076 }
1077
1078 #endif