conservation_rules#

Collection of quantum number conservation rules for particle reactions.

This module is the place where the β€˜expert’ defines the rules that verify quantum numbers of the reaction.

A rule is a function that takes quantum numbers as input and outputs a boolean. There are three different types of rules:

  1. GraphElementRule that work on individual graph edges or nodes.

  2. EdgeQNConservationRule that work on the interaction level, which use ingoing edges, outgoing edges as arguments. E.g.: ChargeConservation.

  3. ConservationRule that work on the interaction level, which use ingoing edges, outgoing edges and a interaction node as arguments. E.g: parity_conservation.

The arguments can be any type of quantum number. However a rule argument resembling edges only accepts EdgeQuantumNumbers. Similarly arguments that resemble a node only accept NodeQuantumNumbers. The argument types do not have to be limited to a single quantum number, but can be a composite (see CParityEdgeInput).

Warning

Besides the rule logic itself, a rule also has the responsibility of stating its run conditions. These run conditions must be stated by the type annotations of its __call__ method. The type annotations therefore are not just there for static type checking: they also carry more information about the rule that is extracted dynamically by the solving module.

Generally, the conditions can be separated into two categories:

  • variable conditions

  • toplogical conditions

Currently, only variable conditions are being used. Topological conditions could be created in the form of Tuple instead of List.

For additive quantum numbers, the decorator additive_quantum_number_rule can be used to automatically generate the appropriate behavior.

The module is therefore strongly typed (both for the reader of the code and for type checking with mypy). An example is HelicityParityEdgeInput, which has been defined to provide type checks on parity_conservation_helicity.

class GraphElementRule(*args, **kwargs)[source]#

Bases: Protocol

__call__(_GraphElementRule__qns: Any) β†’ bool[source]#

Call self as a function.

class EdgeQNConservationRule(*args, **kwargs)[source]#

Bases: Protocol

__call__(_EdgeQNConservationRule__ingoing_edge_qns: List[Any], _EdgeQNConservationRule__outgoing_edge_qns: List[Any]) β†’ bool[source]#

Call self as a function.

class ConservationRule(*args, **kwargs)[source]#

Bases: Protocol

__call__(_ConservationRule__ingoing_edge_qns: List[Any], _ConservationRule__outgoing_edge_qns: List[Any], _ConservationRule__node_qns: Any) β†’ bool[source]#

Call self as a function.

additive_quantum_number_rule(quantum_number: type) β†’ Callable[[Any], EdgeQNConservationRule][source]#

Class decorator for creating an additive conservation rule.

Use this decorator to create a EdgeQNConservationRule for a quantum number to which an additive conservation rule applies:

\[\sum q_{in} = \sum q_{out}\]
Parameters:

quantum_number – Quantum number to which you want to apply the additive conservation check. An example would be EdgeQuantumNumbers.charge.

class ChargeConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for charge conservation.

__call__(ingoing_edge_qns: List[charge], outgoing_edge_qns: List[charge]) β†’ bool#

Call self as a function.

class BaryonNumberConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for baryon_number conservation.

__call__(ingoing_edge_qns: List[baryon_number], outgoing_edge_qns: List[baryon_number]) β†’ bool#

Call self as a function.

class ElectronLNConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for electron_lepton_number conservation.

__call__(ingoing_edge_qns: List[electron_lepton_number], outgoing_edge_qns: List[electron_lepton_number]) β†’ bool#

Call self as a function.

class MuonLNConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for muon_lepton_number conservation.

__call__(ingoing_edge_qns: List[muon_lepton_number], outgoing_edge_qns: List[muon_lepton_number]) β†’ bool#

Call self as a function.

class TauLNConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for tau_lepton_number conservation.

__call__(ingoing_edge_qns: List[tau_lepton_number], outgoing_edge_qns: List[tau_lepton_number]) β†’ bool#

Call self as a function.

class StrangenessConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for strangeness conservation.

__call__(ingoing_edge_qns: List[strangeness], outgoing_edge_qns: List[strangeness]) β†’ bool#

Call self as a function.

class CharmConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for charmness conservation.

__call__(ingoing_edge_qns: List[charmness], outgoing_edge_qns: List[charmness]) β†’ bool#

Call self as a function.

class BottomnessConservation(*args, **kwargs)[source]#

Bases: EdgeQNConservationRule

