particle


Nameparticle JSON
Version 0.23.1 PyPI version JSON
download
home_page
SummaryExtended PDG particle data and MC identification codes
upload_time2023-12-01 13:49:57
maintainer
docs_urlNone
author
requires_python>=3.7
license
keywords hep mc identification codes pdg pdgid particle particle data table particle properties
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: https://github.com/scikit-hep/particle/raw/master/docs/ParticleLogo300.png
    :target: https://github.com/scikit-hep/particle


``Particle``: PDG particle data and identification codes
========================================================

|Scikit-HEP| |PyPI version| |Conda-forge version| |Zenodo DOI|

|GitHub Actions Status: CI| |Code Coverage|

|Binder|


Particle provides a pythonic interface to the `Particle Data Group <http://pdg.lbl.gov/>`_ (PDG)
particle data tables and particle identification codes,
with extended particle information and extra goodies.

The PDG defines the standard particle identification (ID) numbering scheme.
The package provides the ``PDGID`` class implementing queries on those PDG IDs.
The queries are also accessible through free standing functions mimicking,
and expanding from, the HepPID/HepPDT C++ interface.

The ``Particle`` class wraps the information in the PDG particle data tables and
provides an object-oriented interface and powerful search and look-up utilities.


Installation
------------

Install ``particle`` like any other Python package:

.. code-block:: bash

    python -m pip install particle

or similar (use ``--user``, ``virtualenv``, etc. if you wish).


Strict dependencies
-------------------

- `Python <http://docs.python-guide.org/en/latest/starting/installation/>`_ (3.7+)
- `importlib_resources backport <http://importlib-resources.readthedocs.io/en/latest/>`_ if using Python < 3.9
- `attrs <http://www.attrs.org/en/stable/>`_ provides classes without boilerplate (similar to DataClasses in Python 3.7)
- `hepunits <https://github.com/scikit-hep/hepunits>`_ provides units for the Scikit-HEP packages


Changelog
---------

See the `changelog <https://github.com/scikit-hep/particle/blob/master/docs/CHANGELOG.md>`__ for a history of notable changes.


Getting started: PDG IDs
------------------------

.. code-block:: python

    >>> from particle import PDGID
    >>>
    >>> pid = PDGID(211)
    >>> pid
    <PDGID: 211>
    >>> pid.is_meson
    True
    >>> pid = PDGID(99999999)
    >>> pid
    <PDGID: 99999999 (is_valid==False)>

For convenience, all properties of the ``PDGID`` class are available as standalone functions that work on any SupportsInt (including ``Particle``):

.. code-block:: python

    >>> from particle.pdgid import is_meson
    >>>
    >>> is_meson(211)
    True

These composable functions qualifying PDG IDs make it easy to classify particles.
For the sake of example, quarkonia can be specified with the following user-defined functions:

.. code-block:: python

    >>> 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 literals provide (``PDGID`` class) aliases for all particles loaded, with easily recognisable names.
For example:

.. code-block:: python

    >>> 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

You can quickly display ``PDGID`` info from the command line with:

.. code-block:: bash

    $ 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
    ...


Similarly, classes exist to express identification codes used by MC programs,
see information on converters below.


Getting started: Particles
--------------------------

You can use a variety of methods to get particles. If you know the PDG ID number
or, say, the name used in EvtGen, you can get a particle directly.

.. code-block:: python

    >>> 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>

A similar method exists to get a list of particles from a PDG style name:

.. code-block:: python

    >>> Particle.findall(pdg_name="pi")

returns the list of matching particles whose PDG name is "pi",
which in this case comprises the three charged states of the pseudoscalar pion.

Else, and more generally, you can use a search. A basic example is the following:

.. code-block:: python

    >>> 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>

You can search for the properties using keyword arguments, which include
``pdg_name``, ``name``, ``mass``, ``width``, ``charge``, ``three_charge``, ``anti_flag``, ``rank``,
``I``, ``J``, ``G``, ``P``, ``quarks``, ``status``,
``mass_upper``, ``mass_lower``, ``width_upper``, and ``width_lower``.
You can pass a callable or an exact match for any property.
The argument ``particle`` can be set to ``True``/``False``, as well,
to limit the search to particles or antiparticles.

