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,170 @@
|
|
|
1
|
+
"""Native non-stereo graph-composition facade for :class:`SynRule`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, Mapping
|
|
8
|
+
|
|
9
|
+
from synkit.Rule.Apply import (
|
|
10
|
+
EnvironmentToken,
|
|
11
|
+
RuleSpan,
|
|
12
|
+
SystemBoundary,
|
|
13
|
+
rule_from_synrule,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .composition import CompositionResult, RuleOverlap, compose_rules
|
|
17
|
+
from .search import (
|
|
18
|
+
CompositionSearchResult,
|
|
19
|
+
OverlapSearchLimits,
|
|
20
|
+
search_compositions,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SynRuleCompositionIssueCode(str, Enum):
|
|
25
|
+
"""Typed losses refused by the native SynRule composition adapter."""
|
|
26
|
+
|
|
27
|
+
WRONG_TYPE = "SYNRULE_COMPOSITION_WRONG_TYPE"
|
|
28
|
+
STEREO_UNSUPPORTED = "SYNRULE_COMPOSITION_STEREO_UNSUPPORTED"
|
|
29
|
+
WILDCARD_UNSUPPORTED = "SYNRULE_COMPOSITION_WILDCARD_UNSUPPORTED"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class SynRuleCompositionIssue:
|
|
34
|
+
code: SynRuleCompositionIssueCode
|
|
35
|
+
message: str
|
|
36
|
+
context: Mapping[str, Any] = field(default_factory=dict)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class SynRuleCompositionError(ValueError):
|
|
40
|
+
"""Raised rather than silently dropping unsupported SynRule semantics."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, *issues: SynRuleCompositionIssue):
|
|
43
|
+
self.issues = tuple(issues)
|
|
44
|
+
super().__init__("; ".join(issue.message for issue in issues))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _validate_synrule(rule: Any) -> None:
|
|
48
|
+
from synkit.Rule.syn_rule import SynRule
|
|
49
|
+
|
|
50
|
+
if not isinstance(rule, SynRule):
|
|
51
|
+
raise SynRuleCompositionError(
|
|
52
|
+
SynRuleCompositionIssue(
|
|
53
|
+
SynRuleCompositionIssueCode.WRONG_TYPE,
|
|
54
|
+
"Native SynRule composition expects SynRule values.",
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
stereo_fields = (
|
|
58
|
+
"stereo_guards",
|
|
59
|
+
"stereo_effects",
|
|
60
|
+
"stereo_outcomes",
|
|
61
|
+
"stereo_couplings",
|
|
62
|
+
"stereo_query_policies",
|
|
63
|
+
)
|
|
64
|
+
active_stereo = tuple(name for name in stereo_fields if getattr(rule, name, {}))
|
|
65
|
+
if active_stereo:
|
|
66
|
+
raise SynRuleCompositionError(
|
|
67
|
+
SynRuleCompositionIssue(
|
|
68
|
+
SynRuleCompositionIssueCode.STEREO_UNSUPPORTED,
|
|
69
|
+
"The non-stereo LLG compositor cannot erase SynRule stereo semantics.",
|
|
70
|
+
{"fields": active_stereo},
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
wildcard_nodes = tuple(
|
|
74
|
+
sorted(
|
|
75
|
+
{
|
|
76
|
+
repr(node)
|
|
77
|
+
for graph in (rule.left.raw, rule.right.raw)
|
|
78
|
+
for node, attrs in graph.nodes(data=True)
|
|
79
|
+
if "wildcard_role" in attrs
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
if wildcard_nodes:
|
|
84
|
+
raise SynRuleCompositionError(
|
|
85
|
+
SynRuleCompositionIssue(
|
|
86
|
+
SynRuleCompositionIssueCode.WILDCARD_UNSUPPORTED,
|
|
87
|
+
"The current LLG schema cannot erase typed-wildcard contracts.",
|
|
88
|
+
{"nodes": wildcard_nodes},
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _electron_mode(rule: Any, requested: bool | None) -> bool:
|
|
94
|
+
return getattr(rule, "_format", None) == "tuple" if requested is None else requested
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def synrule_to_span(
|
|
98
|
+
rule: Any,
|
|
99
|
+
*,
|
|
100
|
+
electron_complete: bool | None = None,
|
|
101
|
+
boundary: SystemBoundary | str = SystemBoundary.ABSTRACT,
|
|
102
|
+
environment: EnvironmentToken | None = None,
|
|
103
|
+
) -> RuleSpan:
|
|
104
|
+
"""Adapt a supported SynRule to a native DPO span without optional backends."""
|
|
105
|
+
_validate_synrule(rule)
|
|
106
|
+
return rule_from_synrule(
|
|
107
|
+
rule,
|
|
108
|
+
electron_complete=_electron_mode(rule, electron_complete),
|
|
109
|
+
boundary=boundary,
|
|
110
|
+
environment=environment,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _synrule_pair(
|
|
115
|
+
first: Any,
|
|
116
|
+
second: Any,
|
|
117
|
+
electron_complete: bool | None,
|
|
118
|
+
) -> tuple[RuleSpan, RuleSpan]:
|
|
119
|
+
_validate_synrule(first)
|
|
120
|
+
_validate_synrule(second)
|
|
121
|
+
complete = (
|
|
122
|
+
getattr(first, "_format", None) == getattr(second, "_format", None) == "tuple"
|
|
123
|
+
if electron_complete is None
|
|
124
|
+
else electron_complete
|
|
125
|
+
)
|
|
126
|
+
return (
|
|
127
|
+
synrule_to_span(first, electron_complete=complete),
|
|
128
|
+
synrule_to_span(second, electron_complete=complete),
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def compose_synrules(
|
|
133
|
+
first: Any,
|
|
134
|
+
second: Any,
|
|
135
|
+
overlap: Mapping[Any, Any],
|
|
136
|
+
*,
|
|
137
|
+
overlap_edges: set[frozenset[Any]] | None = None,
|
|
138
|
+
electron_complete: bool | None = None,
|
|
139
|
+
) -> CompositionResult:
|
|
140
|
+
"""Compose two SynRules along one caller-declared material overlap."""
|
|
141
|
+
first_span, second_span = _synrule_pair(first, second, electron_complete)
|
|
142
|
+
witness = RuleOverlap.from_mapping(
|
|
143
|
+
first_span.right,
|
|
144
|
+
second_span.left,
|
|
145
|
+
overlap,
|
|
146
|
+
overlap_edges=overlap_edges,
|
|
147
|
+
)
|
|
148
|
+
return compose_rules(first_span, second_span, witness)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def search_synrule_compositions(
|
|
152
|
+
first: Any,
|
|
153
|
+
second: Any,
|
|
154
|
+
*,
|
|
155
|
+
limits: OverlapSearchLimits | None = None,
|
|
156
|
+
electron_complete: bool | None = None,
|
|
157
|
+
) -> CompositionSearchResult:
|
|
158
|
+
"""Return the complete bounded family; never choose a preferred composite."""
|
|
159
|
+
first_span, second_span = _synrule_pair(first, second, electron_complete)
|
|
160
|
+
return search_compositions(first_span, second_span, limits=limits)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
__all__ = [
|
|
164
|
+
"SynRuleCompositionError",
|
|
165
|
+
"SynRuleCompositionIssue",
|
|
166
|
+
"SynRuleCompositionIssueCode",
|
|
167
|
+
"compose_synrules",
|
|
168
|
+
"search_synrule_compositions",
|
|
169
|
+
"synrule_to_span",
|
|
170
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from typing import Union, List, Any
|
|
2
|
+
from synkit.Chem.Reaction import remove_explicit_H_from_rsmi
|
|
3
|
+
from synkit.IO import rsmi_to_graph, setup_logging
|
|
4
|
+
from synkit.Graph.ITS import ITSConstruction, get_rc
|
|
5
|
+
|
|
6
|
+
logger = setup_logging()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def implicit_rule(
|
|
10
|
+
rsmi: Union[str, List[str]], disconnected: bool = True, balance_its: bool = False
|
|
11
|
+
) -> Union[Any, List[Any]]:
|
|
12
|
+
"""Construct reaction-center objects from reaction SMILES by applying
|
|
13
|
+
implicit‐H rules and ITS graph construction.
|
|
14
|
+
|
|
15
|
+
:param rsmi: A reaction SMILES string, or a list thereof.
|
|
16
|
+
:type rsmi: str or list of str
|
|
17
|
+
:param disconnected: Whether to allow disconnected components in the reaction center (default: True).
|
|
18
|
+
:type disconnected: bool, optional
|
|
19
|
+
:param balance_its: Whether to enforce atom‐balance in the ITS graph (default: False).
|
|
20
|
+
:type balance_its: bool, optional
|
|
21
|
+
|
|
22
|
+
:return: The reaction‐center object(s) extracted from the ITS graph.
|
|
23
|
+
:rtype: RC or list of RC
|
|
24
|
+
|
|
25
|
+
:raises ValueError: If an empty SMILES string is provided.
|
|
26
|
+
:raises TypeError: If `rsmi` is not a string or list of strings.
|
|
27
|
+
:raises RuntimeError: If graph conversion or ITS construction fails.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def _process(smiles: str) -> Any:
|
|
31
|
+
if not smiles:
|
|
32
|
+
raise ValueError("Empty reaction SMILES provided.")
|
|
33
|
+
try:
|
|
34
|
+
# 1. Remove explicit hydrogens
|
|
35
|
+
sanitized = remove_explicit_H_from_rsmi(smiles)
|
|
36
|
+
# 2. Convert to reactant/product graphs
|
|
37
|
+
react_graph, prod_graph = rsmi_to_graph(sanitized)
|
|
38
|
+
# 3. Build ITS graph
|
|
39
|
+
its_graph = ITSConstruction().ITSGraph(
|
|
40
|
+
react_graph, prod_graph, balance_its=balance_its
|
|
41
|
+
)
|
|
42
|
+
# 4. Extract reaction center
|
|
43
|
+
return get_rc(its_graph, disconnected=disconnected)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
logger.error("Error processing RSMI '%s': %s", smiles, e)
|
|
46
|
+
raise RuntimeError(f"Failed to construct ITS for '{smiles}': {e}")
|
|
47
|
+
|
|
48
|
+
# Handle single string or list of strings
|
|
49
|
+
if isinstance(rsmi, str):
|
|
50
|
+
return _process(rsmi)
|
|
51
|
+
elif isinstance(rsmi, list):
|
|
52
|
+
return [_process(s) for s in rsmi]
|
|
53
|
+
else:
|
|
54
|
+
raise TypeError(
|
|
55
|
+
f"`rsmi` must be a str or list of str, not {type(rsmi).__name__}"
|
|
56
|
+
)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from collections import deque
|
|
3
|
+
from typing import Tuple, List, Set
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LongestPath:
|
|
7
|
+
def __init__(self, G: nx.Graph):
|
|
8
|
+
"""Initializes the LongestPath object with a graph.
|
|
9
|
+
|
|
10
|
+
:param G: The networkx graph.
|
|
11
|
+
:type G: nx.Graph
|
|
12
|
+
"""
|
|
13
|
+
self.G = G
|
|
14
|
+
self.vertices = len(G.nodes)
|
|
15
|
+
|
|
16
|
+
def BFS(self, u: int) -> Tuple[int, int]:
|
|
17
|
+
"""Performs a Breadth-First Search (BFS) from a given node `u` to find
|
|
18
|
+
the farthest node and its distance.
|
|
19
|
+
|
|
20
|
+
:param u: The starting node for the BFS.
|
|
21
|
+
:type u: int
|
|
22
|
+
|
|
23
|
+
:return: The farthest node from `u` and its distance.
|
|
24
|
+
:rtype: Tuple[int, int]
|
|
25
|
+
"""
|
|
26
|
+
# Initialize visited and distance dictionaries
|
|
27
|
+
visited = {i: False for i in self.G.nodes}
|
|
28
|
+
distance = {i: -1 for i in self.G.nodes}
|
|
29
|
+
|
|
30
|
+
# Distance of `u` from itself is 0
|
|
31
|
+
distance[u] = 0
|
|
32
|
+
queue = deque([u])
|
|
33
|
+
visited[u] = True
|
|
34
|
+
|
|
35
|
+
while queue:
|
|
36
|
+
front = queue.popleft()
|
|
37
|
+
|
|
38
|
+
# Explore neighbors of the current node
|
|
39
|
+
for neighbor in self.G.neighbors(front):
|
|
40
|
+
if not visited[neighbor]:
|
|
41
|
+
visited[neighbor] = True
|
|
42
|
+
distance[neighbor] = distance[front] + 1
|
|
43
|
+
queue.append(neighbor)
|
|
44
|
+
|
|
45
|
+
# Find the farthest node and its distance
|
|
46
|
+
maxDis = 0
|
|
47
|
+
nodeIdx = u # Default to start node if no farther node is found
|
|
48
|
+
for node, dist in distance.items():
|
|
49
|
+
if dist > maxDis:
|
|
50
|
+
maxDis = dist
|
|
51
|
+
nodeIdx = node
|
|
52
|
+
|
|
53
|
+
return nodeIdx, maxDis
|
|
54
|
+
|
|
55
|
+
def LongestPathInDisconnectedGraph(self) -> int:
|
|
56
|
+
"""Finds the longest path in a potentially disconnected graph. The
|
|
57
|
+
graph can consist of multiple components.
|
|
58
|
+
|
|
59
|
+
This method performs a BFS on every unvisited component to find the
|
|
60
|
+
farthest node and computes the longest path across all components.
|
|
61
|
+
|
|
62
|
+
:return: The length of the longest path in the graph across all components.
|
|
63
|
+
:rtype: int
|
|
64
|
+
"""
|
|
65
|
+
visited_components: Set[int] = set()
|
|
66
|
+
longest_path: int = 0
|
|
67
|
+
component_paths: List[Tuple[int, int, int]] = []
|
|
68
|
+
|
|
69
|
+
# Iterate over all nodes to ensure all components are covered
|
|
70
|
+
for node in self.G.nodes:
|
|
71
|
+
if node not in visited_components:
|
|
72
|
+
# First BFS to find one end point of the longest path in this component
|
|
73
|
+
farthest_node, _ = self.BFS(node)
|
|
74
|
+
|
|
75
|
+
# Second BFS from that node to find the actual longest path
|
|
76
|
+
node_2, component_longest_path = self.BFS(farthest_node)
|
|
77
|
+
|
|
78
|
+
# Track the longest path found
|
|
79
|
+
longest_path = max(longest_path, component_longest_path)
|
|
80
|
+
component_paths.append((farthest_node, node_2, component_longest_path))
|
|
81
|
+
|
|
82
|
+
# Mark all nodes in this component as visited
|
|
83
|
+
queue = deque([farthest_node])
|
|
84
|
+
while queue:
|
|
85
|
+
current = queue.popleft()
|
|
86
|
+
if current not in visited_components:
|
|
87
|
+
visited_components.add(current)
|
|
88
|
+
for neighbor in self.G.neighbors(current):
|
|
89
|
+
if neighbor not in visited_components:
|
|
90
|
+
queue.append(neighbor)
|
|
91
|
+
|
|
92
|
+
return longest_path
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from rdkit import Chem
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from synkit.IO.chem_converter import smart_to_gml
|
|
5
|
+
from synkit.Rule.Modify.strip_rule import strip_context
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MoleculeRule:
|
|
9
|
+
"""A class for generating molecule rules, atom-mapped SMILES, and GML
|
|
10
|
+
representations from SMILES strings."""
|
|
11
|
+
|
|
12
|
+
def __init__(self) -> None:
|
|
13
|
+
"""Initializes the MoleculeRule object."""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def remove_edges_from_left_right(input_str: str) -> str:
|
|
18
|
+
"""Remove all contents from the 'left' and 'right' sections of a
|
|
19
|
+
chemical rule description.
|
|
20
|
+
|
|
21
|
+
:param input_str: The string representation of the rule.
|
|
22
|
+
:type input_str: str
|
|
23
|
+
|
|
24
|
+
:return: The modified string with cleared 'left' and 'right' sections.
|
|
25
|
+
:rtype: str
|
|
26
|
+
"""
|
|
27
|
+
# Pattern to match 'left [' to the matching ']'
|
|
28
|
+
left_pattern = r"(left \[)(.*?)(^\s*\])"
|
|
29
|
+
# Pattern to match 'right [' to the matching ']'
|
|
30
|
+
right_pattern = r"(right \[)(.*?)(^\s*\])"
|
|
31
|
+
|
|
32
|
+
# Replace contents within 'left [' and 'right [' sections using non-greedy matching
|
|
33
|
+
# Multiline mode to handle newlines and match start of lines with '^'
|
|
34
|
+
input_str = re.sub(
|
|
35
|
+
left_pattern, r"\1\n \3", input_str, flags=re.DOTALL | re.MULTILINE
|
|
36
|
+
)
|
|
37
|
+
input_str = re.sub(
|
|
38
|
+
right_pattern, r"\1\n \3", input_str, flags=re.DOTALL | re.MULTILINE
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return input_str
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def generate_atom_map(smiles: str) -> Optional[str]:
|
|
45
|
+
"""Generate atom-mapped SMILES by assigning unique map numbers to each
|
|
46
|
+
atom in the molecule.
|
|
47
|
+
|
|
48
|
+
:param smiles: The SMILES string representing the molecule.
|
|
49
|
+
:type smiles: str
|
|
50
|
+
|
|
51
|
+
:return: The atom-mapped SMILES string, or None if the SMILES string is invalid.
|
|
52
|
+
:rtype: Optional[str]
|
|
53
|
+
"""
|
|
54
|
+
mol = Chem.MolFromSmiles(smiles)
|
|
55
|
+
if not mol:
|
|
56
|
+
return None # Invalid SMILES
|
|
57
|
+
|
|
58
|
+
# Assign atom map numbers (1-based index)
|
|
59
|
+
for idx, atom in enumerate(mol.GetAtoms()):
|
|
60
|
+
atom.SetAtomMapNum(idx + 1)
|
|
61
|
+
|
|
62
|
+
# Return the SMILES with atom map
|
|
63
|
+
return Chem.MolToSmiles(mol, canonical=True)
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def generate_molecule_smart(smiles: str) -> Optional[str]:
|
|
67
|
+
"""Generate a SMARTS-like string from atom-mapped SMILES.
|
|
68
|
+
|
|
69
|
+
:param smiles: The SMILES string representing the molecule.
|
|
70
|
+
:type smiles: str
|
|
71
|
+
|
|
72
|
+
:return: The SMARTS-like string derived from atom-mapped SMILES, or None if the SMILES is invalid.
|
|
73
|
+
:rtype: Optional[str]
|
|
74
|
+
"""
|
|
75
|
+
atom_map_smiles = MoleculeRule.generate_atom_map(smiles)
|
|
76
|
+
if atom_map_smiles is None:
|
|
77
|
+
return None # Invalid SMILES
|
|
78
|
+
|
|
79
|
+
# Return the SMARTS-like string
|
|
80
|
+
return f"{atom_map_smiles}>>{atom_map_smiles}"
|
|
81
|
+
|
|
82
|
+
def generate_molecule_rule(
|
|
83
|
+
self,
|
|
84
|
+
smiles: str,
|
|
85
|
+
name: str = "molecule",
|
|
86
|
+
explicit_hydrogen: bool = True,
|
|
87
|
+
sanitize: bool = True,
|
|
88
|
+
) -> Optional[str]:
|
|
89
|
+
"""Generate a GML representation of the molecule rule from SMILES.
|
|
90
|
+
|
|
91
|
+
:param smiles: The SMILES string representing the molecule.
|
|
92
|
+
:type smiles: str
|
|
93
|
+
:param name: The rule name used in GML generation. Defaults to 'molecule'.
|
|
94
|
+
:type name: str, optional
|
|
95
|
+
:param explicit_hydrogen: Whether to include explicit hydrogen atoms in GML. Defaults to True.
|
|
96
|
+
:type explicit_hydrogen: bool, optional
|
|
97
|
+
:param sanitize: Whether to sanitize the molecule before conversion. Defaults to True.
|
|
98
|
+
:type sanitize: bool, optional
|
|
99
|
+
|
|
100
|
+
:return: The GML representation of the molecule rule, or None if invalid.
|
|
101
|
+
:rtype: Optional[str]
|
|
102
|
+
"""
|
|
103
|
+
rsmi = self.generate_molecule_smart(smiles)
|
|
104
|
+
if rsmi is None:
|
|
105
|
+
return None # Invalid SMARTS string
|
|
106
|
+
# Return the GML representation
|
|
107
|
+
gml = smart_to_gml(
|
|
108
|
+
rsmi,
|
|
109
|
+
core=False,
|
|
110
|
+
sanitize=sanitize,
|
|
111
|
+
explicit_hydrogen=explicit_hydrogen,
|
|
112
|
+
rule_name=name,
|
|
113
|
+
)
|
|
114
|
+
gml = strip_context(gml, False)
|
|
115
|
+
return gml
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
from synkit.Rule.Modify.longest_path import LongestPath
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PruneTemplate:
|
|
8
|
+
def __init__(self, templates: List[List[Dict[str, Any]]], graph_key: str) -> None:
|
|
9
|
+
"""Initialize the PruneTemplate object with the provided templates and
|
|
10
|
+
graph key.
|
|
11
|
+
|
|
12
|
+
:param templates: A list of lists containing dictionaries
|
|
13
|
+
where the graph can be accessed by the provided graph_key.
|
|
14
|
+
:type templates: List[List[Dict[str, Any]]]
|
|
15
|
+
:param graph_key: The key used to access the graph from each template dictionary.
|
|
16
|
+
:type graph_key: str
|
|
17
|
+
"""
|
|
18
|
+
self.max_radius = len(templates)
|
|
19
|
+
self.templates = deepcopy(templates)
|
|
20
|
+
self.graph_key = graph_key
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def remove_edges_by_attribute(
|
|
24
|
+
input_graph: nx.Graph, attribute: str = "standard_order", value: Any = 0
|
|
25
|
+
) -> nx.Graph:
|
|
26
|
+
"""Remove edges from the input graph where a given attribute equals a
|
|
27
|
+
specified value.
|
|
28
|
+
|
|
29
|
+
:param input_graph: The input graph from which edges will be removed.
|
|
30
|
+
:type input_graph: nx.Graph
|
|
31
|
+
:param attribute: The edge attribute based on which edges will
|
|
32
|
+
be removed. Default is 'standard_order'.
|
|
33
|
+
:type attribute: str, optional
|
|
34
|
+
:param value: The value of the attribute that determines
|
|
35
|
+
which edges to remove. Default is 0.
|
|
36
|
+
:type value: Any, optional
|
|
37
|
+
|
|
38
|
+
:return: A new graph with the specified edges removed.
|
|
39
|
+
:rtype: nx.Graph
|
|
40
|
+
"""
|
|
41
|
+
# Find edges where the specified attribute equals the given value
|
|
42
|
+
graph = deepcopy(input_graph)
|
|
43
|
+
edges_to_remove = [
|
|
44
|
+
(u, v)
|
|
45
|
+
for u, v, attrs in graph.edges(data=True)
|
|
46
|
+
if attrs.get(attribute) != value
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
graph.remove_edges_from(edges_to_remove)
|
|
50
|
+
|
|
51
|
+
return graph
|
|
52
|
+
|
|
53
|
+
def fit(self) -> List[List[Dict[str, Any]]]:
|
|
54
|
+
"""Prune the templates by removing subgraphs where the longest path is
|
|
55
|
+
shorter than the radius.
|
|
56
|
+
|
|
57
|
+
:return: The pruned list of templates.
|
|
58
|
+
:rtype: List[List[Dict[str, Any]]]
|
|
59
|
+
"""
|
|
60
|
+
for radius, template in enumerate(self.templates):
|
|
61
|
+
if radius > 0:
|
|
62
|
+
for key in reversed(range(len(template))):
|
|
63
|
+
temp = template[key]
|
|
64
|
+
|
|
65
|
+
subgraph = temp.get(self.graph_key, None)[2]
|
|
66
|
+
|
|
67
|
+
if subgraph is None:
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
pruned_graph = PruneTemplate.remove_edges_by_attribute(subgraph)
|
|
71
|
+
|
|
72
|
+
path_calculator = LongestPath(pruned_graph)
|
|
73
|
+
longest_path = path_calculator.LongestPathInDisconnectedGraph()
|
|
74
|
+
|
|
75
|
+
if longest_path < radius:
|
|
76
|
+
template.pop(key)
|
|
77
|
+
|
|
78
|
+
return self.templates
|