Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10880935
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
28 KB
Subscribers
None
View Options
diff --git a/include/Rivet/Tools/ParticleIdUtils.hh b/include/Rivet/Tools/ParticleIdUtils.hh
--- a/include/Rivet/Tools/ParticleIdUtils.hh
+++ b/include/Rivet/Tools/ParticleIdUtils.hh
@@ -1,797 +1,801 @@
// -*- C++ -*-
//
// This file is part of MCUtils -- https://bitbucket.org/andybuckley/mcutils
// Copyright (C) 2013-2016 Andy Buckley <andy.buckley@cern.ch>
//
// Embedding of MCUtils code in other projects is permitted provided this
// notice is retained and the MCUtils namespace and include path are changed.
//
#ifndef RIVET_PARTICLEIDUTILS_HH
#define RIVET_PARTICLEIDUTILS_HH
/// @file Utility functions for querying PDG ID codes (many from HepPID)
/// @author Andy Buckley <andy.buckley@cern.ch>
#include "Rivet/Tools/ParticleName.hh"
#include "Rivet/Math/MathUtils.hh"
namespace Rivet {
namespace PID {
/// @name Utility functions
//@{
/// Absolute value
/// @deprecated Just use abs()!
inline int abspid(int pid) { return abs(pid); }
/// PID digits (base 10) are: n nr nl nq1 nq2 nq3 nj
/// The Location enum provides a convenient index into the PID.
enum Location { nj=1, nq3, nq2, nq1, nl, nr, n, n8, n9, n10 };
/// Split the PID into constituent integers
inline unsigned short _digit(Location loc, int pid) {
// PID digits (base 10) are: n nr nl nq1 nq2 nq3 nj (cf. Location)
int numerator = (int) std::pow(10.0, (loc-1));
return (abs(pid)/numerator) % 10;
}
/// Returns everything beyond the 7th digit (e.g. outside the numbering scheme)
inline int _extraBits(int pid) {
return abs(pid)/10000000;
}
/// @brief Return the first two digits if this is a "fundamental" particle
/// @note ID = 100 is a special case (internal generator ID's are 81-100)
inline int _fundamentalID(int pid) {
if (_extraBits(pid) > 0) return 0;
if (_digit(nq2,pid) == 0 && _digit(nq1,pid) == 0) {
return abs(pid) % 10000;
} else if (abs(pid) <= 100) {
return abs(pid);
} else {
return 0;
}
}
//@}
/// @name Nucleus/ion functions
//@{
/// @brief Is this a nucleus PID?
///
/// This implements the 2006 Monte Carlo nuclear code scheme.
/// Ion numbers are +/- 10LZZZAAAI.
/// AAA is A - total baryon number
/// ZZZ is Z - total charge
/// L is the total number of strange quarks.
/// I is the isomer number, with I=0 corresponding to the ground state.
inline bool isNucleus(int pid) {
// a proton can also be a Hydrogen nucleus
if (abs(pid) == 2212) return true;
// new standard: +/- 10LZZZAAAI
if ((_digit(n10,pid) == 1) && (_digit(n9,pid) == 0)) {
// charge should always be less than or equal to baryon number
// the following line is A >= Z
if ((abs(pid)/10)%1000 >= (abs(pid)/10000)%1000) return true;
}
return false;
}
/// Get the atomic number (number of protons) in a nucleus/ion
/// @note Ion numbers are +/- 10LZZZAAAI.
inline int nuclZ(int pid) {
// A proton can also be a Hydrogen nucleus
if (abs(pid) == 2212) { return 1; }
if (isNucleus(pid)) return (abs(pid)/10000) % 1000;
return 0;
}
/// Alias for nuclZ
/// @deprecated Use nuclZ
inline int Z(int pid) { return nuclZ(pid); }
/// Get the atomic weight (number of nucleons) in a nucleus/ion
/// @note Ion numbers are +/- 10LZZZAAAI.
inline int nuclA(int pid) {
// A proton can also be a Hydrogen nucleus, and we might as well also allow single neutrons
if (abs(pid) == 2212 || abs(pid) == 2112) { return 1; }
if (isNucleus(pid)) return (abs(pid)/10) % 1000;
return 0;
}
/// Alias for nuclA
/// @deprecated Use nuclA
inline int A(int pid) { return nuclA(pid); }
/// If this is a nucleus (ion), get nLambda
/// @note Ion numbers are +/- 10LZZZAAAI.
inline int nuclNlambda(int pid) {
// a proton can also be a Hydrogen nucleus
if (abs(pid) == 2212) { return 0; }
if (isNucleus(pid)) return _digit(n8,pid);
return 0;
}
/// Alias for nuclNlambda
/// @deprecated Use nuclNlambda
inline int lambda(int pid) { return nuclNlambda(pid); }
//@}
/// @name Quark composite functions
//@{
/// Is this a pomeron, odderon, or generic reggeon?
inline bool isReggeon(int pid) {
return pid == 110 || pid == 990 || pid == 9990;
}
/// Check to see if this is a valid meson
inline bool isMeson(int pid) {
if (_extraBits(pid) > 0) return false;
+ // exotica
+ if (_digit(n,pid) > 0 && _digit(n,pid) < 9) return false;
const int aid = abs(pid);
if (aid == 130 || aid == 310 || aid == 210) return true; //< special cases for kaons
if (aid <= 100) return false;
if (_digit(nq1,pid) != 0) return false;
if (_digit(nq2,pid) == 0) return false;
if (_digit(nq3,pid) == 0) return false;
if (_digit(nq2,pid) < _digit(nq3,pid)) return false;
// EvtGen uses some odd numbers
/// @todo Remove special-casing for EvtGen
if (aid == 150 || aid == 350 || aid == 510 || aid == 530) return true;
// Pomeron, Reggeon, etc.
if (isReggeon(pid)) return false; //true; //< WTF?
// Check for illegal antiparticles
if (_digit(nj,pid) > 0 && _digit(nq3,pid) > 0 && _digit(nq2,pid) > 0 && _digit(nq1,pid) == 0) {
return !(_digit(nq3,pid) == _digit(nq2,pid) && pid < 0);
}
return false;
}
/// Check to see if this is a valid baryon
inline bool isBaryon(int pid) {
if (_extraBits(pid) > 0) return false;
+ // exotica
+ if (_digit(n,pid) > 0 && _digit(n,pid) < 9) return false;
if (abs(pid) <= 100) return false;
if (_fundamentalID(pid) <= 100 && _fundamentalID(pid) > 0) return false;
if (abs(pid) == 2110 || abs(pid) == 2210) return true; ///< @todo Why this special case with nJ = 0? What are these? Not listed in RPP MC doc...
if (_digit(nj,pid) == 0) return false;
if (_digit(nq1,pid) == 0 || _digit(nq2,pid) == 0 || _digit(nq3,pid) == 0) return false;
return true;
/// @todo This is more correct by the definition, but the PDG's entries 1212, 1214, 1216, 1218 and 2122, 2124, 2126, 2128 come out as invalid
// if ((_digit(nq1,pid) >= _digit(nq2,pid) && _digit(nq2,pid) >= _digit(nq3,pid)) ||
// (_digit(nq1,pid) > _digit(nq3,pid) && _digit(nq3,pid) > _digit(nq2,pid)) || //< case 6b for lighter quarks in J=1
// (_digit(nq3,pid) > _digit(nq1,pid) && _digit(nq1,pid) > _digit(nq2,pid))) //< case 6e for extra states in excited multiplets
// return true;
// return false;
}
// Check to see if this is a valid diquark
inline bool isDiquark(int pid) {
if (_extraBits(pid) > 0) return false;
if (abs(pid) <= 100) return false;
if (_fundamentalID(pid) <= 100 && _fundamentalID(pid) > 0) return false;
if (_digit(nq1,pid) == 0) return false;
if (_digit(nq2,pid) == 0) return false;
if (_digit(nq3,pid) != 0) return false;
if (_digit(nq1,pid) < _digit(nq2,pid)) return false;
if (_digit(nj,pid) > 0 && _digit(nq3,pid) == 0 && _digit(nq2,pid) > 0 && _digit(nq1,pid) > 0) return true; // diquark signature
// EvtGen uses the diquarks for quark pairs, so, for instance, 5501 is a valid "diquark" for EvtGen
// if (_digit(nj) == 1 && _digit(nq2) == _digit(nq1)) { // illegal
// return false;
// } else {
// return true;
// }
return false;
}
/// @deprecated Use the nicer capitalisation isDiquark(pid)
inline bool isDiQuark(int pid) { return isDiquark(pid); }
/// Check to see if this is a valid pentaquark
inline bool isPentaquark(int pid) {
// a pentaquark is of the form 9abcdej,
// where j is the spin and a, b, c, d, and e are quarks
if (_extraBits(pid) > 0) return false;
if (_digit(n,pid) != 9) return false;
if (_digit(nr,pid) == 9 || _digit(nr,pid) == 0) return false;
if (_digit(nj,pid) == 9 || _digit(nl,pid) == 0) return false;
if (_digit(nq1,pid) == 0) return false;
if (_digit(nq2,pid) == 0) return false;
if (_digit(nq3,pid) == 0) return false;
if (_digit(nj,pid) == 0) return false;
// check ordering
if (_digit(nq2,pid) > _digit(nq1,pid)) return false;
if (_digit(nq1,pid) > _digit(nl,pid)) return false;
if (_digit(nl,pid) > _digit(nr,pid)) return false;
return true;
}
/// Is this a valid hadron ID?
inline bool isHadron(int pid) {
if (_extraBits(pid) > 0) return false;
if (isMeson(pid)) return true;
if (isBaryon(pid)) return true;
if (isPentaquark(pid)) return true;
return false;
}
//@}
/// @name More general particle class identification functions
//@{
/// Is this a valid lepton ID?
inline bool isLepton(int pid) {
if (_extraBits(pid) > 0) return false;
if (_fundamentalID(pid) >= 11 && _fundamentalID(pid) <= 18) return true;
return false;
}
/// Is this a fundamental SUSY particle?
inline bool isSUSY(int pid) {
// Fundamental SUSY particles have n = 1 or 2
if (_extraBits(pid) > 0) return false;
if (_digit(n,pid) != 1 && _digit(n,pid) != 2) return false;
if (_digit(nr,pid) != 0) return false;
// Check fundamental part for SM PID on which it is based
if (_fundamentalID(pid) == 0) return false;
return true;
}
/// Is this an R-hadron?
inline bool isRhadron(int pid) {
// An R-hadron is of the form 10abcdj,
// where j is the spin and a, b, c, and d are quarks or gluons
if (_extraBits(pid) > 0) return false;
if (_digit(n,pid) != 1) return false;
if (_digit(nr,pid) != 0) return false;
// Make sure this isn't a SUSY particle
if (isSUSY(pid)) return false;
// All R-hadrons have at least 3 core digits
if (_digit(nq2,pid) == 0) return false;
if (_digit(nq3,pid) == 0) return false;
if (_digit(nj,pid) == 0) return false;
return true;
}
inline bool isRHadron(int pid) { return isRhadron(pid); }
/// Is this a technicolor particle?
inline bool isTechnicolor(int pid) {
if (_extraBits(pid) > 0) return false;
return _digit(n,pid) == 3;
}
/// Is this an excited (composite) quark or lepton?
inline bool isExcited(int pid) {
if (_extraBits(pid) > 0) return false;
return _digit(n,pid) == 4;
}
/// Is this a Kaluza-Klein excitation?
inline bool isKK(int pid) {
if (_extraBits(pid) > 0) return false;
const int ndigit = _digit(n,pid);
return ndigit == 5 || ndigit == 6;
}
/// Is this a graviton?
inline bool isGraviton(int pid) {
return pid == 39;
}
/// Is this a BSM particle (including graviton)?
inline bool isBSM(int pid) {
return isSUSY(pid) || isRhadron(pid) || isTechnicolor(pid) ||
isExcited(pid) || isKK(pid) || isGraviton(pid);
}
/// Check to see if this is a valid PID (i.e. matches any known scheme)
inline bool _isValid(int pid) {
// Starting with 99 means anything goes (but nothing is known)
if (_digit(n,pid) == 9 && _digit(nr,pid) == 9) return true;
// Check that extra bits are only used for nuclei
if (_extraBits(pid) > 0) return isNucleus(pid);
// Check that it fits into a standard non-nucleus convention
if (isBSM(pid)) return true;
if (isHadron(pid)) return true;
if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return false; // could only have been a tentative hadron, but !isHadron
if (isDiquark(pid)) return true;
if (isReggeon(pid)) return true;
// // Quark digit orderings required by the standard
// if (_digit(nq1,pid) != 0 && _digit(nq1,pid) < _digit(nq2,pid)) return false;
// if (_digit(nq2,pid) != 0 && _digit(nq2,pid) < _digit(nq3,pid)) return false;
// Final check on fundamental ID
return (_fundamentalID(pid) > 0);
}
inline bool isValid(int pid) { return _isValid(pid); }
//@}
/// @name Parton content functions
//@{
inline bool _hasQ(int pid, int q) {
if (abs(pid) == q) return true; //< trivial case!
if (!_isValid(pid)) return false;
if (_extraBits(pid) > 0) return false;
if (_fundamentalID(pid) > 0) return false;
return _digit(nq3,pid) == q || _digit(nq2,pid) == q || _digit(nq1,pid) == q;
}
/// Does this particle contain a down quark?
inline bool hasDown(int pid) { return _hasQ(pid, 1); }
/// Does this particle contain an up quark?
inline bool hasUp(int pid) { return _hasQ(pid, 2); }
/// Does this particle contain a strange quark?
inline bool hasStrange(int pid) { return _hasQ(pid, 3); }
/// Does this particle contain a charm quark?
inline bool hasCharm(int pid) { return _hasQ(pid, 4); }
/// Does this particle contain a bottom quark?
inline bool hasBottom(int pid) { return _hasQ(pid, 5); }
/// Does this particle contain a top quark?
inline bool hasTop(int pid) { return _hasQ(pid, 6); }
//@}
/// @name Angular momentum functions
//@{
/// jSpin returns 2J+1, where J is the total spin
inline int jSpin(int pid) {
const int fund = _fundamentalID(pid);
if (fund > 0) {
// some of these are known
if (fund > 0 && fund < 7) return 2;
if (fund == 9) return 3;
if (fund > 10 && fund < 17) return 2;
if (fund > 20 && fund < 25) return 3;
return 0;
} else if (_extraBits(pid) > 0) {
return 0;
}
return abs(pid) % 10;
}
/// sSpin returns 2S+1, where S is the spin
inline int sSpin(int pid) {
// Handle invalid cases first
if (!isMeson(pid)) return 0;
if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return 0; // tentative ID
// Special generic DM particles with defined spins
const int fund = _fundamentalID(pid);
if (fund == 51 || fund == 54) return 1;
if (fund == 52) return 2;
if (fund == 53 || fund == 55) return 3;
// Calculate from nl and nj digits
const int inl = _digit(nl,pid);
const int js = _digit(nj,pid);
if (inl == 0 && js >= 3) return 1;
else if (inl == 0 && js == 1) return 0;
else if (inl == 1 && js >= 3) return 0;
else if (inl == 2 && js >= 3) return 1;
else if (inl == 1 && js == 1) return 1;
else if (inl == 3 && js >= 3) return 1;
// Default to zero
return 0;
}
/// lSpin returns 2L+1, where L is the orbital angular momentum
inline int lSpin(int pid) {
// Handle invalid cases first
if (!isMeson(pid)) return 0;
if (_digit(n,pid) == 9 && _digit(nr,pid) == 0) return 0; // tentative ID
// Calculate from nl and nj digits
const int inl = _digit(nl,pid);
const int js = _digit(nj,pid);
if (inl == 0 && js == 3) return 0;
else if (inl == 0 && js == 5) return 1;
else if (inl == 0 && js == 7) return 2;
else if (inl == 0 && js == 9) return 3;
else if (inl == 0 && js == 1) return 0;
else if (inl == 1 && js == 3) return 1;
else if (inl == 1 && js == 5) return 2;
else if (inl == 1 && js == 7) return 3;
else if (inl == 1 && js == 9) return 4;
else if (inl == 2 && js == 3) return 1;
else if (inl == 2 && js == 5) return 2;
else if (inl == 2 && js == 7) return 3;
else if (inl == 2 && js == 9) return 4;
else if (inl == 1 && js == 1) return 1;
else if (inl == 3 && js == 3) return 2;
else if (inl == 3 && js == 5) return 3;
else if (inl == 3 && js == 7) return 4;
else if (inl == 3 && js == 9) return 5;
// Default to zero
return 0;
}
//@}
/// @name Charge functions
//@{
/// Three times the EM charge (as integer)
inline int charge3(int pid) {
static int ch100[100] = { -1, 2,-1, 2,-1, 2,-1, 2, 0, 0,
-3, 0,-3, 0,-3, 0,-3, 0, 0, 0,
0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 3, 0, 0, 3, 0, 0, 0,
0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 6, 3, 6, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const unsigned short q1 = _digit(nq1,pid);
const unsigned short q2 = _digit(nq2,pid);
const unsigned short q3 = _digit(nq3,pid);
const int ida = abs(pid);
const int sid = _fundamentalID(pid);
int charge = 0;
if (ida == 0 || _extraBits(pid) > 0) {// ion or illegal
return 0;
} else if (sid > 0 && sid <= 100) {// use table
if (ida == 1000017 || ida == 1000018 || ida == 1000034) charge = 0;
else if (ida > 1000050 && ida <= 1000060) charge = 0; // ?
else if (ida > 50 && ida <= 60) charge = 0; // Generic DM
else if (ida == 5100061 || ida == 5100062) charge = 6;
else charge = ch100[sid-1];
} else if (_digit(nj,pid) == 0) {// KL, Ks, or undefined
return 0;
} else if (isMeson(pid)) {// mesons
if (q2 == 3 || q2 == 5) {
charge = ch100[q3-1] - ch100[q2-1];
} else {
charge = ch100[q2-1] - ch100[q3-1];
}
} else if (isDiQuark(pid)) {// diquarks
charge = ch100[q2-1] + ch100[q1-1];
} else if (isBaryon(pid)) {// baryons
charge = ch100[q3-1] + ch100[q2-1] + ch100[q1-1];
} else {// unknown
return 0;
}
if (pid < 0) charge *= -1;
return charge;
}
/// Alias for charge3
/// @deprecated Prefer charge3
inline int threeCharge(int pid) { return charge3(pid); }
/// Return the absolute value of 3 times the EM charge
inline int abscharge3(int pid) { return std::abs(charge3(pid)); }
/// Return the EM charge (as floating point)
inline double charge(int pid) { return charge3(pid)/3.0; }
/// Return the absolute value of the EM charge (as floating point)
inline double abscharge(int pid) { return abscharge3(pid)/3.0; }
//@}
/// @name General PID-based classifier functions
//@{
/// Determine if the particle is electrically charged
inline bool isCharged(int pid) {
return charge3(pid) != 0;
}
/// Determine if the particle is electrically neutral
inline bool isNeutral(int pid) {
return charge3(pid) == 0;
}
//@}
/// @name Fundamental particles
//@{
/// Determine if the PID is that of a quark
inline bool isQuark(int pid) {
return in_closed_range(abs(pid), 1, 6);
}
/// Determine if the PID is that of a gluon
inline bool isGluon(int pid) {
return pid == GLUON;
}
/// Determine if the PID is that of a parton (quark or gluon)
inline bool isParton(int pid) {
return isGluon(pid) || isQuark(pid);
}
/// Determine if the PID is that of a photon
inline bool isPhoton(int pid) {
return pid == PHOTON;
}
/// Determine if the PID is that of an electron or positron
inline bool isElectron(int pid) {
return abs(pid) == ELECTRON;
}
/// Determine if the PID is that of an muon or antimuon
inline bool isMuon(int pid) {
return abs(pid) == MUON;
}
/// Determine if the PID is that of an tau or antitau
inline bool isTau(int pid) {
return abs(pid) == TAU;
}
/// Determine if the PID is that of a charged lepton
inline bool isChargedLepton(int pid) {
const long apid = abs(pid);
return apid == 11 || apid == 13 || apid == 15;
}
// Alias
inline bool isChLepton(int pid) { return isChargedLepton(pid); }
/// Determine if the PID is that of a neutrino
inline bool isNeutrino(int pid) {
const long apid = abs(pid);
return apid == 12 || apid == 14 || apid == 16;
}
/// Determine if the PID is that of a W+
inline bool isWplus(int pid) {
return pid == WPLUSBOSON;
}
/// Determine if the PID is that of a W-
inline bool isWminus(int pid) {
return pid == WMINUSBOSON;
}
/// Determine if the PID is that of a W+-
inline bool isW(int pid) {
return abs(pid) == WPLUSBOSON;
}
/// Determine if the PID is that of a Z0
inline bool isZ(int pid) {
return pid == Z0BOSON;
}
/// Determine if the PID is that of an SM/lightest SUSY Higgs
inline bool isHiggs(int pid) {
return pid == HIGGSBOSON || pid == 26; //< @todo Check on 26 still needed? (used in HERWIG SUSY, for example)
}
/// @todo isSUSYHiggs?
// /// Determine if the PID is that of a d/dbar
// inline bool isDown(int pid) { return abs(pid) == DQUARK; }
// /// Determine if the PID is that of a u/ubar
// inline bool isUp(int pid) { return abs(pid) == UQUARK; }
/// Determine if the PID is that of a s/sbar
inline bool isStrange(int pid) { return abs(pid) == SQUARK; }
/// Determine if the PID is that of a c/cbar
inline bool isCharm(int pid) { return abs(pid) == CQUARK; }
/// Determine if the PID is that of a b/bbar
inline bool isBottom(int pid) { return abs(pid) == BQUARK; }
/// Determine if the PID is that of a t/tbar
inline bool isTop(int pid) { return abs(pid) == TQUARK; }
//@}
/// @name Hadron and parton flavour classification
//@{
/// Determine if the particle is a heavy flavour hadron or parton
inline bool isHeavyFlavour(int pid) {
return hasCharm(pid) || hasBottom(pid) || hasTop(pid);
}
// /// Determine if the particle is a light-flavour flavour hadron or parton
// inline bool isLightFlavour(int pid) {
// return !isHeavyFlavour();
// }
/// Determine if the PID is that of a heavy parton (c,b,t)
inline bool isHeavyParton(int pid) {
return isParton(pid) && isHeavyFlavour(pid);
}
/// Determine if the PID is that of a light parton (u,d,s)
inline bool isLightParton(int pid) {
return isParton(pid) && !isHeavyFlavour(pid);
}
/// Determine if the PID is that of a heavy flavour (b or c) meson
inline bool isHeavyMeson(int pid) {
return isMeson(pid) && isHeavyFlavour(pid);
}
/// Determine if the PID is that of a heavy flavour (b or c) baryon
inline bool isHeavyBaryon(int pid) {
return isBaryon(pid) && isHeavyFlavour(pid);
}
/// Determine if the PID is that of a heavy flavour (b or c) hadron
inline bool isHeavyHadron(int pid) {
return isHadron(pid) && isHeavyFlavour(pid);
}
/// Determine if the PID is that of a light flavour (not b or c) meson
inline bool isLightMeson(int pid) {
return isMeson(pid) && !isHeavyFlavour(pid);
}
/// Determine if the PID is that of a light flavour (not b or c) baryon
inline bool isLightBaryon(int pid) {
return isBaryon(pid) && !isHeavyFlavour(pid);
}
/// Determine if the PID is that of a light flavour (not b or c) hadron
inline bool isLightHadron(int pid) {
return isHadron(pid) && !isHeavyFlavour(pid);
}
/// Determine if the PID is that of a b-meson.
inline bool isBottomMeson(int pid) {
return hasBottom(pid) && isMeson(pid);
}
/// Determine if the PID is that of a b-baryon.
inline bool isBottomBaryon(int pid) {
return hasBottom(pid) && isBaryon(pid);
}
/// Determine if the PID is that of a b-hadron.
inline bool isBottomHadron(int pid) {
return hasBottom(pid) && isHadron(pid);
}
/// @brief Determine if the PID is that of a c-meson.
///
/// @note Specifically, the _heaviest_ quark is a c: a B_c is a b-meson and NOT a c-meson.
/// Charmonia (closed charm) are counted as c-mesons here.
inline bool isCharmMeson(int pid) {
return isMeson(pid) && hasCharm(pid) &&
!hasBottom(pid);
}
/// @brief Determine if the PID is that of a c-baryon.
///
/// @note Specifically, the _heaviest_ quark is a c: a baryon containing a b & c
/// is a b-baryon and NOT a c-baryon. To test for the simpler case, just use
/// a combination of hasCharm() and isBaryon().
inline bool isCharmBaryon(int pid) {
return isBaryon(pid) && hasCharm(pid) &&
!hasBottom(pid);
}
/// Determine if the PID is that of a c-hadron.
///
/// @note Specifically, the _heaviest_ quark is a c: a baryon containing a b & c
/// is a b-baryon and NOT a c-baryon. To test for the simpler case, just use
/// a combination of hasCharm() and isBaryon().
inline bool isCharmHadron(int pid) {
return isHadron(pid) && hasCharm(pid) &&
!hasBottom(pid);
}
/// Determine if the PID is that of a strange meson
///
/// @note Specifically, the _heaviest_ quark is an s: if it also contains
/// either charm or bottom, it is not considered to be a strange hadron.
inline bool isStrangeMeson(int pid) {
return isMeson(pid) && hasStrange(pid) &&
!(hasBottom(pid) || hasCharm(pid));
}
/// Determine if the PID is that of a strange baryon
///
/// @note Specifically, the _heaviest_ quark is an s: if it also contains
/// either charm or bottom, it is not considered to be a strange hadron.
inline bool isStrangeBaryon(int pid) {
return isBaryon(pid) && hasStrange(pid) &&
!(hasBottom(pid) || hasCharm(pid));
}
/// Determine if the PID is that of a strange hadron
///
/// @note Specifically, the _heaviest_ quark is an s: if it also contains
/// either charm or bottom, it is not considered to be a strange hadron.
inline bool isStrangeHadron(int pid) {
return isHadron(pid) && hasStrange(pid) &&
!(hasBottom(pid) || hasCharm(pid));
}
//@}
/// @name Interaction classifiers
//@{
/// Determine if the PID is that of a strongly interacting particle
inline bool isStrongInteracting(int pid) {
return isParton(pid) || isHadron(pid);
}
/// Determine if the PID is that of a electromagnetically interacting particle
inline bool isEMInteracting(int pid) {
return isCharged(pid) || isPhoton(pid);
}
/// Determine if the PID is that of a weakly interacting particle
///
/// @note Photons are considered weak-interacting, as are all hadrons and
/// leptons (we can't distinguish between L and R fermions at physical particle level).
inline bool isWeakInteracting(int pid) {
return !isGluon(pid) && !isGraviton(pid);
}
//@}
/// @name Other classifiers
//@{
/// Determine if the PID is in the generator-specific range
inline bool isGenSpecific(int pid) {
return in_range(pid, 80, 101);
}
/// Determine if the PID is that of an EW scale resonance
///
/// @todo Also include SUSY, technicolor, etc. etc.? Maybe via a isStandardModel(pid) function, but there are stable BSM particles (in principle)
inline bool isResonance(int pid) {
return isW(pid) || isZ(pid) || isHiggs(pid) || isTop(pid);
}
/// Check the PID for usability in transport codes like Geant4
///
/// @todo Should exclude neutrinos/LSP, since the ATLAS G4 interface deletes them immediately?
inline bool isTransportable(int pid) {
// return !isResonance(pid) && !isParton(pid) && !isGenSpecific(pid);
return isPhoton(pid) || isHadron(pid) || isLepton(pid);
}
//@}
/// @name Particle pair classifiers
/// @todo Make versions that work on PdgIdPair?
//@{
inline bool isSameSign(PdgId a, PdgId b) { return a*b >= 0; }
inline bool isOppSign(PdgId a, PdgId b) { return !isSameSign(a, b); }
inline bool isSameFlav(PdgId a, PdgId b) { return abs(a) == abs(b); }
inline bool isOppFlav(PdgId a, PdgId b) { return !isSameFlav(a, b); }
inline bool isOSSF(PdgId a, PdgId b) { return isOppSign(a, b) && isSameFlav(a, b); }
inline bool isSSSF(PdgId a, PdgId b) { return isSameSign(a, b) && isSameFlav(a, b); }
inline bool isOSOF(PdgId a, PdgId b) { return isOppSign(a, b) && isOppFlav(a, b); }
inline bool isSSOF(PdgId a, PdgId b) { return isSameSign(a, b) && isOppFlav(a, b); }
//@}
}
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 5:37 AM (5 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4982773
Default Alt Text
(28 KB)
Attached To
rRIVETHG rivethg
Event Timeline
Log In to Comment