Source code for yadism.observable_name

"""High level interface to the observable names.

Wrap the name of the observables in order to perform operations on
them. For instance, it checks what kind of observable is being dealt
with and whether or not the given flavor is heavy.

"""

fake_kind = "??"
sfs = ["F2", "FL", "F3", "g1", "gL", "g4"]
# xs = ["XSreduced", "XSyreduced"]
xs = [
    "XSHERANC",
    "XSHERANCAVG",
    "XSHERACC",
    "XSCHORUSCC",
    "XSNUTEVCC",
    "XSNUTEVNU",
    "FW",
    "F1",
    "g5",
    "XSFPFCC",
]
kinds = sfs + xs + [fake_kind]
# external flavors:
heavys = ["charm", "bottom", "top"]
heavylights = [h + "light" for h in heavys]
external_flavors = heavys + ["light", "total"] + heavylights
# internally we allow in addition for the flavor families
flavors = external_flavors + ["heavy"]


[docs] class ObservableName: r"""Wrapper to observable names to easy split them into two parts. Parameters ---------- name : str full observable name """ def __init__(self, name): p = name.split("_") if len(p) == 1: self.kind, self.flavor = p[0], "total" elif len(p) == 2: self.kind, self.flavor = p[0], p[1] else: raise ValueError(f"Unknown obsname {name}") if self.kind not in kinds: raise ValueError(f"Unknown kind {self.kind}") if self.flavor not in flavors: raise ValueError(f"Unknown flavor {self.flavor}") @property def name(self): """Return joint name.""" return self.kind + "_" + self.flavor @property def is_parity_violating(self): """Check if it is a parity violating observable.""" if self.kind in ["F3", "gL", "g4"]: return True return False
[docs] def __eq__(self, other): """Test equality of kind and flavor.""" return self.kind == other.kind and self.flavor == other.flavor
[docs] def apply_kind(self, kind): r"""Create new object with given kind and our flavor. Parameters ---------- kind : str new kind Returns ------- apply_kind : type(self) new kind and our flavor """ return type(self)(kind + "_" + self.flavor)
[docs] def __repr__(self): """Return the full representation name.""" return self.name
[docs] def apply_flavor(self, flavor): r"""Create new object with given flavor and our kind. Parameters ---------- flavor : str new flavor Returns ------- apply_flavor : type(self) our kind and new flavor """ return type(self)(self.kind + "_" + flavor)
@property def is_heavy(self): r"""Check if the given flavor is heavy. Returns ------- is_heavy : bool is a heavy flavor? """ return self.flavor != "light" @property def is_raw_heavy(self): """Check if it is a raw heavy flavor. i.e. charm, bottom, or, top. """ return self.flavor in heavys @property def is_heavylight(self): """Check if it is a heavylight flavor. i.e. charmlight, bottomlight, or, toplight. """ return self.flavor in heavylights @property def is_composed(self): """Check if it is a composed flavor. i.e. total. """ return self.flavor == "total" @property def flavor_family(self): """Return abstract flavor family name.""" if self.is_raw_heavy: return "heavy" if self.is_heavylight: return "light" return self.flavor
[docs] def apply_flavor_family(self): r"""Return name with abstract flavor family name. Returns ------- apply_flavor_family : type(self) new ObservableName """ return self.apply_flavor(self.flavor_family)
@property def hqnumber(self): """Return Heavy quark flavor number""" if self.is_heavylight: idx = heavylights.index(self.flavor) elif self.flavor_family in ["light", "total"]: idx = -4 else: idx = heavys.index(self.flavor) return 4 + idx @property def raw_flavor(self): """Return underlying raw flavor.""" if self.flavor == "light": return self.flavor return heavys[self.hqnumber - 4]
[docs] @classmethod def has_heavies(cls, names): r"""Check if there are any heavy objects in names. Parameters ---------- names : list(str) names to check Returns ------- has_heavies : bool are there heavy obs in names? """ for n in names: if not cls.is_valid(n): continue o = cls(n) if o.is_heavy: return True return False
[docs] @classmethod def has_lights(cls, names): r"""Check if there are any light objects in names. Parameters ---------- names : list(str) names to check Returns ------- has_lights : bool are there light obs in names? """ for n in names: if not cls.is_valid(n): continue o = cls(n) if o.flavor == "light": return True return False
@property def mass_label(self): """Add mass label in the theory runcard.""" if self.flavor == "light": return None else: return f"m{self.flavor[0]}"
[docs] @classmethod def is_valid(cls, name): r"""Test whether the name is a valid observable name. Returns ------- is_valid : bool is valid name? """ try: cls(name) return True except ValueError: return False