Decay chains — decaylanguage.decay#

class decaylanguage.decay.decay.DecayModeDict[source]#
bf: float#
fs: Sequence[str | dict[str, list[DecayModeDict]]]#
model: str#
model_params: str | Sequence[str | Any]#
class decaylanguage.decay.decay.DaughtersDict(iterable=None, **kwds)[source]#

Class holding a decay final state as a dictionary. It is a building block for the digital representation of full decay chains.

Note

This class assumes EvtGen particle names, though this assumption is only relevant for the charge_conjugate method. Otherwise, all other class methods smoothly deal with any kind of particle names (basically an iterable of strings).

Example

A final state such as ‘K+ K- K- pi+ pi0’ is stored as {'K+': 1, 'K-': 2, 'pi+': 1, 'pi0': 1}.

Parameters:
classmethod fromkeys(iterable, v=None)[source]#

Create a new dictionary with keys from iterable and values set to value.

to_string()[source]#

Return the daughters as a string representation (ordered list of names).

Return type:

str

to_list()[source]#

Return the daughters as an ordered list of names.

Return type:

list[str]

charge_conjugate(pdg_name=False)[source]#

Return the charge-conjugate final state.

Parameters:

pdg_name (str, optional, default=False) – Input particle name is the PDG name, not the (default) EvtGen name.

Parameters:

pdg_name (bool)

Return type:

Self

Examples

>>> dd = DaughtersDict({'K+': 2, 'pi0': 1})
>>> dd.charge_conjugate()
<DaughtersDict: ['K-', 'K-', 'pi0']>
>>>
>>> dd = DaughtersDict({'K_S0': 1, 'pi0': 1})
>>> dd.charge_conjugate()
<DaughtersDict: ['K_S0', 'pi0']>
>>>
>>> dd = DaughtersDict({'K(S)0': 1, 'pi+': 1})  # PDG names!
>>> # 'K(S)0' unrecognised in charge conjugation unless specified that these are PDG names
>>> dd.charge_conjugate()
<DaughtersDict: ['ChargeConj(K(S)0)', 'pi-']>
>>> dd.charge_conjugate(pdg_name=True)
<DaughtersDict: ['K(S)0', 'pi-']>
class decaylanguage.decay.decay.DecayMode(bf=0, daughters=None, **info)[source]#

Class holding a particle decay mode, which is typically a branching fraction and a list of final-state particles (i.e. a list of DaughtersDict instances). The class can also contain metadata such as decay model and optional decay-model parameters, as defined for example in .dec decay files.

This class is a building block for the digital representation of full decay chains.

Note

This class assumes EvtGen particle names, though this assumption is only relevant for the charge_conjugate method. Otherwise, all other class methods smoothly deal with any kind of particle names (basically an iterable of strings).

Parameters:
bf#
daughters#
metadata: dict[str, Any]#
classmethod from_dict(decay_mode_dict)[source]#

Constructor from a dictionary of the form {‘bf’: <float>, ‘fs’: […], …}. These two keys are mandatory. All others are interpreted as model information or metadata, see the constructor signature and doc.

Note

This class assumes EvtGen particle names, though this assumption is only relevant for the charge_conjugate method. Otherwise, all other class methods smoothly deal with any kind of particle names (basically an iterable of strings).

Examples

>>> # Simplest construction
>>> DecayMode.from_dict({'bf': 0.98823, 'fs': ['gamma', 'gamma']})
<DecayMode: daughters=gamma gamma, BF=0.98823>
>>> # Decay mode with decay model details
>>> DecayMode.from_dict({'bf': 0.98823,
...                      'fs': ['gamma', 'gamma'],
...                      'model': 'PHSP',
...                      'model_params': ''})
<DecayMode: daughters=gamma gamma, BF=0.98823>
>>> # Decay mode with metadata for generators such as zfit's phasespace
>>> dm = DecayMode.from_dict({'bf': 0.5, 'fs': ["K+, K-"], "zfit": {"B0": "gauss"}})
>>> dm.metadata
{'model': '', 'model_params': '', 'zfit': {'B0': 'gauss'}}
Parameters:

decay_mode_dict (DecayModeDict)

Return type:

Self

classmethod from_pdgids(bf=0, daughters=None, **info)[source]#

Constructor for a final state given as a list of particle PDG IDs.

Parameters:
  • bf (float, optional, default=0) – Decay mode branching fraction.

  • daughters (list or tuple, optional, default=None) – The final-state particle PDG IDs.

  • info (keyword arguments, optional) – Decay mode model information and/or user metadata (aka extra info) By default the following elements are always created: dict(model=’’, model_params=’’). The user can provide any metadata, see the examples below.

