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,225 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from typing import Dict, Any, Tuple, Optional
|
|
3
|
+
from synkit.IO import rsmi_to_graph, graph_to_smi
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class WildCard:
|
|
7
|
+
"""Static utility class for generating reaction SMILES with wildcards by
|
|
8
|
+
augmenting the product graph with subgraphs unique to the reactant and
|
|
9
|
+
patching lost external connections with wildcard atoms ('*').
|
|
10
|
+
|
|
11
|
+
Optionally, can rebalance the reactant side to ensure both sides have
|
|
12
|
+
matching atom maps (by adding wildcard atoms if needed).
|
|
13
|
+
|
|
14
|
+
All methods are static and do not store any internal state.
|
|
15
|
+
|
|
16
|
+
.. rubric:: Example
|
|
17
|
+
|
|
18
|
+
>>> WildCard.rsmi_with_wildcards('CCO>>CC')
|
|
19
|
+
'CCO>>CC*'
|
|
20
|
+
|
|
21
|
+
>>> WildCard.rsmi_with_wildcards('CCO>>CC', rebalance=True)
|
|
22
|
+
'CCO*>>CC*'
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def rsmi_with_wildcards(
|
|
27
|
+
rsmi: str,
|
|
28
|
+
attributes_defaults: Optional[Dict[str, Any]] = None,
|
|
29
|
+
rebalance: bool = False,
|
|
30
|
+
) -> str:
|
|
31
|
+
"""Given a reaction SMILES string, returns a new reaction SMILES where the product
|
|
32
|
+
side contains any disconnected subgraphs unique to the reactant, with lost
|
|
33
|
+
external bonds patched with wildcard atoms. Optionally, also adds wildcards to
|
|
34
|
+
the reactant side to ensure matching atom maps (rebalance).
|
|
35
|
+
|
|
36
|
+
:param rsmi: Reaction SMILES (e.g., 'CCO>>CC')
|
|
37
|
+
:type rsmi: str
|
|
38
|
+
:param attributes_defaults: Optional dictionary of default attributes for wildcards
|
|
39
|
+
:type attributes_defaults: dict, optional
|
|
40
|
+
:param rebalance: Whether to rebalance the reactant side by adding wildcards
|
|
41
|
+
:type rebalance: bool
|
|
42
|
+
:return: Augmented reaction SMILES string
|
|
43
|
+
:rtype: str
|
|
44
|
+
:raises ValueError: If parsing or output generation fails.
|
|
45
|
+
|
|
46
|
+
.. rubric:: Example
|
|
47
|
+
|
|
48
|
+
>>> WildCard.rsmi_with_wildcards('CCO>>CC')
|
|
49
|
+
'CCO>>CC*'
|
|
50
|
+
>>> WildCard.rsmi_with_wildcards('CCO>>CC', rebalance=True)
|
|
51
|
+
'CCO*>>CC*'
|
|
52
|
+
"""
|
|
53
|
+
r, p = WildCard.from_rsmi(rsmi)
|
|
54
|
+
new_r, new_p = WildCard.add_unique_subgraph_with_wildcards(
|
|
55
|
+
r, p, attributes_defaults, rebalance=rebalance
|
|
56
|
+
)
|
|
57
|
+
try:
|
|
58
|
+
return f"{WildCard.to_smi(new_r)}>>{WildCard.to_smi(new_p)}"
|
|
59
|
+
except Exception as e:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
"Could not convert to RSMI after wildcard patching."
|
|
62
|
+
) from e
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def add_unique_subgraph_with_wildcards(
|
|
66
|
+
G: nx.Graph,
|
|
67
|
+
H: nx.Graph,
|
|
68
|
+
attributes_defaults: Optional[Dict[str, Any]] = None,
|
|
69
|
+
rebalance: bool = False,
|
|
70
|
+
) -> Tuple[nx.Graph, nx.Graph]:
|
|
71
|
+
"""Add the subgraph unique to G as a disconnected union to H,
|
|
72
|
+
and patch lost external connections with plain wildcard bonds.
|
|
73
|
+
Optionally, rebalance the reactant side to ensure both sides have
|
|
74
|
+
matching atom maps by adding wildcards.
|
|
75
|
+
|
|
76
|
+
:param G: Reactant graph
|
|
77
|
+
:type G: nx.Graph
|
|
78
|
+
:param H: Product graph
|
|
79
|
+
:type H: nx.Graph
|
|
80
|
+
:param attributes_defaults: Optional attribute defaults for wildcard nodes
|
|
81
|
+
:type attributes_defaults: dict, optional
|
|
82
|
+
:param rebalance: Whether to rebalance the reactant side with wildcards
|
|
83
|
+
:type rebalance: bool
|
|
84
|
+
:return: Tuple (new_G, new_H) with both graphs possibly augmented by wildcards
|
|
85
|
+
:rtype: Tuple[nx.Graph, nx.Graph]
|
|
86
|
+
:raises ValueError: If G or H are not valid graphs.
|
|
87
|
+
|
|
88
|
+
.. rubric:: Example
|
|
89
|
+
|
|
90
|
+
>>> r, p = WildCard.from_rsmi('CCO>>CC')
|
|
91
|
+
>>> r2, p2 = WildCard.add_unique_subgraph_with_wildcards(r, p, rebalance=True)
|
|
92
|
+
"""
|
|
93
|
+
if not isinstance(G, nx.Graph) or not isinstance(H, nx.Graph):
|
|
94
|
+
raise ValueError("G and H must be networkx.Graph instances")
|
|
95
|
+
if G.number_of_nodes() == 0 or H.number_of_nodes() == 0:
|
|
96
|
+
raise ValueError("Both G and H must have at least one node.")
|
|
97
|
+
if not all("atom_map" in d for _, d in G.nodes(data=True)):
|
|
98
|
+
raise ValueError(
|
|
99
|
+
"All reactant nodes must have 'atom_map' attributes for unique subgraph logic."
|
|
100
|
+
)
|
|
101
|
+
if not all("atom_map" in d for _, d in H.nodes(data=True)):
|
|
102
|
+
raise ValueError(
|
|
103
|
+
"All product nodes must have 'atom_map' attributes for unique subgraph logic."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if attributes_defaults is None:
|
|
107
|
+
attributes_defaults = {
|
|
108
|
+
"element": "*",
|
|
109
|
+
"aromatic": False,
|
|
110
|
+
"hcount": 0,
|
|
111
|
+
"charge": 0,
|
|
112
|
+
"neighbors": [],
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Make working copies
|
|
116
|
+
G_new = G.copy()
|
|
117
|
+
H_new = H.copy()
|
|
118
|
+
|
|
119
|
+
# ---------------------------
|
|
120
|
+
# 1. PATCH PRODUCT SIDE (add unique reactant subgraphs and wildcards)
|
|
121
|
+
# ---------------------------
|
|
122
|
+
react_atom_maps = {d["atom_map"] for _, d in G.nodes(data=True)}
|
|
123
|
+
prod_atom_maps = {d["atom_map"] for _, d in H.nodes(data=True)}
|
|
124
|
+
|
|
125
|
+
# Identify nodes and subgraphs unique to reactant
|
|
126
|
+
unique_atom_maps = react_atom_maps - prod_atom_maps
|
|
127
|
+
node_map = {d["atom_map"]: n for n, d in G.nodes(data=True)}
|
|
128
|
+
unique_nodes = [node_map[a] for a in unique_atom_maps if a in node_map]
|
|
129
|
+
|
|
130
|
+
G_unique = G.subgraph(unique_nodes).copy()
|
|
131
|
+
# Add unique reactant fragments to product
|
|
132
|
+
for n, d in G_unique.nodes(data=True):
|
|
133
|
+
H_new.add_node(n, **d)
|
|
134
|
+
for u, v, d in G_unique.edges(data=True):
|
|
135
|
+
H_new.add_edge(u, v, **d)
|
|
136
|
+
|
|
137
|
+
# Add wildcards to patch lost external bonds (reactant → outside)
|
|
138
|
+
existing_ids = set(H_new.nodes)
|
|
139
|
+
next_id = (
|
|
140
|
+
max([n for n in existing_ids if isinstance(n, int)], default=0) + 1
|
|
141
|
+
if existing_ids
|
|
142
|
+
else 1
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
for n in unique_nodes:
|
|
146
|
+
for nbr in G.neighbors(n):
|
|
147
|
+
nbr_map = G.nodes[nbr]["atom_map"]
|
|
148
|
+
if nbr_map not in unique_atom_maps:
|
|
149
|
+
wc_id = next_id
|
|
150
|
+
next_id += 1
|
|
151
|
+
H_new.add_node(
|
|
152
|
+
wc_id,
|
|
153
|
+
**attributes_defaults,
|
|
154
|
+
atom_map=wc_id,
|
|
155
|
+
typesGH=(("*", False, 0, 0, []), ("*", False, 0, 0, [])),
|
|
156
|
+
)
|
|
157
|
+
H_new.add_edge(n, wc_id)
|
|
158
|
+
|
|
159
|
+
# ---------------------------
|
|
160
|
+
# 2. REBALANCE REACTANT SIDE (add wildcards to reactant if required)
|
|
161
|
+
# ---------------------------
|
|
162
|
+
if rebalance:
|
|
163
|
+
prod_atom_maps = {d["atom_map"] for _, d in H_new.nodes(data=True)}
|
|
164
|
+
missing_in_react = prod_atom_maps - react_atom_maps
|
|
165
|
+
if missing_in_react:
|
|
166
|
+
react_existing_ids = set(G_new.nodes)
|
|
167
|
+
react_next_id = (
|
|
168
|
+
max(
|
|
169
|
+
[n for n in react_existing_ids if isinstance(n, int)], default=0
|
|
170
|
+
)
|
|
171
|
+
+ 1
|
|
172
|
+
if react_existing_ids
|
|
173
|
+
else 1
|
|
174
|
+
)
|
|
175
|
+
for missing_map in missing_in_react:
|
|
176
|
+
wc_id = react_next_id
|
|
177
|
+
react_next_id += 1
|
|
178
|
+
G_new.add_node(
|
|
179
|
+
wc_id,
|
|
180
|
+
**attributes_defaults,
|
|
181
|
+
atom_map=missing_map,
|
|
182
|
+
typesGH=(("*", False, 0, 0, []), ("*", False, 0, 0, [])),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return G_new, H_new
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def from_rsmi(rsmi: str) -> Tuple[nx.Graph, nx.Graph]:
|
|
189
|
+
"""Convert a reaction SMILES string into reactant and product graphs.
|
|
190
|
+
|
|
191
|
+
:param rsmi: Reaction SMILES string
|
|
192
|
+
:type rsmi: str
|
|
193
|
+
:return: Tuple (reactant_graph, product_graph)
|
|
194
|
+
:rtype: Tuple[nx.Graph, nx.Graph]
|
|
195
|
+
:raises ValueError: If input cannot be parsed.
|
|
196
|
+
"""
|
|
197
|
+
try:
|
|
198
|
+
return rsmi_to_graph(rsmi)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
raise ValueError(f"Could not parse RSMI: {rsmi}") from e
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def to_smi(G: nx.Graph) -> str:
|
|
204
|
+
"""Convert a networkx molecular graph to a canonical SMILES string.
|
|
205
|
+
|
|
206
|
+
:param G: Molecular graph
|
|
207
|
+
:type G: nx.Graph
|
|
208
|
+
:return: SMILES string
|
|
209
|
+
:rtype: str
|
|
210
|
+
:raises ValueError: If conversion fails.
|
|
211
|
+
"""
|
|
212
|
+
try:
|
|
213
|
+
return graph_to_smi(G)
|
|
214
|
+
except Exception as e:
|
|
215
|
+
raise ValueError("Could not convert graph to SMILES") from e
|
|
216
|
+
|
|
217
|
+
@staticmethod
|
|
218
|
+
def describe():
|
|
219
|
+
"""
|
|
220
|
+
Print a description and usage example for this class.
|
|
221
|
+
"""
|
|
222
|
+
print(WildCard.__doc__)
|
|
223
|
+
|
|
224
|
+
def __repr__(self):
|
|
225
|
+
return "<WildCard: static wildcard-augmentation for reaction SMILES>"
|
synkit/Graph/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# from .Canon import GraphCanonicaliser, CanonicalGraph
|
|
2
|
+
from .utils import (
|
|
3
|
+
remove_wildcard_nodes,
|
|
4
|
+
add_wildcard_subgraph_for_unmapped,
|
|
5
|
+
print_graph_attributes,
|
|
6
|
+
clean_graph_keep_largest_component,
|
|
7
|
+
has_wildcard_node,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# __all__ = [
|
|
11
|
+
# "GraphCanonicaliser",
|
|
12
|
+
# "CanonicalGraph",
|
|
13
|
+
# "remove_wildcard_nodes",
|
|
14
|
+
# "add_wildcard_subgraph_for_unmapped",
|
|
15
|
+
# "print_graph_attributes",
|
|
16
|
+
# "clean_graph_keep_largest_component",
|
|
17
|
+
# ]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Backward-compatible import path for graph canonicalization.
|
|
2
|
+
|
|
3
|
+
The maintained implementation lives in :mod:`synkit.Graph.Canon.canon_graph`.
|
|
4
|
+
Keeping this module as a pure re-export prevents the two historical paths from
|
|
5
|
+
silently diverging again.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .Canon.canon_graph import (
|
|
9
|
+
CanonicalGraph,
|
|
10
|
+
CanonicalRule,
|
|
11
|
+
GraphCanonicaliser,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = ["CanonicalGraph", "CanonicalRule", "GraphCanonicaliser"]
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""synkit.Graph.syn_graph
|
|
2
|
+
======================
|
|
3
|
+
|
|
4
|
+
Wrapper around `networkx.Graph` providing both original and canonical forms,
|
|
5
|
+
plus a SHA‑256 signature for fast isomorphism checks.
|
|
6
|
+
|
|
7
|
+
Key features
|
|
8
|
+
------------
|
|
9
|
+
* **Value‑object semantics** – `__eq__` and `__hash__` use structural plus
|
|
10
|
+
map-invariant stereo identity, so graphs can be used in sets/dicts.
|
|
11
|
+
* **Lazy canonicalisation** – canonical graph & signature are computed once on demand
|
|
12
|
+
(cached internally) to avoid upfront cost when not needed.
|
|
13
|
+
* **Transparent delegation** – any unknown attribute/method is forwarded to the raw graph.
|
|
14
|
+
|
|
15
|
+
.. rubric:: Example
|
|
16
|
+
|
|
17
|
+
>>> G = nx.Graph(); G.add_node(1, element='C')
|
|
18
|
+
>>> SG = SynGraph(G)
|
|
19
|
+
>>> SG.signature # 32‑hex SHA‑256 digest
|
|
20
|
+
'8dc1f7b843e447ff4b67bf0ccc175f63'
|
|
21
|
+
>>> SG.canonical # relabelled, sorted graph
|
|
22
|
+
<networkx.Graph with 1 nodes>
|
|
23
|
+
>>>
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
import hashlib
|
|
28
|
+
from typing import Any, Dict, Iterable, Optional, Tuple, Union
|
|
29
|
+
|
|
30
|
+
import networkx as nx
|
|
31
|
+
|
|
32
|
+
from synkit.Graph.canon_graph import GraphCanonicaliser
|
|
33
|
+
from synkit.Graph.Stereo.identity import (
|
|
34
|
+
stereo_identity_edge_match,
|
|
35
|
+
stereo_identity_form,
|
|
36
|
+
stereo_identity_node_match,
|
|
37
|
+
stereo_identity_signature,
|
|
38
|
+
)
|
|
39
|
+
from synkit.Graph.Stereo.matching import stereo_isomorphic
|
|
40
|
+
|
|
41
|
+
__all__ = ["SynGraph"]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SynGraph:
|
|
45
|
+
"""Wrapper around networkx.Graph providing both its original and
|
|
46
|
+
(optionally) canonicalized form, plus a SHA-256 signature.
|
|
47
|
+
|
|
48
|
+
:param graph: The NetworkX graph to wrap.
|
|
49
|
+
:type graph: nx.Graph
|
|
50
|
+
:param canonicaliser: If provided, used to
|
|
51
|
+
produce the canonical form; otherwise a default is constructed.
|
|
52
|
+
:type canonicaliser: Optional[GraphCanonicaliser]
|
|
53
|
+
:param canon: If True (default), computes and stores both
|
|
54
|
+
`.canonical` and `.signature`. Otherwise they remain None.
|
|
55
|
+
:type canon: bool
|
|
56
|
+
|
|
57
|
+
.. rubric:: Attributes
|
|
58
|
+
|
|
59
|
+
* raw nx.Graph The original graph.
|
|
60
|
+
* canonical Optional[nx.Graph] The canonicalized graph (or None).
|
|
61
|
+
* signature Optional[str] The SHA-256 hex digest (or None).
|
|
62
|
+
|
|
63
|
+
.. rubric:: Methods
|
|
64
|
+
|
|
65
|
+
* get_nodes(data: bool = True) -> Iterable[…]
|
|
66
|
+
* get_edges(data: bool = True) -> Iterable[…]
|
|
67
|
+
* help() Print this API summary.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
graph: nx.Graph,
|
|
73
|
+
canonicaliser: Optional[GraphCanonicaliser] = None,
|
|
74
|
+
canon: bool = True,
|
|
75
|
+
) -> None:
|
|
76
|
+
"""Initialize a SynGraph wrapper.
|
|
77
|
+
|
|
78
|
+
:param graph: Input graph.
|
|
79
|
+
:type graph: nx.Graph
|
|
80
|
+
:param canonicaliser: Canonicaliser instance.
|
|
81
|
+
:type canonicaliser: Optional[GraphCanonicaliser]
|
|
82
|
+
:param canon: Whether to compute canonical form/signature.
|
|
83
|
+
:type canon: bool
|
|
84
|
+
"""
|
|
85
|
+
self._raw: nx.Graph = graph
|
|
86
|
+
self._canonicaliser: GraphCanonicaliser = canonicaliser or GraphCanonicaliser()
|
|
87
|
+
self._do_canon: bool = canon
|
|
88
|
+
|
|
89
|
+
if self._do_canon:
|
|
90
|
+
# build & store canonical graph
|
|
91
|
+
self._canonical: nx.Graph = self._canonicaliser.make_canonical_graph(graph)
|
|
92
|
+
else:
|
|
93
|
+
# skip canonicalisation
|
|
94
|
+
self._canonical = None
|
|
95
|
+
|
|
96
|
+
def __getattr__(self, name: str) -> Any:
|
|
97
|
+
"""Delegate any unknown attribute lookup to the underlying ._raw
|
|
98
|
+
graph."""
|
|
99
|
+
return getattr(self._raw, name)
|
|
100
|
+
|
|
101
|
+
def __eq__(self, other: object) -> bool:
|
|
102
|
+
"""Compare canonical identity, resolving stereo collisions exactly."""
|
|
103
|
+
if not isinstance(other, SynGraph):
|
|
104
|
+
return False
|
|
105
|
+
if self.signature != other.signature:
|
|
106
|
+
return False
|
|
107
|
+
left_stereo = self.stereo_signature
|
|
108
|
+
right_stereo = other.stereo_signature
|
|
109
|
+
if left_stereo is None or right_stereo is None:
|
|
110
|
+
return left_stereo is right_stereo
|
|
111
|
+
return stereo_isomorphic(
|
|
112
|
+
self._raw,
|
|
113
|
+
other._raw,
|
|
114
|
+
node_match=stereo_identity_node_match,
|
|
115
|
+
edge_match=stereo_identity_edge_match,
|
|
116
|
+
unknown_policy="exact",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def __hash__(self) -> int:
|
|
120
|
+
"""Hash on the signature, allowing use in sets and as dict keys."""
|
|
121
|
+
return hash(self.signature)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def raw(self) -> nx.Graph:
|
|
125
|
+
"""The original NetworkX graph."""
|
|
126
|
+
return self._raw
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def canonical(self) -> Optional[nx.Graph]:
|
|
130
|
+
"""The canonicalized graph, or None if canon=False."""
|
|
131
|
+
return self._canonical
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def signature(self) -> Optional[str]:
|
|
135
|
+
"""Combined structural/stereo digest, preserving legacy plain graphs."""
|
|
136
|
+
structural = self.structural_signature
|
|
137
|
+
stereo = self.stereo_signature
|
|
138
|
+
if stereo is None:
|
|
139
|
+
return structural
|
|
140
|
+
return hashlib.sha256(
|
|
141
|
+
f"{structural}|stereo:{stereo}".encode("utf-8")
|
|
142
|
+
).hexdigest()[:32]
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def structural_signature(self) -> str:
|
|
146
|
+
"""Legacy connectivity/Lewis-state signature from the canonicaliser."""
|
|
147
|
+
return self._canonicaliser.canonical_signature(self._raw)
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def stereo_form(self) -> tuple[Any, ...]:
|
|
151
|
+
"""Inspectable map-invariant form of all molecule or ITS stereo layers."""
|
|
152
|
+
return stereo_identity_form(self._raw)
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def stereo_signature(self) -> str | None:
|
|
156
|
+
"""Digest of :attr:`stereo_form`, or ``None`` when stereo is absent."""
|
|
157
|
+
return stereo_identity_signature(self._raw)
|
|
158
|
+
|
|
159
|
+
def get_nodes(
|
|
160
|
+
self, data: bool = True
|
|
161
|
+
) -> Iterable[Union[Any, Tuple[Any, Dict[str, Any]]]]:
|
|
162
|
+
"""Yield nodes from the original graph.
|
|
163
|
+
|
|
164
|
+
:param data: If True, yield (node, data_dict), else just node IDs.
|
|
165
|
+
:type data: bool, default True
|
|
166
|
+
"""
|
|
167
|
+
return self._raw.nodes(data=data)
|
|
168
|
+
|
|
169
|
+
def get_edges(
|
|
170
|
+
self, data: bool = True
|
|
171
|
+
) -> Iterable[Union[Tuple[Any, Any], Tuple[Any, Any, Dict[str, Any]]]]:
|
|
172
|
+
"""Yield edges from the original graph.
|
|
173
|
+
|
|
174
|
+
:param data: If True, yield (u, v, data_dict), else just (u, v).
|
|
175
|
+
:type data: bool, default True
|
|
176
|
+
"""
|
|
177
|
+
return self._raw.edges(data=data)
|
|
178
|
+
|
|
179
|
+
def __repr__(self) -> str:
|
|
180
|
+
try:
|
|
181
|
+
v = self._raw.number_of_nodes()
|
|
182
|
+
e = self._raw.number_of_edges()
|
|
183
|
+
except Exception:
|
|
184
|
+
v = e = 0
|
|
185
|
+
return f"<SynGraph |V|={v} |E|={e} sig={self.signature[:8]}>"
|
|
186
|
+
|
|
187
|
+
def help(self) -> None:
|
|
188
|
+
"""Print a summary of the SynGraph API."""
|
|
189
|
+
print(
|
|
190
|
+
"SynGraph Help\n"
|
|
191
|
+
"----------\n"
|
|
192
|
+
"raw original networkx.Graph\n"
|
|
193
|
+
"canonical canonical networkx.Graph\n"
|
|
194
|
+
"signature combined structural/stereo SHA-256 digest\n"
|
|
195
|
+
"stereo_form inspectable map-invariant descriptor form\n"
|
|
196
|
+
"get_nodes() nodes (with data)\n"
|
|
197
|
+
"get_edges() edges (with data)\n"
|
|
198
|
+
"__eq__/__hash__ use signature for comparisons"
|
|
199
|
+
)
|