扩展PDG粒子数据和MC识别代码
项目描述
粒子: PDG粒子数据和识别代码
Particle库为粒子数据组(PDG)的粒子数据表和粒子识别代码提供了一个Pythonic接口,并扩展了粒子信息以及一些额外功能。
PDG定义了标准的粒子识别(ID)编号方案。该库提供了一个实现PDG ID查询的PDGID
类。查询也可以通过模拟并扩展HepPID/HepPDT C++接口的独立函数来访问。
Particle
类封装了PDG粒子数据表中的信息,并提供了一个面向对象的接口以及强大的搜索和查找工具。
安装
像其他Python库一样安装particle
python -m pip install particle
或类似操作(如果您愿意,可以使用--user
,virtualenv
等)。
严格依赖项
- Python (3.8+)
- 如果您使用的是Python < 3.9,请安装importlib_resources backport
- attrs提供了无需样板代码的类(类似于Python 3.7中的DataClasses)
- hepunits为Scikit-HEP包提供单位
变更日志
有关重要变更的历史记录,请参阅变更日志。
入门:PDG ID
>>> from particle import PDGID
>>>
>>> pid = PDGID(211)
>>> pid
<PDGID: 211>
>>> pid.is_meson
True
>>> pid = PDGID(99999999)
>>> pid
<PDGID: 99999999 (is_valid==False)>
为了方便,PDGID
类的所有属性都作为独立函数提供,这些函数适用于任何SupportsInt(包括Particle
)。
>>> from particle.pdgid import is_meson
>>>
>>> is_meson(211)
True
这些可组合的函数可以用来对PDG ID进行分类。例如,可以使用以下用户定义的函数指定夸克onia:
>>> is_heavy_flavor = lambda x: has_charm(x) or has_bottom(x) or has_top(x)
>>> is_quarkonium = lambda x: is_meson(x) and is_heavy_flavor(x) and Particle.from_pdgid(x).is_self_conjugate
PDG ID文字提供了(PDGID
类)所有加载粒子的别名,具有易于识别的名称。例如:
>>> from particle.pdgid import literals as lid
>>>
>>> lid.pi_plus
<PDGID: 211>
>>>
>>> from particle.pdgid.literals import Lambda_b_0
>>> Lambda_b_0
<PDGID: 5122>
>>> Lambda_b_0.has_bottom
True
您可以使用以下命令从命令行快速显示PDGID
信息:
$ python -m particle pdgid 323
<PDGID: 323>
A None
J 1.0
L 0
S 1
Z None
abspid 323
charge 1.0
has_bottom False
...
类似地,存在类来表示MC程序使用的识别码,有关转换器的信息请参见下文。
入门:粒子
您可以使用各种方法来获取粒子。如果您知道PDG ID号或例如在EvtGen中使用的名称,您可以直接获取一个粒子。
>>> from particle import Particle
>>> Particle.from_pdgid(211)
<Particle: name="pi+", pdgid=211, mass=139.57039 ± 0.00018 MeV>
>>>
>>> Particle.from_evtgen_name("J/psi")
<Particle: name="J/psi(1S)", pdgid=443, mass=3096.900 ± 0.006 MeV>
>>>
>>> Particle.from_nucleus_info(a=12, z=6)
<Particle: name="C12", pdgid=1000060120, mass=11177.9291399 MeV>
存在类似的方法来获取从PDG风格名称获得的粒子列表
>>> Particle.findall(pdg_name="pi")
返回匹配的粒子列表,其PDG名称为"pi",在这种情况下包括伪标量π介子的三种带电状态。
否则,更普遍地,您可以使用搜索。以下是一个基本示例:
>>> next(Particle.finditer('pi')) # first item in iterator of particles
<Particle: name="pi0", pdgid=111, mass=134.9768 ± 0.0005 MeV>
>>>
>>> Particle.findall('pi')[0] # Same as above but returning a list of particles
<Particle: name="pi0", pdgid=111, mass=134.9768 ± 0.0005 MeV>
您可以使用关键字参数搜索属性,这些参数包括pdg_name
,name
,mass
,width
,charge
,three_charge
,anti_flag
,rank
,I
,J
,G
,P
,quarks
,status
,mass_upper
,mass_lower
,width_upper
,和width_lower
。您可以传递一个可调用的函数或任何属性的精确匹配。您还可以将particle
参数设置为True
/False
,以限制搜索到粒子或反粒子。
您还可以使用第一个位置参数构建搜索,它接受一个可调用的函数,该函数接收粒子对象本身。如果第一个位置参数是一个字符串,它将与粒子的name
匹配。
以下是一些可能的复杂搜索,所有这些都可以与Particle.findall
或Particle.finditer
一起使用,其中前者方法提供列表,而后者返回迭代器。
>>> # Print out all particles with asymmetric decay width uncertainties
>>> ps = Particle.finditer(lambda p: p.width_lower != p.width_upper)
>>> for p in ps:
... print(p.name, p.pdgid, p.width_lower, p.width_upper)
>>>
>>> # Find all antiparticles with 'Omega' in the name
>>> Particle.finditer('Omega', particle=False) # several found
>>>
>>> # Find all antiparticles of name=='Omega'
>>> Particle.finditer(name='Omega', particle=False) # none found
>>>
>>> # Find all antiparticles of pdg_name=='Omega'
>>> Particle.findall(pdg_name='Omega', particle=False) # only 1, of course
[<Particle: name="Omega~+", pdgid=-3334, mass=1672.5 ± 0.3 MeV>]
>>>
>>> # Find all neutral beauty hadrons
>>> Particle.findall(lambda p: p.pdgid.has_bottom and p.charge==0)
>>>
>>> # Find all strange mesons with c*tau > 1 meter
>>> from hepunits import meter
>>> Particle.findall(lambda p: p.pdgid.is_meson and p.pdgid.has_strange and p.ctau > 1 * meter, particle=True)
[<Particle: name="K(L)0", pdgid=130, mass=497.611 ± 0.013 MeV>,
<Particle: name="K+", pdgid=321, mass=493.677 ± 0.016 MeV>]
一旦您有了粒子,就可以访问任何属性以及一些方法。尽管它们不是真正的属性,但您可以访问is_name_barred
和spin_type
。您还可以对粒子进行.invert()
。
粒子有大量的打印选项:describe()
,programmatic_name
,latex_name
,html_name
,在笔记本中的HTML打印输出,以及当然还有repr
和str
支持。
您还可以从粒子中获取.pdgid
。对粒子进行排序时,将首先放置abs(PDGID)
最低的粒子。
Particle文字提供了(Particle
类)所有加载粒子的别名,具有易于识别的名称。例如:
>>> from particle import literals as lp
>>> lp.pi_plus
<Particle: name="pi+", pdgid=211, mass=139.57061 ± 0.00024 MeV>
>>>
>>> from particle.literals import Lambda_b_0
>>> Lambda_b_0
<Particle: name="Lambda(b)0", pdgid=5122, mass=5619.60 ± 0.17 MeV>
>>> Lambda_b_0.J
0.5
您可以通过命令行快速搜索粒子(注意:在Windows上,只能使用双引号,单引号可能不会按预期工作)
$ python -m particle search "K*0"
<Particle: name="K*(892)0", pdgid=313, mass=895.55 ± 0.20 MeV>
<Particle: name="K*(1680)0", pdgid=30313, mass=1718 ± 18 MeV>
<Particle: name="K*(1410)0", pdgid=100313, mass=1421 ± 9 MeV>
如果您只选择一个粒子,无论是通过搜索还是通过提供PDG ID号,您都可以看到有关粒子的更多信息
$ python -m particle search 311
Name: K0 ID: 311 Latex: $K^{0}$
Mass = 497.611 ± 0.013 MeV
Width = -1.0 MeV
Q (charge) = 0 J (total angular) = 0.0 P (space parity) = -
C (charge parity) = ? I (isospin) = 1/2 G (G-parity) = ?
SpinType: SpinType.PseudoScalar
Quarks: dS
Antiparticle name: K~0 (antiparticle status: Barred)
高级:加载自定义表
您可以根据需要控制粒子数据表。您可以使用以下语法添加新的数据表
>>> from particle import Particle
>>> Particle.load_table('new_particles.csv', append=True)
您还可以通过append=False
(默认值)完全替换粒子表
如果您希望包附带非默认的数据文件,请按以下步骤操作
>>> from particle import data
>>> Particle.load_table(data.basepath / "particle2024.csv"))
>>> Particle.load_table(data.basepath / "nuclei2022.csv"), append=True) # I still want nuclei info
>>> Particle.table_names() # list the loaded tables
高级:如何创建用户定义的粒子
在某些情况下,创建用户定义的粒子可能很有用。但请谨慎操作,并考虑到许多限制,其中许多将在下面讨论或举例说明!
可能创建的最简单的“粒子”实际上是一个没有任何实际信息存储的占位符
>>> # A Particle instance the simplest possible. Contains basically no info
>>> p = Particle.empty()
>>> p
<Particle: name="Unknown", pdgid=0, mass=None>
>>>
>>> print(p.describe())
Name: Unknown
更有用的粒子定义可能至少涉及名称和PDG ID。重要的是要记住,有意义的PDG ID通过构造编码内部量子数和其他信息。因此,使用“随机”PDG ID定义粒子的结果将是具有未定义的/或错误的属性,如量子数或介子的性质。
>>> p2 = Particle(9912345, 'MyPentaquark')
>>> p2
<Particle: name="MyPentaquark", pdgid=9912345, mass=None>
>>>
>>> p2.pdgid.is_pentaquark
False
>>> print(p2.describe()) # J=2 is an example of something effectively encoded in the PDG ID.
Name: MyPentaquark ID: 9912345 Latex: $Unknown$
Mass = None
Width = None
Q (charge) = None J (total angular) = 2.0 P (space parity) = None
C (charge parity) = None I (isospin) = None G (G-parity) = None
Antiparticle name: MyPentaquark (antiparticle status: Same)
更复杂的定义
>>> p3 = Particle(pdgid=9221132,pdg_name='Theta',three_charge=3,latex_name='\Theta^{+}')
>>> p3
<Particle: name="Theta", pdgid=9221132, mass=None>
>>>
>>> print(p3.describe())
Name: Theta ID: 9221132 Latex: $\Theta^{+}$
Mass = None
Width = None
Q (charge) = + J (total angular) = 0.5 P (space parity) = None
C (charge parity) = None I (isospin) = None G (G-parity) = None
SpinType: SpinType.NonDefined
Antiparticle name: Theta (antiparticle status: Same)
高级:转换
您可以使用particle.particle.convert
中的实用程序转换和更新粒子表。这需要pandas
包,并且仅在Python 3上进行了测试。运行以下命令以获取更多信息
$ python3 -m particle.particle.convert --help
入门:转换器
您可以使用映射类在粒子MC识别代码和粒子名称之间进行转换。请参阅particle.converters
模块以获取可用的映射类。例如
>>> from particle.converters import Pythia2PDGIDBiMap
>>> from particle import PDGID, PythiaID
>>>
>>> pyid = Pythia2PDGIDBiMap[PDGID(9010221)]
>>> pyid
<PythiaID: 10221>
>>> pdgid = Pythia2PDGIDBiMap[PythiaID(10221)]
>>> pdgid
<PDGID: 9010221>
此代码使用了类似于PDGID
的类,这些类包含MC程序使用的粒子识别代码。可能的用例如下
>>> from particle import Particle
>>> from particle import Corsika7ID, Geant3ID, PythiaID
>>>
>>> g3id = Geant3ID(8)
>>> p = Particle.from_pdgid(g3id.to_pdgid())
>>>
>>> (p,) = Particle.finditer(pdgid=g3id.to_pdgid()) # syntax (p,) throws an error if < 1 or > 1 particle is found
>>> p.name
'pi+'
>>> pythiaid = PythiaID(211)
>>> p = Particle.from_pdgid(pythiaid.to_pdgid())
>>> (p,) = Particle.finditer(pdgid=pythiaid.to_pdgid())
>>> p.name
'pi+'
>>> cid = Corsika7ID(5)
>>> p = Particle.from_pdgid(cid.to_pdgid())
>>> p.name
'mu+'
Corsika7
Corsika7ID
类实现了使使用Corsika7输出更容易的功能。有关完整功能集,请参阅particle.corsika
子模块。
Corsika7ID.from_particle_description(from_particle_description: int)
返回(Corsika7ID, bool)
,以自动解析来自Corsika7粒子数据子块的particle_description
。
Corsika7ID.is_particle()
检查ID是否指向实际的粒子或其他内容(如附加信息)。
Corsika7ID.to_pdgid()
如果可能,将Corsika7ID
转换为PDGID
。
入门:特定于实验的模块
如果特定于实验的子模块与包的功能很好地结合,同时提供与实验特别相关的附加功能,则欢迎它们。
LHCb特定模块
通过以下方式提供
>>> from particle import lhcb
它包含以下转换器和函数
>>> dir(lhcb)
['LHCbName2PDGIDBiMap', 'from_lhcb_name', 'to_lhcb_name']
>>> n, e, l = Particle.from_pdgid(-531).name, Particle.from_pdgid(531).evtgen_name, lhcb.to_lhcb_name(Particle.from_pdgid(-531))
>>> print(f"Name: {n}\nEvtGen name: {e}\nLHCb name: {l}")
Name: B(s)~0
EvtGen name: B_s0
LHCb name: B_s~0
>>> p = Particle.from_pdgid(-531)
>>> p
<Particle: name="B(s)~0", pdgid=-531, mass=5366.88 ± 0.14 MeV>
>>>to_lhcb_name(p)
'B_s~0'
PDG ID <-> LHCb名称的转换可通过预定义的双向映射获得,类似于标准(即非特定于实验)转换器中可用的映射
>>> name = LHCbName2PDGIDBiMap[PDGID(-531)]
>>> name
'B_s~0'
>>> pdgid = LHCbName2PDGIDBiMap['B_s~0']
>>> pdgid
<PDGID: -531>
贡献者
在此,我们感谢使本项目成为可能的所有贡献者(表情符号键)
本项目遵循所有贡献者规范。
致谢
英国科学与技术设施委员会(STFC)和利物浦大学为爱德华多·罗德里格斯(2020-)在本项目部分时间工作提供资金。
该项目在2016-2019年由国家科学基金会合作协议OAC-1450377(DIANA/HEP)提供支持,自2019年以来由OAC-1836650(IRIS-HEP)提供支持。本材料中表达的意见、发现、结论或建议均为作者的观点,不一定反映国家科学基金会的观点。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
particle-0.25.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9706748e95a706dffd49426db393298197fe1af819721c5d2c6e515764a1fb01 |
|
MD5 | b1492ad88703782e73a93017eb62449b |
|
BLAKE2b-256 | cc7ac7eaaaee87828bd6104e37a031e715f6bb692e7d62c3de6087da32b3d3bd |
particle-0.25.1-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2fd02b3ba2282cd80fcd98e65f8f537195482c6e52a0895357e833da826eb42a |
|
MD5 | 36c4333f287c537930217b7d83ef75be |
|
BLAKE2b-256 | 7da7622dc5d33e222107bec24dc9eda81d4aa9febf18508dfa43b7d91d96acb7 |