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