You can also build the search yourself with the first positional
argument, which accepts a callable that is given the particle object itself.
If the first positional argument is a string, that will match against the
particle's ``name``.

Here are possible sophisticated searches, all of which work with either
``Particle.findall`` or ``Particle.finditer``, where the former method provides a list
whereas the latter returns an iterator.

.. code-block:: python

    >>> # 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>]

Once you have a particle, any of the properties can be accessed, along with several methods.
Though they are not real properties, you can access ``is_name_barred``, and ``spin_type``.
You can also ``.invert()`` a particle.

There are lots of printing choices for particles:
``describe()``, ``programmatic_name``, ``latex_name``, ``html_name``, HTML printing outs in notebooks,
and of course ``repr`` and ``str`` support.

You can get the ``.pdgid`` from a particle, as well.
Sorting particles will put lowest ``abs(PDGID)`` first.


Particle literals provide (``Particle`` class) aliases for the particles loaded,
with easily recognisable names. For example:

.. code-block:: python

    >>> 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

You can quickly search for particles from the command line with
(note: quotes may be used/needed but only double quotes work as expected on Windows):

.. code-block:: bash

    $ 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>

If you only select one particle, either by a search or by giving the PDG ID number,
you can see more information about the particle:

.. code-block:: bash

    $ 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)


Advanced: Loading custom tables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can control the particle data tables if you so desire. You can append a new data table using the following syntax:

.. code-block:: python

    >>> from particle import Particle
    >>> Particle.load_table('new_particles.csv', append=True)

You can also replace the particle table entirely with ``append=False`` (the default).

If you want a non-default data file distributed with the package just proceed as follows:

.. code-block:: python

    >>> from particle import data
    >>> Particle.load_table(data.basepath / "particle2022.csv"))
    >>> Particle.load_table(data.basepath / "nuclei2022.csv"), append=True)  # I still want nuclei info
    >>> Particle.table_names()  # list the loaded tables


Advanced: how to create user-defined particles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There are situations where it may be handy to create user-defined particles.
But do so with care and having in mind the limitations, many of which are discussed or exemplified below!

The simplest "particle" one may create is effectively a placeholder with no real information stored:

.. code-block:: python

    >>> # 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

A more useful particle definition will likely involve at least a name and a PDG ID.
It is important to keep in mind that a meaningful PDG ID encodes by construction internal quantum numbers
and other information. As such, the definition of a particle with a "random" PDG ID
will result in a particle with undefined and/or wrong properties such as quantum numbers or the quality of being a meson.

.. code-block:: python

    >>> 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)

A yet more sophisticated definition:

.. code-block:: python

    >>> 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)


Advanced: Conversion
^^^^^^^^^^^^^^^^^^^^

You can convert and update the particle tables with the utilities in ``particle.particle.convert``. This requires the
``pandas`` package, and is only tested with Python 3. Run the following command for more help:

.. code-block:: bash

    $ python3 -m particle.particle.convert --help


Getting started: Converters
---------------------------

You can use mapping classes to convert between particle MC identification codes
and particle names. See the ``particle.converters`` modules for the available
mapping classes. For example:

.. code-block:: python

    >>> from particle.converters import Pythia2PDGIDBiMap
    >>> from particle import PDGID, PythiaID
    >>>
    >>> pyid = Pythia2PDGIDBiMap[PDGID(9010221)]
    >>> pyid
    <PythiaID: 10221>

    >>> pdgid = Pythia2PDGIDBiMap[PythiaID(10221)]
    >>> pdgid
    <PDGID: 9010221>

This code makes use of classes similar to ``PDGID``, which hold
particle identification codes used by MC programs.
Possible use cases are the following:

.. code-block:: python

    >>> 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
^^^^^^^^

The ``Corsika7ID`` class implements features to make it easier to work with Corsika7 output.
For a full feature set, please refer to the ``particle.corsika`` submodule.

``Corsika7ID.from_particle_description(from_particle_description: int)`` returns ``(Corsika7ID, bool)``
to automatically parse the ``particle_description`` from the Corsika7 particle data sub-block.

``Corsika7ID.is_particle()`` checks if the ID refers to an actual particle or something else (like additional information).

