Source code for pythiaplotter.utils.pdgid_converter

"""Functions to provide TeX and normal ("raw") particle names for a given PDGID.

Uses the PDGID for TeX names, and Pythia8 for normal names.

TODO: what if pdgid doesn't exist?

TODO: deal with tex entries like: ``25 h^0 / H_1^0``
"""


from __future__ import absolute_import
import re
import xml.etree.ElementTree as ET
from pkg_resources import resource_string


[docs]def load_pdgid_dict(): """Generate dictionary with PDGIDs and corresponding names e.g. ``\pi^0, pi0`` For each PDGID key, we store the tex and "raw" string names, for both particle and antiparticle - Tex names taken from http://cepa.fnal.gov/psm/stdhep/numbers.shtml Although based on 2006 PDG, so bit out of date! To add new particles, either add above or in pdg_all.tex - String names use the ParticleData.xml file from Pythia8/xmldoc. Have copied it into repo, although should probably ask user to link to it. Although the original - it has lots of standard text crap before it - there are typos where <particle ... ends with />, not > giving error ! So stick with mine for now... """ pdgid_dict = {} # get latex names # decode() necessary as "The resource is read in binary fashion, such that the returned # string contains exactly the bytes that are stored in the resource." particle_tex = resource_string('pythiaplotter', "particledata/pdg_all.tex").decode('utf-8') for line in particle_tex.split('\n'): (pid, tex) = line.split(" ", 1) tex = tex.strip() # Generate anti-particle latex tex_anti = "" if "+" in tex: tex_anti = tex.replace('+', '-') elif "-" in tex: tex_anti = tex.replace("-", "+") else: # Only want the bar over the main bit of text - ignore _ or ^ pattern = re.compile(r"[_\^]") stem = pattern.search(tex) if stem: tex_anti = "\\overline{%s}%s" % (tex[:stem.start()], tex[stem.end() - 1:]) else: tex_anti = "\\overline{%s}" % tex # add entry into dictionary, defaults for raw names = tex names pdgid_dict[int(pid)] = dict(tex=tex, raw=tex,) pdgid_dict[-1 * int(pid)] = dict(tex=tex_anti, raw=tex_anti) # get raw string names particle_data = resource_string('pythiaplotter', "particledata/PythiaParticleData.xml") root = ET.ElementTree(ET.fromstring(particle_data)).getroot() # nasty hack... for child in root: pid = int(child.get('id')) name = child.get('name') # if no antiparticle name, use particle name anti_name = child.get('antiName') if child.get('antiName') else name if pid in list(pdgid_dict.keys()): pdgid_dict[pid]["raw"] = name pdgid_dict[-1 * pid]["raw"] = anti_name else: # add new entry, use raw names as defaults for tex names pdgid_dict[pid] = dict(tex=name, raw=name) pdgid_dict[-1 * pid] = dict(tex=anti_name, raw=anti_name) # These are for the CMSSW Pythia6 interface pdgid_dict[88] = dict(latex='junction', latex_anti='junction', raw='junction', raw_anti='junction') pdgid_dict[92] = dict(latex='string', latex_anti='string', raw='string', raw_anti='string') return pdgid_dict
# Dictionary, where PDGID is key, and value is a dictionary with fields for # latex and raw string names. Separate entries for particle & antiparticle PDGID_NAME_DICT = load_pdgid_dict() # Add in custom particles e.g. # PDGID_NAME_DICT[999] = dict(latex="I^0", latex_anti="\\overline{I}^0", # raw="I0", raw_anti="I0")
[docs]def check_pdgid(pdgid): """Check if entry corresponding to given pdgid. If not, throw KeyError.""" if int(pdgid) not in list(PDGID_NAME_DICT.keys()): raise KeyError("%r not in list of valid particle names/PDGIDs. Please " "add custom entry in pdgid_converter.py" % pdgid)
[docs]def pdgid_to_tex(pdgid): """Convert PDGID to TeX-compatible name e.g. ``\pi^0``""" check_pdgid(pdgid) return PDGID_NAME_DICT[int(pdgid)]["tex"]
[docs]def pdgid_to_string(pdgid): """Convert PDGID to readable string (raw) name e.g. ``pi0``""" check_pdgid(pdgid) return PDGID_NAME_DICT[int(pdgid)]["raw"]