Decorated via additive_quantum_number_rule.

Check for bottomness conservation.

__call__(ingoing_edge_qns: List[bottomness], outgoing_edge_qns: List[bottomness]) β†’ bool#

Call self as a function.

parity_conservation(ingoing_edge_qns: List[parity], outgoing_edge_qns: List[parity], l_magnitude: l_magnitude) β†’ bool[source]#

Implement \(P_{in} = P_{out} \cdot (-1)^L\).

class HelicityParityEdgeInput(parity, spin_magnitude, spin_projection)[source]#

Bases: object

parity: parity#
spin_magnitude: spin_magnitude#
spin_projection: spin_projection#
parity_conservation_helicity(ingoing_edge_qns: List[HelicityParityEdgeInput], outgoing_edge_qns: List[HelicityParityEdgeInput], parity_prefactor: parity_prefactor) β†’ bool[source]#

Implements parity conservation for helicity formalism.

Check the following:

\[A_{-\lambda_1-\lambda_2} = P_1 P_2 P_3 (-1)^{S_2+S_3-S_1} A_{\lambda_1\lambda_2}\]
\[\mathrm{parity\,prefactor} = P_1 P_2 P_3 (-1)^{S_2+S_3-S_1}\]

Note

Only the special case \(\lambda_1=\lambda_2=0\) may return False independent on the parity prefactor.

class CParityEdgeInput(spin_magnitude, pid, c_parity=None)[source]#

Bases: object

spin_magnitude: spin_magnitude#
pid: pid#
c_parity: Optional[c_parity]#
class CParityNodeInput(l_magnitude, s_magnitude)[source]#

Bases: object

l_magnitude: l_magnitude#
s_magnitude: s_magnitude#
c_parity_conservation(ingoing_edge_qns: List[CParityEdgeInput], outgoing_edge_qns: List[CParityEdgeInput], interaction_node_qns: CParityNodeInput) β†’ bool[source]#

Check for \(C\)-parity conservation.

Implements \(C_{in} = C_{out}\).

class GParityEdgeInput(isospin_magnitude, spin_magnitude, pid, g_parity=None)[source]#

Bases: object

isospin_magnitude: isospin_magnitude#
spin_magnitude: spin_magnitude#
pid: pid#
g_parity: Optional[g_parity]#
class GParityNodeInput(l_magnitude, s_magnitude)[source]#

Bases: object

l_magnitude: l_magnitude#
s_magnitude: s_magnitude#
g_parity_conservation(ingoing_edge_qns: List[GParityEdgeInput], outgoing_edge_qns: List[GParityEdgeInput], interaction_qns: GParityNodeInput) β†’ bool[source]#

Check for \(G\)-parity conservation.

Implements for \(G_{in} = G_{out}\).

class IdenticalParticleSymmetryOutEdgeInput(spin_magnitude, spin_projection, pid)[source]#

Bases: object

spin_magnitude: spin_magnitude#
spin_projection: spin_projection#
pid: pid#
identical_particle_symmetrization(ingoing_parities: List[parity], outgoing_edge_qns: List[IdenticalParticleSymmetryOutEdgeInput]) β†’ bool[source]#

Verifies multi particle state symmetrization for identical particles.

In case of a multi particle state with identical particles, their exchange symmetry has to follow the spin statistic theorem.

For bosonic systems the total exchange symmetry (parity) has to be even (+1). For fermionic systems the total exchange symmetry (parity) has to be odd (-1).

In case of a particle decaying into N identical particles (N>1), the decaying particle has to have the same parity as required by the spin statistic theorem of the multi body state.

class SpinNodeInput(l_magnitude, l_projection, s_magnitude, s_projection)[source]#

Bases: object

l_magnitude: l_magnitude#
l_projection: l_projection#
s_magnitude: s_magnitude#
s_projection: s_projection#
class SpinMagnitudeNodeInput(l_magnitude, s_magnitude)[source]#

Bases: object

l_magnitude: l_magnitude#
s_magnitude: s_magnitude#
ls_spin_validity(spin_input: SpinNodeInput) β†’ bool[source]#

Check for valid isospin magnitude and projection.

class IsoSpinEdgeInput(isospin_magnitude, isospin_projection)[source]#

Bases: object

isospin_magnitude: isospin_magnitude#
isospin_projection: isospin_projection#
isospin_validity(isospin: IsoSpinEdgeInput) β†’ bool[source]#