Parameters:
Return type:

Self

Note

All particle names are internally saved as EvtGen names, to be consistent with the default class assumption, see class docstring.

Examples

>>> DecayMode.from_pdgids(0.5, [321, -321])
<DecayMode: daughters=K+ K-, BF=0.5>
>>> DecayMode.from_pdgids(0.5, (310, 310))
<DecayMode: daughters=K_S0 K_S0, BF=0.5>
>>> # Decay mode with metadata
>>> dm = DecayMode.from_pdgids(0.5, (310, 310), model="PHSP")
>>> dm.metadata
{'model': 'PHSP', 'model_params': ''}
describe()[source]#

Make a nice high-density string for all decay-mode properties and info.

Return type:

str

to_dict()[source]#

Return the decay mode as a dictionary in the format understood by the DecayChainViewer class.

Examples

>>> dm = DecayMode(0.5, 'K+ K- K- pi- pi0 nu_tau', model='PHSP', study='toy', year=2019)
>>> dm.to_dict()
{'bf': 0.5,
 'fs': ['K+', 'K-', 'K-', 'nu_tau', 'pi-', 'pi0'],
 'model': 'PHSP',
 'model_params': '',
 'study': 'toy',
 'year': 2019}
Return type:

dict[str, int | float | str | list[str]]

charge_conjugate(pdg_name=False)[source]#

Return the charge-conjugate decay mode.

Parameters:

pdg_name (str, optional, default=False) – Input particle name is the PDG name, not the (default) EvtGen name.

Parameters:

pdg_name (bool)

Return type:

Self

Examples

>>> dm = DecayMode(1.0, 'K+ K+ pi-')
>>> dm.charge_conjugate()
<DecayMode: daughters=K- K- pi+, BF=1.0>
>>>
>>> dm = DecayMode(1.0, 'K_S0 pi+')
>>> dm.charge_conjugate()
<DecayMode: daughters=K_S0 pi-, BF=1.0>
>>>
>>> dm = DecayMode(1.0, 'K(S)0 pi+')  # PDG names!
>>> dm.charge_conjugate(pdg_name=True)
<DecayMode: daughters=K(S)0 pi-, BF=1.0>
class decaylanguage.decay.decay.DecayChain(mother, decays)[source]#

Class holding a particle (single) decay chain, which is typically a top-level decay (mother particle, branching fraction and final-state particles) and a set of sub-decays for any non-stable particle in the top-level decay. The whole chain can be seen as a mother particle and a list of chained decay modes.

This class is the main building block for the digital representation of full decay chains.

Note

1) Only single chains are supported, meaning every decaying particle can only define a single decay mode. 2) This class does not assume any kind of particle names (EvtGen, PDG). It is nevertheless advised to default use EvtGen names for consistency with the defaults used in the related classes DecayMode and DaughtersDict, unless there is a good motivation not to.

Parameters:
mother#
decays#
classmethod from_dict(decay_chain_dict)[source]#

Constructor from a decay chain represented as a dictionary. The format is the same as that returned by DecFileParser.build_decay_chains(...).

Parameters:

decay_chain_dict (dict[str, list[DecayModeDict]])

Return type:

Self

top_level_decay()[source]#

Return the top-level decay as a DecayMode instance.

Return type:

DecayMode

property bf: float#

Branching fraction of the top-level decay.

property visible_bf: float#

Visible branching fraction of the whole decay chain.

Note

Calculation requires a flattening of the entire decay chain.

property ndecays: int#

Return the number of decay modes including the top-level decay.

to_string()[source]#

One-line string representation of the entire decay chain. Sub-decays are enclosed in round parentheses.

Examples

>>> dm1 = DecayMode(0.6770, "D0 pi+") # D*+
>>> dm2 = DecayMode(0.0124, "K_S0 pi0") # D0
>>> dm3 = DecayMode(0.692, "pi+ pi-") # K_S0
>>> dm4 = DecayMode(0.98823, "gamma gamma") # pi0
>>> dc = DecayChain("D*+", {"D*+":dm1, "D0":dm2, "K_S0":dm3, "pi0":dm4})
>>> print(dc.to_string())
D*+ -> (D0 -> (K_S0 -> pi+ pi-) (pi0 -> gamma gamma)) pi+
Return type:

str

print_as_tree()[source]#

Tree-structure like print of the entire decay chain.

Examples