``Corsika7ID.to_pdgid()`` converts the ``Corsika7ID`` to a ``PDGID`` if possible.


Getting started: experiment-specific modules
--------------------------------------------

Experiment-specific submodules are welcome if they tie in nicely with the functionality of the package while providing
add-ons of particular relevance to experiments.

LHCb-specific module
^^^^^^^^^^^^^^^^^^^^

Available via

.. code-block:: python

    >>> from particle import lhcb

it contains the following converter and functions:

.. code-block:: python

    >>> dir(lhcb)
    ['LHCbName2PDGIDBiMap', 'from_lhcb_name', 'to_lhcb_name']


.. code-block:: python

    >>> 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'


Conversions PDG ID <-> LHCb name are available via a predefined bidirectional map
similarly to what is available in the standard (i.e. non-experiment-specific) converters:

.. code-block:: python

    >>> name = LHCbName2PDGIDBiMap[PDGID(-531)]
    >>> name
    'B_s~0'

    >>> pdgid = LHCbName2PDGIDBiMap['B_s~0']
    >>> pdgid
    <PDGID: -531>


Acknowledgements
----------------

The UK Science and Technology Facilities Council (STFC) and the University of Liverpool
provide funding for Eduardo Rodrigues (2020-) to work on this project part-time.

Support for this work was provided by the National Science Foundation cooperative agreement OAC-1450377 (DIANA/HEP) in 2016-2019
and has been provided by OAC-1836650 (IRIS-HEP) since 2019.
Any opinions, findings, conclusions or recommendations expressed in this material
are those of the authors and do not necessarily reflect the views of the National Science Foundation.


.. |Scikit-HEP| image:: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg
   :target: https://scikit-hep.org

.. |PyPI version| image:: https://img.shields.io/pypi/v/particle.svg
   :target: https://pypi.python.org/pypi/particle

.. |Conda-forge version| image:: https://img.shields.io/conda/vn/conda-forge/particle.svg
   :target: https://github.com/conda-forge/particle-feedstock

.. |Zenodo DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.2552429.svg
   :target: https://doi.org/10.5281/zenodo.2552429

.. |GitHub Actions Status: CI| image:: https://github.com/scikit-hep/particle/workflows/CI/badge.svg
   :target: https://github.com/scikit-hep/particle/actions

.. |Code Coverage| image:: https://codecov.io/gh/scikit-hep/particle/graph/badge.svg?branch=master
   :target: https://codecov.io/gh/scikit-hep/particle?branch=master

