跳转到主要内容

扩展PDG粒子数据和MC识别代码

项目描述

Particle Logo

粒子: PDG粒子数据和识别代码

Scikit-HEP PyPI Package latest release Conda latest release Zenodo DOI

GitHub Actions Status: CI Code Coverage

Binder

Particle库为粒子数据组(PDG)的粒子数据表和粒子识别代码提供了一个Pythonic接口,并扩展了粒子信息以及一些额外功能。

PDG定义了标准的粒子识别(ID)编号方案。该库提供了一个实现PDG ID查询的PDGID类。查询也可以通过模拟并扩展HepPID/HepPDT C++接口的独立函数来访问。

Particle类封装了PDG粒子数据表中的信息,并提供了一个面向对象的接口以及强大的搜索和查找工具。

安装

像其他Python库一样安装particle

python -m pip install particle

或类似操作(如果您愿意,可以使用--uservirtualenv等)。

严格依赖项

变更日志

有关重要变更的历史记录,请参阅变更日志

入门: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_namenamemasswidthchargethree_chargeanti_flagrankIJGPquarksstatusmass_uppermass_lowerwidth_upper,和width_lower。您可以传递一个可调用的函数或任何属性的精确匹配。您还可以将particle参数设置为True/False,以限制搜索到粒子或反粒子。

您还可以使用第一个位置参数构建搜索,它接受一个可调用的函数,该函数接收粒子对象本身。如果第一个位置参数是一个字符串,它将与粒子的name匹配。

以下是一些可能的复杂搜索,所有这些都可以与Particle.findallParticle.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_barredspin_type。您还可以对粒子进行.invert()

粒子有大量的打印选项:describe()programmatic_namelatex_namehtml_name,在笔记本中的HTML打印输出,以及当然还有reprstr支持。

您还可以从粒子中获取.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>

贡献者

在此,我们感谢使本项目成为可能的所有贡献者(表情符号键

Eduardo Rodrigues
Eduardo Rodrigues

🚧 💻 📖
Henry Schreiner
Henry Schreiner

🚧 💻 📖
Hans Dembinski
Hans Dembinski

💻
Ludwig Neste
Ludwig Neste

💻 📖
Tamas Gal
Tamas Gal

💻
Matthew Feickert
Matthew Feickert

💻
Jost Migenda
Jost Migenda

📖
Jonas Eschle
Jonas Eschle

💻
Chris Burr
Chris Burr

💻
Adam Morris
Adam Morris

💻
Doron Behar
多罗恩·贝哈

📖
Alexander Puck Neuwirth
亚历山大·普克·纽维尔特

📖
Aman Desai
阿曼·德萨伊

💻
Jonathan Tellechea
乔纳森·特莱切亚

📖
Remco de Boer
雷姆科·德博尔

💻
Maximilian Linhoff
马克西米利安·林霍夫

💻

本项目遵循所有贡献者规范

致谢

英国科学与技术设施委员会(STFC)和利物浦大学为爱德华多·罗德里格斯(2020-)在本项目部分时间工作提供资金。

该项目在2016-2019年由国家科学基金会合作协议OAC-1450377(DIANA/HEP)提供支持,自2019年以来由OAC-1836650(IRIS-HEP)提供支持。本材料中表达的意见、发现、结论或建议均为作者的观点,不一定反映国家科学基金会的观点。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

particle-0.25.1.tar.gz (316.6 kB 查看哈希值)

上传时间

构建分布

particle-0.25.1-py3-none-any.whl (290.5 kB 查看哈希值)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面