>>> dm1 = DecayMode(0.028, 'K_S0 pi+ pi-')
>>> dm2 = DecayMode(0.692, 'pi+ pi-')
>>> dc = DecayChain('D0', {'D0':dm1, 'K_S0':dm2})
>>> dc.print_as_tree()
D0
+--> K_S0
|    +--> pi+
|    +--> pi-
+--> pi+
+--> pi-
>>> dm1 = DecayMode(0.0124, 'K_S0 pi0')
>>> dm2 = DecayMode(0.692, 'pi+ pi-')
>>> dm3 = DecayMode(0.98823, 'gamma gamma')
>>> dc = DecayChain('D0', {'D0':dm1, 'K_S0':dm2, 'pi0':dm3})
>>> dc.print_as_tree()
D0
+--> K_S0
|    +--> pi+
|    +--> pi-
+--> pi0
     +--> gamma
     +--> gamma
>>> dm1 = DecayMode(0.6770, 'D0 pi+')
>>> dm2 = DecayMode(0.0124, 'K_S0 pi0')
>>> dm3 = DecayMode(0.692, 'pi+ pi-')
>>> dm4 = DecayMode(0.98823, 'gamma gamma')
>>> dc = DecayChain('D*+', {'D*+':dm1, 'D0':dm2, 'K_S0':dm3, 'pi0':dm4})
>>> dc.print_as_tree()
D*+
+--> D0
|    +--> K_S0
|    |    +--> pi+
|    |    +--> pi-
|    +--> pi0
|         +--> gamma
|         +--> gamma
+--> pi+
Return type:

None

to_dict()[source]#

Return the decay chain as a dictionary representation. The format is the same as DecFileParser.build_decay_chains(...).

Examples

>>> dm1 = DecayMode(0.028, 'K_S0 pi+ pi-')
>>> dm2 = DecayMode(0.692, 'pi+ pi-')
>>> dc = DecayChain('D0', {'D0':dm1, 'K_S0':dm2})
>>> dc.to_dict()
{'D0': [{'bf': 0.028,
    'fs': [{'K_S0': [{'bf': 0.692,
        'fs': ['pi+', 'pi-'],
        'model': '',
        'model_params': ''}]},
     'pi+',
     'pi-'],
    'model': '',
    'model_params': ''}]}
Return type:

dict[str, list[DecayModeDict]]

flatten(stable_particles=())[source]#

Flatten the decay chain replacing all intermediate, decaying particles, with their final states.

Parameters:

stable_particles (collection of str, optional, default=()) – If provided, ignores the sub-decays of the listed particles, considering them as stable. The mother particle is always decayed (flattening its own decay is the whole point), so it is ignored even if present in this collection.

Parameters:

stable_particles (Collection[str])

Return type:

Self

Note

After flattening the only DecayMode metadata kept is that of the top-level decay, i.e. that of the mother particle (nothing else would make sense).

Examples

>>> dm1 = DecayMode(0.0124, 'K_S0 pi0', model='PHSP')
>>> dm2 = DecayMode(0.692, 'pi+ pi-')
>>> dm3 = DecayMode(0.98823, 'gamma gamma')
>>> dc = DecayChain('D0', {'D0':dm1, 'K_S0':dm2, 'pi0':dm3})
>>>
>>> dc.flatten()
<DecayChain: D0 -> gamma gamma pi+ pi- (0 sub-decays), BF=0.008479803984>
>>> dc.flatten().to_dict()
{'D0': [{'bf': 0.008479803984,
   'fs': ['gamma', 'gamma', 'pi+', 'pi-'],
   'model': 'PHSP',
   'model_params': ''}]}
>>> dc.flatten(stable_particles=('K_S0', 'pi0')).decays
{'D0': <DecayMode: daughters=K_S0 pi0, BF=0.0124>}

Submodule with classes and utilities to visualize decay chains. Decay chains are typically provided by the parser of .dec decay files, see the DecFileParser class.

exception decaylanguage.decay.viewer.GraphNotBuiltError[source]#
class decaylanguage.decay.viewer.DecayChainViewer(decaychain, show_effective_bf=False, **attrs)[source]#

The class to visualize a decay chain.

Examples

>>> dfp = DecFileParser('my-Dst-decay-file.dec')
>>> dfp.parse()
>>> chain = dfp.build_decay_chains('D*+')
>>> dcv = DecayChainViewer(chain)
>>> # display the SVG figure in a notebook
>>> dcv

When not in notebooks the graph can easily be visualized with the graphviz.Digraph.render or graphviz.Digraph.view functions, e.g.: >>> dcv.graph.render(filename=”test”, format=”pdf”, view=True, cleanup=True) # doctest: +SKIP

Parameters:
property graph: Digraph#

Get the actual graphviz.Digraph object. The user now has full control …

to_string()[source]#

Return a string representation of the built graph in the DOT language. The function is a trivial shortcut for graphviz.Digraph.source.

Return type:

str