CRN#
Chemical reaction network construction, structure handling, querying, symmetry, Petri-net analysis, and visualization utilities.
Construct#
- class synkit.CRN.Construct.abstract.AbstractReactionExtractor[source]#
Bases:
objectBuild abstract symbolic reaction networks from reaction SMILES lists or SynKit-style module/pathway JSON blocks.
This class supports configurable field names when extracting reactions from JSON-like input records.
Example#
extractor = KEGGExtractor() data = extractor.build_module_json( "M00001", with_compounds=True, with_atom_maps=False, ) abstractor = AbstractReactionExtractor() network = abstractor.build( data=data, deduplicate=True, order="appearance", )
- build(reactions: Sequence[str] | None = None, *, data: Mapping[str, Any] | None = None, drop_missing_smiles_reactions: bool = True, deduplicate: bool = False, templates: Mapping[str, str] | None = None, order: str = 'appearance', reactant_join: str = '+', product_join: str = '+', prefix_module_in_reaction_id: bool = True, reaction_id_keys: Sequence[str] | None = None, reaction_smiles_keys: Sequence[str] | None = None, template_keys: Sequence[str] | None = None, save_as: str | Path | None = None) AbstractReactionNetwork[source]#
Convert full reaction SMILES into an abstract symbolic reaction network.
You may provide either a direct list of reaction SMILES or a module/pathway JSON block.
If
datais provided, field names for reaction identifiers, reaction SMILES strings, and templates may be customized.- Parameters:
reactions (Optional[Sequence[str]]) – Direct reaction SMILES list.
data (Optional[Mapping[str, Any]]) – Module-like or pathway-like reaction JSON block.
drop_missing_smiles_reactions (bool) – Whether to skip records missing reaction SMILES.
deduplicate (bool) – Whether to remove identity and duplicate abstract reactions.
templates (Optional[Mapping[str, str]]) – Optional external mapping from reaction identifiers to templates.
order (str) – Molecule ordering strategy, one of
"appearance"or"sorted".reactant_join (str) – Join token for abstract reactants.
product_join (str) – Join token for abstract products.
prefix_module_in_reaction_id (bool) – Whether to prefix pathway reaction IDs with module IDs.
reaction_id_keys (Optional[Sequence[str]]) – Candidate keys used to find reaction identifiers in each reaction record.
reaction_smiles_keys (Optional[Sequence[str]]) – Candidate keys used to find reaction SMILES strings in each reaction record.
template_keys (Optional[Sequence[str]]) – Candidate keys used to find rule or template strings in each reaction record.
save_as (Optional[PathLike]) – Optional JSON output path.
- Returns:
Abstract symbolic reaction network.
- Return type:
Example#
extractor = KEGGExtractor() data = extractor.build_module_json( "M00001", with_compounds=True, with_atom_maps=False, ) abstractor = AbstractReactionExtractor() network = abstractor.build( data=data, deduplicate=True, order="appearance", reaction_id_keys=["id", "kegg_id", "rid"], reaction_smiles_keys=["smiles", "reaction", "rxn_smiles"], template_keys=["rule", "template", "smirks"], save_as="M00001_abstract.json", )
- build_molecule_pool(parsed_reactions: Sequence[Tuple[List[str], List[str]]], *, order: str = 'appearance') List[str][source]#
Build the unique molecule pool from parsed reactions.
- Parameters:
- Returns:
Ordered unique molecule pool.
- Return type:
List[str]
- Raises:
ValueError – If
orderis not supported.
Example#
molecule_pool = abstractor.build_molecule_pool( parsed_reactions, order="appearance", )
- extract_reactions_and_templates(reactions: Sequence[str] | None = None, *, data: Mapping[str, Any] | None = None, templates: Mapping[str, str] | None = None, drop_missing_smiles_reactions: bool = True, prefix_module_in_reaction_id: bool = True, reaction_id_keys: Sequence[str] | None = None, reaction_smiles_keys: Sequence[str] | None = None, template_keys: Sequence[str] | None = None) Tuple[List[str], Dict[str, str]][source]#
Extract reaction SMILES and rule-template mappings from raw inputs.
Either a direct list of reaction SMILES or a JSON data block may be provided. If both are given, the explicit
reactionslist takes precedence for reaction extraction, whiletemplatesis still merged.When
datais used, the user may customize which keys are searched for reaction identifiers, reaction SMILES strings, and templates.- Parameters:
reactions (Optional[Sequence[str]]) – Direct reaction SMILES list.
data (Optional[Mapping[str, Any]]) – Module-like or pathway-like JSON block.
templates (Optional[Mapping[str, str]]) – Optional external mapping from reaction identifiers to templates.
drop_missing_smiles_reactions (bool) – Whether to skip records that do not contain a reaction SMILES string.
prefix_module_in_reaction_id (bool) – Whether to prefix reaction identifiers with module IDs in pathway-style inputs.
reaction_id_keys (Optional[Sequence[str]]) – Candidate keys used to find reaction identifiers in each reaction record. The keys are tried in order.
reaction_smiles_keys (Optional[Sequence[str]]) – Candidate keys used to find reaction SMILES strings in each reaction record. The keys are tried in order.
template_keys (Optional[Sequence[str]]) – Candidate keys used to find rule or template strings in each reaction record. The keys are tried in order.
- Returns:
Tuple of reaction SMILES list and template mapping.
- Return type:
Example#
extractor = KEGGExtractor() data = extractor.build_module_json( "M00001", with_compounds=True, with_atom_maps=False, ) abstractor = AbstractReactionExtractor() reactions, templates = abstractor.extract_reactions_and_templates( data=data, reaction_id_keys=["id", "kegg_id", "rid"], reaction_smiles_keys=["smiles", "reaction", "rxn_smiles"], template_keys=["rule", "template", "smirks"], )
- iter_reaction_records(data: Mapping[str, Any]) Iterable[Tuple[Mapping[str, Any], str]][source]#
Iterate over reaction records from a module-like or pathway-like JSON block.
Supported structures include:
module-like: ``{“reactions”: […]}`
pathway-like:
{"by_module": {"M00001": {"reactions": [...]}, ...}}
- Parameters:
data (Mapping[str, Any]) – Input JSON-like mapping.
- Yields:
Tuples of
(reaction_record, module_id).- Return type:
Example#
abstractor = AbstractReactionExtractor() for record, module_id in abstractor.iter_reaction_records(data): print(module_id, record.get("id"))
- class synkit.CRN.Construct.abstract.AbstractReactionNetwork(molecule_pool: ~typing.List[str], reactions: ~typing.List[str], templates: ~typing.Dict[str, str] = <factory>, label_to_molecule: ~typing.Dict[str, str] = <factory>)[source]#
Bases:
objectSymbolic abstraction of a reaction network.
- Parameters:
molecule_pool (List[str]) – Unique molecule pool in the original full representation.
reactions (List[str]) – Abstract symbolic reactions such as
"A+B>>C+D".templates (Dict[str, str]) – Optional mapping from reaction identifiers to rule or template strings.
label_to_molecule (Dict[str, str]) – Mapping from abstract labels back to original molecule strings.
- save_json(path: str | Path, *, name: str | None = None) None[source]#
Save the abstract network as a JSON file.
- Parameters:
path (PathLike) – Output JSON path.
name (Optional[str]) – Optional metadata name. If omitted, the filename stem is used.
- Returns:
None- Return type:
None
Example#
network.save_json("abstract_network.json")
- to_dict() Dict[str, Any][source]#
Convert the abstract network to a plain dictionary.
- Returns:
Dictionary representation of the abstract network.
- Return type:
Dict[str, Any]
Example#
payload = network.to_dict()
- to_json_payload(name: str = 'abstract_reaction_network') Dict[str, Any][source]#
Convert the abstract network into a SynKit-style JSON payload.
- Parameters:
name (str) – Name stored in the metadata block.
- Returns:
JSON-serializable payload.
- Return type:
Dict[str, Any]
Example#
payload = network.to_json_payload(name="glycolysis_abstract")
- synkit.CRN.Construct.abstract.deduplicate_abstract_reactions(reactions: Sequence[str]) List[str][source]#
Remove identity reactions and duplicate abstract reactions.
Reactant and product order are normalized internally before comparison. The original retained representative is the first encountered entry.
- Parameters:
reactions (Sequence[str]) – Abstract reactions such as
"A+B>>C+D".- Returns:
Filtered abstract reactions.
- Return type:
List[str]
Example#
filtered = deduplicate_abstract_reactions( ["A+B>>C", "B+A>>C", "A>>A"] )
- class synkit.CRN.Construct.builder.CRNExpand(rules: 'List[Any]', repeats: 'int' = 50, explicit_h: 'bool' = False, implicit_temp: 'bool' = False, strategy: 'Optional[str]' = None, keep_aam: 'bool' = True, max_components: 'int' = 3, use_frontier: 'bool' = True, max_mixtures_per_rule_step: 'int' = 50000, max_tasks_per_step: 'int' = 200000, allow_self_mixtures: 'bool' = False, skip_no_change: 'bool' = True, allow_empty_side: 'bool' = False, dedup_delta: 'bool' = True, dedup_across_rules: 'bool' = False)[source]#
Bases:
object- build(seeds: Iterable[str], *, parallel: bool = False, max_workers: int | None = None, reset: bool = True) DiGraph[source]#
- derivations: DerivationLog#
- state: DerivationState#
- strategy_engine: FrontierStrategy#
- synkit.CRN.Construct.builder.build_crn_from_smarts(rules: List[str], seeds: List[str], *, repeats: int = 50, explicit_h: bool = False, implicit_temp: bool = False, strategy: str | None = None, keep_aam: bool = True, parallel: bool = False, max_workers: int | None = None, max_components: int = 3, use_frontier: bool = True, max_mixtures_per_rule_step: int = 50000, max_tasks_per_step: int = 200000, allow_self_mixtures: bool = False, skip_no_change: bool = True, allow_empty_side: bool = False, dedup_delta: bool = True, dedup_across_rules: bool = False) DiGraph[source]#
- class synkit.CRN.Construct.derivation.DerivationLog(records: 'List[DerivationRecord]' = <factory>)[source]#
Bases:
object- append(*, event_id: int, label: str, step: int, rule_index: int, reactants: Tuple[str, ...], products: Tuple[str, ...]) None[source]#
- records: List[DerivationRecord]#
- class synkit.CRN.Construct.derivation.DerivationRecord(event_id: int, label: str, step: int, rule_index: int, reactants: Tuple[str, ...], products: Tuple[str, ...])[source]#
Bases:
objectAbstract direct derivation record.
This stores the reaction event as multisets of standardized species without changing the public NetworkX CRN representation.
- class synkit.CRN.Construct.flattener.ReactionDeltaFlattener(graph: 'nx.DiGraph', skip_no_change: 'bool' = True, allow_empty_side: 'bool' = False, deduplicate: 'bool' = True)[source]#
Bases:
object- build() ReactionDeltaFlattener[source]#
- synkit.CRN.Construct.keys.make_dedup_key(*, dedup_across_rules: bool, rule_index: int, r_keep_keys: Tuple[str, ...], p_keep_keys: Tuple[str, ...]) Tuple[int | None, Tuple[str, ...], Tuple[str, ...]][source]#
- synkit.CRN.Construct.mixtures.iter_mixtures_arity1(pool_keys: List[str], frontier_keys: List[str], *, use_frontier: bool, cap: int) Iterator[Tuple[str, ...]][source]#
- synkit.CRN.Construct.mixtures.iter_mixtures_arity2(pool_keys: List[str], frontier_keys: List[str], *, use_frontier: bool, allow_self_mixtures: bool, cap: int) Iterator[Tuple[str, ...]][source]#
- synkit.CRN.Construct.mixtures.iter_mixtures_arityk(pool_keys: List[str], frontier_keys: List[str], *, use_frontier: bool, allow_self_mixtures: bool, arity: int, cap: int) Iterator[Tuple[str, ...]][source]#
- synkit.CRN.Construct.smiles.assign_deterministic_maps_and_canonical(nomap_smiles: str) str | None[source]#
- synkit.CRN.Construct.smiles.standardize_smiles_rdkit(smiles: str, *, keep_aam: bool) str | None[source]#
Standardize one SMILES string.
- Behavior:
If RDKit is unavailable: passthrough.
If keep_aam=False: strip atom maps, remove Hs, return canonical SMILES.
- If keep_aam=True:
keep mapped canonical SMILES if maps already exist
otherwise assign deterministic maps and return canonical mapped SMILES
- class synkit.CRN.Construct.state.DerivationState(pool_keys: Set[str] = <factory>, frontier_keys: Set[str] = <factory>, step: int = 0)[source]#
Bases:
objectLightweight builder state inspired by derivation-graph builders.
This keeps the active chemical universe separate from the graph object so the orchestration layer does not need to treat NetworkX as its working memory for frontier expansion.
- class synkit.CRN.Construct.strategy.FrontierStrategy[source]#
Bases:
objectDefault strategy with the same semantics as the validated monolith.
The purpose is not to change chemistry, only to separate the exploration strategy from the builder. This mirrors the derivation-graph idea of having an execution policy distinct from rule application.
- synkit.CRN.Construct.worker.apply_rule_worker(args: Tuple[int, Any, str, bool, bool, str | None, Tuple[str, ...]]) Tuple[int, Tuple[str, ...], List[str]][source]#
Apply one rule to one substrate mixture.
This intentionally preserves the behavior of the validated monolith: - automorphism=True - order-preserving deduplication of raw output strings
- class synkit.CRN.Construct.DAG.crn.CRN(rule_list: List[Dict[str, Any]], smiles_list: str | Sequence[str], *, n_repeats: int = 3, prune: bool = True, strategy: str | Strategy = Strategy.BACKTRACK, verbosity: int = 0)[source]#
Bases:
objectExpand an initial pool of molecules through several rounds of rule application using MODReactor under the hood.
Public attributes#
- initial_smilesList[str]
The starting set of molecules.
- n_repeatsint
Number of expansion rounds requested.
- roundsList[Tuple[str, List[str]]]
[(“Round 1”, [rxn₁, …]), …] — kept for backwards compatibility.
- final_smilesList[str]
Unique molecule SMILES present after the last round.
- rule_countint
How many rules were supplied.
Public helpers#
- run() -> CRN
Rebuild the network from scratch (chainable).
- product_sets -> Dict[str, List[str]]
Mapping of round‑tag → reaction‑SMILES list.
- get_reaction_smiles() -> Dict[str, List[str]]
Same as product_sets (alias).
- help()
Human‑readable summary.
- class synkit.CRN.Construct.DAG.mod_crn.MODCRN(rule_db_path: str | List[str], initial_smiles: List[str], n_repeats: int = 2)[source]#
Bases:
objectMODCRN ======
High-level class for constructing, inspecting, and reporting a chemical reaction network using the MØD derivation graph (DG) API.
Key Features#
Flexible rule loading: accept a JSON database path or a list of GML strings.
Initial molecule deduplication via graph isomorphism.
Customizable iterative strategy for rule applications.
Built-in summary and external report export.
Parameters#
- rule_db_pathUnion[str, List[str]]
Path to a JSON rule database or list of GML rule strings.
- initial_smilesList[str]
SMILES strings of the seed molecules.
- repeatsint, default=2
Number of repeat cycles for rule application.
Properties#
- rulesList[Rule]
Loaded Rule objects for network construction.
- graphsList[Graph]
Deduplicated initial Graph objects.
- derivation_graphDG
The active derivation graph instance.
- num_verticesint
Number of molecules in the derivation graph.
- num_edgesint
Number of reactions in the derivation graph.
Methods#
- build() -> None
Populate the derivation graph with the configured strategy.
- print_summary() -> None
Print and save a concise summary of the derivation graph.
- export_report(path: str) -> None
Generate an external report via the mod_post CLI.
- help() -> None
Print usage examples and API summarylog.
- class synkit.CRN.Construct.DAG.syncrn.ReactionDeltaFlattener(graph: 'nx.DiGraph', skip_no_change: 'bool' = True, allow_empty_side: 'bool' = False, deduplicate: 'bool' = True)[source]#
Bases:
object- build() ReactionDeltaFlattener[source]#
- class synkit.CRN.Construct.DAG.syncrn.SynCRN(rules: 'List[Any]', repeats: 'int' = 50, explicit_h: 'bool' = False, implicit_temp: 'bool' = False, strategy: 'Optional[str]' = None, keep_aam: 'bool' = True, max_components: 'int' = 3, use_frontier: 'bool' = True, max_mixtures_per_rule_step: 'int' = 50000, max_tasks_per_step: 'int' = 200000, skip_no_change: 'bool' = True, allow_empty_side: 'bool' = False, dedup_delta: 'bool' = True, dedup_across_rules: 'bool' = False)[source]#
Bases:
object
- synkit.CRN.Construct.DAG.syncrn.build_syncrn_from_smarts(rules: List[str], seeds: List[str], *, repeats: int = 50, explicit_h: bool = False, implicit_temp: bool = False, strategy: str | None = None, keep_aam: bool = True, parallel: bool = False, max_workers: int | None = None, max_components: int = 3, use_frontier: bool = True, max_mixtures_per_rule_step: int = 50000, max_tasks_per_step: int = 200000, skip_no_change: bool = True, allow_empty_side: bool = False, dedup_delta: bool = True, dedup_across_rules: bool = False) DiGraph[source]#
Structure#
- class synkit.CRN.Structure.reaction.RXNSide(counts: Dict[str, int]=<factory>)[source]#
Bases:
objectStoichiometric multiset for one reaction side.
- class synkit.CRN.Structure.reaction.Reaction(id: str, source_node_id: Hashable, source_kind: str, lhs: RXNSide, rhs: RXNSide, label: str | None = None, step: int | None = None, rule_index: int | None = None, app_index: int | None = None, rule_repr: str | None = None, rule_id: str | None = None, source_attrs: Dict[str, ~typing.Any]=<factory>, metadata: Dict[str, ~typing.Any]=<factory>, reactant_edge_attrs: Dict[str, ~typing.Dict[str, ~typing.Any]]=<factory>, product_edge_attrs: Dict[str, ~typing.Dict[str, ~typing.Any]]=<factory>)[source]#
Bases:
objectCanonical concrete reaction instance.
- Parameters:
id (str) – Stable internal reaction id such as
r_1.source_node_id (Hashable) – Original reaction-node id in the source graph.
source_kind (str) – Original source node kind, often
"rule".lhs (RXNSide) – Reactant multiset.
rhs (RXNSide) – Product multiset.
label (Optional[str]) – Optional reaction label.
step (Optional[int]) – Optional expansion or generation step.
rule_index (Optional[int]) – Optional original rule index.
app_index (Optional[int]) – Optional application index.
rule_repr (Optional[str]) – Optional original rule/template string.
rule_id (Optional[str]) – Optional associated abstract rule id.
source_attrs (Dict[str, Any]) – Exact original node attributes from the source graph.
metadata (Dict[str, Any]) – Extra canonical metadata.
reactant_edge_attrs (Dict[str, Dict[str, Any]]) – Original edge attributes for reactant arcs, keyed by internal species id.
product_edge_attrs (Dict[str, Dict[str, Any]]) – Original edge attributes for product arcs, keyed by internal species id.
- format(species_token: Callable[[str], str], *, include_id: bool = True, include_rule: bool = False, include_step: bool = False, arrow: str = '>>') str[source]#
Format the full reaction as text.
- Parameters:
species_token (Callable[[str], str]) – Function mapping internal species ids to display text.
include_id (bool) – Whether to include the internal reaction id.
include_rule (bool) – Whether to include rule provenance.
include_step (bool) – Whether to include the step field.
arrow (str) – Arrow string used between sides.
- Returns:
Human-readable reaction string.
- Return type:
- class synkit.CRN.Structure.rule.Rule(id: str, rule_index: int | None = None, rule_repr: str | None = None, label: str | None = None, metadata: Dict[str, ~typing.Any]=<factory>)[source]#
Bases:
objectAbstract rule provenance shared by one or more concrete reactions.
This does not become a node in the bipartite CRN graph. Instead, reaction nodes may carry
kind="rule"in the input graph while still being interpreted as concrete reaction instances that reference a rule record.- Parameters:
- class synkit.CRN.Structure.species.Species(id: str, source_node_id: Hashable, label: str, smiles: str | None = None, source_attrs: Dict[str, ~typing.Any]=<factory>, metadata: Dict[str, ~typing.Any]=<factory>)[source]#
Bases:
objectCanonical species record.
- Parameters:
id (str) – Stable internal species id such as
s_1.source_node_id (Hashable) – Original node id in the source NetworkX graph.
label (str) – Human-readable display label.
smiles (Optional[str]) – Optional SMILES string.
source_attrs (Dict[str, Any]) – Exact original node attributes from the source graph.
metadata (Dict[str, Any]) – Optional extra canonical metadata.
- class synkit.CRN.Structure.syncrn.SynCRN(species: Dict[str, ~synkit.CRN.Structure.species.Species]=<factory>, reactions: Dict[str, ~synkit.CRN.Structure.reaction.Reaction]=<factory>, rules: Dict[str, ~synkit.CRN.Structure.rule.Rule]=<factory>, graph_attrs: Dict[str, ~typing.Any]=<factory>, metadata: Dict[str, ~typing.Any]=<factory>)[source]#
Bases:
objectCanonical reaction-system object for SynKit-CRN.
Official representations exposed by this object#
SynCRN: master reaction-system objectSynCRN.to_digraph(): species–reaction bipartite graph viewSynCRN.to_stoichiometric_matrices(): matrix view for stoichiometric analysisSynCRN.to_petrinet(): pre/post incidence view for pathwaysSynCRN.to_equations(): human-readable reaction list
Design notes#
Input digraph nodes with
kind="rule"are preserved exactly on round-trip viaReaction.source_kindandReaction.source_attrs. They are also normalized as concrete reaction instances for downstream computation.- param species:
Mapping from internal species ids to Species records.
- type species:
Dict[str, Species]
- param reactions:
Mapping from internal reaction ids to Reaction records.
- type reactions:
Dict[str, Reaction]
- param rules:
Mapping from internal rule ids to Rule records.
- type rules:
Dict[str, Rule]
- param graph_attrs:
Original graph-level attributes from the input digraph.
- type graph_attrs:
Dict[str, Any]
- param metadata:
Additional canonical metadata for the SynCRN object.
- type metadata:
Dict[str, Any]
Example#
syn = SynCRN.from_reaction_strings(["A>>B", "B>>C"]) print(syn.n_species) print(syn.to_equations())
- describe(*, include_species: bool = False, species: str = 'label') str[source]#
Return a human-readable multiline description of the network.
- Parameters:
- Returns:
Multiline text description.
- Return type:
Example#
print(syn.describe(include_species=True, species="label"))
- format_reaction(reaction_id: str, *, species: str = 'label', include_id: bool = True, include_rule: bool = False, include_step: bool = False, arrow: str = '>>') str[source]#
Format one reaction as text.
- Parameters:
reaction_id (str) – Internal reaction id.
species (str) – Species display mode.
include_id (bool) – Whether to include the internal reaction id.
include_rule (bool) – Whether to include rule provenance.
include_step (bool) – Whether to include step provenance.
arrow (str) – Arrow string between lhs and rhs.
- Returns:
Human-readable reaction string.
- Return type:
Example#
syn.format_reaction("r_1", species="label", include_rule=True)
- classmethod from_digraph(crn: DiGraph, *, species_kind: str = 'species', reaction_kinds: Tuple[str, ...] = ('reaction', 'rule'), species_prefix: str = 's_', reaction_prefix: str = 'r_', rule_prefix: str = 'rule_', strict: bool = True) SynCRN[source]#
Build a canonical SynCRN object from a species–reaction bipartite digraph.
The current SynKit-CRN graph frequently stores concrete reaction-instance nodes with
kind="rule". This constructor preserves that original kind inReaction.source_kindwhile also converting such nodes into concrete reaction instances for downstream computation.- Parameters:
crn (nx.DiGraph) – Directed bipartite graph with species and reaction-like nodes.
species_kind (str) – Node-kind value used for species nodes.
reaction_kinds (Tuple[str, ...]) – Node-kind values used for reaction-instance nodes.
species_prefix (str) – Prefix for generated internal species ids.
reaction_prefix (str) – Prefix for generated internal reaction ids.
rule_prefix (str) – Prefix for generated internal rule ids.
strict (bool) – Whether malformed graph structure should raise an error.
- Returns:
Canonical SynCRN object.
- Return type:
- Raises:
TypeError – If
crnis not annx.DiGraph.
Example#
syn = SynCRN.from_digraph(crn) print(syn.to_equations())
- classmethod from_reaction_strings(rxns: List[str], rules: List[str | None] | None = None, *, parser: Callable[[str], Any] | None = None, strict: bool = True) SynCRN[source]#
Build a SynCRN object directly from reaction strings.
Reactions and rules are interpreted pairwise, so
rxns[i]corresponds torules[i].ID policy#
This constructor uses plain numeric string ids instead of prefixed ids.
Species ids:
"1","2", …Reaction ids: continue after species ids
Rule ids:
"1","2", … within the separate rule table
Species are indexed by first appearance in the input reactions.
- param rxns:
List of reaction strings such as
"2A>>B+3C".- type rxns:
List[str]
- param rules:
Optional list of rule strings pairwise aligned with
rxns.- type rules:
Optional[List[Optional[str]]]
- param parser:
Optional side parser. It should accept one side string such as
"2A+B"and return either a mapping, an object withto_dict(), or an object withitems().- type parser:
Optional[Callable[[str], Any]]
- param strict:
Whether malformed reaction strings or empty sides should raise an error.
- type strict:
bool
- returns:
Canonical SynCRN object.
- rtype:
SynCRN
- raises TypeError:
If
rxnsorruleshave invalid types.- raises ValueError:
If reaction strings are malformed or rules are not pairwise aligned.
Example#
syn = SynCRN.from_reaction_strings(["2A>>B+3C"]) syn = SynCRN.from_reaction_strings( ["A+B>>C", "C>>D"], rules=["rule_1", "rule_2"], parser=RXNSide.from_str, )
- property n_reactions: int#
Return the number of reactions.
- Returns:
Number of reactions.
- Return type:
- property n_rules: int#
Return the number of unique abstract rules.
- Returns:
Number of rules.
- Return type:
- property reaction_ids: List[str]#
Return the internal reaction order.
- Returns:
Ordered list of reaction ids.
- Return type:
List[str]
Example#
print(syn.reaction_ids)
- property rule_ids: List[str]#
Return the internal rule order.
- Returns:
Ordered list of rule ids.
- Return type:
List[str]
Example#
print(syn.rule_ids)
- property species_ids: List[str]#
Return the internal species order.
- Returns:
Ordered list of species ids.
- Return type:
List[str]
Example#
print(syn.species_ids)
- to_dict() Dict[str, Any][source]#
Return a nested JSON-like dictionary representation.
- Returns:
Full SynCRN object as a dictionary.
- Return type:
Dict[str, Any]
Example#
data = syn.to_dict() print(data["species"].keys())
- to_digraph(*, node_ids: str = 'source', reaction_kind: str | None = None, include_internal_ids: bool = True) DiGraph[source]#
Reconstruct a species–reaction bipartite digraph.
By default, this method preserves original node ids and original reaction-node kinds. This means that input reaction nodes with
kind="rule"will still appear askind="rule"after round-trip.- Parameters:
- Returns:
Reconstructed bipartite digraph.
- Return type:
nx.DiGraph
- Raises:
ValueError – If
node_idsis not"source"or"internal".
Example#
g2 = syn.to_digraph() g3 = syn.to_digraph(node_ids="internal", reaction_kind="reaction")
- to_equations(*, species: str = 'label', include_id: bool = True, include_rule: bool = False, include_step: bool = False, arrow: str = '>>') List[str][source]#
Return the network as a list of formatted reaction equations.
- Parameters:
- Returns:
List of formatted reaction equations.
- Return type:
List[str]
Example#
eqs = syn.to_equations(species="smiles", include_rule=True) print("\n".join(eqs))
- to_petrinet() Dict[str, Any][source]#
Return a Petri-net style pre/post incidence view.
The returned dictionary contains:
places: species idstransitions: reaction idspre: input incidence mappost: output incidence map
- Returns:
Petri-net incidence representation.
- Return type:
Dict[str, Any]
Example#
pn = syn.to_petrinet() print(pn["pre"]) print(pn["post"])
- to_stoichiometric_matrices() Dict[str, Any][source]#
Construct stoichiometric matrices in canonical species and reaction order.
The returned dictionary contains:
species_orderreaction_orderS_minus: reactant-incidence matrixS_plus: product-incidence matrixS: net stoichiometric matrix
- Returns:
Stoichiometric matrix view of the network.
- Return type:
Dict[str, Any]
Example#
mats = syn.to_stoichiometric_matrices() print(mats["species_order"]) print(mats["reaction_order"]) print(mats["S"])
Pathway#
- class synkit.CRN.Pathway.pathfinder.PathFinderConfig(max_depth: int = 12, max_paths: int = 20, stop_after_first: bool = False, deduplicate_by_flow: bool = True)[source]#
Bases:
objectConfiguration for qualitative pathway search.
This configuration controls the breadth-first search over qualitative set-semantics states.
- Parameters:
max_depth (int) – Maximum number of reaction firings allowed in a candidate pathway.
max_paths (int) – Maximum number of pathway candidates to return.
stop_after_first (bool) – Whether to stop the search immediately after the first accepted candidate is found.
deduplicate_by_flow (bool) – Whether to deduplicate candidates by their reaction-count flow vector rather than retaining multiple sequences with the same aggregate flow.
- class synkit.CRN.Pathway.pathfinder.PathwayCandidate(reactions: List[str], flow: Dict[str, int], reached_species: List[str], depth: int, realizable: bool | None = None, certificate: List[str] | None = None)[source]#
Bases:
objectOne qualitative pathway candidate returned by
PathwayFinder.A candidate stores both the ordered reaction sequence used during qualitative search and the corresponding aggregated reaction-count flow.
- Parameters:
reactions (List[str]) – Ordered list of reaction ids in the candidate sequence.
flow (Dict[str, int]) – Aggregated reaction firing counts derived from
reactions.reached_species (List[str]) – Sorted list of species reachable after firing the candidate sequence in qualitative set semantics.
depth (int) – Length of the reaction sequence.
realizable (Optional[bool]) – Optional exact realizability verdict computed afterwards from Petri-net semantics.
certificate (Optional[List[str]]) – Optional firing certificate returned by exact realizability checking.
- class synkit.CRN.Pathway.pathfinder.PathwayFinder(config: PathFinderConfig | None = None)[source]#
Bases:
objectQualitative source-to-target pathway search for SynCRN-like inputs.
This class searches in set semantics: a reaction is usable once all its reactant species are present in the current available set, and firing it adds its product species to that set.
Species are not consumed during the qualitative search. Exact stoichiometric and token-based validation can be applied afterwards using
validate_candidates().- find_paths_set(*, source_species: Iterable[str], target_species: Iterable[str], max_depth: int | None = None, max_paths: int | None = None, stop_after_first: bool | None = None, deduplicate_by_flow: bool | None = None) List[PathwayCandidate][source]#
Find qualitative source-to-target pathways using set semantics.
The search is performed by breadth-first expansion over reachable species sets. At each step, enabled reactions add their product species to the current set without consuming reactants.
- Parameters:
source_species (Iterable[str]) – Initial source species assumed to be present.
target_species (Iterable[str]) – Target species that must all be contained in the reached set.
max_depth (Optional[int]) – Optional override for maximum search depth. If
None, the value from the configuration is used.max_paths (Optional[int]) – Optional override for maximum number of returned candidates. If
None, the value from the configuration is used.stop_after_first (Optional[bool]) – Optional override controlling whether to stop after the first accepted candidate.
deduplicate_by_flow (Optional[bool]) – Optional override controlling whether candidates are deduplicated by aggregate flow.
- Returns:
List of qualitative pathway candidates satisfying the target condition.
- Return type:
List[PathwayCandidate]
- Raises:
RuntimeError – If no network has been loaded.
ValueError – If
target_speciesis empty.
- load_hypergraph(vertices: Iterable[str], edges: Mapping[str, Tuple[Mapping[str, int], Mapping[str, int]]]) PathwayFinder[source]#
Load a qualitative reaction hypergraph directly.
The hypergraph is represented by a set of species vertices and a mapping from reaction ids to
(tail, head)multisets, wheretailis the reactant side andheadis the product side.- Parameters:
- Returns:
The current finder instance.
- Return type:
- load_syncrn(crn: object, *, species: str = 'label', reaction: str = 'id') PathwayFinder[source]#
Load a SynCRN-like object through its incidence representation.
The CRN is tokenized into species and reaction identifiers suitable for qualitative search.
- Parameters:
- Returns:
The current finder instance.
- Return type:
- validate_candidates(crn: object, candidates: List[PathwayCandidate], *, initial_marking: Mapping[str, int], species: str = 'label', reaction: str = 'id') List[PathwayCandidate][source]#
Validate qualitative candidates by exact Petri-net realizability.
For each candidate, the aggregated reaction-count flow is checked using
PathwayRealizability. The returned candidates preserve the original qualitative information and add realizability metadata.- Parameters:
crn (object) – SynCRN-like object used for exact validation.
candidates (List[PathwayCandidate]) – Qualitative candidates to validate.
initial_marking (Mapping[str, int]) – Initial place marking used for exact realizability checking.
species (str) – Species naming mode passed through to
PathwayRealizability.load_syncrn_and_flow().reaction (str) – Reaction naming mode passed through to
PathwayRealizability.load_syncrn_and_flow().
- Returns:
New list of candidates augmented with realizability verdicts and certificates.
- Return type:
List[PathwayCandidate]
- synkit.CRN.Pathway.pathfinder.run_pathfinder_from_syncrn(crn: object, *, source_species: Iterable[str], target_species: Iterable[str], initial_marking: Mapping[str, int] | None = None, species: str = 'label', reaction: str = 'id', max_depth: int = 12, max_paths: int = 20, validate: bool = False, verbose: bool = True) List[PathwayCandidate][source]#
Convenience harness for qualitative pathway search on a SynCRN object.
This helper constructs a
PathwayFinder, loads the CRN, runs qualitative search, and optionally validates the returned candidates by exact realizability.- Parameters:
crn (object) – SynCRN-like object to analyze.
source_species (Iterable[str]) – Initial source species assumed to be present.
target_species (Iterable[str]) – Target species that must all be reachable.
initial_marking (Optional[Mapping[str, int]]) – Optional initial marking used only when
validate=True.species (str) – Species naming mode used when tokenizing the CRN.
reaction (str) – Reaction naming mode used when tokenizing the CRN.
max_depth (int) – Maximum qualitative search depth.
max_paths (int) – Maximum number of pathway candidates to return.
validate (bool) – Whether to validate candidates by exact Petri-net realizability.
verbose (bool) – Whether to print a simple textual summary of the returned candidates.
- Returns:
List of qualitative pathway candidates, optionally enriched with exact realizability results.
- Return type:
List[PathwayCandidate]
- Raises:
ValueError – If
validate=Truebutinitial_markingis not provided.
- class synkit.CRN.Pathway.reachability.PathwayReachability(config: ReachabilityConfig | None = None)[source]#
Bases:
objectForward reachability utilities for SynCRN pathway analysis.
This class provides layered forward propagation over a reaction hypergraph. It supports two related semantics:
Set semantics: a reaction is enabled once all reactant species are present in the reachable set; stoichiometric multiplicities are ignored for enabling.
Multiset semantics: a reaction is enabled only when the current marking contains enough copies of each reactant species to satisfy stoichiometric coefficients.
The class can be loaded either from tokenized
vertices/edgesdata or directly from a SynCRN-like object viaload_syncrn().Internally, reactions are stored as a mapping
reaction_id -> (tail_multiset, head_multiset)where the tail is the reactant multiset and the head is the product multiset.
- Parameters:
config (Optional[ReachabilityConfig]) – Optional reachability configuration. If omitted, a default
ReachabilityConfigis used.
Example#
rr = PathwayReachability() rr.load_hypergraph( vertices=["A", "B", "C", "D"], edges={ "r1": ({"A": 1, "B": 1}, {"C": 1}), "r2": ({"C": 1}, {"D": 1}), }, ) result = rr.compute_layers_set(initial_species=["A", "B"]) print(result.species_first_depth) # {'A': 0, 'B': 0, 'C': 1, 'D': 2}
- compute_layers_multiset(initial_marking: Mapping[str, int], max_layers: int | None = None) ReachabilityResult[source]#
Compute layered forward reachability in multiset semantics.
In this mode, species counts matter. A reaction is enabled only if the current marking contains enough multiplicity for every reactant. At each layer, all currently enabled reactions are fired once in batch.
This procedure is useful when approximate token-flow behavior is desired, but it should not be confused with exhaustive Petri-net reachability analysis over all possible firing sequences.
- Parameters:
- Returns:
Reachability result containing the full layered traversal trace.
- Return type:
Example#
rr = PathwayReachability().load_hypergraph( vertices=["A", "B", "C"], edges={ "r1": ({"A": 2}, {"B": 1}), "r2": ({"B": 1}, {"C": 1}), }, ) result = rr.compute_layers_multiset(initial_marking={"A": 2}) print(result.species_first_depth) # {'A': 0, 'B': 1, 'C': 2}
- compute_layers_set(initial_species: Iterable[str], max_layers: int | None = None) ReachabilityResult[source]#
Compute layered forward reachability in set semantics.
In this mode, only species presence matters. Stoichiometric multiplicities are ignored when deciding whether a reaction is enabled.
The algorithm proceeds layer by layer: 1. find all reactions whose reactants are already reachable, 2. keep only reactions not previously seen as enabled, 3. collect all products they produce, 4. add any newly produced species to the reachable set.
- Parameters:
- Returns:
Reachability result containing the full layered traversal trace.
- Return type:
Example#
rr = PathwayReachability().load_hypergraph( vertices=["A", "B", "C", "D"], edges={ "r1": ({"A": 1, "B": 1}, {"C": 1}), "r2": ({"C": 1}, {"D": 1}), }, ) result = rr.compute_layers_set(initial_species=["A", "B"]) for layer in result.layers: print(layer.depth, layer.newly_reachable_species) # 1 ['C'] # 2 ['D']
- export_layers_json(result: ReachabilityResult, fn: str) PathwayReachability[source]#
Export a reachability result to a JSON file.
The output contains the initial species set, first-depth maps, and the full list of layered traversal records.
- Parameters:
result (ReachabilityResult) – Reachability result to serialize.
fn (str) – Output JSON filename.
- Returns:
The current instance, to allow fluent chaining.
- Return type:
- Raises:
OSError – Raised if the target file cannot be written.
Example#
rr.export_layers_json(result, "reachability_layers.json")
- load_hypergraph(vertices: Iterable[str], edges: Mapping[str, Tuple[Mapping[str, int], Mapping[str, int]]]) PathwayReachability[source]#
Load a tokenized reaction hypergraph directly.
Each edge must map a reaction identifier to a pair
(tail_multiset, head_multiset), where both multisets map species identifiers to strictly positive stoichiometric coefficients.Non-positive coefficients are discarded during normalization.
- Parameters:
- Returns:
The current instance, to allow fluent chaining.
- Return type:
Example#
rr = PathwayReachability().load_hypergraph( vertices=["A", "B", "C"], edges={ "r1": ({"A": 1}, {"B": 1}), "r2": ({"B": 1}, {"C": 1}), }, )
- load_syncrn(crn: object, *, species: str = 'label', reaction: str = 'id') PathwayReachability[source]#
Load reachability data from a SynCRN-like object.
This method delegates tokenization to
tokenize_syncrn_incidence(), then stores both the tokenized hypergraph and the forward/backward token-id lookup tables.- Parameters:
- Returns:
The current instance, to allow fluent chaining.
- Return type:
Example#
rr = PathwayReachability().load_syncrn( syncrn_object, species="label", reaction="id", )
- class synkit.CRN.Pathway.reachability.ReachabilityConfig(max_layers: int = 10000, stop_when_no_new_species: bool = True)[source]#
Bases:
objectConfiguration for forward reachability traversal.
This configuration controls how many propagation layers are explored and whether the traversal should terminate as soon as no newly reachable species are discovered.
- Parameters:
Example#
cfg = ReachabilityConfig( max_layers=100, stop_when_no_new_species=True, )
- class synkit.CRN.Pathway.reachability.ReachabilityLayer(depth: int, newly_enabled_reactions: List[str], newly_reachable_species: List[str], all_reachable_species: List[str])[source]#
Bases:
objectOne forward reachability layer.
A layer summarizes what became newly active at a given traversal depth. In set semantics, a reaction is considered enabled when all of its reactant species are already reachable. In multiset semantics, a reaction is enabled when the current marking contains sufficient multiplicity for each reactant.
- Parameters:
depth (int) – Layer index, starting at
1for the first propagation step.newly_enabled_reactions (List[str]) – Reaction identifiers that became enabled at this layer.
newly_reachable_species (List[str]) – Species that became reachable for the first time at this layer.
all_reachable_species (List[str]) – Complete set of reachable species after this layer is applied.
Example#
layer = ReachabilityLayer( depth=2, newly_enabled_reactions=["r3", "r4"], newly_reachable_species=["E", "F"], all_reachable_species=["A", "B", "C", "D", "E", "F"], )
- class synkit.CRN.Pathway.reachability.ReachabilityResult(initial_species: List[str], layers: List[ReachabilityLayer], species_first_depth: Dict[str, int], reaction_first_depth: Dict[str, int])[source]#
Bases:
objectContainer for forward reachability results.
This object stores the initial support, the layered traversal trace, and the first depth at which each species or reaction became reachable or enabled.
- Parameters:
initial_species (List[str]) – Initial reachable species support used to seed the traversal.
layers (List[ReachabilityLayer]) – Ordered list of reachability layers.
species_first_depth (Dict[str, int]) – Mapping from species identifier to the first layer depth at which that species became reachable. Initial species are assigned depth
0.reaction_first_depth (Dict[str, int]) – Mapping from reaction identifier to the first layer depth at which that reaction became enabled.
Example#
result = ReachabilityResult( initial_species=["A", "B"], layers=[], species_first_depth={"A": 0, "B": 0}, reaction_first_depth={}, )
- layers: List[ReachabilityLayer]#
- synkit.CRN.Pathway.reachability.run_reachability_from_syncrn(crn: object, initial_species: Iterable[str], *, species: str = 'label', reaction: str = 'id', verbose: bool = True) Tuple[PathwayReachability, ReachabilityResult][source]#
Run layered qualitative reachability directly from a SynCRN-like object.
This convenience function constructs a
PathwayReachabilityinstance, loads the tokenized SynCRN representation, computes set-based layered reachability, and optionally prints a human-readable traversal summary.- Parameters:
crn (object) – SynCRN-like object to analyze.
initial_species (Iterable[str]) – Initial reachable species set.
species (str) – Species attribute used during tokenization.
reaction (str) – Reaction attribute used during tokenization.
verbose (bool) – If
True, print the tokenized edges and each traversal layer.
- Returns:
Pair
(reachability_engine, result).- Return type:
Example#
rr, result = run_reachability_from_syncrn( syncrn_object, initial_species=["A", "B"], species="label", reaction="id", verbose=True, )
- synkit.CRN.Pathway.reachability.syncrn_to_reachability_inputs(crn: object, *, species: str = 'label', reaction: str = 'id') Tuple[List[str], Dict[str, Tuple[Dict[str, int], Dict[str, int]]]][source]#
Convert a SynCRN-like object into tokenized reachability inputs.
This is a lightweight adapter returning only the tokenized species list and reaction hyperedges needed by
PathwayReachability.- Parameters:
- Returns:
Pair
(vertices, edges)whereverticesis the species token list andedgesmaps reaction token to(tail_multiset, head_multiset).- Return type:
Tuple[List[str], Dict[str, Tuple[Dict[str, int], Dict[str, int]]]]
Example#
vertices, edges = syncrn_to_reachability_inputs( syncrn_object, species="label", reaction="id", )
- class synkit.CRN.Pathway.realizability.PathwayRealizability(config: RealizabilityConfig | None = None)[source]#
Bases:
objectExact flow-realizability utilities for SynCRN-like inputs.
A pathway flow is realizable if there exists an ordering of reaction firings such that:
each selected reaction is fired exactly the requested number of times,
the execution starts from the supplied initial marking,
every firing respects stoichiometric token consumption and production.
Unspecified reactions default to flow 0.
The class supports:
loading directly from tokenized hypergraph-style inputs,
loading from a SynCRN-like object,
exact bounded BFS realizability testing,
a sufficient acyclicity test via a König-style construction,
scaled realizability,
borrow realizability.
- Parameters:
config (Optional[RealizabilityConfig]) – Optional configuration for bounded realizability search. If
None, a defaultRealizabilityConfigis used.
Example#
pr = PathwayRealizability().load_syncrn_and_flow( syn, flow={"12": 1, "13": 1}, species="label", reaction="id", ) pr.build_petri_net_from_flow() ok, cert = pr.is_realizable() print(ok, cert)
- build_petri_net_from_flow() PathwayRealizability[source]#
Build an augmented Petri net encoding the requested pathway flow.
For every active reaction
eidwith requested flowf > 0, two auxiliary places are created:__ext__{eid}: supply place initialized withftokens,__target__{eid}: target place expected to accumulateftokens.
The reaction transition consumes one token from the supply place on each firing and produces one token in the target place on each firing. This enforces exact realization of the requested number of firings.
- Returns:
The current instance.
- Return type:
- Raises:
RuntimeError – If no pathway data has been loaded.
ValueError – If a negative flow value is encountered.
Example#
pr = PathwayRealizability().load_syncrn_and_flow( syn, flow={"12": 1, "13": 1}, ) pr.build_petri_net_from_flow() print(pr.initial_marking) print(pr.goal_exact)
- property certificate: List[str] | None#
Return the most recently found firing certificate.
- Returns:
Realizing firing sequence, or
Noneif none is cached.- Return type:
Optional[List[TransitionId]]
- export_pnml(fn: str) PathwayRealizability[source]#
Export the current augmented Petri net to a JSON-based PNML-like file.
The exported structure contains places, transitions, initial marking, and active goal constraints. Despite the method name, the file written here is JSON rather than XML PNML.
- Parameters:
fn (str) – Output filename.
- Returns:
The current instance.
- Return type:
Example#
pr.export_pnml("pathway_realizability.json")
- property goal_atleast: Dict[str, int]#
Return lower-bound target marking constraints.
- Returns:
Lower-bound goal marking constraints.
- Return type:
Dict[Place, int]
- property goal_exact: Dict[str, int]#
Return exact target marking constraints.
- Returns:
Exact goal marking constraints.
- Return type:
Dict[Place, int]
- property initial_marking: Dict[str, int]#
Return the active initial marking of the augmented Petri net.
- Returns:
Initial marking.
- Return type:
Dict[Place, int]
- Raises:
RuntimeError – If the initial marking has not yet been initialized.
- is_borrow_realizable(max_borrow_each: int = 2) Tuple[bool, Mapping[str, int] | None][source]#
Test realizability when temporary borrowed initial tokens are allowed.
Every combination of per-species borrowed tokens from 0 up to
max_borrow_eachis tried. For a candidate borrow multiset, the borrowed tokens are added to the initial marking and then imposed again as lower-bound final goals ingoal_atleastso that the borrowed material must be returned.- Parameters:
max_borrow_each (int) – Maximum borrowed amount tested independently for each species.
- Returns:
Pair
(success, borrow)whereborrowis the first successful borrow multiset, orNoneif no tested borrow succeeds.- Return type:
Example#
ok, borrow = pr.is_borrow_realizable(max_borrow_each=1) print(ok, borrow)
- is_realizable(max_states: int | None = None, max_depth: int | None = None) Tuple[bool, List[str] | None][source]#
Test exact realizability by bounded breadth-first search.
The search explores reachable Petri-net markings while recording firing sequences. A certificate is returned when a goal-satisfying marking is found.
- Parameters:
- Returns:
Pair
(is_realizable, certificate)wherecertificateis a realizing transition sequence if one is found.- Return type:
Tuple[bool, Optional[List[TransitionId]]]
Example#
ok, cert = pr.is_realizable(max_states=50000, max_depth=2000) print(ok) print(cert)
- is_realizable_via_konig() bool[source]#
Apply a König-style sufficient acyclicity test.
A directed bipartite dependency graph is built using:
species vertices
("v", species)active-reaction vertices
("e", reaction)
with edges:
species -> reaction for reactant incidence,
reaction -> species for product incidence.
If this dependency graph is acyclic, the active flow is certified realizable by this sufficient test.
- Returns:
Trueif the sufficient acyclicity condition holds, elseFalse.- Return type:
Example#
if pr.is_realizable_via_konig(): print("Guaranteed realizable by sufficient test")
- is_scaled_realizable(k_max: int = 4) Tuple[bool, int | None][source]#
Test whether a scaled version of the requested flow is realizable.
For each integer
kfrom 1 tok_max, the requested flow is scaled tok * flowand tested for exact realizability.- Parameters:
k_max (int) – Maximum scale factor to try.
- Returns:
Pair
(success, k)wherekis the first successful scale factor, orNoneif no tested scale succeeds.- Return type:
Example#
ok, k = pr.is_scaled_realizable(k_max=5) print(ok, k)
- load_hypergraph_and_flow(vertices: Iterable[str], edges: Mapping[str, Tuple[Mapping[str, int], Mapping[str, int]]], flow: Mapping[str, int], *, initial_marking: Mapping[str, int] | None = None) PathwayRealizability[source]#
Load tokenized hypergraph data and a requested pathway flow.
The
edgesmapping is interpreted asreaction_id -> (tail_multiset, head_multiset). Reactions not present inflowdefault to 0. Negative flow values are excluded here and validated again later during Petri-net construction.- Parameters:
vertices (Iterable[str]) – Iterable of species tokens.
edges (Mapping[str, Tuple[Mapping[str, int], Mapping[str, int]]]) – Mapping from reaction token to
(tail, head)multisets.flow (Mapping[str, int]) – Requested reaction firing counts.
initial_marking (Optional[Mapping[str, int]]) – Optional initial species marking.
- Returns:
The current instance.
- Return type:
Example#
pr = PathwayRealizability().load_hypergraph_and_flow( vertices=["A", "B", "C"], edges={ "r1": ({"A": 1}, {"B": 1}), "r2": ({"B": 1}, {"C": 1}), }, flow={"r1": 1, "r2": 1}, initial_marking={"A": 1}, )
- load_syncrn_and_flow(crn: object, flow: Mapping[str, int] | None = None, *, initial_marking: Mapping[str, int] | None = None, species: str = 'label', reaction: str = 'id') PathwayRealizability[source]#
Load a SynCRN-like object together with a requested pathway flow.
The SynCRN object is tokenized via
tokenize_syncrn_incidence(). User-supplied flow and marking keys are resolved flexibly against token, internal id, label, and source node id.- Parameters:
- Returns:
The current instance.
- Return type:
Example#
pr = PathwayRealizability().load_syncrn_and_flow( syn, flow={"12": 1, "13": 1}, initial_marking={"A": 2}, species="label", reaction="id", )
- property petri: PetriNet#
Return the active Petri net.
- Returns:
Augmented Petri net for realizability checking.
- Return type:
- Raises:
RuntimeError – If the Petri net has not yet been built.
- set_initial_marking(marking: Mapping[str, int]) PathwayRealizability[source]#
Replace the user-provided initial marking.
This resets any previously built Petri-net instance, goals, and cached firing certificate.
- Parameters:
- Returns:
The current instance.
- Return type:
- summary() RealizabilitySummary[source]#
Return a compact summary of the current realizability instance.
- Returns:
Serializable instance summary.
- Return type:
Example#
info = pr.summary() print(info.active_flow)
- class synkit.CRN.Pathway.realizability.RealizabilityConfig(max_states: int = 100000, max_depth: int = 10000)[source]#
Bases:
objectConfiguration for bounded realizability search.
- Parameters:
Example#
cfg = RealizabilityConfig( max_states=200_000, max_depth=5_000, )
- class synkit.CRN.Pathway.realizability.RealizabilitySummary(n_species: int, n_reactions: int, active_flow: Dict[str, int]=<factory>, initial_marking: Dict[str, int]=<factory>, goal_exact: Dict[str, int]=<factory>, goal_atleast: Dict[str, int]=<factory>)[source]#
Bases:
objectSmall serializable summary of the active realizability instance.
- Parameters:
n_species (int) – Number of species currently loaded in the instance.
n_reactions (int) – Number of reactions currently loaded in the instance.
active_flow (Dict[str, int]) – Active reaction flow restricted to reactions with positive requested firing count.
initial_marking (Dict[str, int]) – Initial marking supplied by the user before Petri-net augmentation.
goal_exact (Dict[str, int]) – Exact target marking constraints currently imposed on the auxiliary Petri-net places.
goal_atleast (Dict[str, int]) – Lower-bound target marking constraints currently imposed on the auxiliary Petri-net places.
Example#
summary = pr.summary() print(summary.n_species) print(summary.active_flow)
- synkit.CRN.Pathway.realizability.run_realizability_from_syncrn(crn: object, flow: Mapping[str, int] | None = None, *, initial_marking: Mapping[str, int] | None = None, species: str = 'label', reaction: str = 'id', verbose: bool = True) Tuple[PathwayRealizability, Dict[str, object]][source]#
Run König-style and exact BFS realizability tests on a SynCRN-like object.
This convenience wrapper:
loads the SynCRN object and requested flow,
builds the augmented Petri net,
applies the sufficient König-style acyclicity test,
runs exact bounded BFS realizability search,
optionally prints a human-readable summary.
- Parameters:
crn (object) – SynCRN-like object.
flow (Optional[Mapping[str, int]]) – Optional requested reaction firing counts.
initial_marking (Optional[Mapping[str, int]]) – Optional initial marking.
species (str) – Species tokenization mode.
reaction (str) – Reaction tokenization mode.
verbose (bool) – Whether to print a textual summary.
- Returns:
Pair
(pathway_realizability_instance, info_dict).- Return type:
Tuple[PathwayRealizability, Dict[str, object]]
Example#
pr, info = run_realizability_from_syncrn( syn, flow={"12": 1, "13": 1}, initial_marking={"A": 2}, verbose=True, ) print(info["konig"]) print(info["bfs"]) print(info["certificate"])
- synkit.CRN.Pathway.realizability.syncrn_to_pr_inputs(crn: object, flow: Mapping[str, int] | None = None, *, initial_marking: Mapping[str, int] | None = None, species: str = 'label', reaction: str = 'id') Tuple[List[str], Dict[str, Tuple[Dict[str, int], Dict[str, int]]], Dict[str, int], Dict[str, int]][source]#
Convert a SynCRN-like object into tokenized pathway-realizability inputs.
The returned tuple contains:
species tokens,
reaction-tokenized hyperedges,
resolved flow map keyed by reaction token,
resolved initial marking keyed by species token.
- Parameters:
- Returns:
Tuple
(vertices, edges, flow_map, marking_map).- Return type:
- Tuple[
List[str], Dict[str, Tuple[Dict[str, int], Dict[str, int]]], Dict[str, int], Dict[str, int],
]
Example#
vertices, edges, flow_map, marking_map = syncrn_to_pr_inputs( syn, flow={"12": 1}, initial_marking={"A": 2}, species="label", reaction="id", )
Petri net#
- class synkit.CRN.Petrinet.analyzer.PetriAnalyzer(crn: Any, *, rtol: float = 1e-12, max_siphon_size: int | None = None)[source]#
Bases:
objectOOP wrapper for Petri-net style analysis on SynCRN-like inputs.
Accepted inputs are canonical SynCRN objects, SynCRN bipartite digraphs, and
PetriNetobjects.The analyzer caches computed results so repeated access to already computed diagnostics does not trigger recomputation.
- Parameters:
Examples#
analyzer = PetriAnalyzer(crn, rtol=1e-12, max_siphon_size=4) analyzer.compute_all() print(analyzer.summary) print(analyzer.as_dict()) print(analyzer.explain())
- as_dict() Dict[str, Any][source]#
Convert the current analyzer state into a serializable dictionary.
- Returns:
Dictionary containing cached analysis results and metadata.
- Return type:
Dict[str, Any]
Examples#
analyzer = PetriAnalyzer(crn).compute_all() payload = analyzer.as_dict() print(payload["persistence_ok"])
- check_persistence() PetriAnalyzer[source]#
Evaluate and cache the siphon-based persistence condition.
Both the boolean persistence condition and the detailed explanation structure are computed and stored.
- Returns:
The analyzer itself, enabling method chaining.
- Return type:
Examples#
analyzer = PetriAnalyzer(crn).check_persistence() print(analyzer.persistence_ok) print(analyzer.persistence_details)
- compute_all() PetriAnalyzer[source]#
Compute all supported Petri-style diagnostics.
This is equivalent to calling
compute_semiflows(),compute_siphons_traps(), andcheck_persistence()in sequence.- Returns:
The analyzer itself, enabling method chaining.
- Return type:
Examples#
analyzer = PetriAnalyzer(crn).compute_all() print(analyzer.summary)
- compute_semiflows() PetriAnalyzer[source]#
Compute and cache P-semiflows and T-semiflows.
- Returns:
The analyzer itself, enabling method chaining.
- Return type:
Examples#
analyzer = PetriAnalyzer(crn).compute_semiflows() print(analyzer.p_semiflows) print(analyzer.t_semiflows)
- compute_siphons_traps() PetriAnalyzer[source]#
Compute and cache siphons and traps.
- Returns:
The analyzer itself, enabling method chaining.
- Return type:
Examples#
analyzer = PetriAnalyzer(crn).compute_siphons_traps() print(analyzer.siphons) print(analyzer.traps)
- explain() str[source]#
Return a compact human-readable explanation of current results.
- Returns:
Summary string describing persistence and the number of computed objects, or a message indicating that no computation has been run.
- Return type:
Examples#
analyzer = PetriAnalyzer(crn).compute_all() print(analyzer.explain())
- property p_semiflows: ndarray | None#
Return cached P-semiflows.
- Returns:
Cached P-semiflow basis, or
Noneif not yet computed.- Return type:
Optional[numpy.ndarray]
- property persistence_details: PersistenceCheckResult | None#
Return cached detailed persistence analysis.
- Returns:
Cached persistence detail object, or
Noneif not yet computed.- Return type:
Optional[PersistenceCheckResult]
- property persistence_ok: bool | None#
Return cached persistence status.
- Returns:
Cached persistence status, or
Noneif not yet computed.- Return type:
Optional[bool]
- property petri: PetriNet#
Return the internal Petri-net representation.
- Returns:
Internal Petri-net view used for structural analysis.
- Return type:
- property siphons: List[Set[str]] | None#
Return cached siphons.
- Returns:
Cached siphons, or
Noneif not yet computed.- Return type:
Optional[List[Set[str]]]
- property summary: PetriSummary | None#
Return a structured summary if all diagnostics are available.
- Returns:
A
PetriSummaryif all components are computed, otherwiseNone.- Return type:
Optional[PetriSummary]
- class synkit.CRN.Petrinet.analyzer.PetriSummary(p_semiflows: ndarray, t_semiflows: ndarray, siphons: List[Set[str]], traps: List[Set[str]], persistence_ok: bool, place_order: List[str], transition_order: List[str])[source]#
Bases:
objectStructured container summarizing Petri-style SynCRN diagnostics.
- Parameters:
p_semiflows (numpy.ndarray) – Numerical basis of P-semiflows, arranged as columns.
t_semiflows (numpy.ndarray) – Numerical basis of T-semiflows, arranged as columns.
siphons (List[Set[str]]) – Detected siphons as sets of place labels.
traps (List[Set[str]]) – Detected traps as sets of place labels.
persistence_ok (bool) – Whether the tested siphon-based persistence condition is satisfied.
place_order (List[str]) – Place ordering associated with the Petri/stoichiometric representation.
transition_order (List[str]) – Transition ordering associated with the Petri/stoichiometric representation.
- p_semiflows: ndarray#
- t_semiflows: ndarray#
- class synkit.CRN.Petrinet.net.PetriNet[source]#
Bases:
objectMinimal Petri net container with marking semantics and SynCRN metadata.
Places correspond to species and transitions correspond to reactions. The class stores a lightweight Petri-net representation with utilities for adding places and transitions, checking enabledness, firing transitions, and converting between mapping-based and tuple-based markings.
Attributes#
- places:
Set of place identifiers.
- transitions:
Mapping from transition id to
Transition.- place_labels:
Optional human-readable labels for places.
- transition_labels:
Optional human-readable labels for transitions.
- place_source_node_ids:
Provenance mapping for places.
- transition_source_node_ids:
Provenance mapping for transitions.
- graph_attrs:
Graph-level metadata copied from the source.
- metadata:
Additional metadata.
Example#
net = PetriNet() net.add_place("A") net.add_place("B") net.add_transition("r1", pre={"A": 1}, post={"B": 1}) m0 = {"A": 1} assert net.enabled(m0, "r1") m1 = net.fire(m0, "r1") print(m1) # {'A': 0, 'B': 1}
- add_place(p: str, *, label: str | None = None, source_node_id: Hashable | None = None) None[source]#
Add a place to the Petri net.
If the place already exists, only optional metadata is updated.
- Parameters:
p (Place) – Place identifier.
label (Optional[str]) – Optional display label.
source_node_id (Optional[Hashable]) – Optional provenance node id from the source CRN.
- Returns:
None
- Return type:
None
- add_transition(tid: str, pre: Mapping[str, int], post: Mapping[str, int], *, label: str | None = None, source_reaction_id: str | None = None, metadata: MutableMapping[str, Any] | None = None) None[source]#
Add or replace a transition in the Petri net.
Zero or invalid non-positive weights are filtered out before storage. Any places referenced by
preorpostare created automatically.- Parameters:
tid (TransitionId) – Transition identifier.
pre (Mapping[Place, int]) – Input arc multiset mapping
place -> coefficient.post (Mapping[Place, int]) – Output arc multiset mapping
place -> coefficient.label (Optional[str]) – Optional display label.
source_reaction_id (Optional[str]) – Optional source reaction identifier.
metadata (Optional[MutableMapping[str, Any]]) – Optional metadata attached to the transition.
- Returns:
None
- Return type:
None
Example#
net.add_transition( "r1", pre={"A": 2, "B": 1}, post={"C": 1}, label="2A + B -> C", )
- enabled(marking: Mapping[str, int], tid: str) bool[source]#
Test whether a transition is enabled under a marking.
A transition is enabled if every required input place has at least the corresponding token count.
- Parameters:
marking (Marking) – Current marking as
place -> token_count.tid (TransitionId) – Transition identifier.
- Returns:
Trueif the transition is enabled, elseFalse.- Return type:
- fire(marking: Mapping[str, int], tid: str) Dict[str, int][source]#
Fire a transition and return the successor marking.
This function does not itself check enabledness. If the transition is not enabled, negative token counts may appear in the result.
- Parameters:
marking (Marking) – Current marking.
tid (TransitionId) – Transition identifier to fire.
- Returns:
Successor marking after consuming
preand producingpost.- Return type:
Dict[Place, int]
Example#
m0 = {"A": 2, "B": 1} m1 = net.fire(m0, "r1")
- classmethod from_syncrn(crn: Any) PetriNet[source]#
Build a Petri-net view directly from SynCRN incidence data.
- Parameters:
crn (Any) – SynCRN-like object or SynCRN bipartite digraph.
- Returns:
Petri net constructed from the canonical incidence view.
- Return type:
Example#
net = PetriNet.from_syncrn(crn) print(net.place_order) print(net.transition_order)
- marking_to_tuple(m: Mapping[str, int]) Tuple[int, ...][source]#
Convert a mapping-based marking into a tuple in place order.
- Parameters:
m (Marking) – Marking mapping.
- Returns:
Tuple of token counts aligned to
place_order.- Return type:
Tuple[int, …]
- place_name(p: str) str[source]#
Return the display label of a place if available.
- Parameters:
p (Place) – Place identifier.
- Returns:
Display label or the identifier itself.
- Return type:
- property place_order: List[str]#
Return places in insertion order.
- Returns:
Ordered place identifiers.
- Return type:
List[Place]
- to_pre_post() Dict[str, Any][source]#
Export the Petri net as place-indexed pre/post adjacency maps.
The returned structure is often convenient for reachability, firing, or incidence-based downstream algorithms.
- Returns:
Dictionary containing places, transitions, labels, pre/post maps, graph attributes, and metadata.
- Return type:
Dict[str, Any]
Example#
data = net.to_pre_post() print(data["pre"]) print(data["post"])
- transition_name(tid: str) str[source]#
Return the display label of a transition if available.
- Parameters:
tid (TransitionId) – Transition identifier.
- Returns:
Display label or the identifier itself.
- Return type:
- property transition_order: List[str]#
Return transitions in insertion order.
- Returns:
Ordered transition identifiers.
- Return type:
List[TransitionId]
- tuple_to_marking(values: Iterable[int]) Dict[str, int][source]#
Convert a tuple-like token vector into a sparse marking mapping.
Zero entries are omitted from the returned dictionary.
- Parameters:
values (Iterable[int]) – Iterable of token counts aligned to
place_order.- Returns:
Sparse marking mapping.
- Return type:
Dict[Place, int]
- class synkit.CRN.Petrinet.net.SynCRNIncidence(species_order: ~typing.List[str], reaction_order: ~typing.List[str], species_labels: ~typing.Dict[str, str], reaction_labels: ~typing.Dict[str, str], pre: ~typing.Dict[str, ~typing.Dict[str, int]], post: ~typing.Dict[str, ~typing.Dict[str, int]], species_source_node_ids: ~typing.Dict[str, ~typing.Hashable] = <factory>, reaction_source_node_ids: ~typing.Dict[str, ~typing.Hashable] = <factory>, graph_attrs: ~typing.Dict[str, ~typing.Any] = <factory>, metadata: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#
Bases:
objectCanonical species–reaction incidence view extracted from a SynCRN-like object.
This dataclass stores a normalized incidence representation that can be constructed either from a SynCRN-style object exposing
speciesandreactionsmappings, or from a bipartitenetworkx.DiGraphreturned bySynCRN.to_digraph().The canonical representation separates:
species order
reaction order
species and reaction labels
pre-incidence stoichiometry
post-incidence stoichiometry
source-node provenance metadata
- Parameters:
species_order (List[str]) – Ordered list of canonical species identifiers.
reaction_order (List[str]) – Ordered list of canonical reaction identifiers.
species_labels (Dict[str, str]) – Mapping from species identifier to display label.
reaction_labels (Dict[str, str]) – Mapping from reaction identifier to display label.
pre (Dict[str, Dict[str, int]]) – Mapping
reaction_id -> {species_id: stoichiometric_coefficient}for reactants / input arcs.post (Dict[str, Dict[str, int]]) – Mapping
reaction_id -> {species_id: stoichiometric_coefficient}for products / output arcs.species_source_node_ids (Dict[str, Hashable]) – Mapping from canonical species identifier to original source node id.
reaction_source_node_ids (Dict[str, Hashable]) – Mapping from canonical reaction identifier to original source node id.
graph_attrs (Dict[str, Any]) – Graph-level metadata copied from the source object or source graph.
metadata (Dict[str, Any]) – Additional extraction metadata.
Example#
incidence = SynCRNIncidence( species_order=["A", "B", "C"], reaction_order=["r1"], species_labels={"A": "A", "B": "B", "C": "C"}, reaction_labels={"r1": "A + B -> C"}, pre={"r1": {"A": 1, "B": 1}}, post={"r1": {"C": 1}}, )
- class synkit.CRN.Petrinet.net.Transition(tid: str, pre: ~typing.Dict[str, int], post: ~typing.Dict[str, int], label: str | None = None, source_reaction_id: str | None = None, metadata: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#
Bases:
objectPetri-net transition with stoichiometric input/output multisets.
A transition corresponds to one reaction node in the source SynCRN-like representation.
- Parameters:
tid (TransitionId) – Canonical transition identifier.
pre (Dict[Place, int]) – Input multiset mapping
place -> coefficient.post (Dict[Place, int]) – Output multiset mapping
place -> coefficient.label (Optional[str]) – Optional display label.
source_reaction_id (Optional[str]) – Optional source reaction identifier from the original CRN object.
metadata (Dict[str, Any]) – Optional transition metadata dictionary.
Example#
t = Transition( tid="r1", pre={"A": 1, "B": 2}, post={"C": 1}, label="A + 2B -> C", )
- synkit.CRN.Petrinet.net.extract_syncrn_incidence(crn: Any) SynCRNIncidence[source]#
Extract a canonical incidence view from a SynCRN-like object or digraph.
The function accepts three input styles:
a
networkx.DiGraphin SynCRN bipartite formata SynCRN-like object exposing
speciesandreactionsan object exposing
to_digraph()that returns such a graph
- Parameters:
crn (Any) – SynCRN-like object or bipartite digraph.
- Returns:
Canonical incidence representation.
- Return type:
- Raises:
TypeError – If the input cannot be interpreted as a supported SynCRN source.
Example#
incidence = extract_syncrn_incidence(crn) print(incidence.pre) print(incidence.post)
- class synkit.CRN.Petrinet.persistence.PersistenceCheckResult(persistence_ok: bool, siphons: List[Set[str]], semiflow_supports: List[Set[str]], uncovered_siphons: List[Set[str]])[source]#
Bases:
objectStructured result of the siphon-based persistence sufficient test.
- synkit.CRN.Petrinet.persistence.siphon_persistence_condition(crn: Any, *, rtol: float = 1e-12, max_siphon_size: int | None = None) bool[source]#
Check the Angeli–De Leenheer–Sontag siphon/P-semiflow sufficient condition.
The condition holds when every minimal siphon contains the support of some P-semiflow.
- synkit.CRN.Petrinet.persistence.siphon_persistence_details(crn: Any, *, rtol: float = 1e-12, max_siphon_size: int | None = None, support_tol: float = 1e-08) PersistenceCheckResult[source]#
Return detailed information for the siphon-based persistence test.
- synkit.CRN.Petrinet.semiflows.find_p_semiflows(crn: Any, *, rtol: float = 1e-12) ndarray[source]#
Compute P-semiflows, also called place invariants.
P-semiflows form a basis of the left kernel of the stoichiometric matrix, that is
ker(S^T). The returned matrix has shape(n_species, k), where each column is one basis vector.For SynCRN-like graph inputs, the computation delegates to
synkit.CRN.Props.stoich.left_nullspace(). For nativePetriNetinputs, the stoichiometric matrix is built locally and the null space is computed numerically.- Parameters:
crn (Any) – Petri net, SynCRN-like object, or supported bipartite graph.
rtol (float) – Relative tolerance used for null-space detection.
- Returns:
Matrix whose columns form a basis of the P-semiflow space.
- Return type:
np.ndarray
Example#
from synkit.CRN.Structure import SynCRN from synkit.CRN.Petrinet.semiflows import find_p_semiflows syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"]) basis = find_p_semiflows(syn) print(basis.shape)
- synkit.CRN.Petrinet.semiflows.find_t_semiflows(crn: Any, *, rtol: float = 1e-12) ndarray[source]#
Compute T-semiflows, also called transition invariants.
T-semiflows form a basis of the right kernel of the stoichiometric matrix, that is
ker(S). The returned matrix has shape(n_reactions, k), where each column is one basis vector.For SynCRN-like graph inputs, the computation delegates to
synkit.CRN.Props.stoich.right_nullspace(). For nativePetriNetinputs, the stoichiometric matrix is built locally and the null space is computed numerically.- Parameters:
crn (Any) – Petri net, SynCRN-like object, or supported bipartite graph.
rtol (float) – Relative tolerance used for null-space detection.
- Returns:
Matrix whose columns form a basis of the T-semiflow space.
- Return type:
np.ndarray
Example#
from synkit.CRN.Structure import SynCRN from synkit.CRN.Petrinet.semiflows import find_t_semiflows syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"]) basis = find_t_semiflows(syn) print(basis.shape)
- synkit.CRN.Petrinet.semiflows.semiflow_supports(crn: Any, *, kind: str = 'p', rtol: float = 1e-12, support_tol: float = 1e-08) List[Dict[str, float]][source]#
Return sparsified P-semiflow or T-semiflow supports.
The result is a list of sparse dictionaries, one per basis column. For P-semiflows, keys are species or place identifiers. For T-semiflows, keys are reaction or transition identifiers.
- Parameters:
crn (Any) – Petri net, SynCRN-like object, or supported bipartite graph.
kind (str) – Either
"p"for P-semiflows or"t"for T-semiflows.rtol (float) – Relative tolerance used for null-space detection.
support_tol (float) – Threshold below which basis coefficients are treated as zero when constructing sparse supports.
- Returns:
List of sparse support dictionaries.
- Return type:
- Raises:
ValueError – If
kindis not"p"or"t".
Example#
from synkit.CRN.Structure import SynCRN from synkit.CRN.Petrinet.semiflows import semiflow_supports syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"]) p_supports = semiflow_supports(syn, kind="p") t_supports = semiflow_supports(syn, kind="t") print(p_supports) print(t_supports)
- synkit.CRN.Petrinet.semiflows.stoichiometric_matrix(crn: Any) Tuple[List[str], List[str], ndarray][source]#
Return row order, column order, and stoichiometric matrix for a network.
This is a thin wrapper around
synkit.CRN.Props.stoichfor SynCRN-like graph inputs, augmented with explicit row and column orders so semiflow supports can be interpreted. For nativePetriNetinputs, the matrix is assembled directly from the transition multisets.Supported inputs include:
a
PetriNeta SynCRN-like object accepted by
synkit.CRN.Props.helper._as_graph()a NetworkX bipartite graph in SynCRN species-rule format
- Parameters:
crn (Any) – Petri net, SynCRN-like object, or supported bipartite graph.
- Returns:
Tuple
(species_order, reaction_order, S), wherespecies_orderdefines the row labels ofSandreaction_orderdefines the column labels.- Return type:
Example#
from synkit.CRN.Structure import SynCRN from synkit.CRN.Petrinet.semiflows import stoichiometric_matrix syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"]) species_order, reaction_order, S = stoichiometric_matrix(syn) print(species_order) print(reaction_order) print(S.shape)
- synkit.CRN.Petrinet.structure.find_siphons(crn: Any, *, max_size: int | None = None, names: str = 'label') List[Set[str]][source]#
Enumerate inclusion-minimal siphons of a SynCRN Petri-net view.
The search is performed by brute-force subset enumeration up to the requested size bound, followed by inclusion-minimal filtering.
- Parameters:
- Returns:
Inclusion-minimal siphons.
- Return type:
List[Set[str]]
- synkit.CRN.Petrinet.structure.find_traps(crn: Any, *, max_size: int | None = None, names: str = 'label') List[Set[str]][source]#
Enumerate inclusion-minimal traps of a SynCRN Petri-net view.
The search is performed by brute-force subset enumeration up to the requested size bound, followed by inclusion-minimal filtering.
- Parameters:
- Returns:
Inclusion-minimal traps.
- Return type:
List[Set[str]]
- synkit.CRN.Petrinet.structure.species_transition_neighborhoods(crn: Any) Dict[str, Dict[str, List[str]]][source]#
Return per-species producer and consumer transition neighborhoods.
This is a small structural helper that is often useful when debugging siphons, traps, and reachability issues.
The returned dictionary is keyed by internal place id. For each place, the value contains the display label, the transitions that produce tokens into the place, and the transitions that consume tokens from it.
Properties#
- class synkit.CRN.Props.dynamics.StructuralSingularitySummary(n_species: int, structural_rank: int, has_perfect_matching: bool, pattern_singular: bool, determinant_checked: bool, determinant_expr: Any | None = None, determinant_is_zero: bool | None = None)[source]#
Bases:
objectSummary of structural singularity diagnostics for a symbolic Jacobian.
The diagnostics are species-level because the Jacobian is a species-by-species object, even though the underlying SynCRN graph is bipartite with species nodes and rule nodes.
- Parameters:
n_species (int) – Number of species, i.e. Jacobian dimension.
structural_rank (int) – Structural rank inferred from the Jacobian sparsity pattern.
has_perfect_matching (bool) – Whether the bipartite sparsity graph admits a perfect matching.
pattern_singular (bool) – Whether the Jacobian is singular at the structural-pattern level.
determinant_checked (bool) – Whether an exact symbolic determinant was computed.
determinant_expr (Optional[Any]) – Exact symbolic determinant expression, if evaluated.
determinant_is_zero (Optional[bool]) – Whether the exact symbolic determinant simplified to zero.
Example#
summary = StructuralSingularitySummary( n_species=3, structural_rank=2, has_perfect_matching=False, pattern_singular=True, determinant_checked=False, ) print(summary.classification) print(summary.to_dict())
- property classification: str#
Return a concise structural-singularity classification label.
Possible values include pattern-level singularity, exact symbolic singularity, exact symbolic nonsingularity, or the case where only the sparsity-pattern analysis was performed.
- Returns:
Classification string summarizing the diagnostic outcome.
- Return type:
Example#
summary = StructuralSingularitySummary( n_species=4, structural_rank=4, has_perfect_matching=True, pattern_singular=False, determinant_checked=True, determinant_is_zero=False, ) print(summary.classification)
- to_dict() Dict[str, Any][source]#
Convert the summary to a plain dictionary.
Symbolic determinant expressions are stringified so the result is easier to serialize or log.
- Returns:
Plain dictionary representation of the summary.
- Return type:
Dict[str, Any]
Example#
d = summary.to_dict() print(d["classification"])
- synkit.CRN.Props.dynamics.jacobian_sign_pattern(crn: Any, *, tol: float = 1e-12) Tuple[List[Any], ndarray][source]#
Compute the structural sign pattern of the symbolic Jacobian.
Returned entries are one of:
"0""+""-""mixed"
The value
"mixed"means that multiple structurally valid paths exist with conflicting positive and negative net effects.- Parameters:
crn (Any) – SynCRN graph or SynCRN-like object in the species/rule representation.
tol (float) – Tolerance used for structural zero testing.
- Returns:
Tuple containing:
species node order,
Jacobian sign-pattern matrix.
- Return type:
Tuple[List[Any], numpy.ndarray]
Example#
species_order, P = jacobian_sign_pattern(crn) print(species_order) print(P)
- synkit.CRN.Props.dynamics.jacobian_sparsity(crn: Any, *, tol: float = 1e-12) Tuple[List[Any], ndarray][source]#
Return the boolean sparsity pattern of the symbolic Jacobian.
Entry
A[i, k]isTrueif specieskcan structurally influence speciesithrough at least one rule under the local linearized dynamics.- Parameters:
crn (Any) – SynCRN graph or SynCRN-like object in the species/rule representation.
tol (float) – Tolerance used for structural zero testing.
- Returns:
Tuple containing:
species node order,
boolean Jacobian sparsity matrix.
- Return type:
Tuple[List[Any], numpy.ndarray]
Example#
species_order, A = jacobian_sparsity(crn) print(species_order) print(A.astype(int))
- synkit.CRN.Props.dynamics.species_influence_graph(crn: Any, *, tol: float = 1e-12, use_labels: bool = False) DiGraph[source]#
Build the species influence graph induced by the symbolic Jacobian.
Nodes represent species. A directed edge
u -> vis added when speciesucan structurally influence speciesvin the local linearized dynamics.Edge attribute
signis one of:"+""-""mixed"
Additional edge attributes record the original source and target species node identifiers.
- Parameters:
- Returns:
Directed species influence graph.
- Return type:
nx.DiGraph
Example#
G_inf = species_influence_graph(crn, use_labels=True) print(G_inf.nodes(data=True)) print(G_inf.edges(data=True))
- synkit.CRN.Props.dynamics.structural_singularity_summary(crn: Any, *, tol: float = 1e-12, max_exact_size: int = 7, symbol_prefix: str = 'rprime') StructuralSingularitySummary[source]#
Diagnose structural singularity of the symbolic Jacobian.
This routine performs two levels of analysis:
structural-rank and perfect-matching diagnostics on the Jacobian sparsity pattern, and
optional exact symbolic determinant evaluation for sufficiently small systems.
Pattern-level singularity indicates that the Jacobian is singular for all admissible parameter values consistent with the sparsity structure. If the pattern is not singular, an exact determinant test may still detect symbolic cancellation and prove singularity for small systems.
- Parameters:
crn (Any) – SynCRN graph or SynCRN-like object in the species/rule representation.
tol (float) – Tolerance used for structural zero testing.
max_exact_size (int) – Maximum number of species for which the exact symbolic determinant is computed.
symbol_prefix (str) – Prefix used for symbolic reactivity variables.
- Returns:
Structured summary of Jacobian structural-singularity diagnostics.
- Return type:
- Raises:
ImportError – If exact symbolic determinant evaluation is requested but
sympyis not available.
Example#
summary = structural_singularity_summary( crn, max_exact_size=6, symbol_prefix="rprime", ) print(summary) print(summary.to_dict()) print(summary.classification)
- synkit.CRN.Props.dynamics.symbolic_jacobian(crn: Any, *, symbol_prefix: str = 'rprime', tol: float = 1e-12) Tuple[List[Any], List[Any], 'sp.Matrix'][source]#
Build the symbolic Jacobian
G = S R.Here
Sis the species-by-rule stoichiometric matrix andRis the rule-by-species symbolic reactivity matrix induced by reactant incidence. The resulting Jacobian is a species-by-species symbolic matrix describing local structural influence in the CRN dynamics.- Parameters:
crn (Any) – SynCRN graph or SynCRN-like object in the species/rule representation.
symbol_prefix (str) – Prefix used for symbolic reactivity variables.
tol (float) – Tolerance forwarded to
symbolic_reactivity_matrix().
- Returns:
Tuple containing:
species node order,
rule node order,
symbolic Jacobian
G.
- Return type:
Tuple[List[Any], List[Any], sp.Matrix]
- Raises:
ImportError – If
sympyis not available.
Example#
species_order, rule_order, G = symbolic_jacobian(crn) print(G.shape) print(G)
- synkit.CRN.Props.dynamics.symbolic_reactivity_matrix(crn: Any, *, symbol_prefix: str = 'rprime', tol: float = 1e-12) Tuple[List[Any], List[Any], 'sp.Matrix'][source]#
Build the symbolic reactivity matrix
R.For a SynCRN with
n_speciesspecies nodes andn_rulesrule nodes, the matrixRhas shape(n_rules, n_species). EntryR[j, i]is a positive symbolic variable if speciesiis a reactant of rulej, and zero otherwise.This matrix captures the structural dependence of reaction rates on species concentrations without assuming a specific kinetic law beyond positive reactant sensitivity.
- Parameters:
- Returns:
Tuple containing:
species node order,
rule node order,
symbolic reactivity matrix
R.
- Return type:
Tuple[List[Any], List[Any], sp.Matrix]
- Raises:
ImportError – If
sympyis not available.
Example#
species_order, rule_order, R = symbolic_reactivity_matrix(crn) print(species_order) print(rule_order) print(R)
- class synkit.CRN.Props.stoich.StoichSummary(n_species: int, n_reactions: int, rank: int)[source]#
Bases:
objectLightweight stoichiometric summary of a SynCRN.
The field name
n_reactionsis retained for backward compatibility even though the current SynCRN representation uses rule nodes as process columns.- Parameters:
- classmethod from_crn(crn: Any) StoichSummary[source]#
Construct a summary directly from a CRN object or graph.
- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
- Returns:
Stoichiometric summary derived from the CRN.
- Return type:
- property is_full_rank: bool#
Whether the stoichiometric matrix has full rank.
- Returns:
Truewhenrank == min(n_species, n_reactions), otherwiseFalse.- Return type:
- synkit.CRN.Props.stoich.build_S(crn: Any) Tuple[List[Any], List[Any], ndarray][source]#
Build the stoichiometric matrix
S = S^+ - S^-.- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
- Returns:
A 3-tuple
(species_order, rule_order, S)whereSis the species x rule stoichiometric matrix.- Return type:
Tuple[List[Any], List[Any], np.ndarray]
- synkit.CRN.Props.stoich.build_S_minus_plus(crn: Any) Tuple[List[Any], List[Any], ndarray, ndarray][source]#
Build the reactant matrix
S^-and product matrixS^+from a SynCRN.The input is interpreted as a bipartite species-rule incidence graph. Rows correspond to species nodes and columns correspond to rule nodes.
Graph conventions#
- Nodes:
species nodes have
kind="species"rule nodes have
kind="rule"
- Edges:
role:"reactant"or"product"stoich: stoichiometric coefficient, default1.0
Orientation#
The graph may be directed or undirected. The edge
roleattribute is treated as the source of truth, and endpoint order is not assumed to encode reactant/product direction.- param crn:
A NetworkX bipartite graph or a SynCRN-like object containing one.
- type crn:
Any
- returns:
A 4-tuple
(species_order, rule_order, S_minus, S_plus)wherespecies_orderdefines row order,rule_orderdefines column order,S_minuscontains reactant stoichiometries, andS_pluscontains product stoichiometries.- rtype:
Tuple[List[Any], List[Any], np.ndarray, np.ndarray]
- synkit.CRN.Props.stoich.integer_conservation_laws(crn: Any, *, rtol: float = 1e-12) List[List[int]][source]#
Return an approximate minimal integer basis for
ker(S^T).Each returned vector corresponds to an approximate conservation law over species, obtained by converting floating null-space basis vectors into reduced integer vectors.
- synkit.CRN.Props.stoich.left_nullspace(crn: Any, *, rtol: float = 1e-12) ndarray[source]#
Compute a basis for the left null space
ker(S^T).In CRN language, these directions correspond to conservation-law vectors over species.
- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
rtol (float) – Relative tolerance used in null-space computation.
- Returns:
Matrix whose columns form a basis of
ker(S^T).- Return type:
np.ndarray
- synkit.CRN.Props.stoich.left_right_kernels(crn: Any, *, rtol: float = 1e-12) Tuple[ndarray, ndarray][source]#
Compute both left and right kernels of the stoichiometric matrix.
- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
rtol (float) – Relative tolerance used in null-space computation.
- Returns:
Pair
(left_basis, right_basis)whereleft_basisspansker(S^T)andright_basisspansker(S).- Return type:
Tuple[np.ndarray, np.ndarray]
- synkit.CRN.Props.stoich.right_nullspace(crn: Any, *, rtol: float = 1e-12) ndarray[source]#
Compute a basis for the right null space
ker(S).In CRN or Petri-net language, these directions correspond to rule-flux modes or T-semiflows.
- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
rtol (float) – Relative tolerance used in null-space computation.
- Returns:
Matrix whose columns form a basis of
ker(S).- Return type:
np.ndarray
- synkit.CRN.Props.stoich.stoichiometric_matrix(crn: Any) ndarray[source]#
Return the species x rule stoichiometric matrix
S.- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
- Returns:
Stoichiometric matrix with species as rows and rule nodes as columns.
- Return type:
np.ndarray
- synkit.CRN.Props.stoich.stoichiometric_rank(crn: Any, *, tol: float = 1e-10) int[source]#
Compute the numerical rank of the stoichiometric matrix.
- synkit.CRN.Props.stoich.summary(crn: Any) StoichSummary[source]#
Compute a quick stoichiometric summary.
- Parameters:
crn (Any) – A NetworkX bipartite graph or a SynCRN-like object containing one.
- Returns:
Lightweight stoichiometric summary of the CRN.
- Return type:
- class synkit.CRN.Props.thermo.ThermoSummary(conservative: bool | None, consistent: bool | None, example_conservation_law: ndarray | None, irreversible_futile_cycles: bool)[source]#
Bases:
objectLightweight container summarizing thermodynamic-like stoichiometric properties of a chemical reaction network.
This dataclass gathers the main outputs of the thermo module into a single object for convenient downstream inspection, reporting, or serialization. It is intentionally compact and stores only the most interpretable summary flags and one example conservation-law vector when available.
- Parameters:
conservative (Optional[bool]) – Whether the network is conservative, i.e. whether there exists a strictly positive vector \(m > 0\) such that \(m^T S = 0\). The value may be
Noneif the check is inconclusive.consistent (Optional[bool]) – Whether the network is consistent, i.e. whether there exists a strictly positive vector \(v > 0\) such that \(S v = 0\). The value may be
Noneif the check is inconclusive.example_conservation_law (Optional[numpy.ndarray]) – Example normalized strictly positive left-kernel vector when one is found, otherwise
None.irreversible_futile_cycles (bool) – Boolean indicator of whether the right kernel \(\ker(S)\) is non-trivial. This is used here as a structural proxy for the presence of futile-cycle-like steady flux modes.
from synkit.CRN.Props.thermo import compute_thermo_summary summary = compute_thermo_summary(hg) print(summary.conservative) print(summary.consistent) print(summary.irreversible_futile_cycles) print(summary.example_conservation_law)
- synkit.CRN.Props.thermo.compute_conservativity(crn: Any, *, rtol: float = 1e-12, eps: float = 1e-08) tuple[bool | None, ndarray | None][source]#
Compute the conservativity status of a network together with an example positive conservation law when available.
This is the more informative counterpart of
is_conservative(). It checks whether there exists a strictly positive vector \(m > 0\) such that \(m^T S = 0\), and if successful it also returns one normalized example vector.- Parameters:
- Returns:
Tuple
(flag, m)whereflagis the conservativity result andmis an example normalized strictly positive conservation law if one was found, otherwiseNone.- Return type:
Tuple[Optional[bool], Optional[numpy.ndarray]]
from synkit.CRN.Props.thermo import compute_conservativity flag, m = compute_conservativity(hg) print("Conservative?", flag) if m is not None: print("Example law:", m)
- synkit.CRN.Props.thermo.compute_thermo_summary(crn: Any, *, rtol: float = 1e-12, eps: float = 1e-08) ThermoSummary[source]#
Compute a composite
ThermoSummarydescribing key thermodynamic-like and structural stoichiometric properties of a chemical reaction network.This helper combines the main thermo-related analyses into a single call:
conservativity: whether there exists a strictly positive vector
\(m > 0\) such that \(m^T S = 0\), - consistency: whether there exists a strictly positive flux vector \(v > 0\) such that \(S v = 0\), - irreversible futile-cycle proxy: whether the right kernel \(\ker(S)\) is non-trivial, - example conservation law: one normalized strictly positive left-kernel vector, when such a vector can be found.
The returned summary is intended as a lightweight diagnostic object for quick inspection of CRN thermodynamic structure without calling each helper individually.
- Parameters:
crn (Any) – Hypergraph or bipartite NetworkX graph representing the chemical reaction network.
rtol (float) – Relative tolerance used in nullspace-based computations, especially when estimating kernel dimensions or checking whether the right kernel is non-trivial.
eps (float) – Absolute positivity threshold used when testing whether a candidate conservation law or flux mode is strictly positive.
- Returns:
A
ThermoSummaryinstance containing conservativity, consistency, an optional example positive conservation law, and a Boolean indicator for non-trivial steady-state flux cycles.- Return type:
from synkit.CRN.Props.thermo import compute_thermo_summary summary = compute_thermo_summary(hg) print("Conservative:", summary.conservative) print("Consistent:", summary.consistent) print("Has futile-cycle proxy:", summary.irreversible_futile_cycles) if summary.example_conservation_law is not None: print("Example conservation law:", summary.example_conservation_law)
Note
The field
irreversible_futile_cyclesis used here as a structural proxy based on the existence of nonzero vectors in \(\ker(S)\). It should be interpreted as a stoichiometric indicator rather than as a full mechanistic proof of thermodynamic infeasibility.
- synkit.CRN.Props.thermo.has_irreversible_futile_cycles(crn: Any, *, rtol: float = 1e-12) bool[source]#
Check whether the network admits non-trivial steady-state flux modes.
This function tests whether the right kernel \(\ker(S)\) is non-trivial, i.e. whether there exists a nonzero vector \(v\) such that
\[S v = 0.\]A non-trivial right kernel indicates the presence of flux-mode-like directions that do not change net species amounts. In this module, this is used as a structural proxy for irreversible futile cycles, although it should be interpreted cautiously as a stoichiometric indicator rather than a full mechanistic proof.
- Parameters:
crn (Any) – Hypergraph or bipartite NetworkX graph representing the chemical reaction network.
rtol (float) – Relative tolerance used in the nullspace computation.
- Returns:
Trueif \(\ker(S)\) is non-trivial, otherwiseFalse.- Return type:
from synkit.CRN.Props.thermo import has_irreversible_futile_cycles has_cycles = has_irreversible_futile_cycles(hg) print("Has futile-cycle-like modes?", has_cycles)
- synkit.CRN.Props.thermo.is_conservative(crn: Any, *, eps: float = 1e-08, rtol: float = 1e-12) bool | None[source]#
Check whether the chemical reaction network is conservative.
A network is called conservative here if there exists a strictly positive vector \(m > 0\) such that
\[m^T S = 0,\]where \(S\) is the stoichiometric matrix. Such a vector can be interpreted as a positive conservation law over species.
This function returns only the Boolean-style status of the check. Use
compute_conservativity()when an example conservation-law vector is also desired.- Parameters:
- Returns:
Trueif a strictly positive conservation law exists,Falseif no such law exists,Noneif the result is inconclusive.
- Return type:
Optional[bool]
from synkit.CRN.Props.thermo import is_conservative flag = is_conservative(hg) print("Conservative?", flag)
- synkit.CRN.Props.thermo.is_consistent(crn: Any, *, eps: float = 1e-08) bool | None[source]#
Check whether the chemical reaction network is consistent.
Consistency is tested here by asking whether there exists a strictly positive flux vector \(v > 0\) such that
\[S v = 0,\]where \(S\) is the stoichiometric matrix. In CRN terminology, this corresponds to the existence of a strictly positive right-kernel vector, or equivalently a positive T-semiflow.
If SciPy is available, the function attempts a linear-programming check. Otherwise it falls back to a nullspace-based heuristic.
- Parameters:
crn (Any) – Hypergraph or bipartite NetworkX graph representing the chemical reaction network.
eps (float) – Absolute lower bound used to enforce strict positivity of candidate flux vectors.
- Returns:
Trueif a strictly positive right-kernel vector exists,Falseif no such vector exists,Noneif the result is inconclusive.
- Return type:
Optional[bool]
from synkit.CRN.Props.thermo import is_consistent flag = is_consistent(hg) print("Consistent?", flag)
- synkit.CRN.Props.thermo.left_nullspace_from_matrix(S: ndarray, *, rtol: float = 1e-12) ndarray[source]#
Compute a basis for the left kernel \(\ker(S^T)\) directly from a stoichiometric matrix.
This helper is a matrix-level analogue of the graph-based nullspace functions in
stoich. It is useful when the stoichiometric matrix is already available and one wants to avoid reconstructing it from the CRN representation.If SciPy is available, the function uses
scipy.linalg.null_space(). Otherwise it falls back to an SVD-based implementation using NumPy.- Parameters:
S (numpy.ndarray) – Stoichiometric matrix of shape
(n_species, n_reactions).rtol (float) – Relative tolerance used to determine the effective numerical rank in the nullspace computation.
- Returns:
Matrix whose columns form a basis for \(\ker(S^T)\). The returned array has shape
(n_species, k), wherekis the dimension of the left kernel.- Return type:
numpy.ndarray
import numpy as np from synkit.CRN.Props.thermo import left_nullspace_from_matrix S = np.array([[-1.0], [1.0]]) L = left_nullspace_from_matrix(S) print(L.shape)
Query#
- class synkit.CRN.Query.kegg_api.KEGGClient(base_url: str = 'https://rest.kegg.jp', timeout: float = 60.0)[source]#
Bases:
objectLightweight REST client for the KEGG API.
This client provides a minimal wrapper around the KEGG REST interface and returns raw response text for a requested endpoint.
Example#
client = KEGGClient( base_url="https://rest.kegg.jp", timeout=30.0, ) text = client.get_text("get/hsa00010")
- get_optional_text(path: str) str | None[source]#
Send a GET request and return the response text when available.
Unlike
get_text(), this method suppressesrequests.HTTPErrorand returnsNonefor HTTP-level failures such as404 Not Found.- Parameters:
path (str) – Relative KEGG REST path.
- Returns:
Response text if the request succeeds, otherwise
Nonewhen an HTTP error occurs.- Return type:
Optional[str]
- Raises:
requests.RequestException – Raised for non-HTTP request failures, such as connection errors or timeouts.
Example#
client = KEGGClient() maybe_text = client.get_optional_text("get/hsa00010") if maybe_text is not None: print(maybe_text[:200])
- get_text(path: str) str[source]#
Send
GET <base_url>/<path>and return the response body as text.- Parameters:
path (str) – Relative KEGG REST path, for example
"get/hsa00010".- Returns:
Raw text returned by the KEGG REST API.
- Return type:
- Raises:
requests.HTTPError – Raised when the server responds with an HTTP error status.
requests.RequestException – Raised for transport-level request failures.
Example#
client = KEGGClient() entry_text = client.get_text("get/hsa00010")
- class synkit.CRN.Query.kegg_extract.KEGGExtractor(client: KEGGClient | None = None, mapper_cls: type[Any] | None = None)[source]#
Bases:
objectHigh-level extractor for KEGG pathway and module reaction data.
This class orchestrates KEGG entry retrieval, module membership parsing, reaction equation collection, compound-table construction, reaction SMILES assembly, and optional atom mapping.
- Parameters:
client (Optional[KEGGClient]) – Optional KEGG REST client. When omitted, a default
KEGGClientinstance is created during__post_init__().mapper_cls (Optional[type[Any]]) – Optional atom-mapper class used by
atom_map_reactions(). The class must be instantiable without arguments and must provideget_attention_guided_atom_maps.
Example#
extractor = KEGGExtractor() data = extractor.build_module_json( "M00001", with_compounds=True, with_atom_maps=False, )
- atom_map_reactions(reaction_smiles_by_id: Mapping[str, str]) dict[str, str | None][source]#
Atom-map reaction SMILES using RXNMapper.
- Parameters:
reaction_smiles_by_id (Mapping[str, str]) – Mapping
{reaction_id: reaction_smiles}.- Returns:
Mapping
{reaction_id: mapped_reaction_smiles_or_none}.- Return type:
Example#
mapped = extractor.atom_map_reactions({"R00001": "CCO>>CC=O"})
- build_compound_table(compound_ids: list[str]) dict[str, dict[str, Any]][source]#
Build a compound table for a list of KEGG compound identifiers.
Each returned record includes the KEGG compound identifier, the primary compound name, the optional MOL block, and a canonical SMILES string derived from the MOL block when RDKit parsing succeeds.
- Parameters:
- Returns:
Compound table of the form
{cid: {"id", "name", "smiles", "molblock"}}.- Return type:
Example#
compounds = extractor.build_compound_table(["C00001", "C00002"])
- build_kegg_json(equations_by_rid: dict[str, str | None], *, smiles_by_rid: Mapping[str, str] | None = None, rules_by_rid: Mapping[str, str | None] | None = None, molecules_by_cid: Mapping[str, Mapping[str, Any]] | None = None) dict[str, Any][source]#
Build a compact KEGG JSON block with reactions and molecules.
- Parameters:
equations_by_rid (dict[str, Optional[str]]) – Reaction equations keyed by reaction identifier.
smiles_by_rid (Optional[Mapping[str, str]]) – Optional reaction SMILES keyed by reaction identifier.
rules_by_rid (Optional[Mapping[str, Optional[str]]]) – Optional atom-mapped reaction strings keyed by reaction identifier.
molecules_by_cid (Optional[Mapping[str, Mapping[str, Any]]]) – Optional molecule table keyed by compound identifier.
- Returns:
Dictionary with
"reactions"and"molecules"entries.- Return type:
Example#
data = extractor.build_kegg_json(equations_by_rid)
- build_missing_compound_report(equations_by_rid: dict[str, str | None], compounds_by_cid: Mapping[str, Mapping[str, Any]]) dict[str, Any][source]#
Build a report for compounds lacking SMILES.
- Parameters:
- Returns:
Report containing missing compounds and per-reaction provenance.
- Return type:
Example#
report = extractor.build_missing_compound_report( equations_by_rid, compounds_by_cid, )
- build_module_json(module_id: str, *, with_compounds: bool = True, with_atom_maps: bool = True, save_as: str | None = None) dict[str, Any][source]#
Build a JSON block for a KEGG module.
- Parameters:
- Returns:
Module JSON dictionary.
- Return type:
Example#
data = extractor.build_module_json( "M00001", with_compounds=True, with_atom_maps=False, )
- build_pathway_json(pathway_id: str, *, with_compounds: bool = True, with_atom_maps: bool = True, save_as: str | None = None) dict[str, Any][source]#
Build a JSON block for a KEGG pathway, organized by module.
- Parameters:
- Returns:
Pathway JSON dictionary.
- Return type:
Example#
data = extractor.build_pathway_json( "hsa00010", with_compounds=True, with_atom_maps=False, )
- build_reaction_smiles_dict(parsed_by_rid: Mapping[str, Any], compounds_by_cid: Mapping[str, Mapping[str, Any]]) tuple[dict[str, str], dict[str, dict[str, list[str]]]][source]#
Build reaction SMILES strings for parsed KEGG equations.
- Parameters:
- Returns:
Tuple
(reaction_smiles_by_id, missing_by_id).- Return type:
Example#
rsmi_by_rid, missing = extractor.build_reaction_smiles_dict( parsed_by_rid, compounds_by_cid, )
- client: KEGGClient | None#
- get_compound_molblock(compound_id: str) str | None[source]#
Retrieve the KEGG MOL block for a compound.
- Parameters:
compound_id (str) – KEGG compound identifier.
- Returns:
MOL block text when available, otherwise
None.- Return type:
Optional[str]
Example#
molblock = extractor.get_compound_molblock("C00001")
- get_compound_name(compound_id: str) str | None[source]#
Retrieve the primary KEGG compound name.
When multiple synonyms are present in the
NAMEfield, only the first entry is returned.- Parameters:
compound_id (str) – KEGG compound identifier such as
"C00001".- Returns:
Primary compound name if available, otherwise
None.- Return type:
Optional[str]
Example#
name = extractor.get_compound_name("C00001")
- get_equation_for_reaction(reaction_id: str) str | None[source]#
Fetch the KEGG equation string for a reaction.
- Parameters:
reaction_id (str) – KEGG reaction identifier such as
"R00200".- Returns:
Equation string when present, otherwise
None.- Return type:
Optional[str]
Example#
equation = extractor.get_equation_for_reaction("R00200")
- get_module_equations(module_id: str) dict[str, str | None][source]#
Build a reaction-to-equation mapping for a KEGG module.
- Parameters:
module_id (str) – KEGG module identifier.
- Returns:
Mapping from reaction identifier to equation string.
- Return type:
Example#
equations = extractor.get_module_equations("M00001")
- get_modules_from_pathway(pathway_id: str) list[str][source]#
Extract module IDs from a KEGG pathway entry.
- Parameters:
pathway_id (str) – KEGG pathway identifier such as
"hsa00010".- Returns:
Canonical KEGG module identifiers such as
["M00001", "M00002"].- Return type:
Example#
modules = extractor.get_modules_from_pathway("hsa00010")
- get_pathway_equations(pathway_id: str) dict[str, dict[str, str | None]][source]#
Build nested module/reaction equation mappings for a pathway.
- Parameters:
pathway_id (str) – KEGG pathway identifier.
- Returns:
Mapping of the form
{module_id: {reaction_id: equation}}.- Return type:
Example#
nested = extractor.get_pathway_equations("hsa00010")
- get_reaction_ids_from_module(module_id: str) list[str][source]#
Collect KEGG reaction IDs from a module entry, preserving module order when directional REACTION lines can be parsed.
- Parameters:
module_id (str) – KEGG module identifier such as
"M00001".- Returns:
Sorted unique KEGG reaction identifiers.
- Return type:
Example#
reaction_ids = extractor.get_reaction_ids_from_module("M00001")
- class synkit.CRN.Query.kegg_impute.KEGGImputer(extractor: KEGGExtractor | None = None)[source]#
Bases:
objectImpute missing compound SMILES and repair reaction records in KEGG-style module or pathway JSON blocks.
The imputer supports two fix types through the same
fixesargument:molecule fixes, for example
{"id": "C00404a", "smiles": "..."}reaction fixes, for example
{"id": "R02189", "reaction": "C00404 + C00267 <=> C00404a + C00668"}
Reaction fixes are applied first, then molecule fixes are applied, and finally impacted reaction SMILES, atom-mapped rules, and missing-compound summaries are rebuilt.
- Parameters:
extractor (Optional[KEGGExtractor]) – Optional high-level KEGG extractor used for atom-mapping utilities and missing-compound report generation. When omitted, a default
KEGGExtractorinstance is created.
Example#
imputer = KEGGImputer() updated = imputer.impute_module( module_data, fixes=[ { "id": "R02189", "reaction": "C00404 + C00267 <=> C00404a + C00668", }, { "id": "C00404a", "name": "Polyphosphate fragment", "smiles": "O=P(O)(O)OP(=O)(O)O", }, ], )
- extractor: KEGGExtractor | None = None#
- impute_module(module_data: Dict[str, Any], fixes: List[Dict[str, str]], save_as: str | None = None, *, molecule_id_key: str = 'id', reaction_id_key: str = 'id', equation_key: str = 'reaction', reaction_smiles_key: str = 'smiles', reaction_rule_key: str = 'rule') Dict[str, Any][source]#
Apply molecule and reaction fixes to a module JSON block.
Reaction fixes are applied first, then molecule fixes are applied, then impacted reaction SMILES and atom-mapped rules are rebuilt, and finally the
missingblock is regenerated by delegating toKEGGExtractor.build_missing_compound_report().- Parameters:
module_data (Dict[str, Any]) – Module JSON dictionary.
fixes (List[Dict[str, str]]) – List of mixed fix records. Reaction fixes must contain the reaction identifier key and the equation key. Molecule fixes use molecule identifiers and optional
"name"/"smiles"fields.save_as (Optional[str]) – Optional output path.
molecule_id_key (str) – Molecule identifier key.
reaction_id_key (str) – Reaction identifier key.
equation_key (str) – Equation text key.
reaction_smiles_key (str) – Reaction SMILES field key.
reaction_rule_key (str) – Atom-mapped rule field key.
- Returns:
Updated module JSON dictionary.
- Return type:
Dict[str, Any]
Example#
updated = imputer.impute_module( module_data, fixes=[ { "id": "R02189", "reaction": "C00404 + C00267 <=> C00404a + C00668", }, { "id": "C00404a", "name": "Polyphosphate fragment", "smiles": "O=P(O)(O)OP(=O)(O)O", }, ], )
- impute_pathway(pathway_data: Dict[str, Any], fixes: List[Dict[str, str]], save_as: str | None = None, *, molecule_id_key: str = 'id', reaction_id_key: str = 'id', equation_key: str = 'reaction', reaction_smiles_key: str = 'smiles', reaction_rule_key: str = 'rule') Dict[str, Any][source]#
Apply molecule and reaction fixes across all modules in a pathway JSON block.
Each module is processed independently through
impute_module(), then the pathway-levelmissingsummary is rebuilt by aggregating the updated module summaries.- Parameters:
pathway_data (Dict[str, Any]) – Pathway JSON dictionary with
"by_module".fixes (List[Dict[str, str]]) – Mixed reaction and molecule fix records.
save_as (Optional[str]) – Optional output path.
molecule_id_key (str) – Molecule identifier key.
reaction_id_key (str) – Reaction identifier key.
equation_key (str) – Equation text key.
reaction_smiles_key (str) – Reaction SMILES field key.
reaction_rule_key (str) – Atom-mapped rule field key.
- Returns:
Updated pathway JSON dictionary.
- Return type:
Dict[str, Any]
Example#
updated = imputer.impute_pathway( pathway_data, fixes=[ { "id": "R02189", "reaction": "C00404 + C00267 <=> C00404a + C00668", }, { "id": "C00404a", "name": "Polyphosphate fragment", "smiles": "O=P(O)(O)OP(=O)(O)O", }, ], )
- class synkit.CRN.Query.kegg_parse.KEGGEquation(reactants: list[tuple[str, int]], products: list[tuple[str, int]], reversible: bool)[source]#
Bases:
objectStructured representation of a parsed KEGG reaction equation.
- Parameters:
Example#
equation = KEGGEquation( reactants=[("C00001", 1), ("C00002", 2)], products=[("C00008", 1)], reversible=False, )
- synkit.CRN.Query.kegg_parse.equation_to_text(parsed: KEGGEquation, arrow: str | None = None) str[source]#
Convert KEGGEquation back to text, optionally forcing the arrow from the module hint.
- synkit.CRN.Query.kegg_parse.expand_stoichiometry(items: Sequence[tuple[str, int]]) list[str][source]#
Expand stoichiometric pairs into repeated KEGG compound identifiers.
For example,
[("C00001", 2), ("C00002", 1)]becomes["C00001", "C00001", "C00002"].- Parameters:
items (Sequence[tuple[str, int]]) – Compound/coefficient pairs.
- Returns:
Expanded compound identifier list.
- Return type:
Example#
expanded = expand_stoichiometry([("C00001", 2), ("C00002", 1)])
- synkit.CRN.Query.kegg_parse.get_compound_ids_from_equations(equations_by_rid: Mapping[str, str | None]) tuple[list[str], dict[str, KEGGEquation]][source]#
Collect all compound identifiers appearing across KEGG reaction equations.
Empty or missing equation strings are skipped.
- Parameters:
equations_by_rid (Mapping[str, Optional[str]]) – Mapping from reaction identifier to KEGG equation string.
- Returns:
A tuple containing the sorted unique compound identifiers and the parsed equations keyed by reaction identifier.
- Return type:
Example#
compound_ids, parsed = get_compound_ids_from_equations( {"R00001": "C00001 + C00002 => C00003"} )
- synkit.CRN.Query.kegg_parse.get_compound_ids_from_text(text: str) list[str][source]#
Extract sorted unique KEGG compound identifiers from free text.
- Parameters:
text (str) – Source text that may contain KEGG compound identifiers.
- Returns:
Sorted unique KEGG compound identifiers.
- Return type:
Example#
ids = get_compound_ids_from_text("C00001 and C00002 appear here")
- synkit.CRN.Query.kegg_parse.molblock_to_smiles(molblock: str | None) str | None[source]#
Convert a MOL block into canonical RDKit SMILES.
- Parameters:
molblock (Optional[str]) – MOL block text, typically retrieved from a KEGG compound record.
- Returns:
Canonical RDKit SMILES when parsing succeeds, otherwise
None.- Return type:
Optional[str]
Example#
smiles = molblock_to_smiles(molblock_text)
- synkit.CRN.Query.kegg_parse.normalize_module_id(module_id: str) str | None[source]#
Normalize a token to canonical KEGG module form.
Supported examples include strings such as
"hsa_M00001"and"M00001", both of which normalize to"M00001".- Parameters:
module_id (str) – Raw module token or containing text.
- Returns:
Canonical KEGG module identifier, or
Nonewhen no module identifier is present.- Return type:
Optional[str]
Example#
canonical = normalize_module_id("hsa_M00001")
- synkit.CRN.Query.kegg_parse.orient_equation_to_module(parsed: KEGGEquation, left_ids: list[str], right_ids: list[str]) KEGGEquation[source]#
Orient a parsed KEGG equation according to module direction.
- synkit.CRN.Query.kegg_parse.parse_equation(equation: str) KEGGEquation[source]#
Parse a KEGG equation string into reactants, products, and arrow type.
Supported arrows are
<=>,<->,=>,->,<=, and<-.- Parameters:
equation (str) – KEGG equation string.
- Returns:
Parsed equation object.
- Return type:
- Raises:
ValueError – Raised when the equation does not contain a supported KEGG arrow.
Example#
parsed = parse_equation("C00001 + C00002 <=> C00003")
- synkit.CRN.Query.kegg_parse.parse_kegg_field_blocks(text: str, field: str) list[str][source]#
Extract payloads from a KEGG flatfile field, including continuation lines.
Continuation lines are recognized as lines beginning with spaces or tabs and are concatenated to the payload of the preceding field occurrence.
- param text:
Raw KEGG flatfile text.
- type text:
str
- param field:
Flatfile field name such as
"MODULE","REACTION","EQUATION", or"NAME".- type field:
str
- returns:
One payload string per matching field occurrence.
- rtype:
list[str]
text = ( "MODULE M00001 Glycolysis
- “
“ continuation line
- “
) payloads = parse_kegg_field_blocks(text, “MODULE”)
- synkit.CRN.Query.kegg_parse.parse_module_reaction_directions(text: str) dict[str, tuple[list[str], list[str], str]][source]#
Parse directional hints from a KEGG MODULE entry.
Returns#
- dict
Mapping: {
reaction_id: (left_compound_ids, right_compound_ids, arrow)
}
- synkit.CRN.Query.kegg_parse.parse_side(side: str) list[tuple[str, int]][source]#
Parse one side of a KEGG equation into compound/stoichiometry pairs.
For example,
"2 C00139 + C00001"becomes[("C00139", 2), ("C00001", 1)].- Parameters:
side (str) – One side of a KEGG equation.
- Returns:
Parsed
(compound_id, coefficient)pairs.- Return type:
- Raises:
ValueError – Raised when any term does not match KEGG compound-stoichiometry syntax.
Example#
items = parse_side("2 C00139 + C00001")
- synkit.CRN.Query.kegg_parse.reaction_smiles_from_equation(parsed_equation: KEGGEquation, compounds_by_cid: Mapping[str, Mapping[str, Any]]) tuple[str, dict[str, list[str]]][source]#
Build reaction SMILES from a parsed KEGG equation and compound table.
Stoichiometric multiplicities are expanded into repeated SMILES fragments. Missing compounds are reported separately for reactants and products.
- Parameters:
parsed_equation (KEGGEquation) – Parsed KEGG equation object.
compounds_by_cid (Mapping[str, Mapping[str, Any]]) – Compound table keyed by KEGG compound identifier. Each record should provide a
"smiles"entry.
- Returns:
Tuple
(reaction_smiles, missing)wheremissingcontains lists of unresolved reactant and product KEGG compound identifiers.- Return type:
Example#
parsed = parse_equation("C00001 + C00002 => C00003") reaction_smiles, missing = reaction_smiles_from_equation( parsed, { "C00001": {"smiles": "O"}, "C00002": {"smiles": "CCO"}, "C00003": {"smiles": "CC(=O)O"}, }, )
Symmetry#
- class synkit.CRN.Symmetry.automorphism.CRNAutomorphism(source: Any, *, include_rule: bool = True, include_stoich: bool = True, wl_iters: int = 20, wl_digest_size: int = 16, config: SymmetryConfig | None = None)[source]#
Bases:
objectExact automorphism analysis for a chemical reaction network graph.
This class provides a convenient public interface for exact automorphism queries, orbit extraction, and quick nontrivial-symmetry checks. When possible, it reuses an existing exact canonicalization engine so that canonicalization and automorphism queries share the same cached search.
- Parameters:
source (Any) – Input source. This may be: - a CRN-like object - a NetworkX graph - an existing
CRNCanonicalizer- an existingIRCanonicalEngineinclude_rule (bool) – Whether rule/reaction nodes should be included when constructing the internal graph representation.
include_stoich (bool) – Whether stoichiometric information should be included in the internal representation.
wl_iters (int) – Maximum number of Weisfeiler-Lehman refinement iterations.
wl_digest_size (int) – Digest size used by the WL canonicalizer.
config (Optional[SymmetryConfig]) – Symmetry configuration controlling semantic versus topological matching. If
None,SymmetryConfig.semantic()is used.
Notes#
For best performance, construct a
CRNCanonicalizerfirst and pass it here so canonicalization and automorphism queries reuse the same cached exact search engine.Examples#
from synkit.CRN.Sym.auto import CRNAutomorphism auto = CRNAutomorphism(crn) print(auto.has_nontrivial_automorphism()) print(auto.orbits()) summary = auto.summary(max_count=50, timeout_sec=10.0) print(summary.automorphism_count)
- property G: DiGraph#
Return the internal directed graph used for analysis.
- Returns:
Internal directed graph.
- Return type:
nx.DiGraph
- automorphisms_iter(*, max_count: int | None = None, timeout_sec: float | None = None) Iterator[Dict[Any, Any]][source]#
Iterate over sampled automorphism mappings.
This method delegates to the exact IR engine and yields the sampled automorphism mappings that were collected during the search.
- Parameters:
- Yields:
Automorphism mappings as
node -> nodedictionaries.- Return type:
Iterator[Dict[Any, Any]]
Examples#
auto = CRNAutomorphism(crn) for mapping in auto.automorphisms_iter(max_count=5): print(mapping)
- has_nontrivial_automorphism(*, timeout_sec: float | None = 5.0) bool[source]#
Check whether the graph has a nontrivial automorphism.
A fast WL-based orbit test is used first. If WL leaves no ambiguous cells, the graph is treated as having no nontrivial automorphism. Otherwise, an exact search is run and stopped after two equivalent automorphisms are found.
- orbits(*, max_count: int = 1000, timeout_sec: float | None = 5.0) List[Set[Any]][source]#
Compute orbit classes from sampled automorphisms.
- synkit.CRN.Symmetry.automorphism.detect_automorphisms(source: Any, *, max_count: int = 100, timeout_sec: float | None = 5.0, **kwargs: Any) AutomorphismResult[source]#
Convenience wrapper for automorphism detection.
- Parameters:
source (Any) – Input source, canonicalizer, or engine.
max_count (int) – Maximum number of sampled mappings to retain.
timeout_sec (Optional[float]) – Optional timeout in seconds.
kwargs (Any) – Additional keyword arguments forwarded to
CRNAutomorphism.
- Returns:
Automorphism summary result.
- Return type:
AutomorphismResult
Examples#
result = detect_automorphisms(crn, max_count=50, timeout_sec=10.0) print(result.automorphism_count) print(result.orbits)
- class synkit.CRN.Symmetry.canon.CRNCanonicalizer(source: Any, *, include_rule: bool = True, include_stoich: bool = True, wl_iters: int = 20, wl_digest_size: int = 16, config: SymmetryConfig | None = None)[source]#
Bases:
objectExact canonicalizer and symmetry analyzer backed by one shared IR engine.
This is the preferred high-level entry point when a chemical reaction network or related graph-like source needs both:
a canonical form
exact automorphism information
orbit information for symmetric nodes
The class combines a fast Weisfeiler–Lehman (WL) based pre-analysis with an exact IR-based canonicalization backend. The underlying exact engine is shared across methods so intermediate work can be reused.
- Parameters:
source (Any) – Input object to canonicalize. This is typically a SynCRN-like object or a graph representation accepted by the internal canonicalization engine.
include_rule (bool) – Whether rule / reaction nodes should be included explicitly in the canonicalization model.
include_stoich (bool) – Whether stoichiometric information should be included in the canonical representation and symmetry analysis.
wl_iters (int) – Number of WL refinement iterations used by the approximate canonicalizer.
wl_digest_size (int) – Digest size used for WL hashing.
config (Optional[SymmetryConfig]) – Optional symmetry / semantic configuration. If
None, a semantic default configuration is used.
Example#
canon = CRNCanonicalizer( syncrn, include_rule=True, include_stoich=True, ) key = canon.canonical_key() orbits = canon.orbits() has_symmetry = canon.has_nontrivial_automorphism()
- property G: DiGraph#
Return the internal directed graph used by the exact engine.
- Returns:
Internal graph representation.
- Return type:
nx.DiGraph
- automorphism_result(*, max_count: int = 100, timeout_sec: float | None = 5.0)[source]#
Return the exact automorphism analysis result.
The returned object depends on the internal engine and usually contains automorphism count, sample permutations, sample mappings, orbit information, and timing metadata.
- canonical_graph(*, timeout_sec: float | None = None) DiGraph[source]#
Return a canonically relabeled graph.
Nodes are relabeled according to the exact canonical order using consecutive integer labels starting from 1.
- Parameters:
timeout_sec (Optional[float]) – Optional timeout in seconds.
- Returns:
Canonically relabeled copy of the internal graph.
- Return type:
nx.DiGraph
Example#
g_canon = canon.canonical_graph() print(g_canon.nodes())
- canonical_key(*, timeout_sec: float | None = None)[source]#
Return the exact canonical key.
The exact type depends on the underlying canonical engine.
- Parameters:
timeout_sec (Optional[float]) – Optional timeout in seconds.
- Returns:
Canonical key representing the isomorphism class of the source.
- canonical_order(*, timeout_sec: float | None = None) List[Any][source]#
Return the exact canonical node order.
- Parameters:
timeout_sec (Optional[float]) – Optional timeout in seconds.
- Returns:
Canonical ordering of nodes.
- Return type:
List[Any]
- canonical_result(*, timeout_sec: float | None = None) CanonicalResult[source]#
Compute or retrieve the exact canonicalization result.
This method delegates to the shared exact engine and returns the full canonicalization result object, which typically includes the canonical order, canonical key, and timing information.
- Parameters:
timeout_sec (Optional[float]) – Optional timeout in seconds for the exact canonicalization search. If
None, the engine default behavior is used.- Returns:
Exact canonicalization result.
- Return type:
CanonicalResult
Example#
res = canon.canonical_result(timeout_sec=5.0) print(res.canonical_order) print(res.canonical_key)
- property engine: IRCanonicalEngine#
Return the shared exact IR canonicalization engine.
- Returns:
Exact canonicalization / symmetry engine.
- Return type:
IRCanonicalEngine
- property graph_type: str#
Return a string describing the interpreted graph type.
- Returns:
Graph type label reported by the engine.
- Return type:
- has_nontrivial_automorphism(*, timeout_sec: float | None = 5.0) bool[source]#
Test whether the source has a nontrivial automorphism.
A fast WL orbit partition is used as an early filter. If all WL orbits are singletons, the method immediately returns
False. Otherwise an exact search is performed and the source is considered symmetric if the automorphism count is greater than 1.- Parameters:
timeout_sec (Optional[float]) – Timeout in seconds for the exact symmetry check.
- Returns:
Trueif a non-identity automorphism exists, elseFalse.- Return type:
Example#
if canon.has_nontrivial_automorphism(): print("Symmetry detected")
- orbits(*, max_count: int = 1000, timeout_sec: float | None = 5.0) List[Set[Any]][source]#
Return exact node orbits under the automorphism group.
Nodes are in the same orbit if an automorphism can map one node to the other.
- Parameters:
- Returns:
List of exact orbit sets.
- Return type:
List[Set[Any]]
Example#
for orbit in canon.orbits(): print(sorted(orbit))
- summary(*, max_count: int = 100, timeout_sec: float | None = 5.0, include_automorphisms: bool = True) Dict[str, Any][source]#
Return a summary dictionary for canonicalization and symmetry analysis.
If
include_automorphismsisTrue, the summary includes exact automorphism information, sample permutations, orbit data, and early-stop metadata. Otherwise only canonicalization data is returned.- Parameters:
- Returns:
Summary dictionary containing canonical and optionally symmetry information.
- Return type:
Dict[str, Any]
Example#
info = canon.summary(include_automorphisms=True) print(info["canonical_key"]) print(info["automorphism_count"])
- wl_orbits() List[Set[Any]][source]#
Return WL-refined approximate orbit classes.
These are not guaranteed to equal the exact automorphism orbits, but they are often useful as a fast symmetry approximation or as a filter before running exact search.
- Returns:
Approximate orbit partition from WL refinement.
- Return type:
List[Set[Any]]
- synkit.CRN.Symmetry.canon.canonical(source: Any, **kwargs: Any) DiGraph[source]#
Return the canonically relabeled graph for a source object.
This is a convenience wrapper around
CRNCanonicalizer.- Parameters:
source (Any) – Input object to canonicalize.
kwargs (Any) – Additional keyword arguments forwarded to
CRNCanonicalizer.
- Returns:
Canonically relabeled directed graph.
- Return type:
nx.DiGraph
Example#
g_canon = canonical( syncrn, include_rule=True, include_stoich=True, )
- class synkit.CRN.Symmetry.isomorphism.CRNIsomorphism(source: Any, *, include_rule: bool = True, include_stoich: bool = True, wl_iters: int = 20, wl_digest_size: int = 16, config: SymmetryConfig | None = None)[source]#
Bases:
objectPairwise graph isomorphism and subgraph isomorphism for CRN graphs.
This class wraps a CRN graph representation together with the node and edge matchers required for exact VF2-style isomorphism checks. It also provides a fast invariant-based rejection step using graph signatures derived from node tokens, edge tokens, degree histograms, and WL color histograms.
- Parameters:
source (Any) – Input source accepted by
WLCanonicalizer, such as a CRN-like object or a NetworkX graph.include_rule (bool) – Whether rule/reaction nodes should be included in the internal graph representation.
include_stoich (bool) – Whether stoichiometric information should be included in the internal graph representation.
wl_iters (int) – Maximum number of Weisfeiler-Lehman refinement iterations.
wl_digest_size (int) – Digest size used by the WL canonicalizer.
config (Optional[SymmetryConfig]) – Symmetry configuration controlling semantic versus topological matching. If
None,SymmetryConfig.semantic()is used.
Examples#
from synkit.CRN.Sym.iso import CRNIsomorphism iso_a = CRNIsomorphism(crn_a) iso_b = CRNIsomorphism(crn_b) result = iso_a.isomorphic_to(iso_b) print(result.isomorphic) print(result.mapping) sub = iso_a.subgraph_isomorphic_to(iso_b) print(sub.isomorphic)
- property G: DiGraph#
Return the internal directed graph.
- Returns:
Internal directed graph used for isomorphism analysis.
- Return type:
nx.DiGraph
- isomorphic_to(other: CRNIsomorphism) IsomorphismResult[source]#
Test graph isomorphism against another CRN isomorphism wrapper.
A fast signature check is applied first. If signatures disagree, the graphs are rejected immediately without invoking the exact VF2 matcher.
- Parameters:
other (CRNIsomorphism) – Other graph wrapper to compare against.
- Returns:
Exact isomorphism result.
- Return type:
IsomorphismResult
Examples#
iso_a = CRNIsomorphism(crn_a) iso_b = CRNIsomorphism(crn_b) result = iso_a.isomorphic_to(iso_b) print(result.isomorphic)
- subgraph_isomorphic_to(host: CRNIsomorphism) IsomorphismResult[source]#
Test whether this graph is subgraph-isomorphic to a host graph.
This method checks whether
selfcan be embedded intohostusing directed VF2 subgraph matching.- Parameters:
host (CRNIsomorphism) – Host graph wrapper.
- Returns:
Subgraph isomorphism result.
- Return type:
IsomorphismResult
Examples#
pattern = CRNIsomorphism(pattern_crn) host = CRNIsomorphism(host_crn) result = pattern.subgraph_isomorphic_to(host) print(result.isomorphic)
- synkit.CRN.Symmetry.isomorphism.are_isomorphic(a: Any, b: Any, **kwargs: Any) bool[source]#
Convenience wrapper for pairwise graph isomorphism.
- Parameters:
a (Any) – First graph-like source.
b (Any) – Second graph-like source.
kwargs (Any) – Additional keyword arguments forwarded to
CRNIsomorphism.
- Returns:
Trueif the two inputs are isomorphic.- Return type:
Examples#
ok = are_isomorphic(crn_a, crn_b, include_rule=True) print(ok)
- synkit.CRN.Symmetry.isomorphism.are_subhypergraph_isomorphic(pattern: Any, host: Any, **kwargs: Any) bool[source]#
Convenience wrapper for subgraph isomorphism.
- Parameters:
pattern (Any) – Pattern graph-like source.
host (Any) – Host graph-like source.
kwargs (Any) – Additional keyword arguments forwarded to
CRNIsomorphism.
- Returns:
Trueifpatternis subgraph-isomorphic tohost.- Return type:
Examples#
ok = are_subhypergraph_isomorphic(pattern_crn, host_crn) print(ok)
- class synkit.CRN.Symmetry.symmetry.CRNSymmetry(source: Any, *, include_rule: bool = True, include_stoich: bool = True, wl_iters: int = 20, wl_digest_size: int = 16, config: SymmetryConfig | None = None)[source]#
Bases:
objectUnified façade for WL, automorphism, canonicalization, and isomorphism.
- class synkit.CRN.Symmetry.wl_canon.WLCanonicalResult(canon_graph: DiGraph, graph_type: str, canonical_order: List[Any], canonical_key: Any, automorphism_count: int | None, orbits: List[Set[Any]], colors: Dict[Any, str], color_hist: Dict[str, int], iters_run: int, stabilized: bool, exact: bool, elapsed_seconds: float)[source]#
Bases:
objectApproximate canonicalization result from WL refinement.
This mirrors the exact canonicalizer style, but remains approximate.
- Parameters:
canon_graph (nx.DiGraph) – Graph canonically relabeled according to the WL order.
graph_type (str) – Graph representation type, e.g.
"bipartite"or"species".canonical_order (List[Any]) – Deterministic node order induced by the final WL partition.
canonical_key (Any) – Canonical graph key derived from the WL order.
automorphism_count (Optional[int]) – Approximate automorphism count from WL cells.
orbits (List[Set[Any]]) – Approximate node orbits from the final WL cells.
colors (Dict[Any, str]) – Final WL color mapping.
iters_run (int) – Number of WL iterations actually performed.
stabilized (bool) – Whether WL refinement stabilized before the maximum iteration count.
exact (bool) – Always
Falsefor WL refinement.elapsed_seconds (float) – Runtime in seconds for building the result object.
- class synkit.CRN.Symmetry.wl_canon.WLCanonicalizer(source: Any, *, include_rule: bool = True, include_stoich: bool = True, n_iter: int = 20, digest_size: int = 16, include_in_neighbors: bool = True, include_out_neighbors: bool = True, estimate_automorphisms: bool = True, automorphism_cap: int = 1000000000000000000, config: SymmetryConfig | None = None)[source]#
Bases:
objectFast approximate canonicalizer for SynKit CRN graphs using direction-aware 1-WL refinement.
This class is designed as a lightweight companion to the exact CRN canonicalizer. It gives:
deterministic WL-based canonical relabeling
approximate orbit partitions
approximate automorphism counts from WL cells
fast signatures for cheap prefiltering
Compared with the exact canonicalizer, this class is much faster but not guaranteed to distinguish all non-isomorphic graphs or recover exact automorphism groups.
- Parameters:
source (Any) – Input CRN representation. This may be a prepared
networkx.DiGraph, an object exposingto_digraph(), or any object accepted byprepare_graph().include_rule (bool) – Whether rule nodes should be included in the prepared graph.
include_stoich (bool) – Whether stoichiometric edge attributes should be preserved during graph preparation.
n_iter (int) – Maximum number of WL refinement iterations.
digest_size (int) – Digest size used when hashing node and edge signatures.
include_in_neighbors (bool) – Whether incoming neighbors should contribute to refinement.
include_out_neighbors (bool) – Whether outgoing neighbors should contribute to refinement.
estimate_automorphisms (bool) – Whether to compute an approximate automorphism count from the final WL cells.
automorphism_cap (int) – Cap applied to approximate automorphism counts.
config (Optional[SymmetryConfig]) – Symmetry semantics configuration controlling which node and edge attributes participate in WL coloring.
Example#
from synkit.CRN.Sym import WLCanonicalizer, SymmetryConfig wl = WLCanonicalizer( syn.to_digraph(), include_rule=True, config=SymmetryConfig.topological(), ) print(wl.has_nontrivial_automorphism()) print(wl.orbits()) print(wl.canonical_order()) print(wl.summary()["automorphism_count"])
- property G: DiGraph#
Return the prepared graph.
- Returns:
Prepared directed graph.
- Return type:
nx.DiGraph
Example#
wl = WLCanonicalizer(syn) print(wl.G.number_of_nodes(), wl.G.number_of_edges())
- canonical_graph() DiGraph[source]#
Return the canonically relabeled graph using the WL order.
- Returns:
WL-canonically relabeled graph.
- Return type:
nx.DiGraph
Example#
wl = WLCanonicalizer(syn) G_can = wl.canonical_graph() print(sorted(G_can.nodes()))
- canonical_key() Any[source]#
Return the canonical key induced by the WL order.
- Returns:
WL canonical key.
- Return type:
Any
Example#
wl = WLCanonicalizer(syn) print(wl.canonical_key())
- canonical_order() List[Any][source]#
Return the deterministic WL node order.
- Returns:
WL-based canonical node order.
- Return type:
List[Any]
Example#
wl = WLCanonicalizer(syn) print(wl.canonical_order())
- canonical_result() WLCanonicalResult[source]#
Build an approximate canonicalization result in a CRN-canon-like format.
- Returns:
Approximate canonicalization result.
- Return type:
Example#
wl = WLCanonicalizer(syn) result = wl.canonical_result() print(result.canonical_order) print(result.automorphism_count)
- color_of(v: Any) str[source]#
Return the final WL color of one node.
- Parameters:
v (Any) – Node identifier.
- Returns:
Final WL color.
- Return type:
Example#
wl = WLCanonicalizer(syn) print(wl.color_of(1))
- colors() Dict[Any, str][source]#
Return final WL colors.
- Returns:
Mapping from node to final color.
- Return type:
Dict[Any, str]
Example#
wl = WLCanonicalizer(syn) print(wl.colors())
- fast_signature() Tuple[Any, ...][source]#
Return a fast graph signature using graph statistics and WL color histogram.
This is useful as a cheap prefilter before exact graph isomorphism or exact canonicalization.
- Returns:
Fast graph signature.
- Return type:
Tuple[Any, …]
Example#
wl = WLCanonicalizer(syn) print(wl.fast_signature())
- graph() DiGraph[source]#
Alias for
canonical_graph(), matching the older canon style.- Returns:
WL-canonically relabeled graph.
- Return type:
nx.DiGraph
Example#
wl = WLCanonicalizer(syn) G_can = wl.graph()
- property graph_type: str#
Return the graph representation type.
- Returns:
Graph representation type.
- Return type:
Example#
wl = WLCanonicalizer(syn, include_rule=True) print(wl.graph_type)
- has_nontrivial_automorphism() bool[source]#
Heuristically detect whether symmetry may be present.
This is approximate and simply checks whether any WL color cell has size greater than one.
- Returns:
Trueif WL detects a non-singleton cell, elseFalse.- Return type:
Example#
wl = WLCanonicalizer(syn) print(wl.has_nontrivial_automorphism())
- orbits() List[Set[Any]][source]#
Return approximate WL orbit sets.
- Returns:
Approximate orbits induced by final WL colors.
- Return type:
List[Set[Any]]
Example#
wl = WLCanonicalizer(syn) print(wl.orbits())
- summary() Dict[str, Any][source]#
Return a dictionary summary in a format close to the exact canonicalizer.
The reported automorphism count and orbit sets are WL-based approximations.
- Returns:
Summary dictionary.
- Return type:
Dict[str, Any]
Example#
wl = WLCanonicalizer(syn) info = wl.summary() print(info["automorphism_count"]) print(info["orbits"])
- synkit.CRN.Symmetry.wl_canon.wl_canonical(source: Any, **kwargs: Any) DiGraph[source]#
Convenience function returning the WL-canonically relabeled graph.
- Parameters:
source (Any) – Input CRN representation.
kwargs (Any) – Additional keyword arguments forwarded to
WLCanonicalizer.
- Returns:
WL-canonically relabeled graph.
- Return type:
nx.DiGraph
Example#
from synkit.CRN.Sym import SymmetryConfig, wl_canonical G_can = wl_canonical( syn.to_digraph(), include_rule=True, config=SymmetryConfig.topological(), )
Visualization#
- class synkit.CRN.Visualize.crn_vis.CRNVis(graph: DiGraph, layout: str = 'bipartite', species_label: str = 'index', rule_label: str = 'name', font_size: int = 6)[source]#
Bases:
objectLightweight visualizer for CRN-style DAGs built by
DAG.The visualizer expects a directed bipartite graph where:
Species nodes have
kind='species'and asmilesattribute.Rule nodes have
kind='rule'andrule_index/rule_nameattributes.Edges are annotated with
role='reactant'orrole='product'.
- Parameters:
graph (
networkx.DiGraph) – Directed CRN graph to visualize.layout (str) – Layout strategy.
"bipartite"places species on the left and rules on the right;"spring"usesnetworkx.spring_layout().species_label (str) – Label type for species nodes, either
"index"(node id) or"smiles"(SMILES string).rule_label (str) – Label type for rule nodes, either
"name"(rule_name) or"index"(r{rule_index}).font_size (int) – Font size for node labels.
- draw(ax: 'matplotlib.axes.Axes' | None = None, show: bool = False)[source]#
Draw the CRN DAG using
matplotlib.Species nodes are drawn as circles, rule nodes as squares. Reactant edges (species→rule) are dashed; product edges (rule→species) are solid.
- Parameters:
ax (matplotlib.axes.Axes or None) – Optional matplotlib axes to draw on. If
None, a new figure and axes are created.show (bool) – If
True, callmatplotlib.pyplot.show()at the end.
- Returns:
Tuple of (figure, axes) used for drawing.
- Return type:
(matplotlib.figure.Figure, matplotlib.axes.Axes)
- synkit.CRN.Visualize.labels.build_edge_labels(graph: DiGraph, *, mode: str = 'none', max_chars: int | None = 20) Dict[tuple[Hashable, Hashable], str][source]#
- synkit.CRN.Visualize.labels.build_node_labels(graph: DiGraph, *, species_nodes: Iterable[Hashable], rule_nodes: Iterable[Hashable], species_label: str = 'label', rule_label: str = 'label', show_species_labels: bool = True, show_rule_labels: bool = True, max_chars: int | None = 32, wrap_at: int | None = None) Dict[Hashable, str][source]#
- synkit.CRN.Visualize.layout.available_layouts() List[str][source]#
Return the list of supported layout names.
- Returns:
Supported layout names, including
"auto".- Return type:
List[str]
names = available_layouts() print(names)
- synkit.CRN.Visualize.layout.bipartite_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable], node_spacing: float = 1.4, layer_spacing: float = 3.0, orientation: str = 'vertical') Dict[Hashable, Tuple[float, float]][source]#
Compute a two-layer species-rule layout.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
node_spacing (float) – Spacing between adjacent nodes within a layer.
layer_spacing (float) – Distance between the species and rule layers.
orientation (str) – Layout orientation. Must be
"vertical"or"horizontal".
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- Raises:
ValueError – If
orientationis not supported.
- synkit.CRN.Visualize.layout.choose_auto_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable]) str[source]#
Choose a layout heuristically.
Preference is given to step-aware layouts when rule step annotations are available. Larger or denser graphs are routed to layouts that typically reduce clutter.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
- Returns:
Selected layout name.
- Return type:
- synkit.CRN.Visualize.layout.circular_bipartite_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable], species_radius: float = 2.5, rule_radius: float = 4.0) Dict[Hashable, Tuple[float, float]][source]#
Compute a circular bipartite layout using two concentric circles.
Species and rule nodes are placed on separate rings.
- Parameters:
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- synkit.CRN.Visualize.layout.compute_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable], layout: str = 'step', node_spacing: float = 1.4, layer_spacing: float = 2.5, seed: int = 0, orientation: str = 'vertical') Dict[Hashable, Tuple[float, float]][source]#
Compute node positions for CRN visualization.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
layout (str) – Layout name. Supported values are
"auto","step","bipartite","multipartite_step","radial_step","circular_bipartite","degree_shell","spring","kamada_kawai","spectral","shell","spiral", and"random".node_spacing (float) – Spacing between nodes within a layer for layouts that support it.
layer_spacing (float) – Spacing between layers for layouts that support it.
seed (int) – Random seed for stochastic layouts.
orientation (str) – Orientation for the bipartite layout. Must be
"vertical"or"horizontal".
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- Raises:
ValueError – If the requested layout name is not supported.
pos = compute_layout( graph, species_nodes=species_nodes, rule_nodes=rule_nodes, layout="auto", )
- synkit.CRN.Visualize.layout.degree_shell_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable]) Dict[Hashable, Tuple[float, float]][source]#
Compute a degree-based shell layout.
Nodes with the highest degree are placed in the inner shell, followed by medium-degree and lower-degree shells.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- synkit.CRN.Visualize.layout.multipartite_step_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable]) Dict[Hashable, Tuple[float, float]][source]#
Compute a multipartite layout using inferred step layers.
This layout is useful for larger step-annotated graphs where a simple custom step layout becomes crowded.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- synkit.CRN.Visualize.layout.radial_step_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable], radius_step: float = 1.8) Dict[Hashable, Tuple[float, float]][source]#
Compute a radial step layout using concentric circles.
Logical layers are mapped to increasing radii.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
radius_step (float) – Radial increment between adjacent logical layers.
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
- synkit.CRN.Visualize.layout.step_layout(graph: DiGraph, *, species_nodes: List[Hashable], rule_nodes: List[Hashable], node_spacing: float = 1.4, layer_spacing: float = 2.5) Dict[Hashable, Tuple[float, float]][source]#
Compute a layered step-wise layout.
Species and rule nodes are assigned to alternating logical x-layers inferred from rule steps and incidence relationships.
- Parameters:
graph (nx.DiGraph) – Directed graph containing species and rule nodes.
species_nodes (List[Hashable]) – List of species node identifiers.
rule_nodes (List[Hashable]) – List of rule node identifiers.
node_spacing (float) – Vertical spacing between nodes in the same layer.
layer_spacing (float) – Horizontal spacing between adjacent layers.
- Returns:
Mapping from node identifier to
(x, y)coordinates.- Return type:
Pos
pos = step_layout( graph, species_nodes=species_nodes, rule_nodes=rule_nodes, node_spacing=1.6, layer_spacing=3.0, )
- class synkit.CRN.Visualize.palette.ColorPalette(background: str, species_fill: str, species_edge: str, rule_fill: str, rule_edge: str, reactant_edge: str, product_edge: str, other_edge: str, highlight_node: str, highlight_edge: str, label_text: str, node_index_text: str, legend_text: str, title_text: str)[source]#
Bases:
objectMuted publication-style palette for CRN visualization.
The defaults are intentionally restrained: muted species and rule colors, light paper-like background, and neutral label text.
- with_overrides(**kwargs) ColorPalette[source]#
- synkit.CRN.Visualize.palette.get_palette(name: str = 'paper_sage', **overrides) ColorPalette[source]#
- class synkit.CRN.Visualize.validation.CRNGraphInfo(species_nodes: 'List[Hashable]', rule_nodes: 'List[Hashable]', is_dag: 'bool')[source]#
Bases:
object
- synkit.CRN.Visualize.validation.validate_crn_graph(graph: DiGraph, *, strict: bool = True) CRNGraphInfo[source]#
- class synkit.CRN.Visualize.vis.CRNStyle(figsize: Tuple[float, float] = (12.0, 7.0), species_node_shape: str = 'o', rule_node_shape: str = 's', species_node_size: int = 760, rule_node_size: int = 540, edge_width: float = 1.2, highlight_edge_width: float = 2.1, reactant_style: str = 'dashed', product_style: str = 'solid', other_style: str = 'solid', arrows: bool = True, arrowstyle: str = '-|>', arrowsize: int = 12, font_size: int = 8, alpha: float = 0.98, margins: float = 0.12, show_label_boxes: bool = False, label_box_alpha: float = 0.0, curved_edges: bool = False, curve_radius: float = 0.0, scale_edge_width_by_stoich: bool = True, stoich_width_factor: float = 0.4, linewidths: float = 1.0, highlight_linewidths: float = 1.6, edge_alpha: float = 0.9, node_alpha: float = 1.0, show_node_outline: bool = True, label_fontweight: str = 'regular', auto_reduce_labels_when_dense: bool = True, dense_node_threshold: int = 45, dense_edge_threshold: int = 70, dense_font_size: int = 7)[source]#
Bases:
objectVisual style configuration for CRN plots.
The defaults are tuned for muted publication-style figures with straight edges, no label boxes, moderate alpha, and restrained line widths.
- Parameters:
species_node_shape (str) – Matplotlib marker shape for species nodes.
rule_node_shape (str) – Matplotlib marker shape for rule nodes.
species_node_size (int) – Node size for species nodes.
rule_node_size (int) – Node size for rule nodes.
edge_width (float) – Base width for regular edges.
highlight_edge_width (float) – Width for highlighted edges.
reactant_style (str) – Line style for reactant edges.
product_style (str) – Line style for product edges.
other_style (str) – Line style for untyped edges.
arrows (bool) – Whether to draw arrows on edges.
arrowstyle (str) – Matplotlib arrow style string.
arrowsize (int) – Arrow size for directed edges.
font_size (int) – Default node label font size.
alpha (float) – General alpha value retained for backward compatibility.
margins (float) – Plot margins passed to the axes.
show_label_boxes (bool) – Whether node labels should be drawn with a bbox.
label_box_alpha (float) – Alpha for label boxes.
curved_edges (bool) – Whether to draw curved edges.
curve_radius (float) – Radius used when curved edges are enabled.
scale_edge_width_by_stoich (bool) – Whether edge widths should scale by stoichiometry.
stoich_width_factor (float) – Increment added per stoichiometric unit above 1.
linewidths (float) – Line width for normal node outlines.
highlight_linewidths (float) – Line width for highlighted node outlines.
edge_alpha (float) – Alpha value for edges.
node_alpha (float) – Alpha value for nodes.
show_node_outline (bool) – Whether node outlines should be visible.
label_fontweight (str) – Font weight used for node labels.
auto_reduce_labels_when_dense (bool) – Whether to reduce label font size for dense graphs.
dense_node_threshold (int) – Node threshold for classifying a graph as dense.
dense_edge_threshold (int) – Edge threshold for classifying a graph as dense.
dense_font_size (int) – Reduced label font size used for dense graphs.
- class synkit.CRN.Visualize.vis.CRNVis(graph: DiGraph, layout: str = 'auto', species_label: str = 'label', rule_label: str = 'label', show_species_labels: bool = True, show_rule_labels: bool = True, font_size: int | None = None, max_label_chars: int | None = 28, wrap_label_at: int | None = None, style: CRNStyle = <factory>, palette: ColorPalette | str = 'nature_journal', palette_overrides: dict[str, str] | None=None, rule_color_mode: str = 'palette', rule_color_attr: str | None = None, rule_cmap: str = 'Greys', species_color_mode: str = 'palette', species_color_attr: str | None = None, species_cmap: str = 'Greys', node_color_overrides: Hashable, str] | None=None, node_spacing: float = 1.35, layer_spacing: float = 2.5, orientation: str = 'vertical', seed: int = 0, strict: bool = True)[source]#
Bases:
objectVisualization helper for chemical reaction networks.
- Parameters:
graph (nx.DiGraph) – Directed CRN graph to visualize.
layout (str) – Layout name passed to
compute_layout().species_label (str) – Node attribute used for species labels.
rule_label (str) – Node attribute used for rule labels.
show_species_labels (bool) – Whether species labels should be shown.
show_rule_labels (bool) – Whether rule labels should be shown.
font_size (Optional[int]) – Optional label font size override.
max_label_chars (Optional[int]) – Optional maximum number of characters per label.
wrap_label_at (Optional[int]) – Optional wrapping width for labels.
style (CRNStyle) – Style configuration object.
palette (ColorPalette | str) – Palette instance or palette name.
palette_overrides (Optional[dict[str, str]]) – Optional keyword overrides applied to the palette.
rule_color_mode (str) – Rule coloring mode.
rule_color_attr (Optional[str]) – Node attribute used when rule coloring mode is
"attribute".rule_cmap (str) – Matplotlib colormap name used for rule categorical colors.
species_color_mode (str) – Species coloring mode.
species_color_attr (Optional[str]) – Node attribute used when species coloring mode is
"attribute".species_cmap (str) – Matplotlib colormap name used for species categorical colors.
node_color_overrides (Optional[Mapping[Hashable, str]]) – Explicit per-node color overrides.
node_spacing (float) – Spacing passed to supported layouts.
layer_spacing (float) – Layer spacing passed to supported layouts.
orientation (str) – Orientation passed to supported layouts.
seed (int) – Random seed passed to stochastic layouts.
strict (bool) – Whether graph validation should be strict.
- dense_graph() bool[source]#
Return whether the graph should be treated as dense.
- Returns:
Trueif the graph exceeds node or edge thresholds.- Return type:
- draw(ax: Any = None, *, title: str | None = None, show: bool = False, with_legend: bool = True, edge_label_mode: str = 'none', highlight_nodes: Iterable[Hashable] | None = None, highlight_edges: Iterable[Tuple[Hashable, Hashable]] | None = None, highlight_cycles: bool = False, hide_axis: bool = True, auto_align_dense: bool = False) tuple[Any, Any, dict[Hashable, tuple[float, float]]][source]#
Draw the CRN.
- Parameters:
ax (Any) – Existing Matplotlib axes. If
None, a new figure and axes are created.title (Optional[str]) – Optional plot title.
show (bool) – Whether to call
matplotlib.pyplot.show().with_legend (bool) – Whether to draw the default legend.
edge_label_mode (str) – Edge label mode passed to
edge_labels().highlight_nodes (Optional[Iterable[Hashable]]) – Optional nodes to highlight.
highlight_edges (Optional[Iterable[Tuple[Hashable, Hashable]]]) – Optional edges to highlight.
highlight_cycles (bool) – Whether to highlight species-containing strongly connected components.
hide_axis (bool) – Whether to hide axes decoration.
auto_align_dense (bool) – Whether to temporarily switch to automatic layout for dense graphs.
- Returns:
Figure, axes, and node positions.
- Return type:
- edge_labels(*, mode: str = 'none') dict[tuple[Hashable, Hashable], str][source]#
Build edge labels for the current graph.
- property is_dag: bool#
Return whether the graph is acyclic.
- Returns:
Trueif the graph is a DAG, elseFalse.- Return type:
- palette: ColorPalette | str = 'nature_journal'#
- positions() dict[Hashable, tuple[float, float]][source]#
Compute node positions for the current graph and layout settings.
- property rule_nodes: list[Hashable]#
Return validated rule nodes.
- Returns:
Rule node identifiers.
- Return type:
list[Hashable]
- save(path: str | Path, *, dpi: int = 300, bbox_inches: str = 'tight', **draw_kwargs: Any) Path[source]#
Draw and save the CRN figure.
- property species_nodes: list[Hashable]#
Return validated species nodes.
- Returns:
Species node identifiers.
- Return type:
list[Hashable]
- strongly_connected_species() list[set[Hashable]][source]#
Return strongly connected components containing at least one species node.