synkit 1.6.5__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- synkit/CRN/Benchmark/__init__.py +53 -0
- synkit/CRN/Benchmark/crosschecks.py +13 -0
- synkit/CRN/Benchmark/kegg.py +12 -0
- synkit/CRN/Benchmark/networks.py +13 -0
- synkit/CRN/Benchmark/scaling.py +13 -0
- synkit/CRN/Benchmark/validate.py +13 -0
- synkit/CRN/Construct/__init__.py +16 -0
- synkit/CRN/Construct/abstract.py +668 -0
- synkit/CRN/Construct/arity.py +36 -0
- synkit/CRN/Construct/builder.py +619 -0
- synkit/CRN/Construct/derivation.py +63 -0
- synkit/CRN/Construct/flattener.py +100 -0
- synkit/CRN/Construct/keys.py +14 -0
- synkit/CRN/Construct/mixtures.py +117 -0
- synkit/CRN/Construct/rdkit_worker.py +69 -0
- synkit/CRN/Construct/smiles.py +99 -0
- synkit/CRN/Construct/state.py +31 -0
- synkit/CRN/Construct/strategy.py +75 -0
- synkit/CRN/Construct/worker.py +42 -0
- synkit/CRN/IO/__init__.py +36 -0
- synkit/CRN/IO/sbml.py +925 -0
- synkit/CRN/Pathway/__init__.py +72 -0
- synkit/CRN/Pathway/_adapter.py +333 -0
- synkit/CRN/Pathway/pathfinder.py +500 -0
- synkit/CRN/Pathway/reachability.py +796 -0
- synkit/CRN/Pathway/realizability.py +1322 -0
- synkit/CRN/Petrinet/__init__.py +93 -0
- synkit/CRN/Petrinet/analyzer.py +486 -0
- synkit/CRN/Petrinet/minimal_semiflows.py +436 -0
- synkit/CRN/Petrinet/net.py +1041 -0
- synkit/CRN/Petrinet/persistence.py +97 -0
- synkit/CRN/Petrinet/semiflows.py +483 -0
- synkit/CRN/Petrinet/siphon_search.py +402 -0
- synkit/CRN/Petrinet/structure.py +286 -0
- synkit/CRN/Props/__init__.py +130 -0
- synkit/CRN/Props/_rank.py +29 -0
- synkit/CRN/Props/deficiency.py +953 -0
- synkit/CRN/Props/dynamics.py +832 -0
- synkit/CRN/Props/helper.py +151 -0
- synkit/CRN/Props/stoich.py +751 -0
- synkit/CRN/Props/thermo.py +584 -0
- synkit/CRN/Query/__init__.py +66 -0
- synkit/CRN/Query/cache.py +41 -0
- synkit/CRN/Query/kegg_api.py +99 -0
- synkit/CRN/Query/kegg_extract.py +714 -0
- synkit/CRN/Query/kegg_impute.py +707 -0
- synkit/CRN/Query/kegg_parse.py +480 -0
- synkit/CRN/Query/to_syncrn.py +290 -0
- synkit/CRN/README.md +234 -0
- synkit/CRN/Structure/__init__.py +12 -0
- synkit/CRN/Structure/_graph_io.py +713 -0
- synkit/CRN/Structure/_matrices.py +88 -0
- synkit/CRN/Structure/_parse.py +544 -0
- synkit/CRN/Structure/reaction.py +237 -0
- synkit/CRN/Structure/rule.py +55 -0
- synkit/CRN/Structure/species.py +46 -0
- synkit/CRN/Structure/syncrn.py +929 -0
- synkit/CRN/Symmetry/__init__.py +20 -0
- synkit/CRN/Symmetry/_common.py +1059 -0
- synkit/CRN/Symmetry/_ir.py +940 -0
- synkit/CRN/Symmetry/automorphism.py +472 -0
- synkit/CRN/Symmetry/canon.py +441 -0
- synkit/CRN/Symmetry/isomorphism.py +412 -0
- synkit/CRN/Symmetry/symmetry.py +61 -0
- synkit/CRN/Symmetry/wl_canon.py +967 -0
- synkit/CRN/Visualize/__init__.py +11 -0
- synkit/CRN/Visualize/labels.py +113 -0
- synkit/CRN/Visualize/layout.py +708 -0
- synkit/CRN/Visualize/palette.py +292 -0
- synkit/CRN/Visualize/validation.py +122 -0
- synkit/CRN/Visualize/vis.py +1152 -0
- synkit/CRN/__init__.py +233 -0
- synkit/CRN/_build.py +50 -0
- synkit/CRN/_native_build.py +175 -0
- synkit/CRN/analysis.py +629 -0
- synkit/CRN/backend.py +74 -0
- synkit/CRN/cpp/CMakeLists.txt +58 -0
- synkit/CRN/cpp/algebra.cpp +46 -0
- synkit/CRN/cpp/closure.cpp +29 -0
- synkit/CRN/cpp/exact.h +55 -0
- synkit/CRN/cpp/pathway.cpp +46 -0
- synkit/CRN/cpp/semiflows.cpp +209 -0
- synkit/CRN/cpp/structural.cpp +240 -0
- synkit/CRN/cpp/symmetry.cpp +45 -0
- synkit/CRN/cpp/write_manifest.cmake +28 -0
- synkit/CRN/kinds.py +137 -0
- synkit/CRN/lib/synkit_crn.dll +0 -0
- synkit/CRN/lib/synkit_crn.json +33 -0
- synkit/CRN/native.py +388 -0
- synkit/CRN/native_analysis.py +459 -0
- synkit/Chem/Cluster/__init__.py +0 -0
- synkit/Chem/Cluster/butina.py +140 -0
- synkit/Chem/Fingerprint/__init__.py +0 -0
- synkit/Chem/Fingerprint/fp_calculator.py +155 -0
- synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
- synkit/Chem/Fingerprint/transformation_fp.py +139 -0
- synkit/Chem/Mapper/README.rst +43 -0
- synkit/Chem/Mapper/__init__.py +255 -0
- synkit/Chem/Mapper/_compat.py +130 -0
- synkit/Chem/Mapper/adapters/__init__.py +1 -0
- synkit/Chem/Mapper/adapters/prediction.py +126 -0
- synkit/Chem/Mapper/adapters/template.py +412 -0
- synkit/Chem/Mapper/chem/__init__.py +52 -0
- synkit/Chem/Mapper/chem/aam.py +673 -0
- synkit/Chem/Mapper/chem/blind.py +160 -0
- synkit/Chem/Mapper/chem/its.py +309 -0
- synkit/Chem/Mapper/chem/smiles.py +564 -0
- synkit/Chem/Mapper/graph/__init__.py +66 -0
- synkit/Chem/Mapper/graph/automorphism.py +395 -0
- synkit/Chem/Mapper/graph/blockcut.py +98 -0
- synkit/Chem/Mapper/graph/labeled_graph.py +104 -0
- synkit/Chem/Mapper/graph/refine.py +176 -0
- synkit/Chem/Mapper/graph/synkit_adapter.py +110 -0
- synkit/Chem/Mapper/io/__init__.py +13 -0
- synkit/Chem/Mapper/io/idxmapstr.py +82 -0
- synkit/Chem/Mapper/mapper.py +685 -0
- synkit/Chem/Mapper/reaction_search.py +554 -0
- synkit/Chem/Mapper/reporting/__init__.py +1 -0
- synkit/Chem/Mapper/reporting/alternatives.py +451 -0
- synkit/Chem/Mapper/reporting/analysis.py +681 -0
- synkit/Chem/Mapper/reporting/native_analysis.py +485 -0
- synkit/Chem/Mapper/reporting/spectrum.py +642 -0
- synkit/Chem/Mapper/solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/__init__.py +141 -0
- synkit/Chem/Mapper/solvers/exact/assignment/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_certificate.py +113 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_domains.py +162 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_verification.py +58 -0
- synkit/Chem/Mapper/solvers/exact/assignment/incremental_assignment.py +247 -0
- synkit/Chem/Mapper/solvers/exact/certificate.py +128 -0
- synkit/Chem/Mapper/solvers/exact/core.py +183 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/bounds.py +319 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/exhaustive.py +179 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/inputs.py +283 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/records.py +242 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/search.py +1025 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/verify.py +378 -0
- synkit/Chem/Mapper/solvers/exact/edit_support.py +375 -0
- synkit/Chem/Mapper/solvers/exact/hybrid.py +224 -0
- synkit/Chem/Mapper/solvers/exact/hydrogen.py +264 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/branching.py +499 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumerate.py +1050 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumeration_result.py +30 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/kernel.py +256 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/milp.py +194 -0
- synkit/Chem/Mapper/solvers/exact/native/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/native/build.py +154 -0
- synkit/Chem/Mapper/solvers/exact/native/candidates.py +593 -0
- synkit/Chem/Mapper/solvers/exact/native/canonical.py +396 -0
- synkit/Chem/Mapper/solvers/exact/native/disk_frontier.py +415 -0
- synkit/Chem/Mapper/solvers/exact/native/frontier.py +390 -0
- synkit/Chem/Mapper/solvers/exact/native/hydrogen_quotient.py +213 -0
- synkit/Chem/Mapper/solvers/exact/native/its.py +528 -0
- synkit/Chem/Mapper/solvers/exact/native/native_distance.cpp +2803 -0
- synkit/Chem/Mapper/solvers/exact/native/orbit_aggregation.py +328 -0
- synkit/Chem/Mapper/solvers/exact/native/parallel.py +205 -0
- synkit/Chem/Mapper/solvers/exact/native/pmcd.py +203 -0
- synkit/Chem/Mapper/solvers/exact/native/runtime.py +40 -0
- synkit/Chem/Mapper/solvers/exact/native/search.py +294 -0
- synkit/Chem/Mapper/solvers/exact/native/separator.py +224 -0
- synkit/Chem/Mapper/solvers/exact/native_build.py +12 -0
- synkit/Chem/Mapper/solvers/exact/pabs/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/pabs/cost_lattice.py +43 -0
- synkit/Chem/Mapper/solvers/exact/pabs/factor_spectrum.py +110 -0
- synkit/Chem/Mapper/solvers/exact/pabs/multi_shell.py +368 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation.py +679 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_bounds.py +436 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_limits.py +13 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_search.py +856 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_symmetry.py +66 -0
- synkit/Chem/Mapper/solvers/exact/pabs/residual_typed_bonds.py +136 -0
- synkit/Chem/Mapper/solvers/exact/pabs/reward_frontier.py +201 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_bound.py +258 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_spectrum.py +308 -0
- synkit/Chem/Mapper/solvers/exact/pabs/sparse_reward_bound.py +207 -0
- synkit/Chem/Mapper/solvers/exact/pabs/suffix_spectrum.py +299 -0
- synkit/Chem/Mapper/solvers/exact/search.py +55 -0
- synkit/Chem/Mapper/solvers/exact/seeds/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed.py +104 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_fragments.py +148 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_relaxation.py +181 -0
- synkit/Chem/Mapper/solvers/exact/symmetry.py +223 -0
- synkit/Chem/Mapper/solvers/native/__init__.py +4 -0
- synkit/Chem/Mapper/solvers/native/assignment.py +99 -0
- synkit/Chem/Mapper/solvers/native/astar.py +22 -0
- synkit/Chem/Mapper/solvers/native/build.py +385 -0
- synkit/Chem/Mapper/solvers/native/classification.py +641 -0
- synkit/Chem/Mapper/solvers/native/core.py +378 -0
- synkit/Chem/Mapper/solvers/native/cpp/CMakeLists.txt +120 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/map_reaction.cpp +29 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/slap_graph.cpp +63 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/assignment/assignment.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/astar.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/bound.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/pmcd_witness.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/runtime.h +130 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/hydrogen/hydrogen.h +73 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mapper.h +175 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mces/mces.h +9 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/pabs/seed.h +34 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/reaction/reaction.h +30 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/sepdp/sepdp.h +21 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/slap.h +72 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/solvers/solvers.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/classification.h +140 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/cpabs.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/assignment/abb.cpp +302 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/CMakeLists.txt +12 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/README.md +47 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar.cpp +228 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar_graph.cpp +37 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/bound.cpp +212 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/dispatch.cpp +272 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/pmcd_witness.cpp +36 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/hydrogen/hydrogen.cpp +380 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/README.md +57 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/mces.cpp +287 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/bridge.cpp +334 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/chemical_floor.inc +181 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/endpoint_symmetry.inc +104 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/exact_helpers.h +20 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_assignment_certificate.h +165 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_certificate.h +125 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_model.h +365 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_provider.inc +319 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_rounding.inc +170 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_test_hooks.h +342 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/objective_reduction.inc +137 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/overlap_dual.inc +351 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/profile_seed.inc +214 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/seed_heuristics.inc +640 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_embedding.cpp +430 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_root_lp.h +176 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/test_hooks.inc +262 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/reaction/reaction.cpp +611 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/README.md +61 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/sepdp.cpp +253 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/slap.cpp +810 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/formulation.h +138 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/maxsat.cpp +526 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/ortools.cpp +475 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/seed.h +80 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/weighted_cnf.h +256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/README.md +43 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/dfs.cpp +123 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/edit_support.cpp +224 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification.cpp +553 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_pipeline.cpp +124 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_stream.h +13 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/cpabs.cpp +455 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/edge_deck.cpp +743 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naugraph.c +732 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.c +94 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.h +49 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.c +1771 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.h +133 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nautil.c +750 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naututil.h +355 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.c +1256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.h +1544 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.c +1131 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.h +70 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/sorttemplates.c +580 -0
- synkit/Chem/Mapper/solvers/native/hydrogen.py +711 -0
- synkit/Chem/Mapper/solvers/native/implicit.py +506 -0
- synkit/Chem/Mapper/solvers/native/implicit_certificate.py +187 -0
- synkit/Chem/Mapper/solvers/native/implicit_preparation.py +309 -0
- synkit/Chem/Mapper/solvers/native/lib/synkit_mapper.dll +0 -0
- synkit/Chem/Mapper/solvers/native/mces.py +16 -0
- synkit/Chem/Mapper/solvers/native/reaction.py +179 -0
- synkit/Chem/Mapper/solvers/native/reaction_build.py +277 -0
- synkit/Chem/Mapper/solvers/native/reaction_text.py +26 -0
- synkit/Chem/Mapper/solvers/native/runtime.py +242 -0
- synkit/Chem/Mapper/solvers/native/sepdp.py +47 -0
- synkit/Chem/Mapper/solvers/native/slap.py +266 -0
- synkit/Chem/Mapper/solvers/native/solvers.py +67 -0
- synkit/Chem/Mapper/solvers/native/stereo.py +86 -0
- synkit/Chem/Mapper/solvers/native/supporting.py +34 -0
- synkit/Chem/Mapper/solvers/native/symmetry.py +91 -0
- synkit/Chem/Mapper/solvers/slap/__init__.py +29 -0
- synkit/Chem/Mapper/solvers/slap/lap.py +174 -0
- synkit/Chem/Mapper/solvers/slap/sequential.py +696 -0
- synkit/Chem/Mapper/validation/__init__.py +1 -0
- synkit/Chem/Mapper/validation/aam_validator.py +442 -0
- synkit/Chem/Mapper/validation/annotations.py +274 -0
- synkit/Chem/Mapper/validation/bonds.py +124 -0
- synkit/Chem/Mapper/validation/cohorts.py +72 -0
- synkit/Chem/Mapper/validation/identifiability.py +150 -0
- synkit/Chem/Mapper/validation/numerical_scope.py +36 -0
- synkit/Chem/Mapper/validation/orbits.py +137 -0
- synkit/Chem/Molecule/__init__.py +0 -0
- synkit/Chem/Molecule/_chirality_loci.py +165 -0
- synkit/Chem/Molecule/_chirality_types.py +231 -0
- synkit/Chem/Molecule/_helical_loci.py +167 -0
- synkit/Chem/Molecule/_stereo_axis_evidence.py +202 -0
- synkit/Chem/Molecule/_stereo_element_detection.py +193 -0
- synkit/Chem/Molecule/_stereo_orientation_constraints.py +511 -0
- synkit/Chem/Molecule/_tetrahedral_carriers.py +63 -0
- synkit/Chem/Molecule/atom_features.py +379 -0
- synkit/Chem/Molecule/chirality.py +1041 -0
- synkit/Chem/Molecule/cip_assignment.py +569 -0
- synkit/Chem/Molecule/cip_ranking.py +843 -0
- synkit/Chem/Molecule/coordinate_stereo.py +503 -0
- synkit/Chem/Molecule/derived_stereo_naming.py +165 -0
- synkit/Chem/Molecule/descriptors.py +452 -0
- synkit/Chem/Molecule/formula.py +249 -0
- synkit/Chem/Molecule/global_stereo.py +175 -0
- synkit/Chem/Molecule/graph_annotator.py +300 -0
- synkit/Chem/Molecule/standardize.py +817 -0
- synkit/Chem/Molecule/stereo_evidence.py +179 -0
- synkit/Chem/Molecule/stereo_perception.py +1032 -0
- synkit/Chem/Molecule/valence.py +123 -0
- synkit/Chem/Reaction/Mapper/__init__.py +44 -0
- synkit/Chem/Reaction/__init__.py +20 -0
- synkit/Chem/Reaction/aam_validator.py +5 -0
- synkit/Chem/Reaction/balance_check.py +138 -0
- synkit/Chem/Reaction/canon_rsmi.py +249 -0
- synkit/Chem/Reaction/cleaning.py +58 -0
- synkit/Chem/Reaction/deionize.py +199 -0
- synkit/Chem/Reaction/explicit_h_audit.py +232 -0
- synkit/Chem/Reaction/fix_aam.py +64 -0
- synkit/Chem/Reaction/neutralize.py +207 -0
- synkit/Chem/Reaction/radical_wildcard.py +224 -0
- synkit/Chem/Reaction/standardize.py +203 -0
- synkit/Chem/Reaction/tautomerize.py +205 -0
- synkit/Chem/__init__.py +1 -0
- synkit/Chem/utils.py +315 -0
- synkit/Data/__init__.py +0 -0
- synkit/Data/aldol.json.gz +1 -0
- synkit/Data/gen_partial_aam.py +147 -0
- synkit/Data/paracetamol.json.gz +1 -0
- synkit/Graph/Canon/__init__.py +16 -0
- synkit/Graph/Canon/_native/__init__.py +13 -0
- synkit/Graph/Canon/_native/build.py +93 -0
- synkit/Graph/Canon/_native/lib/synkit_canon.dll +0 -0
- synkit/Graph/Canon/_native/prepare.py +49 -0
- synkit/Graph/Canon/_native/runtime.py +140 -0
- synkit/Graph/Canon/_native/search.py +137 -0
- synkit/Graph/Canon/canon_algs.py +228 -0
- synkit/Graph/Canon/canon_graph.py +531 -0
- synkit/Graph/Canon/cpp/CMakeLists.txt +42 -0
- synkit/Graph/Canon/cpp/README.md +123 -0
- synkit/Graph/Canon/cpp/examples/canonical_graph.cpp +16 -0
- synkit/Graph/Canon/cpp/include/synkit_canon/canon.h +85 -0
- synkit/Graph/Canon/cpp/src/canonical.cpp +391 -0
- synkit/Graph/Canon/cpp/src/symmetry.h +83 -0
- synkit/Graph/Canon/cpp/tests/symmetry.cpp +93 -0
- synkit/Graph/Canon/exact.py +1020 -0
- synkit/Graph/Canon/exact_refinement.py +368 -0
- synkit/Graph/Canon/nauty.py +143 -0
- synkit/Graph/Context/__init__.py +0 -0
- synkit/Graph/Context/hier_context.py +244 -0
- synkit/Graph/Context/radius_expand.py +252 -0
- synkit/Graph/FG/__init__.py +19 -0
- synkit/Graph/FG/api.py +39 -0
- synkit/Graph/FG/audit.py +155 -0
- synkit/Graph/FG/catalog.py +919 -0
- synkit/Graph/FG/detector.py +288 -0
- synkit/Graph/FG/model.py +97 -0
- synkit/Graph/FG/recognizers.py +274 -0
- synkit/Graph/FG/ring_system.py +154 -0
- synkit/Graph/Feature/Descriptors/topology.py +857 -0
- synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
- synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +222 -0
- synkit/Graph/Feature/__init__.py +5 -0
- synkit/Graph/Feature/graph_descriptors.py +323 -0
- synkit/Graph/Feature/graph_fps.py +96 -0
- synkit/Graph/Feature/graph_signature.py +239 -0
- synkit/Graph/Feature/hash_fps.py +133 -0
- synkit/Graph/Feature/morgan_fps.py +88 -0
- synkit/Graph/Feature/path_fps.py +81 -0
- synkit/Graph/Feature/wl_hash.py +134 -0
- synkit/Graph/Fusion/__init__.py +85 -0
- synkit/Graph/Fusion/candidate.py +559 -0
- synkit/Graph/Fusion/constructor.py +877 -0
- synkit/Graph/Fusion/identity.py +184 -0
- synkit/Graph/Fusion/interface.py +700 -0
- synkit/Graph/Fusion/search.py +241 -0
- synkit/Graph/Hyrogen/__init__.py +6 -0
- synkit/Graph/Hyrogen/_misc.py +591 -0
- synkit/Graph/Hyrogen/hcomplete.py +995 -0
- synkit/Graph/Hyrogen/hcomplete_legacy.py +368 -0
- synkit/Graph/Hyrogen/hcompletion_algorithms.py +713 -0
- synkit/Graph/Hyrogen/hextend.py +570 -0
- synkit/Graph/Hyrogen/hextend_legacy.py +215 -0
- synkit/Graph/ITS/__init__.py +4 -0
- synkit/Graph/ITS/its_builder.py +120 -0
- synkit/Graph/ITS/its_construction.py +719 -0
- synkit/Graph/ITS/its_decompose.py +572 -0
- synkit/Graph/ITS/its_destruction.py +331 -0
- synkit/Graph/ITS/its_expand.py +1251 -0
- synkit/Graph/ITS/its_relabel.py +187 -0
- synkit/Graph/ITS/its_reverter.py +356 -0
- synkit/Graph/ITS/normalize_aam.py +145 -0
- synkit/Graph/ITS/partial_its.py +238 -0
- synkit/Graph/ITS/rc_extractor.py +656 -0
- synkit/Graph/ITS/stereo.py +74 -0
- synkit/Graph/MTG/__init__.py +107 -0
- synkit/Graph/MTG/gluing.py +451 -0
- synkit/Graph/MTG/history.py +928 -0
- synkit/Graph/MTG/inventory.py +118 -0
- synkit/Graph/MTG/local.py +447 -0
- synkit/Graph/MTG/mcs_matcher.py +246 -0
- synkit/Graph/MTG/mtg.py +611 -0
- synkit/Graph/MTG/mtg_explore.py +74 -0
- synkit/Graph/MTG/observation.py +209 -0
- synkit/Graph/MTG/process.py +577 -0
- synkit/Graph/MTG/queries.py +66 -0
- synkit/Graph/MTG/realization.py +95 -0
- synkit/Graph/MTG/series_parallel.py +107 -0
- synkit/Graph/MTG/utils.py +424 -0
- synkit/Graph/Matcher/__init__.py +10 -0
- synkit/Graph/Matcher/approx_mcs.py +1264 -0
- synkit/Graph/Matcher/auto_est.py +736 -0
- synkit/Graph/Matcher/automorphism.py +314 -0
- synkit/Graph/Matcher/batch_cluster.py +224 -0
- synkit/Graph/Matcher/dedup_matches.py +247 -0
- synkit/Graph/Matcher/graph_cluster.py +191 -0
- synkit/Graph/Matcher/graph_matcher.py +312 -0
- synkit/Graph/Matcher/graph_morphism.py +421 -0
- synkit/Graph/Matcher/mcs_matcher.py +804 -0
- synkit/Graph/Matcher/multi_turbo_iso.py +186 -0
- synkit/Graph/Matcher/orbit.py +284 -0
- synkit/Graph/Matcher/partial_matcher.py +694 -0
- synkit/Graph/Matcher/sing.py +544 -0
- synkit/Graph/Matcher/subgraph_matcher.py +812 -0
- synkit/Graph/Matcher/turbo_iso.py +272 -0
- synkit/Graph/Matcher/wl_sel.py +537 -0
- synkit/Graph/Mech/__init__.py +26 -0
- synkit/Graph/Mech/conversion.py +1466 -0
- synkit/Graph/Mech/conversion_debug.py +237 -0
- synkit/Graph/Mech/electron_accounting.py +200 -0
- synkit/Graph/Mech/lwg_editor.py +406 -0
- synkit/Graph/Mech/lwg_ops.py +313 -0
- synkit/Graph/Morphism/__init__.py +99 -0
- synkit/Graph/Morphism/constraints.py +460 -0
- synkit/Graph/Morphism/llg.py +999 -0
- synkit/Graph/Morphism/morphism.py +349 -0
- synkit/Graph/Morphism/stereo.py +258 -0
- synkit/Graph/Morphism/stereo_morphism.py +383 -0
- synkit/Graph/Morphism/stereo_morphism_helpers.py +957 -0
- synkit/Graph/Morphism/stereo_morphism_types.py +117 -0
- synkit/Graph/Stereo/__init__.py +376 -0
- synkit/Graph/Stereo/_descriptor_core.py +207 -0
- synkit/Graph/Stereo/_descriptor_serialization.py +138 -0
- synkit/Graph/Stereo/canonical.py +648 -0
- synkit/Graph/Stereo/changes.py +964 -0
- synkit/Graph/Stereo/composition.py +391 -0
- synkit/Graph/Stereo/configured.py +946 -0
- synkit/Graph/Stereo/couplings.py +245 -0
- synkit/Graph/Stereo/descriptors.py +1030 -0
- synkit/Graph/Stereo/enumeration.py +597 -0
- synkit/Graph/Stereo/extended_descriptors.py +406 -0
- synkit/Graph/Stereo/global_configured.py +152 -0
- synkit/Graph/Stereo/global_stereo.py +304 -0
- synkit/Graph/Stereo/identity.py +648 -0
- synkit/Graph/Stereo/interchange.py +496 -0
- synkit/Graph/Stereo/legacy.py +460 -0
- synkit/Graph/Stereo/matching.py +899 -0
- synkit/Graph/Stereo/native.py +154 -0
- synkit/Graph/Stereo/orbits.py +668 -0
- synkit/Graph/Stereo/outcomes.py +99 -0
- synkit/Graph/Stereo/pairwise.py +350 -0
- synkit/Graph/Stereo/rdkit_adapter.py +662 -0
- synkit/Graph/Stereo/rdkit_identity.py +118 -0
- synkit/Graph/Stereo/rdkit_resonance.py +140 -0
- synkit/Graph/Stereo/reaction_interchange.py +266 -0
- synkit/Graph/Stereo/semantics.py +296 -0
- synkit/Graph/Stereo/supports.py +257 -0
- synkit/Graph/Stereo/wire.py +339 -0
- synkit/Graph/Wildcard/__init__.py +0 -0
- synkit/Graph/Wildcard/fuse_graph.py +156 -0
- synkit/Graph/Wildcard/graph_wc.py +303 -0
- synkit/Graph/Wildcard/its_merge.py +857 -0
- synkit/Graph/Wildcard/radwc.py +114 -0
- synkit/Graph/Wildcard/wc_matcher.py +576 -0
- synkit/Graph/Wildcard/wildcard.py +225 -0
- synkit/Graph/__init__.py +17 -0
- synkit/Graph/canon_graph.py +14 -0
- synkit/Graph/syn_graph.py +199 -0
- synkit/Graph/utils.py +324 -0
- synkit/IO/__init__.py +4 -0
- synkit/IO/chem_converter.py +1059 -0
- synkit/IO/combinatorial/__init__.py +8 -0
- synkit/IO/combinatorial/gml_to_graph.py +223 -0
- synkit/IO/combinatorial/graph_to_gml.py +280 -0
- synkit/IO/combinatorial/graph_to_smarts.py +186 -0
- synkit/IO/combinatorial/smarts_expander.py +147 -0
- synkit/IO/combinatorial/smarts_generalizer.py +133 -0
- synkit/IO/combinatorial/smarts_to_graph.py +179 -0
- synkit/IO/conversion.py +42 -0
- synkit/IO/data_io.py +269 -0
- synkit/IO/data_process.py +143 -0
- synkit/IO/debug.py +73 -0
- synkit/IO/gml_to_nx.py +150 -0
- synkit/IO/graph_to_mol.py +199 -0
- synkit/IO/mol_to_graph.py +1105 -0
- synkit/IO/mol_to_graph_chemistry.py +545 -0
- synkit/IO/nx_to_gml.py +209 -0
- synkit/IO/smiles_to_id.py +123 -0
- synkit/Mechanism/__init__.py +151 -0
- synkit/Mechanism/adapters.py +136 -0
- synkit/Mechanism/audit.py +323 -0
- synkit/Mechanism/benchmark.py +638 -0
- synkit/Mechanism/compatibility.py +13 -0
- synkit/Mechanism/drawing.py +85 -0
- synkit/Mechanism/electron_models.py +725 -0
- synkit/Mechanism/equivalence.py +521 -0
- synkit/Mechanism/evidence.py +262 -0
- synkit/Mechanism/interchange.py +141 -0
- synkit/Mechanism/model.py +918 -0
- synkit/Mechanism/neighbor_stereo.py +312 -0
- synkit/Mechanism/radical_data.py +740 -0
- synkit/Mechanism/replay.py +986 -0
- synkit/Mechanism/schema.py +264 -0
- synkit/Mechanism/stereo_state.py +416 -0
- synkit/Mechanism/symbols.py +91 -0
- synkit/Rule/Apply/__init__.py +35 -0
- synkit/Rule/Apply/conditions.py +45 -0
- synkit/Rule/Apply/dpo.py +998 -0
- synkit/Rule/Apply/rule_matcher.py +218 -0
- synkit/Rule/Apply/validation.py +354 -0
- synkit/Rule/Compose/__init__.py +106 -0
- synkit/Rule/Compose/_identity.py +43 -0
- synkit/Rule/Compose/composition.py +976 -0
- synkit/Rule/Compose/laws.py +439 -0
- synkit/Rule/Compose/search.py +771 -0
- synkit/Rule/Compose/synrule.py +170 -0
- synkit/Rule/Modify/__init__.py +0 -0
- synkit/Rule/Modify/implict_rule.py +56 -0
- synkit/Rule/Modify/longest_path.py +92 -0
- synkit/Rule/Modify/molecule_rule.py +115 -0
- synkit/Rule/Modify/prune_templates.py +78 -0
- synkit/Rule/Modify/rule_utils.py +194 -0
- synkit/Rule/Modify/strip_rule.py +97 -0
- synkit/Rule/__init__.py +28 -0
- synkit/Rule/generic_stereo.py +884 -0
- synkit/Rule/stereo_identity.py +271 -0
- synkit/Rule/syn_rule.py +1090 -0
- synkit/Synthesis/MSR/__init__.py +0 -0
- synkit/Synthesis/MSR/path_finder.py +239 -0
- synkit/Synthesis/Metrics/__init__.py +0 -0
- synkit/Synthesis/Metrics/_base.py +52 -0
- synkit/Synthesis/Metrics/_plot.py +129 -0
- synkit/Synthesis/Metrics/_ranking.py +179 -0
- synkit/Synthesis/RBL/__init__.py +80 -0
- synkit/Synthesis/RBL/engine.py +1249 -0
- synkit/Synthesis/RBL/matching.py +652 -0
- synkit/Synthesis/RBL/overlap.py +336 -0
- synkit/Synthesis/RBL/pipeline.py +376 -0
- synkit/Synthesis/RBL/policy.py +139 -0
- synkit/Synthesis/RBL/proof.py +370 -0
- synkit/Synthesis/RBL/reaction.py +506 -0
- synkit/Synthesis/RBL/state.py +169 -0
- synkit/Synthesis/RBL/validation.py +1060 -0
- synkit/Synthesis/Reactor/__init__.py +60 -0
- synkit/Synthesis/Reactor/core/__init__.py +1 -0
- synkit/Synthesis/Reactor/core/engine.py +967 -0
- synkit/Synthesis/Reactor/core/product.py +621 -0
- synkit/Synthesis/Reactor/core/rewrite.py +561 -0
- synkit/Synthesis/Reactor/core/strategy.py +44 -0
- synkit/Synthesis/Reactor/matching/__init__.py +1 -0
- synkit/Synthesis/Reactor/matching/mixin.py +920 -0
- synkit/Synthesis/Reactor/matching/policy.py +345 -0
- synkit/Synthesis/Reactor/matching/symmetry.py +309 -0
- synkit/Synthesis/Reactor/output/__init__.py +1 -0
- synkit/Synthesis/Reactor/output/deduplication.py +703 -0
- synkit/Synthesis/Reactor/output/policy.py +16 -0
- synkit/Synthesis/Reactor/output/serialization.py +485 -0
- synkit/Synthesis/Reactor/output/structural.py +893 -0
- synkit/Synthesis/Reactor/stereo/__init__.py +1 -0
- synkit/Synthesis/Reactor/stereo/assignment.py +35 -0
- synkit/Synthesis/Reactor/stereo/mixin.py +780 -0
- synkit/Synthesis/Reactor/variants/__init__.py +1 -0
- synkit/Synthesis/Reactor/variants/imbalanced.py +180 -0
- synkit/Synthesis/Reactor/variants/partial.py +84 -0
- synkit/Synthesis/Reactor/workflow/__init__.py +1 -0
- synkit/Synthesis/Reactor/workflow/batch.py +550 -0
- synkit/Synthesis/Reactor/workflow/benchmark.py +143 -0
- synkit/Synthesis/Reactor/workflow/postprocess.py +267 -0
- synkit/Synthesis/Reactor/workflow/rule_filter.py +210 -0
- synkit/Synthesis/__init__.py +0 -0
- synkit/Synthesis/reactor_utils.py +316 -0
- synkit/Utils/__init__.py +0 -0
- synkit/Utils/utils.py +172 -0
- synkit/Vis/__init__.py +91 -0
- synkit/Vis/crn/__init__.py +40 -0
- synkit/Vis/epd/__init__.py +20 -0
- synkit/Vis/epd/arrows.py +425 -0
- synkit/Vis/epd/chem.py +197 -0
- synkit/Vis/epd/constants.py +83 -0
- synkit/Vis/epd/layout.py +283 -0
- synkit/Vis/epd/mapping.py +51 -0
- synkit/Vis/epd/models.py +136 -0
- synkit/Vis/epd/render.py +543 -0
- synkit/Vis/epd/utils.py +108 -0
- synkit/Vis/epd/visualizer.py +811 -0
- synkit/Vis/graph_visualizer.py +375 -0
- synkit/Vis/its/__init__.py +19 -0
- synkit/Vis/its/drawer.py +615 -0
- synkit/Vis/its_drawer.py +35 -0
- synkit/Vis/molecule/__init__.py +31 -0
- synkit/Vis/molecule/drawer.py +563 -0
- synkit/Vis/molecule/reaction.py +285 -0
- synkit/Vis/molecule_drawer.py +33 -0
- synkit/Vis/mtg/__init__.py +17 -0
- synkit/Vis/mtg/drawer.py +769 -0
- synkit/Vis/mtg_drawer.py +34 -0
- synkit/Vis/pdf_writer.py +146 -0
- synkit/Vis/reaction/__init__.py +19 -0
- synkit/Vis/reaction/rule.py +141 -0
- synkit/Vis/reaction/rxn.py +532 -0
- synkit/Vis/reaction_drawer.py +41 -0
- synkit/Vis/space/__init__.py +17 -0
- synkit/Vis/space/chemical.py +80 -0
- synkit/Vis/space/embedding.py +87 -0
- synkit/Vis/vis_synedu/Vis/__init__.py +7 -0
- synkit/Vis/vis_synedu/Vis/dpo.py +862 -0
- synkit/Vis/vis_synedu/rxn_vis.py +377 -0
- synkit/Vis/vis_synedu/vis.py +501 -0
- synkit/Vis/visual_drawer.py +215 -0
- synkit/Vis/visual_model.py +520 -0
- synkit/__init__.py +3 -0
- synkit/_native.py +91 -0
- synkit/examples.py +50 -0
- synkit/version.py +23 -0
- synkit-1.6.5.dist-info/METADATA +156 -0
- synkit-1.6.5.dist-info/RECORD +636 -0
- synkit-1.6.5.dist-info/WHEEL +4 -0
- synkit-1.6.5.dist-info/licenses/LICENSE +21 -0
- synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"""Bridge from KEGG equations to :class:`~synkit.CRN.Structure.syncrn.SynCRN`.
|
|
2
|
+
|
|
3
|
+
:mod:`synkit.CRN.Query` retrieves and parses KEGG data; this module turns that
|
|
4
|
+
data into the canonical network object the rest of :mod:`synkit.CRN` analyses.
|
|
5
|
+
It is the join between the *curated-pathway* entry point and the analysis stack,
|
|
6
|
+
so a KEGG module can be pushed straight through conservation laws, semiflows,
|
|
7
|
+
siphons, persistence and realizability.
|
|
8
|
+
|
|
9
|
+
Two conversion choices matter for the result:
|
|
10
|
+
|
|
11
|
+
- **Reversible equations.** KEGG writes ``<=>`` for a reversible reaction. A
|
|
12
|
+
``SynCRN`` reaction is directed, so a reversible equation becomes two
|
|
13
|
+
reactions by default (``expand_reversible``). This matters: weak
|
|
14
|
+
reversibility, persistence and siphon verdicts all change if the reverse
|
|
15
|
+
direction is dropped.
|
|
16
|
+
- **Currency metabolites.** ATP, ADP, NAD+, water and phosphate participate in
|
|
17
|
+
most reactions of a pathway and dominate its structural analysis — every
|
|
18
|
+
siphon and most semiflows end up describing cofactor recycling rather than
|
|
19
|
+
the pathway. Passing ``drop_compounds=CURRENCY_COMPOUNDS`` removes them, which
|
|
20
|
+
is the usual convention when analysing a pathway's carbon skeleton.
|
|
21
|
+
|
|
22
|
+
.. rubric:: Example
|
|
23
|
+
|
|
24
|
+
.. code-block:: python
|
|
25
|
+
|
|
26
|
+
from synkit.CRN.Query import syncrn_from_kegg_equations
|
|
27
|
+
|
|
28
|
+
crn = syncrn_from_kegg_equations(
|
|
29
|
+
{"R01786": "C00002 + C00267 => C00008 + C00668"}
|
|
30
|
+
)
|
|
31
|
+
print(crn.to_equations(species="label"))
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
from typing import Any, Dict, Iterable, Mapping, Optional, Set
|
|
37
|
+
|
|
38
|
+
import networkx as nx
|
|
39
|
+
|
|
40
|
+
from ..Structure.syncrn import SynCRN
|
|
41
|
+
from .kegg_parse import parse_equation
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"CURRENCY_COMPOUNDS",
|
|
45
|
+
"syncrn_from_kegg_equations",
|
|
46
|
+
"syncrn_from_kegg_module",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
#: KEGG compound ids for the usual currency metabolites.
|
|
50
|
+
#:
|
|
51
|
+
#: These appear in most reactions of any pathway, so leaving them in makes the
|
|
52
|
+
#: structural analysis describe cofactor turnover instead of the pathway.
|
|
53
|
+
CURRENCY_COMPOUNDS: Set[str] = {
|
|
54
|
+
"C00001", # H2O
|
|
55
|
+
"C00002", # ATP
|
|
56
|
+
"C00003", # NAD+
|
|
57
|
+
"C00004", # NADH
|
|
58
|
+
"C00005", # NADPH
|
|
59
|
+
"C00006", # NADP+
|
|
60
|
+
"C00008", # ADP
|
|
61
|
+
"C00009", # orthophosphate
|
|
62
|
+
"C00013", # diphosphate
|
|
63
|
+
"C00020", # AMP
|
|
64
|
+
"C00080", # H+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _side_counts(
|
|
69
|
+
items: Iterable[Any],
|
|
70
|
+
*,
|
|
71
|
+
drop: Set[str],
|
|
72
|
+
) -> Dict[str, int]:
|
|
73
|
+
"""Aggregate one parsed equation side into ``compound -> coefficient``.
|
|
74
|
+
|
|
75
|
+
:param items:
|
|
76
|
+
``(compound_id, coefficient)`` pairs from a parsed KEGG equation.
|
|
77
|
+
:type items: Iterable[Any]
|
|
78
|
+
|
|
79
|
+
:param drop:
|
|
80
|
+
Compound ids to exclude.
|
|
81
|
+
:type drop: Set[str]
|
|
82
|
+
|
|
83
|
+
:return:
|
|
84
|
+
Coefficients keyed by compound id, with dropped compounds removed.
|
|
85
|
+
:rtype: Dict[str, int]
|
|
86
|
+
"""
|
|
87
|
+
counts: Dict[str, int] = {}
|
|
88
|
+
for compound_id, coefficient in items:
|
|
89
|
+
if compound_id in drop:
|
|
90
|
+
continue
|
|
91
|
+
counts[compound_id] = counts.get(compound_id, 0) + int(coefficient)
|
|
92
|
+
return counts
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def syncrn_from_kegg_equations(
|
|
96
|
+
equations: Mapping[str, Optional[str]],
|
|
97
|
+
*,
|
|
98
|
+
names: Optional[Mapping[str, str]] = None,
|
|
99
|
+
expand_reversible: bool = True,
|
|
100
|
+
drop_compounds: Iterable[str] = (),
|
|
101
|
+
skip_empty: bool = True,
|
|
102
|
+
strict: bool = False,
|
|
103
|
+
) -> SynCRN:
|
|
104
|
+
"""Build a :class:`SynCRN` from KEGG reaction equations.
|
|
105
|
+
|
|
106
|
+
:param equations:
|
|
107
|
+
Mapping from KEGG reaction id to equation string, as returned by
|
|
108
|
+
:meth:`~synkit.CRN.Query.kegg_extract.KEGGExtractor.get_module_equations`.
|
|
109
|
+
Entries with no equation are skipped.
|
|
110
|
+
:type equations: Mapping[str, Optional[str]]
|
|
111
|
+
|
|
112
|
+
:param names:
|
|
113
|
+
Optional mapping from compound id to a display name, used as the species
|
|
114
|
+
label. Compound ids are used when a name is missing.
|
|
115
|
+
:type names: Optional[Mapping[str, str]]
|
|
116
|
+
|
|
117
|
+
:param expand_reversible:
|
|
118
|
+
Whether a reversible KEGG equation (``<=>``) becomes two directed
|
|
119
|
+
reactions.
|
|
120
|
+
:type expand_reversible: bool
|
|
121
|
+
|
|
122
|
+
:param drop_compounds:
|
|
123
|
+
Compound ids to exclude from every reaction, typically
|
|
124
|
+
:data:`CURRENCY_COMPOUNDS`.
|
|
125
|
+
:type drop_compounds: Iterable[str]
|
|
126
|
+
|
|
127
|
+
:param skip_empty:
|
|
128
|
+
Whether reactions left with no reactant *and* no product after dropping
|
|
129
|
+
compounds are omitted rather than kept as empty reactions.
|
|
130
|
+
:type skip_empty: bool
|
|
131
|
+
|
|
132
|
+
:param strict:
|
|
133
|
+
Whether malformed structure should raise; forwarded to
|
|
134
|
+
:meth:`SynCRN.from_digraph`.
|
|
135
|
+
:type strict: bool
|
|
136
|
+
|
|
137
|
+
:return:
|
|
138
|
+
Canonical network object whose reaction labels are the KEGG reaction
|
|
139
|
+
ids and whose species labels are compound names (or ids).
|
|
140
|
+
:rtype: SynCRN
|
|
141
|
+
|
|
142
|
+
.. rubric:: Example
|
|
143
|
+
|
|
144
|
+
.. code-block:: python
|
|
145
|
+
|
|
146
|
+
crn = syncrn_from_kegg_equations(
|
|
147
|
+
{"R01015": "C00111 <=> C00118"},
|
|
148
|
+
names={"C00111": "DHAP", "C00118": "GAP"},
|
|
149
|
+
)
|
|
150
|
+
print(crn.n_reactions)
|
|
151
|
+
# 2
|
|
152
|
+
"""
|
|
153
|
+
drop = set(drop_compounds)
|
|
154
|
+
label_of = dict(names or {})
|
|
155
|
+
|
|
156
|
+
graph = nx.DiGraph()
|
|
157
|
+
graph.graph["source"] = "kegg"
|
|
158
|
+
seen_species: Set[str] = set()
|
|
159
|
+
|
|
160
|
+
def _ensure_species(compound_id: str) -> None:
|
|
161
|
+
if compound_id in seen_species:
|
|
162
|
+
return
|
|
163
|
+
seen_species.add(compound_id)
|
|
164
|
+
graph.add_node(
|
|
165
|
+
compound_id,
|
|
166
|
+
kind="species",
|
|
167
|
+
label=label_of.get(compound_id, compound_id),
|
|
168
|
+
kegg_compound=compound_id,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def _add_reaction(
|
|
172
|
+
node_id: str,
|
|
173
|
+
*,
|
|
174
|
+
label: str,
|
|
175
|
+
lhs: Dict[str, int],
|
|
176
|
+
rhs: Dict[str, int],
|
|
177
|
+
kegg_id: str,
|
|
178
|
+
direction: str,
|
|
179
|
+
) -> None:
|
|
180
|
+
if skip_empty and not lhs and not rhs:
|
|
181
|
+
return
|
|
182
|
+
for compound_id in list(lhs) + list(rhs):
|
|
183
|
+
_ensure_species(compound_id)
|
|
184
|
+
graph.add_node(
|
|
185
|
+
node_id,
|
|
186
|
+
kind="reaction",
|
|
187
|
+
label=label,
|
|
188
|
+
kegg_reaction=kegg_id,
|
|
189
|
+
direction=direction,
|
|
190
|
+
)
|
|
191
|
+
for compound_id, coefficient in lhs.items():
|
|
192
|
+
graph.add_edge(compound_id, node_id, role="reactant", stoich=coefficient)
|
|
193
|
+
for compound_id, coefficient in rhs.items():
|
|
194
|
+
graph.add_edge(node_id, compound_id, role="product", stoich=coefficient)
|
|
195
|
+
|
|
196
|
+
for kegg_id, equation in equations.items():
|
|
197
|
+
if not equation:
|
|
198
|
+
continue
|
|
199
|
+
parsed = parse_equation(equation)
|
|
200
|
+
lhs = _side_counts(parsed.reactants, drop=drop)
|
|
201
|
+
rhs = _side_counts(parsed.products, drop=drop)
|
|
202
|
+
|
|
203
|
+
reverse = parsed.reversible and expand_reversible
|
|
204
|
+
_add_reaction(
|
|
205
|
+
kegg_id,
|
|
206
|
+
label=kegg_id,
|
|
207
|
+
lhs=lhs,
|
|
208
|
+
rhs=rhs,
|
|
209
|
+
kegg_id=kegg_id,
|
|
210
|
+
direction="forward",
|
|
211
|
+
)
|
|
212
|
+
if reverse:
|
|
213
|
+
_add_reaction(
|
|
214
|
+
f"{kegg_id}_rev",
|
|
215
|
+
label=f"{kegg_id}_rev",
|
|
216
|
+
lhs=rhs,
|
|
217
|
+
rhs=lhs,
|
|
218
|
+
kegg_id=kegg_id,
|
|
219
|
+
direction="reverse",
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
return SynCRN.from_digraph(graph, strict=strict)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def syncrn_from_kegg_module(
|
|
226
|
+
module_id: str,
|
|
227
|
+
*,
|
|
228
|
+
extractor: Any = None,
|
|
229
|
+
with_names: bool = True,
|
|
230
|
+
**kwargs: Any,
|
|
231
|
+
) -> SynCRN:
|
|
232
|
+
"""Fetch a KEGG module and build a :class:`SynCRN` from it.
|
|
233
|
+
|
|
234
|
+
This performs live KEGG REST requests. For a reproducible, offline network
|
|
235
|
+
use :func:`syncrn_from_kegg_equations` with cached equations — see
|
|
236
|
+
:mod:`synkit.CRN.Query.cache`.
|
|
237
|
+
|
|
238
|
+
:param module_id:
|
|
239
|
+
KEGG module identifier such as ``"M00001"``.
|
|
240
|
+
:type module_id: str
|
|
241
|
+
|
|
242
|
+
:param extractor:
|
|
243
|
+
Optional :class:`~synkit.CRN.Query.kegg_extract.KEGGExtractor` instance.
|
|
244
|
+
A default one is created when omitted.
|
|
245
|
+
:type extractor: Any
|
|
246
|
+
|
|
247
|
+
:param with_names:
|
|
248
|
+
Whether compound names should be fetched and used as species labels.
|
|
249
|
+
This costs one request per compound.
|
|
250
|
+
:type with_names: bool
|
|
251
|
+
|
|
252
|
+
:param kwargs:
|
|
253
|
+
Extra keyword arguments forwarded to
|
|
254
|
+
:func:`syncrn_from_kegg_equations`.
|
|
255
|
+
:type kwargs: Any
|
|
256
|
+
|
|
257
|
+
:return:
|
|
258
|
+
Canonical network object for the module.
|
|
259
|
+
:rtype: SynCRN
|
|
260
|
+
|
|
261
|
+
.. rubric:: Example
|
|
262
|
+
|
|
263
|
+
.. code-block:: python
|
|
264
|
+
|
|
265
|
+
crn = syncrn_from_kegg_module("M00001", drop_compounds=CURRENCY_COMPOUNDS)
|
|
266
|
+
print(crn.n_species, crn.n_reactions)
|
|
267
|
+
"""
|
|
268
|
+
if extractor is None:
|
|
269
|
+
from .kegg_extract import KEGGExtractor
|
|
270
|
+
|
|
271
|
+
extractor = KEGGExtractor()
|
|
272
|
+
|
|
273
|
+
equations = extractor.get_module_equations(module_id)
|
|
274
|
+
|
|
275
|
+
names: Dict[str, str] = {}
|
|
276
|
+
if with_names:
|
|
277
|
+
compound_ids: Set[str] = set()
|
|
278
|
+
for equation in equations.values():
|
|
279
|
+
if not equation:
|
|
280
|
+
continue
|
|
281
|
+
parsed = parse_equation(equation)
|
|
282
|
+
for compound_id, _ in list(parsed.reactants) + list(parsed.products):
|
|
283
|
+
compound_ids.add(compound_id)
|
|
284
|
+
for compound_id in sorted(compound_ids):
|
|
285
|
+
name = extractor.get_compound_name(compound_id)
|
|
286
|
+
if name:
|
|
287
|
+
names[compound_id] = name
|
|
288
|
+
|
|
289
|
+
kwargs.setdefault("names", names or None)
|
|
290
|
+
return syncrn_from_kegg_equations(equations, **kwargs)
|
synkit/CRN/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Biochemical model analysis
|
|
2
|
+
|
|
3
|
+
`CRNAnalysis` owns a detached snapshot. Editing the source model does not change
|
|
4
|
+
an existing analysis. Build a new analysis to inspect edits. Existing lower-level
|
|
5
|
+
CRNT, Petri-net, pathway and construction APIs remain available.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from synkit.CRN import CRNAnalysis, Scenario, read_sbml
|
|
9
|
+
|
|
10
|
+
model = read_sbml('model.xml')
|
|
11
|
+
a = CRNAnalysis(model, Scenario.from_model(model))
|
|
12
|
+
print(a.audit().to_dict())
|
|
13
|
+
print(a.conservation().to_dict())
|
|
14
|
+
print(a.structure().to_dict())
|
|
15
|
+
print(a.accessibility(['glucose']).to_dict())
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Selectors accept stable ids, source ids or unique labels. Ambiguous names raise.
|
|
19
|
+
SBML boundary flags, compartments and initial values are retained in species
|
|
20
|
+
`source_attrs`; initial concentrations are **not** converted to integer tokens.
|
|
21
|
+
Nonintegral stoichiometry is rejected rather than silently truncated. Explicit
|
|
22
|
+
normalization is required before using discrete reaction semantics.
|
|
23
|
+
|
|
24
|
+
`Scenario(chemostats=('ATP',))` declares an unlimited external reservoir.
|
|
25
|
+
`Scenario(drop_species=('ATP',))` changes the reaction equations by deleting
|
|
26
|
+
incidences. Both are explicit and operate on a copy. Conservation results cover
|
|
27
|
+
internal species under the selected reservoir policy. CRNT structure includes
|
|
28
|
+
the retained equations; closed-system theorem verdicts do not automatically
|
|
29
|
+
apply to chemostatted dynamics.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
outcome = a.verify_pathway(flow, {'glucose': 1, 'ATP': 2}, max_states=100000)
|
|
33
|
+
rescue = a.minimum_supplements(
|
|
34
|
+
flow, initial_marking={'glucose': 1}, allowed=['ATP', 'NAD+'],
|
|
35
|
+
max_added=4, max_candidates=10000,
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Every successful certificate is replayed against reaction records. Rescue
|
|
40
|
+
minimizes weighted added tokens **within the declared per-species box**; it
|
|
41
|
+
never asserts global optimality. State/depth limits propagate to inconclusive
|
|
42
|
+
results, including unresolved cheaper supplementation candidates.
|
|
43
|
+
|
|
44
|
+
`flux_feasibility(bounds=..., required=...)` solves a different question:
|
|
45
|
+
steady-state flux on internal species. All stored reactions are directed;
|
|
46
|
+
default flux bounds are nonnegative. Require positive reaction throughput to
|
|
47
|
+
exclude the zero solution. `blocked_reactions` uses an explicit positive
|
|
48
|
+
threshold and reports unknowns when its total time budget expires. LP results
|
|
49
|
+
are numerical and carry the method; they are not exact rational proofs.
|
|
50
|
+
|
|
51
|
+
Use `a.compare(other_analysis)` for aligned incidence and structural changes.
|
|
52
|
+
Comparisons require corresponding stable identities; unrelated imported models
|
|
53
|
+
must first be aligned. `audit()` checks elemental and charge balance when
|
|
54
|
+
SMILES exist and otherwise records unknown balance, not success. Open exchange
|
|
55
|
+
reactions can naturally have nonzero elemental balance.
|
|
56
|
+
|
|
57
|
+
## Optional exact C++ analysis
|
|
58
|
+
|
|
59
|
+
Platform wheels include the full CRN backend. `native_backend()` selects the
|
|
60
|
+
installed library without compiling, downloading, or requiring local Boost
|
|
61
|
+
headers. `backend='cpp'` also uses the bundled library when no explicit path is
|
|
62
|
+
supplied. The default `backend='auto'` retains Python unless a native context
|
|
63
|
+
or library path is selected.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from synkit.CRN import native_backend, crnt_summary
|
|
67
|
+
|
|
68
|
+
with native_backend():
|
|
69
|
+
report = crnt_summary(model)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For source development, the top-level CMake project builds all SynKit native
|
|
73
|
+
components together. The explicit `build_native` helper uses the same CRN
|
|
74
|
+
CMake target for focused builds with GCC, Clang, or MSVC:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from synkit.CRN import (build_native, conserved_moieties, enumerate_semiflows,
|
|
78
|
+
enumerate_structural_sets, PetriAnalyzer)
|
|
79
|
+
|
|
80
|
+
library = build_native('/tmp/synkit-crn-native', with_semiflows=True)
|
|
81
|
+
pools = conserved_moieties(model, library_path=library)
|
|
82
|
+
analyzer = PetriAnalyzer(model, library_path=library).compute_all()
|
|
83
|
+
|
|
84
|
+
# Structured results for explicit resource budgets:
|
|
85
|
+
result = enumerate_semiflows(
|
|
86
|
+
model.to_stoichiometric_matrices()['S'], kind='p', library_path=library,
|
|
87
|
+
time_limit=30, max_candidates=1_000_000, max_rows=100_000,
|
|
88
|
+
max_results=10_000, max_coefficient_bits=4096,
|
|
89
|
+
)
|
|
90
|
+
siphons = enumerate_structural_sets(model, library_path=library,
|
|
91
|
+
time_limit=30, max_nodes=200_000)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The C++ backend implements the **entire exact minimal P/T-semiflow enumeration**:
|
|
95
|
+
Farkas elimination, primitive integer normalization, bitset support filtering and
|
|
96
|
+
deduplication. Coefficients use Boost.Multiprecision arbitrary-precision integers.
|
|
97
|
+
All returned native semiflows are independently checked against the original
|
|
98
|
+
integer matrix in Python. Matrix input is checked int64 without float rounding;
|
|
99
|
+
output coefficients may exceed int64. A modular full-rank certificate provides
|
|
100
|
+
an exact early exit when the relevant kernel is empty.
|
|
101
|
+
|
|
102
|
+
The **entire minimal siphon/trap search** also runs in C++, using implication
|
|
103
|
+
propagation over selected and excluded species, disjoint branching, and closure
|
|
104
|
+
minimization. Each reported minimal set blocks further supersets. Least-species
|
|
105
|
+
roots cover all nonempty models, and each implication branch covers every
|
|
106
|
+
remaining choice. Returned sets use stable species ids. `max_nodes` counts
|
|
107
|
+
search states plus closure-minimization calls. Set `max_nodes=None`,
|
|
108
|
+
`time_limit=None`, or `max_results=None` to disable that individual limit on
|
|
109
|
+
structural enumeration; this requires a newly built structural ABI 2 library.
|
|
110
|
+
|
|
111
|
+
`backend='auto'` uses C++ when an explicit `library_path` is supplied; otherwise
|
|
112
|
+
it retains Python. `backend='python'` selects the reference implementation.
|
|
113
|
+
Importing never compiles or downloads anything. Build manifests record source
|
|
114
|
+
hashes, compiler versions, capabilities and library integrity metadata. CMake
|
|
115
|
+
builds also record the Boost version. Explicit development builds fingerprint
|
|
116
|
+
the Boost header tree and configured toolchain. Installed wheels verify library
|
|
117
|
+
bytes against the wheel's final `RECORD`, including changes made by wheel repair.
|
|
118
|
+
Native Conda packages verify the installed library hashes recorded in
|
|
119
|
+
`conda-meta`, including prefix relocation and code signing performed by Conda
|
|
120
|
+
or Mamba. These packages include the same three native libraries and need no
|
|
121
|
+
compiler or Boost headers at runtime.
|
|
122
|
+
|
|
123
|
+
Source native builds require CMake 3.20 or newer, a C++17 compiler, and installed
|
|
124
|
+
Boost headers. The builder checks standard include locations, `BOOST_INCLUDE_DIR`, and existing
|
|
125
|
+
Conda header caches. Use `boost_include_dir='/path/to/include'` for an explicit
|
|
126
|
+
location. `with_semiflows=False` builds native structural enumeration using only
|
|
127
|
+
the C++ standard library; `with_semiflows=True` fails clearly if headers are absent.
|
|
128
|
+
|
|
129
|
+
Deadlines, candidate/row/result caps and coefficient-bit caps return
|
|
130
|
+
`complete=False` with the termination reason. Intermediate cone tableau rows are
|
|
131
|
+
never returned as completed semiflows. The list-returning `minimal_semiflows`
|
|
132
|
+
and `conserved_moieties` APIs raise `SemiflowSearchLimit` with the structured
|
|
133
|
+
result when native search is incomplete. Timing reports include preparation and
|
|
134
|
+
witness checking; the native deadline bounds search, not later serialization.
|
|
135
|
+
|
|
136
|
+
`PetriAnalyzer` reuses computed semiflows and complete siphon enumeration for
|
|
137
|
+
persistence instead of repeating those searches. Partial enumeration cannot
|
|
138
|
+
certify persistence. Legacy persistence details return `None` when node or size
|
|
139
|
+
limits prevent a sound conclusion.
|
|
140
|
+
|
|
141
|
+
`has_stoichiometric_dependencies` tests linear dependence; the historical
|
|
142
|
+
`has_irreversible_futile_cycles` now tests nonnegative structural circulation.
|
|
143
|
+
Neither substitutes for thermodynamic analysis with measured/estimated energies
|
|
144
|
+
and declared concentrations and conditions.
|
|
145
|
+
|
|
146
|
+
`pathways(seeds, targets, initial_marking=...)` suggests bounded qualitative
|
|
147
|
+
candidates and verifies each against the inventory. Its candidate list is never
|
|
148
|
+
advertised as exhaustive. Use prescribed-flow verification when reaction
|
|
149
|
+
multiplicities, including repeated firings, matter.
|
|
150
|
+
|
|
151
|
+
The optional `to_cobra(bounds=..., exchange_bounds=...)` bridge requires a
|
|
152
|
+
separate COBRApy installation and explicit bounds for every directed reaction
|
|
153
|
+
and selected chemostat exchange. The exported model can then use COBRApy FVA,
|
|
154
|
+
blocked-reaction and deletion analyses. No physiological capacities are inferred.
|
|
155
|
+
|
|
156
|
+
## Research code and migration
|
|
157
|
+
|
|
158
|
+
Benchmarks, reference networks, independent cross-checks and biochemical case
|
|
159
|
+
studies belong to `Experiment/CRN/`, not the runtime analysis package:
|
|
160
|
+
|
|
161
|
+
- `Experiment.CRN.benchmarks`: reference fixtures, independent checks, validation,
|
|
162
|
+
KEGG case studies, synthetic generators and timing harnesses;
|
|
163
|
+
- `Experiment/CRN/data/kegg_modules.json`: the reviewed four-module dataset.
|
|
164
|
+
|
|
165
|
+
These are included in the source distribution, not the wheel. The deprecated
|
|
166
|
+
`synkit.CRN.Benchmark` namespace contains only forwarding shims for existing
|
|
167
|
+
source-checkout consumers. It imports no research code until accessed; consumers
|
|
168
|
+
of these old names must migrate and have the experiment source available.
|
|
169
|
+
|
|
170
|
+
For a reusable offline KEGG workflow, supply your own cache explicitly:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from synkit.CRN.Query import load_kegg_cache, build_cached_kegg_crn
|
|
174
|
+
|
|
175
|
+
cache = load_kegg_cache('my_modules.json')
|
|
176
|
+
model = build_cached_kegg_crn(cache, 'M00001')
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The generic converter retains all participants by default; currency removal is
|
|
180
|
+
an explicit `drop_compounds` choice. It never imports experiment helpers or
|
|
181
|
+
implicitly loads the experimental dataset.
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
## Native CRN analysis coverage
|
|
185
|
+
|
|
186
|
+
Exact production analysis is available through
|
|
187
|
+
Python interfaces to native kernels:
|
|
188
|
+
|
|
189
|
+
| Computation | Native implementation | Python interface |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| Exact rank and rational conservation basis | `cpp/algebra.cpp` | `matrix_analysis`, `integer_conservation_laws` |
|
|
192
|
+
| Complexes, linkage/SCC structure, deficiency and theorem inputs | `cpp/algebra.cpp` | `crnt_summary` |
|
|
193
|
+
| Minimal P/T-semiflows and conserved pools | `cpp/semiflows.cpp` | `minimal_semiflows`, `conserved_moieties` |
|
|
194
|
+
| Minimal siphons, traps and the paired exhaustive baseline | `cpp/structural.cpp` | `find_siphons`, `find_traps`, native exhaustive helper |
|
|
195
|
+
| Prescribed-flux execution and qualitative target search | `cpp/pathway.cpp` | `PathwayRealizability`, `qualitative_path` |
|
|
196
|
+
| Exact topological canonicalization and automorphism groups | `cpp/symmetry.cpp` | `canonical`, `CRNAutomorphism.summary`, `graph_symmetry` |
|
|
197
|
+
| Positive-kernel feasibility | HiGHS C++ via SciPy | `is_conservative`, `is_consistent` |
|
|
198
|
+
| Formose SMARTS application | RDKit C++ | `CRNExpand(rule_backend='rdkit', keep_aam=False)` |
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from synkit.CRN import build_native, native_backend, crnt_summary
|
|
202
|
+
|
|
203
|
+
library = build_native('/tmp/crn-native', with_semiflows=True)
|
|
204
|
+
with native_backend(library):
|
|
205
|
+
report = crnt_summary(model)
|
|
206
|
+
# Other supported analysis entry points share this task-local backend.
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The native symmetry interfaces currently cover the complete topological
|
|
210
|
+
species/reaction graph used by the studies; unsupported semantic matching options
|
|
211
|
+
raise instead of silently running another implementation. Exact and qualitative
|
|
212
|
+
pathway certificates are replayed in Python. Native incomplete algebra or
|
|
213
|
+
canonicalization never becomes a claimed exact result.
|
|
214
|
+
|
|
215
|
+
Experiment CLI entry points default to C++. `--backend python` selects the
|
|
216
|
+
reference workflow; `--native-library` reuses an explicit build and
|
|
217
|
+
`--native-build-dir` controls a requested build. Imports never compile anything.
|
|
218
|
+
The runner propagates the backend into subprocesses and timing workers. Evidence
|
|
219
|
+
records the library/build digest, capabilities and native operation counts.
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
python Experiment/CRN/run_all.py --backend cpp --quick --offline \
|
|
223
|
+
--with-biomodels \
|
|
224
|
+
--output-dir /tmp/crn-native-evidence --summary /tmp/crn-native-evidence/summary.json
|
|
225
|
+
python -m pytest Test/CRN/test_native_analysis.py Test/CRN/test_native_semiflows.py -q
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Python remains responsible for input/output, experiment orchestration, theorem
|
|
229
|
+
wording, molecular canonicalization calls and independent certificate checks.
|
|
230
|
+
The numerical SVD and CRNT4SBML comparisons deliberately retain their independent
|
|
231
|
+
reference implementations. The paired closure/exhaustive timing uses C++ for
|
|
232
|
+
both production algorithms, so its ratio does not compare C++ with Python.
|
|
233
|
+
Timing values depend on the workload, backend and recorded machine. Use newly
|
|
234
|
+
generated evidence for performance comparisons.
|