molfoundry.atomtracing#

Atom tracing over derivation graphs: a bridge from a DG through DGVertexMapper into the vendored saturate-tracer engine.

Saturation-based atom tracing for derivation graphs.

This subpackage vendors the saturate-tracer engine (AstrorEnales/saturate-tracer) and adds DGAtomTracing, which builds those inputs directly from a DG using the atom-atom maps that DGVertexMapper recovers from each derivation.

from molfoundry import DG, smiles, ruleGMLString, addSubset from molfoundry.atomtracing import DGAtomTracing, by_element

dg = … # a built derivation graph inputs = DGAtomTracing.from_dg(dg, vertex_filter=by_element(“C”)) sat = inputs.build_tracer() sat.run()

The drawing helpers need the optional drawing extra (rdkit, cairosvg, matplotlib, networkx, pygraphviz). Their heavy imports are lazy, so importing this package never requires the extra; only calling a draw function does.

class molfoundry.atomtracing.SaturateTracer(reaction_rules, injected_template_instances=None, custom_initial_configuration=None, label_sets=None, templates=None, remove_duplicate_rules=True, log_duplicate_rules=True, verbose=False)[source]#

Bases: object

Parameters:
  • reaction_rules (List[ReactionRule])

  • injected_template_instances (Set[TemplateInstance] | None)

  • custom_initial_configuration (Set[TemplateInstance] | None)

  • label_sets (Set[LabelSet] | None)

  • templates (Set[Template] | None)

  • remove_duplicate_rules (bool | None)

  • log_duplicate_rules (bool | None)

  • verbose (bool | None)

run(limit_hyperedges=None)[source]#
Parameters:

limit_hyperedges (int | None)

get_all_origin_id_positions(origin_id)[source]#

Find all position IDs where the origin ID has been traced to.

Parameters:

origin_id (int)

Return type:

Set[int]

get_all_origin_species_targets(species_origin_ids)[source]#

Find all targets the origin specie(s) has been traced to.

Parameters:

species_origin_ids (Set[int])

Return type:

Set[TemplateInstance]

get_all_position_id_labelings(position_id)[source]#

Find all origin IDs of a specific position ID.

Parameters:

position_id (int)

Return type:

Set[int]

get_all_species_labelings(position_ids)[source]#

Find all template instances of a specific template.

Parameters:

position_ids (Set[int])

Return type:

Set[TemplateInstance]

get_all_origin_target_labelings(origin_position_ids, target_position_ids)[source]#

Find all template instances of a specific target template and from a specific origin template.

Parameters:
  • origin_position_ids (Set[int])

  • target_position_ids (Set[int])

Return type:

Set[TemplateInstance]

labeling_to_display_str(labeling, unlabeled_text=None)[source]#
Parameters:
  • labeling (Tuple)

  • unlabeled_text (str | None)

Return type:

str

class molfoundry.atomtracing.LabelSet(ids, name=None)[source]#

Bases: object

Parameters:
ids: frozenset[int]#
name: str#
class molfoundry.atomtracing.ReactionRule(educts, products, name=None, color=None)[source]#

Bases: object

Parameters:
educts: List[Dict[int, int]]#
products: List[Tuple[int, ...]]#
name: str | None#
color: str | None#
educts_product_indices: List[Dict[int, Tuple[int, int]]]#
func: Callable[[Tuple[TemplateInstance, ...]], List[TemplateInstance]]#
reverse(name=None)[source]#
Parameters:

name (str | None)

class molfoundry.atomtracing.Template(ids, name=None, smiles=None)[source]#

Bases: object

Parameters:
ids: Tuple[int, ...]#
smiles: str | None#
name: str | None#
identity_instance()[source]#
unlabeled_instance()[source]#
type molfoundry.atomtracing.TemplateInstance = Tuple[Tuple[int, int], ...]#
class molfoundry.atomtracing.DGAtomTracing[source]#

Bases: object

Static helpers translating a DG into atom-tracing inputs.

from_dg() converts a whole derivation graph; from_hyperedges() converts an explicit subset of its hyperedges. Both return TracerInputs.

static from_dg(dg, *, vertex_filter=None, maps_per_edge=65535, on_unbalanced='skip', verbose=False)[source]#

Build TracerInputs from every hyperedge of dg.