.. |Binder| image:: https://mybinder.org/badge_logo.svg
   :target: https://mybinder.org/v2/gh/scikit-hep/particle/master?urlpath=lab/tree/notebooks/ParticleDemo.ipynb

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "particle",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "Scikit-HEP <scikit-hep-admins@googlegroups.com>",
    "keywords": "HEP,MC identification codes,PDG,PDGID,particle,particle data table,particle properties",
    "author": "",
    "author_email": "Eduardo Rodrigues <eduardo.rodrigues@cern.ch>, Henry Schreiner <henryfs@princeton.edu>",
    "download_url": "https://files.pythonhosted.org/packages/d2/6e/5388aff56642e195a4a51cbcf25fe274ab372cd53f408fb98092b9d07256/particle-0.23.1.tar.gz",
    "platform": null,
    "description": ".. image:: https://github.com/scikit-hep/particle/raw/master/docs/ParticleLogo300.png\n    :target: https://github.com/scikit-hep/particle\n\n\n``Particle``: PDG particle data and identification codes\n========================================================\n\n|Scikit-HEP| |PyPI version| |Conda-forge version| |Zenodo DOI|\n\n|GitHub Actions Status: CI| |Code Coverage|\n\n|Binder|\n\n\nParticle provides a pythonic interface to the `Particle Data Group <http://pdg.lbl.gov/>`_ (PDG)\nparticle data tables and particle identification codes,\nwith extended particle information and extra goodies.\n\nThe PDG defines the standard particle identification (ID) numbering scheme.\nThe package provides the ``PDGID`` class implementing queries on those PDG IDs.\nThe queries are also accessible through free standing functions mimicking,\nand expanding from, the HepPID/HepPDT C++ interface.\n\nThe ``Particle`` class wraps the information in the PDG particle data tables and\nprovides an object-oriented interface and powerful search and look-up utilities.\n\n\nInstallation\n------------\n\nInstall ``particle`` like any other Python package:\n\n.. code-block:: bash\n\n    python -m pip install particle\n\nor similar (use ``--user``, ``virtualenv``, etc. if you wish).\n\n\nStrict dependencies\n-------------------\n\n- `Python <http://docs.python-guide.org/en/latest/starting/installation/>`_ (3.7+)\n- `importlib_resources backport <http://importlib-resources.readthedocs.io/en/latest/>`_ if using Python < 3.9\n- `attrs <http://www.attrs.org/en/stable/>`_ provides classes without boilerplate (similar to DataClasses in Python 3.7)\n- `hepunits <https://github.com/scikit-hep/hepunits>`_ provides units for the Scikit-HEP packages\n\n\nChangelog\n---------\n\nSee the `changelog <https://github.com/scikit-hep/particle/blob/master/docs/CHANGELOG.md>`__ for a history of notable changes.\n\n\nGetting started: PDG IDs\n------------------------\n\n.. code-block:: python\n\n    >>> from particle import PDGID\n    >>>\n    >>> pid = PDGID(211)\n    >>> pid\n    <PDGID: 211>\n    >>> pid.is_meson\n    True\n    >>> pid = PDGID(99999999)\n    >>> pid\n    <PDGID: 99999999 (is_valid==False)>\n\nFor convenience, all properties of the ``PDGID`` class are available as standalone functions that work on any SupportsInt (including ``Particle``):\n\n.. code-block:: python\n\n    >>> from particle.pdgid import is_meson\n    >>>\n    >>> is_meson(211)\n    True\n\nThese composable functions qualifying PDG IDs make it easy to classify particles.\nFor the sake of example, quarkonia can be specified with the following user-defined functions:\n\n.. code-block:: python\n\n    >>> is_heavy_flavor = lambda x: has_charm(x) or has_bottom(x) or has_top(x)\n    >>> is_quarkonium = lambda x: is_meson(x) and is_heavy_flavor(x) and Particle.from_pdgid(x).is_self_conjugate\n\nPDG ID literals provide (``PDGID`` class) aliases for all particles loaded, with easily recognisable names.\nFor example:\n\n.. code-block:: python\n\n    >>> from particle.pdgid import literals as lid\n    >>>\n    >>> lid.pi_plus\n    <PDGID: 211>\n    >>>\n    >>> from particle.pdgid.literals import Lambda_b_0\n    >>> Lambda_b_0\n    <PDGID: 5122>\n    >>> Lambda_b_0.has_bottom\n    True\n\nYou can quickly display ``PDGID`` info from the command line with:\n\n.. code-block:: bash\n\n    $ python -m particle pdgid 323\n    <PDGID: 323>\n    A              None\n    J              1.0\n    L              0\n    S              1\n    Z              None\n    abspid         323\n    charge         1.0\n    has_bottom     False\n    ...\n\n\nSimilarly, classes exist to express identification codes used by MC programs,\nsee information on converters below.\n\n\nGetting started: Particles\n--------------------------\n\nYou can use a variety of methods to get particles. If you know the PDG ID number\nor, say, the name used in EvtGen, you can get a particle directly.\n\n.. code-block:: python\n\n    >>> from particle import Particle\n    >>> Particle.from_pdgid(211)\n    <Particle: name=\"pi+\", pdgid=211, mass=139.57039 \u00b1 0.00018 MeV>\n    >>>\n    >>> Particle.from_evtgen_name(\"J/psi\")\n    <Particle: name=\"J/psi(1S)\", pdgid=443, mass=3096.900 \u00b1 0.006 MeV>\n    >>>\n    >>> Particle.from_nucleus_info(a=12, z=6)\n    <Particle: name=\"C12\", pdgid=1000060120, mass=11177.9291399 MeV>\n\nA similar method exists to get a list of particles from a PDG style name:\n\n.. code-block:: python\n\n    >>> Particle.findall(pdg_name=\"pi\")\n\nreturns the list of matching particles whose PDG name is \"pi\",\nwhich in this case comprises the three charged states of the pseudoscalar pion.\n\nElse, and more generally, you can use a search. A basic example is the following:\n\n.. code-block:: python\n\n    >>> next(Particle.finditer('pi'))  # first item in iterator of particles\n    <Particle: name=\"pi0\", pdgid=111, mass=134.9768 \u00b1 0.0005 MeV>\n    >>>\n    >>> Particle.findall('pi')[0]  # Same as above but returning a list of particles\n    <Particle: name=\"pi0\", pdgid=111, mass=134.9768 \u00b1 0.0005 MeV>\n\nYou can search for the properties using keyword arguments, which include\n``pdg_name``, ``name``, ``mass``, ``width``, ``charge``, ``three_charge``, ``anti_flag``, ``rank``,\n``I``, ``J``, ``G``, ``P``, ``quarks``, ``status``,\n``mass_upper``, ``mass_lower``, ``width_upper``, and ``width_lower``.\nYou can pass a callable or an exact match for any property.\nThe argument ``particle`` can be set to ``True``/``False``, as well,\nto limit the search to particles or antiparticles.\n\nYou can also build the search yourself with the first positional\nargument, which accepts a callable that is given the particle object itself.\nIf the first positional argument is a string, that will match against the\nparticle's ``name``.\n\nHere are possible sophisticated searches, all of which work with either\n``Particle.findall`` or ``Particle.finditer``, where the former method provides a list\nwhereas the latter returns an iterator.\n\n.. code-block:: python\n\n    >>> # Print out all particles with asymmetric decay width uncertainties\n    >>> ps = Particle.finditer(lambda p: p.width_lower != p.width_upper)\n    >>> for p in ps:\n    ...     print(p.name, p.pdgid, p.width_lower, p.width_upper)\n    >>>\n    >>> # Find all antiparticles with 'Omega' in the name\n    >>> Particle.finditer('Omega', particle=False)   # several found\n    >>>\n    >>> # Find all antiparticles of name=='Omega'\n    >>> Particle.finditer(name='Omega', particle=False)  # none found\n    >>>\n    >>> # Find all antiparticles of pdg_name=='Omega'\n    >>> Particle.findall(pdg_name='Omega', particle=False)  # only 1, of course\n    [<Particle: name=\"Omega~+\", pdgid=-3334, mass=1672.5 \u00b1 0.3 MeV>]\n    >>>\n    >>> # Find all neutral beauty hadrons\n    >>> Particle.findall(lambda p: p.pdgid.has_bottom and p.charge==0)\n    >>>\n    >>> # Find all strange mesons with c*tau > 1 meter\n    >>> from hepunits import meter\n    >>> Particle.findall(lambda p: p.pdgid.is_meson and p.pdgid.has_strange and p.ctau > 1 * meter, particle=True)\n    [<Particle: name=\"K(L)0\", pdgid=130, mass=497.611 \u00b1 0.013 MeV>,\n     <Particle: name=\"K+\", pdgid=321, mass=493.677 \u00b1 0.016 MeV>]\n\nOnce you have a particle, any of the properties can be accessed, along with several methods.\nThough they are not real properties, you can access ``is_name_barred``, and ``spin_type``.\nYou can also ``.invert()`` a particle.\n\nThere are lots of printing choices for particles:\n``describe()``, ``programmatic_name``, ``latex_name``, ``html_name``, HTML printing outs in notebooks,\nand of course ``repr`` and ``str`` support.\n\nYou can get the ``.pdgid`` from a particle, as well.\nSorting particles will put lowest ``abs(PDGID)`` first.\n\n\nParticle literals provide (``Particle`` class) aliases for the particles loaded,\nwith easily recognisable names. For example:\n\n.. code-block:: python\n\n    >>> from particle import literals as lp\n    >>> lp.pi_plus\n    <Particle: name=\"pi+\", pdgid=211, mass=139.57061 \u00b1 0.00024 MeV>\n    >>>\n    >>> from particle.literals import Lambda_b_0\n    >>> Lambda_b_0\n    <Particle: name=\"Lambda(b)0\", pdgid=5122, mass=5619.60 \u00b1 0.17 MeV>\n    >>> Lambda_b_0.J\n    0.5\n\nYou can quickly search for particles from the command line with\n(note: quotes may be used/needed but only double quotes work as expected on Windows):\n\n.. code-block:: bash\n\n    $ python -m particle search \"K*0\"\n    <Particle: name=\"K*(892)0\", pdgid=313, mass=895.55 \u00b1 0.20 MeV>\n    <Particle: name=\"K*(1680)0\", pdgid=30313, mass=1718 \u00b1 18 MeV>\n    <Particle: name=\"K*(1410)0\", pdgid=100313, mass=1421 \u00b1 9 MeV>\n\nIf you only select one particle, either by a search or by giving the PDG ID number,\nyou can see more information about the particle:\n\n.. code-block:: bash\n\n    $ python -m particle search 311\n    Name: K0             ID: 311          Latex: $K^{0}$\n    Mass  = 497.611 \u00b1 0.013 MeV\n    Width = -1.0 MeV\n    Q (charge)        = 0       J (total angular) = 0.0      P (space parity) = -\n    C (charge parity) = ?       I (isospin)       = 1/2      G (G-parity)     = ?\n        SpinType: SpinType.PseudoScalar\n        Quarks: dS\n        Antiparticle name: K~0 (antiparticle status: Barred)\n\n\nAdvanced: Loading custom tables\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can control the particle data tables if you so desire. You can append a new data table using the following syntax:\n\n.. code-block:: python\n\n    >>> from particle import Particle\n    >>> Particle.load_table('new_particles.csv', append=True)\n\nYou can also replace the particle table entirely with ``append=False`` (the default).\n\nIf you want a non-default data file distributed with the package just proceed as follows:\n\n.. code-block:: python\n\n    >>> from particle import data\n    >>> Particle.load_table(data.basepath / \"particle2022.csv\"))\n    >>> Particle.load_table(data.basepath / \"nuclei2022.csv\"), append=True)  # I still want nuclei info\n    >>> Particle.table_names()  # list the loaded tables\n\n\nAdvanced: how to create user-defined particles\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThere are situations where it may be handy to create user-defined particles.\nBut do so with care and having in mind the limitations, many of which are discussed or exemplified below!\n\nThe simplest \"particle\" one may create is effectively a placeholder with no real information stored:\n\n.. code-block:: python\n\n    >>> # A Particle instance the simplest possible. Contains basically no info\n    >>> p = Particle.empty()\n    >>> p\n    <Particle: name=\"Unknown\", pdgid=0, mass=None>\n    >>>\n    >>> print(p.describe())\n    Name: Unknown\n\nA more useful particle definition will likely involve at least a name and a PDG ID.\nIt is important to keep in mind that a meaningful PDG ID encodes by construction internal quantum numbers\nand other information. As such, the definition of a particle with a \"random\" PDG ID\nwill result in a particle with undefined and/or wrong properties such as quantum numbers or the quality of being a meson.\n\n.. code-block:: python\n\n    >>> p2 = Particle(9912345, 'MyPentaquark')\n    >>> p2\n    <Particle: name=\"MyPentaquark\", pdgid=9912345, mass=None>\n    >>>\n    >>> p2.pdgid.is_pentaquark\n    False\n    >>> print(p2.describe())  # J=2 is an example of something effectively encoded in the PDG ID.\n    Name: MyPentaquark   ID: 9912345      Latex: $Unknown$\n    Mass  = None\n    Width = None\n    Q (charge)        = None    J (total angular) = 2.0      P (space parity) = None\n    C (charge parity) = None    I (isospin)       = None     G (G-parity)     = None\n        Antiparticle name: MyPentaquark (antiparticle status: Same)\n\nA yet more sophisticated definition:\n\n.. code-block:: python\n\n    >>> p3 = Particle(pdgid=9221132,pdg_name='Theta',three_charge=3,latex_name='\\Theta^{+}')\n    >>> p3\n    <Particle: name=\"Theta\", pdgid=9221132, mass=None>\n    >>>\n    >>> print(p3.describe())\n    Name: Theta          ID: 9221132      Latex: $\\Theta^{+}$\n    Mass  = None\n    Width = None\n    Q (charge)        = +       J (total angular) = 0.5      P (space parity) = None\n    C (charge parity) = None    I (isospin)       = None     G (G-parity)     = None\n        SpinType: SpinType.NonDefined\n        Antiparticle name: Theta (antiparticle status: Same)\n\n\nAdvanced: Conversion\n^^^^^^^^^^^^^^^^^^^^\n\nYou can convert and update the particle tables with the utilities in ``particle.particle.convert``. This requires the\n``pandas`` package, and is only tested with Python 3. Run the following command for more help:\n\n.. code-block:: bash\n\n    $ python3 -m particle.particle.convert --help\n\n\nGetting started: Converters\n---------------------------\n\nYou can use mapping classes to convert between particle MC identification codes\nand particle names. See the ``particle.converters`` modules for the available\nmapping classes. For example:\n\n.. code-block:: python\n\n    >>> from particle.converters import Pythia2PDGIDBiMap\n    >>> from particle import PDGID, PythiaID\n    >>>\n    >>> pyid = Pythia2PDGIDBiMap[PDGID(9010221)]\n    >>> pyid\n    <PythiaID: 10221>\n\n    >>> pdgid = Pythia2PDGIDBiMap[PythiaID(10221)]\n    >>> pdgid\n    <PDGID: 9010221>\n\nThis code makes use of classes similar to ``PDGID``, which hold\nparticle identification codes used by MC programs.\nPossible use cases are the following:\n\n.. code-block:: python\n\n    >>> from particle import Particle\n    >>> from particle import Corsika7ID, Geant3ID, PythiaID\n    >>>\n    >>> g3id = Geant3ID(8)\n    >>> p = Particle.from_pdgid(g3id.to_pdgid())\n    >>>\n    >>> (p,) = Particle.finditer(pdgid=g3id.to_pdgid())  # syntax (p,) throws an error if < 1 or > 1 particle is found\n    >>> p.name\n    'pi+'\n\n    >>> pythiaid = PythiaID(211)\n    >>> p = Particle.from_pdgid(pythiaid.to_pdgid())\n\n    >>> (p,) = Particle.finditer(pdgid=pythiaid.to_pdgid())\n    >>> p.name\n    'pi+'\n\n    >>> cid = Corsika7ID(5)\n    >>> p = Particle.from_pdgid(cid.to_pdgid())\n    >>> p.name\n    'mu+'\n\nCorsika7\n^^^^^^^^\n\nThe ``Corsika7ID`` class implements features to make it easier to work with Corsika7 output.\nFor a full feature set, please refer to the ``particle.corsika`` submodule.\n\n``Corsika7ID.from_particle_description(from_particle_description: int)`` returns ``(Corsika7ID, bool)``\nto automatically parse the ``particle_description`` from the Corsika7 particle data sub-block.\n\n``Corsika7ID.is_particle()`` checks if the ID refers to an actual particle or something else (like additional information).\n\n``Corsika7ID.to_pdgid()`` converts the ``Corsika7ID`` to a ``PDGID`` if possible.\n\n\nGetting started: experiment-specific modules\n--------------------------------------------\n\nExperiment-specific submodules are welcome if they tie in nicely with the functionality of the package while providing\nadd-ons of particular relevance to experiments.\n\nLHCb-specific module\n^^^^^^^^^^^^^^^^^^^^\n\nAvailable via\n\n.. code-block:: python\n\n    >>> from particle import lhcb\n\nit contains the following converter and functions:\n\n.. code-block:: python\n\n    >>> dir(lhcb)\n    ['LHCbName2PDGIDBiMap', 'from_lhcb_name', 'to_lhcb_name']\n\n\n.. code-block:: python\n\n    >>> n, e, l = Particle.from_pdgid(-531).name, Particle.from_pdgid(531).evtgen_name, lhcb.to_lhcb_name(Particle.from_pdgid(-531))\n    >>> print(f\"Name: {n}\\nEvtGen name: {e}\\nLHCb name: {l}\")\n    Name: B(s)~0\n    EvtGen name: B_s0\n    LHCb name: B_s~0\n\n    >>> p = Particle.from_pdgid(-531)\n    >>> p\n    <Particle: name=\"B(s)~0\", pdgid=-531, mass=5366.88 \u00b1 0.14 MeV>\n    >>>to_lhcb_name(p)\n    'B_s~0'\n\n\nConversions PDG ID <-> LHCb name are available via a predefined bidirectional map\nsimilarly to what is available in the standard (i.e. non-experiment-specific) converters:\n\n.. code-block:: python\n\n    >>> name = LHCbName2PDGIDBiMap[PDGID(-531)]\n    >>> name\n    'B_s~0'\n\n    >>> pdgid = LHCbName2PDGIDBiMap['B_s~0']\n    >>> pdgid\n    <PDGID: -531>\n\n\nAcknowledgements\n----------------\n\nThe UK Science and Technology Facilities Council (STFC) and the University of Liverpool\nprovide funding for Eduardo Rodrigues (2020-) to work on this project part-time.\n\nSupport for this work was provided by the National Science Foundation cooperative agreement OAC-1450377 (DIANA/HEP) in 2016-2019\nand has been provided by OAC-1836650 (IRIS-HEP) since 2019.\nAny opinions, findings, conclusions or recommendations expressed in this material\nare those of the authors and do not necessarily reflect the views of the National Science Foundation.\n\n\n.. |Scikit-HEP| image:: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg\n   :target: https://scikit-hep.org\n\n.. |PyPI version| image:: https://img.shields.io/pypi/v/particle.svg\n   :target: https://pypi.python.org/pypi/particle\n\n.. |Conda-forge version| image:: https://img.shields.io/conda/vn/conda-forge/particle.svg\n   :target: https://github.com/conda-forge/particle-feedstock\n\n.. |Zenodo DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.2552429.svg\n   :target: https://doi.org/10.5281/zenodo.2552429\n\n.. |GitHub Actions Status: CI| image:: https://github.com/scikit-hep/particle/workflows/CI/badge.svg\n   :target: https://github.com/scikit-hep/particle/actions\n\n.. |Code Coverage| image:: https://codecov.io/gh/scikit-hep/particle/graph/badge.svg?branch=master\n   :target: https://codecov.io/gh/scikit-hep/particle?branch=master\n\n.. |Binder| image:: https://mybinder.org/badge_logo.svg\n   :target: https://mybinder.org/v2/gh/scikit-hep/particle/master?urlpath=lab/tree/notebooks/ParticleDemo.ipynb\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Extended PDG particle data and MC identification codes",
    "version": "0.23.1",
    "project_urls": {
        "Homepage": "https://github.com/scikit-hep/particle"
    },
    "split_keywords": [
        "hep",
        "mc identification codes",
        "pdg",
        "pdgid",
        "particle",
        "particle data table",
        "particle properties"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "28c481d9080d92aa12e8b249a88780fece43c50acec6c876454c7b32cc320d84",
                "md5": "54e939d683b0bc4aaef4ffa866ccd231",
                "sha256": "1c68a36f1c3640bd8e5d4f47fc026064aa28264dfd283121d1f784d55947f1b7"
            },
            "downloads": -1,
            "filename": "particle-0.23.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "54e939d683b0bc4aaef4ffa866ccd231",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 289289,
            "upload_time": "2023-12-01T13:49:55",
            "upload_time_iso_8601": "2023-12-01T13:49:55.310227Z",
            "url": "https://files.pythonhosted.org/packages/28/c4/81d9080d92aa12e8b249a88780fece43c50acec6c876454c7b32cc320d84/particle-0.23.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d26e5388aff56642e195a4a51cbcf25fe274ab372cd53f408fb98092b9d07256",
                "md5": "8862f28dad312909e187fbac96600144",
                "sha256": "eee28b0e846bfea4dfd70e9ec5ffe3244613db08b6b6a9b773f55a4310752fab"
            },
            "downloads": -1,
            "filename": "particle-0.23.1.tar.gz",
            "has_sig": false,
            "md5_digest": "8862f28dad312909e187fbac96600144",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 313729,
            "upload_time": "2023-12-01T13:49:57",
            "upload_time_iso_8601": "2023-12-01T13:49:57.696127Z",
            "url": "https://files.pythonhosted.org/packages/d2/6e/5388aff56642e195a4a51cbcf25fe274ab372cd53f408fb98092b9d07256/particle-0.23.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-01 13:49:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "scikit-hep",
    "github_project": "particle",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "particle"
}
        
Elapsed time: 0.16024s