Check for valid isospin magnitude and projection.

isospin_conservation(ingoing_isospins: List[IsoSpinEdgeInput], outgoing_isospins: List[IsoSpinEdgeInput]) β†’ bool[source]#

Check for isospin conservation.

Implements

\[|I_1 - I_2| \leq I \leq |I_1 + I_2|\]

Also checks \(I_{1,z} + I_{2,z} = I_z\) and if Clebsch-Gordan coefficients are all 0.

class SpinEdgeInput(spin_magnitude, spin_projection)[source]#

Bases: object

spin_magnitude: spin_magnitude#
spin_projection: spin_projection#
spin_validity(spin: SpinEdgeInput) β†’ bool[source]#

Check for valid spin magnitude and projection.

spin_conservation(ingoing_spins: List[SpinEdgeInput], outgoing_spins: List[SpinEdgeInput], interaction_qns: SpinNodeInput) β†’ bool[source]#

Check for spin conservation.

Implements

\[|S_1 - S_2| \leq S \leq |S_1 + S_2|\]

and

\[|L - S| \leq J \leq |L + S|\]

Also checks \(M_1 + M_2 = M\) and if Clebsch-Gordan coefficients are all 0.

See also

/docs/usage/ls-coupling

spin_magnitude_conservation(ingoing_spins: List[SpinEdgeInput], outgoing_spins: List[SpinEdgeInput], interaction_qns: SpinMagnitudeNodeInput) β†’ bool[source]#

Check for spin conservation.

Implements

\[|S_1 - S_2| \leq S \leq |S_1 + S_2|\]

and

\[|L - S| \leq J \leq |L + S|\]
clebsch_gordan_helicity_to_canonical(ingoing_spins: List[SpinEdgeInput], outgoing_spins: List[SpinEdgeInput], interaction_qns: SpinNodeInput) β†’ bool[source]#

Implement Clebsch-Gordan checks.

For \(S_1, S_2\) to \(S\) and the \(L,S\) to \(J\) coupling based on the conversion of helicity to canonical amplitude sums.

Note

This rule does not check that the spin magnitudes couple correctly to \(L\) and \(S\), as this is already performed by spin_magnitude_conservation.

helicity_conservation(ingoing_spin_mags: List[spin_magnitude], outgoing_helicities: List[spin_projection]) β†’ bool[source]#

Implementation of helicity conservation.

Check for \(|\lambda_2-\lambda_3| \leq S_1\).

class GellMannNishijimaInput(charge, isospin_projection=None, strangeness=None, charmness=None, bottomness=None, topness=None, baryon_number=None, electron_lepton_number=None, muon_lepton_number=None, tau_lepton_number=None)[source]#

Bases: object

charge: charge#
isospin_projection: Optional[isospin_projection]#
strangeness: Optional[strangeness]#
charmness: Optional[charmness]#
bottomness: Optional[bottomness]#
topness: Optional[topness]#
baryon_number: Optional[baryon_number]#
electron_lepton_number: Optional[electron_lepton_number]#
muon_lepton_number: Optional[muon_lepton_number]#
tau_lepton_number: Optional[tau_lepton_number]#
gellmann_nishijima(edge_qns: GellMannNishijimaInput) β†’ bool[source]#

Check the Gell-Mann–Nishijima formula.

Gell-Mann–Nishijima formula:

\[Q = I_3 + \frac{1}{2}(B+S+C+B'+T)\]

where \(Q\) is charge (computed), \(I_3\) is Spin.projection of isospin, \(B\) is baryon_number, \(S\) is strangeness, \(C\) is charmness, \(B'\) is bottomness, and \(T\) is topness.

class MassEdgeInput(mass, width=None)[source]#

Bases: object

mass: mass#
width: Optional[width]#
class MassConservation(width_factor: float)[source]#

Bases: object

Mass conservation rule.

__call__(ingoing_edge_qns: List[MassEdgeInput], outgoing_edge_qns: List[MassEdgeInput]) β†’ bool[source]#

Implements mass conservation.

\(M_{out} - N \cdot W_{out} < M_{in} + N \cdot W_{in}\)

It makes sure that the net mass outgoing state \(M_{out}\) is smaller than the net mass of the ingoing state \(M_{in}\). Also the width \(W\) of the states is taken into account.