Parameters:
  • dg (DG) – the DG to translate; each hyperedge becomes one or more reaction rules and contributes its educt/product compounds as templates.

  • vertex_filter (Callable[[Vertex], bool] | None) – which atoms to trace. None traces every atom (hydrogens included); pass e.g. by_element() to restrict to an element. Only atoms this selects get position IDs, appear in templates, and constrain conservation.

  • maps_per_edge (int) – how many atom-atom maps to enumerate per hyperedge. One map is the canonical labeling; a symmetric molecule admits several maps that give genuinely different atom traces (e.g. the two ends of succinate), so raise this to capture that symmetry. Each map becomes a rule sharing the hyperedge’s name; the tracer removes any that turn out identical. The orbit of maps can be large, hence the cap. vertex_filter is handed to the mapper, so the maps enumerated are only those distinct on the traced atoms: symmetry among untraced atoms (hydrogen relabelings, say) is pruned before a map is ever produced, not deduplicated afterward.

  • on_unbalanced (str) – what to do when a hyperedge creates or destroys a traced atom and so cannot be represented. "skip" (default) records it in skipped_edges and moves on; "error" raises ValueError.

  • verbose (bool) – print a line for every skipped hyperedge.

Return type:

TracerInputs

static from_hyperedges(edges, *, vertex_filter=None, maps_per_edge=65535, on_unbalanced='skip', verbose=False)[source]#

Build TracerInputs from a collection of hyperedges.

Parameters:
  • edges (Iterable[HyperEdge]) – the hyperedges to translate; each becomes one or more reaction rules and contributes its educt/product compounds as templates.

  • vertex_filter (Callable[[Vertex], bool] | None) – which atoms to trace. None traces every atom (hydrogens included); pass e.g. by_element() to restrict to an element. Only atoms this selects get position IDs, appear in templates, and constrain conservation.

  • maps_per_edge (int) – how many atom-atom maps to enumerate per hyperedge. One map is the canonical labeling; a symmetric molecule admits several maps that give genuinely different atom traces (e.g. the two ends of succinate), so raise this to capture that symmetry. Each map becomes a rule sharing the hyperedge’s name; the tracer removes any that turn out identical. The orbit of maps can be large, hence the cap. vertex_filter is handed to the mapper, so the maps enumerated are only those distinct on the traced atoms: symmetry among untraced atoms (hydrogen relabelings, say) is pruned before a map is ever produced, not deduplicated afterward.

  • on_unbalanced (str) – what to do when a hyperedge creates or destroys a traced atom and so cannot be represented. "skip" (default) records it in skipped_edges and moves on; "error" raises ValueError.

  • verbose (bool) – print a line for every skipped hyperedge.

Return type:

TracerInputs

class molfoundry.atomtracing.TracerInputs(templates, rules, template_by_graph_id, position_id_by_atom, skipped_edges)[source]#

Bases: object

Everything needed to trace a network, produced by DGAtomTracing.

templates and rules are the two arguments a SaturateTracer takes; the remaining fields expose the bookkeeping so callers can build label sets and initial configurations that target specific compounds or atoms, and can map traced positions back to the DG.

Parameters:
templates: Set[Template]#

One Template per compound that carries at least one traced atom.

rules: List[ReactionRule]#

One ReactionRule per hyperedge per atom-atom map that could be traced.

template_by_graph_id: Dict[int, Template]#

DG-vertex graph id -> its Template.

position_id_by_atom: Dict[Tuple[int, int], int]#

(graph id, atom vertex id) -> the atom’s global position ID.

skipped_edges: List[Tuple[int, str]]#

(hyperedge id, reason) for every hyperedge that produced no rule.

build_tracer(**kwargs)[source]#

Construct a SaturateTracer from these templates and rules.

Extra keyword arguments (label_sets, custom_initial_configuration, verbose, …) are forwarded to SaturateTracer unchanged.

The rule list is copied first, because SaturateTracer removes duplicate rules from the list it is given, and we do not want to mutate self.rules.

Return type:

SaturateTracer

template_of(vertex)[source]#

The template of a compound, given its DG vertex, its graph, or one of its atom vertices. Returns None when that compound has no traced atoms.

Parameters:

vertex (Graph | Vertex | Vertex)

Return type:

Template | None

position_id(atom)[source]#

The global position ID of an atom vertex, or None when it is not traced.

Parameters:

atom (Vertex)

Return type:

int | None

label_set_of(template, name=None)[source]#

A LabelSet covering every position of template – i.e. the compound uniformly labeled, all of its traced atoms one indistinguishable origin.

Parameters:
Return type:

LabelSet

molfoundry.atomtracing.by_element(*symbols)[source]#

A VertexFilter keeping only atoms of the given element symbol(s).

by_element("C") traces carbon; by_element("C", "N") traces carbon and nitrogen. Vertices without a valid element (e.g. electrons in an EFG graph) never match.

Parameters:

symbols (str)

Return type:

Callable[[Vertex], bool]

molfoundry.atomtracing.heavy_atoms(v)[source]#

A VertexFilter keeping every atom except hydrogen.

Useful when a graph carries explicit hydrogens (as SMILES-derived graphs do) and you want to trace the heavy-atom skeleton without hydrogens exploding the maps.

Parameters:

v (Vertex)

Return type:

bool

type molfoundry.atomtracing.DrawStyle = Literal['name', 'pid', 'oid', 'image']#
type molfoundry.atomtracing.DrawLayout = Literal['dot', 'neato', 'circo']#
molfoundry.atomtracing.get_origin_id_color_map(ids)[source]#
Parameters:

ids (List[int] | Tuple[int, ...])

Return type:

Dict[int, str]

molfoundry.atomtracing.draw(tracer, file_path=None, origin_id_colors_map=None, highlight_position_ids=None, title=None, style=DefaultDrawStyle, horizontal=False, layout='dot', graphviz_graph_attr=None)[source]#
Parameters:
  • tracer (SaturateTracer)

  • file_path (str | None)

  • origin_id_colors_map (Dict[int, str] | None)

  • highlight_position_ids (Set[int] | None)

  • title (str | None)

  • style (Tuple[DrawStyle, ...] | None)

  • horizontal (bool | None)

  • layout (DrawLayout | None)

  • graphviz_graph_attr (Dict[str, str] | None)

molfoundry.atomtracing.draw_reaction_network(tracer, file_path=None, origin_id_colors_map=None, highlight_position_ids=None, title=None, style=('name', 'pid', 'image'), horizontal=False, layout='dot', graphviz_graph_attr=None)[source]#
Parameters:
  • tracer (SaturateTracer)

  • file_path (str | None)

  • origin_id_colors_map (Dict[int, str] | None)

  • highlight_position_ids (Set[int] | None)

  • title (str | None)

  • style (Tuple[DrawStyle, ...] | None)

  • horizontal (bool | None)

  • layout (DrawLayout | None)

  • graphviz_graph_attr (Dict[str, str] | None)

molfoundry.atomtracing.draw_filtered_target(tracer, target_ids, file_path=None, origin_id_colors_map=None, highlight_position_ids=None, title=None, style=DefaultDrawStyle, horizontal=False, layout='dot', graphviz_graph_attr=None)[source]#
Parameters:
  • tracer (SaturateTracer)

  • target_ids (Set[int])

  • file_path (str | None)

  • origin_id_colors_map (Dict[int, str] | None)

  • highlight_position_ids (Set[int] | None)

  • title (str | None)

  • style (Tuple[DrawStyle, ...] | None)

  • horizontal (bool | None)

  • layout (DrawLayout | None)

  • graphviz_graph_attr (Dict[str, str] | None)

molfoundry.atomtracing.draw_filtered_source(tracer, origin_ids, file_path=None, origin_id_colors_map=None, highlight_position_ids=None, title=None, style=DefaultDrawStyle, horizontal=False, layout='dot', graphviz_graph_attr=None)[source]#
Parameters:
  • tracer (SaturateTracer)

  • origin_ids (Set[int])

  • file_path (str | None)

  • origin_id_colors_map (Dict[int, str] | None)

  • highlight_position_ids (Set[int] | None)

  • title (str | None)

  • style (Tuple[DrawStyle, ...] | None)

  • horizontal (bool | None)

  • layout (DrawLayout | None)

  • graphviz_graph_attr (Dict[str, str] | None)

molfoundry.atomtracing.draw_filtered_source_target(tracer, origin_ids, target_ids, file_path=None, origin_id_colors_map=None, highlight_position_ids=None, title=None, style=DefaultDrawStyle, horizontal=False, layout='dot', graphviz_graph_attr=None)[source]#
Parameters: