topology#
import qrules.topology
Functionality for Topology and Transition instances.
Main interfaces
Topologyand its builder functionscreate_isobar_topologies()andcreate_n_body_topology().Transitionand its two implementationsMutableTransitionandFrozenTransition.
- class FrozenDict(*args, **kwargs)[source]#
Bases:
frozendict,Generic[KT,VT]A sortable version of
frozendict.
- class Edge(originating_node_id: int | None = None, ending_node_id: int | None = None)[source]#
Bases:
objectStruct-like definition of an edge, used in
Topology.edges.- originating_node_id: int | None[source]#
Node ID where the
Edgestarts.An
Edgeis incoming to aTopologyif itsoriginating_node_idisNone(seeincoming_edge_ids).
- ending_node_id: int | None[source]#
Node ID where the
Edgeends.An
Edgeis outgoing from aTopologyif itsending_node_idisNone(seeoutgoing_edge_ids).
- class Topology(nodes: Iterable[int], edges: Mapping[int, Edge])[source]#
Bases:
objectDirected Feynman-like graph without edge or node properties.
A
Topologyis directed in the sense that its edges are ingoing and outgoing to specific nodes. This is to mimic Feynman graphs, which have a time axis. Note that aTopologyis not strictly speaking a graph from graph theory, because it allows open edges, like a Feynman-diagram.The edges and nodes can be provided with properties with a
Transition, which contains atopology.As opposed to a
MutableTopology, aTopologyis frozen, hashable, and ordered, so that it can be used as a kind of fingerprint for aTransition. In addition, the IDs ofedgesare guaranteed to be sequential integers and follow a specific pattern:incoming_edge_ids(initial_states) are always negative.outgoing_edge_ids(final_states) lie in the range0...n-1withnthe number of final states.intermediate_edge_idscontinue counting fromn.
See also
MutableTopology.organize_edge_ids().Example
Isobar decay topologies can best be created as follows:
>>> topologies = create_isobar_topologies(number_of_final_states=3) >>> len(topologies) 1 >>> topologies[0] Topology(nodes=..., edges=...)
- incoming_edge_ids: frozenset[int][source]#
Edge IDs of edges that have no
originating_node_id.Transition.initial_statesprovide properties for these edges.
- outgoing_edge_ids: frozenset[int][source]#
Edge IDs of edges that have no
ending_node_id.Transition.final_statesprovide properties for these edges.
- is_isomorphic(other: Topology) bool[source]#
Check if two graphs are isomorphic.
Returns
Trueif the two graphs have a one-to-one mapping of the node IDs and edge IDs.Warning
Not yet implemented.
- relabel_edges(old_to_new: Mapping[int, int]) Topology[source]#
Create a new
Topologywith new edge IDs.This method is particularly useful when creating permutations of a
Topology, e.g.:>>> topologies = create_isobar_topologies(3) >>> len(topologies) 1 >>> topology = topologies[0] >>> final_state_ids = topology.outgoing_edge_ids >>> permuted_topologies = { ... topology.relabel_edges(dict(zip(final_state_ids, permutation))) ... for permutation in itertools.permutations(final_state_ids) ... } >>> len(permuted_topologies) 3
- get_originating_node_list(topology: Topology, edge_ids: Iterable[int]) list[int][source]#
Get list of node ids from which the supplied edges originate from.
- class MutableTopology(nodes: Iterable[int] = NOTHING, edges: Mapping[int, Edge] = NOTHING)[source]#
Bases:
objectMutable version of a
Topology.A
MutableTopologycan be used to conveniently build up aTopology(see e.g.SimpleStateTransitionTopologyBuilder). It does not have restrictions on the numbering of edge and node IDs.- nodes: set[int][source]#
See
Topology.nodes.
- add_node(node_id: int) None[source]#
Adds a node with number
node_id.- Raises:
ValueError – if
node_idalready exists innodes.
- add_edges(edge_ids: Iterable[int]) None[source]#
Add edges with the ids in the
edge_idslist.- Raises:
ValueError – if
edge_idsalready exist inedges.
- attach_edges_to_node_ingoing(ingoing_edge_ids: Iterable[int], node_id: int) None[source]#
Attach existing edges to nodes.
So that the are ingoing to these nodes.
- Parameters:
- Raises:
ValueError – if an edge not doesn’t exist.
ValueError – if an edge ID is already an ingoing node.
- organize_edge_ids() MutableTopology[source]#
Organize edge IDS so that they lie in range
[-m, n+i].Here,
mis the number ofincoming_edge_ids,nis the number ofoutgoing_edge_ids, andiis the number ofintermediate_edge_ids.In other words, relabel the edges so that:
incoming edge IDs lie in the range
[-1, -2, ...],outgoing edge IDs lie in the range
[0, 1, ..., n],intermediate edge IDs lie in the range
[n+1, n+2, ...].
- freeze() Topology[source]#
Create an immutable
Topologyfrom thisMutableTopology.You may need to call
organize_edge_ids()first.
- class InteractionNode(number_of_ingoing_edges: int, number_of_outgoing_edges: int)[source]#
Bases:
objectHelper class for the
SimpleStateTransitionTopologyBuilder.
- class SimpleStateTransitionTopologyBuilder(interaction_node_set: Iterable[InteractionNode])[source]#
Bases:
objectSimple topology builder.
Recursively tries to add the interaction nodes to available open end edges/lines in all combinations until the number of open end lines matches the final state lines.
- interaction_node_set: list[InteractionNode][source]#
- create_isobar_topologies(number_of_final_states: int) tuple[Topology, ...][source]#
Builder function to create a set of unique isobar decay topologies.
- Parameters:
number_of_final_states – The number of
outgoing_edge_ids(final_states).- Returns:
A sorted
tupleof non-isomorphicTopologyinstances, all with the same number of final states.
Example
- create_n_body_topology(number_of_initial_states: int, number_of_final_states: int) Topology[source]#
Create a
Topologythat connects all edges through a single node.These types of “\(n\)-body topologies” are particularly important for
check_reaction_violations()andconservation_rules.- Parameters:
number_of_initial_states – The number of
incoming_edge_ids(initial_states).number_of_final_states – The number of
outgoing_edge_ids(final_states).
Example
>>> topology = create_n_body_topology( ... number_of_initial_states=2, ... number_of_final_states=5, ... ) >>> topology Topology(nodes=..., edges...) >>> len(topology.nodes) 1 >>> len(topology.incoming_edge_ids) 2 >>> len(topology.outgoing_edge_ids) 5
- class Transition[source]#
Bases:
ABC,Generic[EdgeType,NodeType]Mapping of edge and node properties over a
Topology.This interface class describes a transition from an initial state to a final state by providing a mapping of properties over the
edgesandnodesof itstopology. Since aTopologybehaves like a Feynman graph, edges are considered as “states” and nodes are considered asinteractionsbetween those states.There are two implementation classes:
FrozenTransition: a complete, hashable and ordered mapping of properties over theedgesandnodesin itstopology.MutableTransition: comparable toMutableTopologyin that it is used internally when finding solutions through theStateTransitionManageretc.
These classes are also provided with mixin attributes
initial_states,final_states,intermediate_states, andfilter_states().- abstract property topology: Topology[source]#
Topologyover whichstatesandinteractionsare defined.
- class FrozenTransition(topology: Topology, states, interactions)[source]#
Bases:
Transition,Generic[EdgeType,NodeType]Defines a frozen mapping of edge and node properties on a
Topology.- states: FrozenDict[int, EdgeType][source]#
- interactions: FrozenDict[int, NodeType][source]#
- unfreeze() MutableTransition[EdgeType, NodeType][source]#
Convert into a
MutableTransition.
- convert() FrozenTransition[EdgeType, NodeType][source]#
- convert(state_converter: Callable[[EdgeType], NewEdgeType]) FrozenTransition[NewEdgeType, NodeType]
- convert(*, interaction_converter: Callable[[NodeType], NewNodeType]) FrozenTransition[EdgeType, NewNodeType]
- convert(state_converter: Callable[[EdgeType], NewEdgeType], interaction_converter: Callable[[NodeType], NewNodeType]) FrozenTransition[NewEdgeType, NewNodeType]
Cast the edge and/or node properties to another type.
- class MutableTransition(topology: Topology, states: Mapping[int, EdgeType] = NOTHING, interactions: Mapping[int, NodeType] = NOTHING)[source]#
Bases:
Transition,Generic[EdgeType,NodeType]Mutable implementation of a
Transition.Mainly used internally by the
StateTransitionManagerto build solutions.- compare(other: MutableTransition, state_comparator: Callable[[EdgeType, EdgeType], bool] | None = None, interaction_comparator: Callable[[NodeType, NodeType], bool] | None = None) bool[source]#
- freeze() FrozenTransition[EdgeType, NodeType][source]#
Convert into a
FrozenTransition.