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,267 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Iterable, List, Dict, Any, Callable, Optional
|
|
3
|
+
|
|
4
|
+
from joblib import Parallel, delayed
|
|
5
|
+
import joblib
|
|
6
|
+
|
|
7
|
+
# optional progress bar
|
|
8
|
+
try:
|
|
9
|
+
from tqdm.auto import tqdm
|
|
10
|
+
except ImportError: # tqdm not installed
|
|
11
|
+
tqdm = None
|
|
12
|
+
|
|
13
|
+
from synkit.Chem.Reaction.standardize import Standardize
|
|
14
|
+
from synkit.Chem.utils import clean_radical_rsmi
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _TqdmJoblib:
|
|
18
|
+
def __init__(self, tqdm_obj):
|
|
19
|
+
self.tqdm_obj = tqdm_obj
|
|
20
|
+
self._old_batch_callback = None
|
|
21
|
+
|
|
22
|
+
def __enter__(self):
|
|
23
|
+
self._old_batch_callback = joblib.parallel.BatchCompletionCallBack
|
|
24
|
+
|
|
25
|
+
class TqdmBatchCompletionCallback(joblib.parallel.BatchCompletionCallBack): # type: ignore[valid-type]
|
|
26
|
+
def __call__(self_inner, *args, **kwargs):
|
|
27
|
+
try:
|
|
28
|
+
self.tqdm_obj.update(n=self_inner.batch_size)
|
|
29
|
+
except Exception:
|
|
30
|
+
pass
|
|
31
|
+
return super(TqdmBatchCompletionCallback, self_inner).__call__(
|
|
32
|
+
*args, **kwargs
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
joblib.parallel.BatchCompletionCallBack = TqdmBatchCompletionCallback # type: ignore[attr-defined]
|
|
36
|
+
return self.tqdm_obj
|
|
37
|
+
|
|
38
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
39
|
+
joblib.parallel.BatchCompletionCallBack = self._old_batch_callback
|
|
40
|
+
self.tqdm_obj.close()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PostSyn:
|
|
44
|
+
"""
|
|
45
|
+
Post-processing helper for reaction data: standardize reactions and clean AAM strings,
|
|
46
|
+
with optional parallelism, progress reporting, and filtering of incomplete reaction SMILES
|
|
47
|
+
inside fw/bw lists. Input keys for reaction, fw, and bw are configurable.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
n_jobs: int = 1,
|
|
53
|
+
verbose: int = 2,
|
|
54
|
+
standardizer: Optional[Standardize] = None,
|
|
55
|
+
reaction_key: str = "reactions",
|
|
56
|
+
fw_key: str = "fw",
|
|
57
|
+
bw_key: str = "bw",
|
|
58
|
+
) -> None:
|
|
59
|
+
"""
|
|
60
|
+
:param n_jobs: number of parallel jobs.
|
|
61
|
+
:param verbose: verbosity level (0=errors only,1=warnings,2=info,3=debug).
|
|
62
|
+
:param standardizer: optional Standardize instance.
|
|
63
|
+
:param reaction_key: key in input dict holding the reaction SMILES.
|
|
64
|
+
:param fw_key: key for forward AAMs/reaction SMILES list.
|
|
65
|
+
:param bw_key: key for backward AAMs/reaction SMILES list.
|
|
66
|
+
"""
|
|
67
|
+
self.n_jobs = n_jobs
|
|
68
|
+
self.verbose = verbose
|
|
69
|
+
self.std = standardizer if standardizer is not None else Standardize()
|
|
70
|
+
self.reaction_key = reaction_key
|
|
71
|
+
self.fw_key = fw_key
|
|
72
|
+
self.bw_key = bw_key
|
|
73
|
+
|
|
74
|
+
self.logger = logging.getLogger(self.__class__.__name__)
|
|
75
|
+
self._configure_logger()
|
|
76
|
+
|
|
77
|
+
def _configure_logger(self):
|
|
78
|
+
if not self.logger.hasHandlers():
|
|
79
|
+
handler = logging.StreamHandler()
|
|
80
|
+
fmt = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
|
81
|
+
handler.setFormatter(logging.Formatter(fmt))
|
|
82
|
+
self.logger.addHandler(handler)
|
|
83
|
+
if self.verbose >= 3:
|
|
84
|
+
self.logger.setLevel(logging.DEBUG)
|
|
85
|
+
elif self.verbose == 2:
|
|
86
|
+
self.logger.setLevel(logging.INFO)
|
|
87
|
+
elif self.verbose == 1:
|
|
88
|
+
self.logger.setLevel(logging.WARNING)
|
|
89
|
+
else:
|
|
90
|
+
self.logger.setLevel(logging.ERROR)
|
|
91
|
+
|
|
92
|
+
def clean_aam(
|
|
93
|
+
self, list_aam: Iterable[str], remove_radical: bool = True
|
|
94
|
+
) -> List[str]:
|
|
95
|
+
"""
|
|
96
|
+
Remove atom-atom mappings, optionally clean radicals, deduplicate while preserving order.
|
|
97
|
+
"""
|
|
98
|
+
seen = set()
|
|
99
|
+
unique = []
|
|
100
|
+
for smi in list_aam:
|
|
101
|
+
try:
|
|
102
|
+
no_aam = self.std.fit(smi, remove_aam=True)
|
|
103
|
+
if remove_radical:
|
|
104
|
+
no_aam = clean_radical_rsmi(no_aam)
|
|
105
|
+
if no_aam and no_aam not in seen:
|
|
106
|
+
seen.add(no_aam)
|
|
107
|
+
unique.append(no_aam)
|
|
108
|
+
except Exception as exc:
|
|
109
|
+
self.logger.debug(
|
|
110
|
+
"Failed to clean AAM for %r: %s",
|
|
111
|
+
smi,
|
|
112
|
+
exc,
|
|
113
|
+
exc_info=self.verbose >= 3,
|
|
114
|
+
)
|
|
115
|
+
return unique
|
|
116
|
+
|
|
117
|
+
def _rxn_has_both_sides(self, rxn: Any) -> bool:
|
|
118
|
+
if not isinstance(rxn, str):
|
|
119
|
+
return False
|
|
120
|
+
if ">>" in rxn:
|
|
121
|
+
left, right = rxn.split(">>", 1)
|
|
122
|
+
return bool(left.strip()) and bool(right.strip())
|
|
123
|
+
parts = rxn.split(">")
|
|
124
|
+
if len(parts) == 3:
|
|
125
|
+
reactants, _, products = parts
|
|
126
|
+
return bool(reactants.strip()) and bool(products.strip())
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
def _process_single(self, value: Dict[str, Any]) -> Dict[str, Any]:
|
|
130
|
+
"""
|
|
131
|
+
Worker: standardize reaction and clean fw/bw lists based on configured keys.
|
|
132
|
+
"""
|
|
133
|
+
result = dict(value) # shallow copy
|
|
134
|
+
|
|
135
|
+
# Standardize reaction
|
|
136
|
+
raw_rxn = value.get(self.reaction_key)
|
|
137
|
+
if raw_rxn is None:
|
|
138
|
+
self.logger.warning(
|
|
139
|
+
"Missing reaction key '%s' in value: %r", self.reaction_key, value
|
|
140
|
+
)
|
|
141
|
+
result["std_rxn"] = None
|
|
142
|
+
else:
|
|
143
|
+
try:
|
|
144
|
+
result["std_rxn"] = self.std.fit(raw_rxn)
|
|
145
|
+
except Exception as exc:
|
|
146
|
+
self.logger.warning("Standardization failed for %r: %s", raw_rxn, exc)
|
|
147
|
+
result["std_rxn"] = None
|
|
148
|
+
|
|
149
|
+
# Clean fw list
|
|
150
|
+
try:
|
|
151
|
+
raw_fw = value.get(self.fw_key, [])
|
|
152
|
+
cleaned_fw = self.clean_aam(raw_fw)
|
|
153
|
+
result[self.fw_key] = cleaned_fw
|
|
154
|
+
except Exception as exc:
|
|
155
|
+
self.logger.debug(
|
|
156
|
+
"Failed cleaning fw (%s) for %r: %s",
|
|
157
|
+
self.fw_key,
|
|
158
|
+
value,
|
|
159
|
+
exc,
|
|
160
|
+
exc_info=self.verbose >= 3,
|
|
161
|
+
)
|
|
162
|
+
result[self.fw_key] = []
|
|
163
|
+
|
|
164
|
+
# Clean bw list
|
|
165
|
+
try:
|
|
166
|
+
raw_bw = value.get(self.bw_key, [])
|
|
167
|
+
cleaned_bw = self.clean_aam(raw_bw)
|
|
168
|
+
result[self.bw_key] = cleaned_bw
|
|
169
|
+
except Exception as exc:
|
|
170
|
+
self.logger.debug(
|
|
171
|
+
"Failed cleaning bw (%s) for %r: %s",
|
|
172
|
+
self.bw_key,
|
|
173
|
+
value,
|
|
174
|
+
exc,
|
|
175
|
+
exc_info=self.verbose >= 3,
|
|
176
|
+
)
|
|
177
|
+
result[self.bw_key] = []
|
|
178
|
+
|
|
179
|
+
return result
|
|
180
|
+
|
|
181
|
+
def _run_serial(
|
|
182
|
+
self, seq: List[Dict[str, Any]], progress: bool
|
|
183
|
+
) -> List[Dict[str, Any]]:
|
|
184
|
+
results = []
|
|
185
|
+
iterator = seq
|
|
186
|
+
if progress:
|
|
187
|
+
if tqdm:
|
|
188
|
+
iterator = tqdm(seq, desc="PostSyn", unit="item")
|
|
189
|
+
else:
|
|
190
|
+
self.logger.info("tqdm not available; running without progress bar.")
|
|
191
|
+
for v in iterator:
|
|
192
|
+
results.append(self._process_single(v))
|
|
193
|
+
return results
|
|
194
|
+
|
|
195
|
+
def _run_parallel(
|
|
196
|
+
self, seq: List[Dict[str, Any]], progress: bool
|
|
197
|
+
) -> List[Dict[str, Any]]:
|
|
198
|
+
if progress and tqdm:
|
|
199
|
+
try:
|
|
200
|
+
with _TqdmJoblib(tqdm(total=len(seq), desc="PostSyn", unit="item")):
|
|
201
|
+
return Parallel(
|
|
202
|
+
n_jobs=self.n_jobs, backend="loky", verbose=self.verbose
|
|
203
|
+
)(delayed(self._process_single)(v) for v in seq)
|
|
204
|
+
except Exception as e:
|
|
205
|
+
self.logger.warning(
|
|
206
|
+
"Progress-wrapped parallel execution failed (%s); falling back to normal Parallel.",
|
|
207
|
+
e,
|
|
208
|
+
)
|
|
209
|
+
elif progress and not tqdm:
|
|
210
|
+
self.logger.info(
|
|
211
|
+
"tqdm not installed; running parallel without progress bar."
|
|
212
|
+
)
|
|
213
|
+
return Parallel(n_jobs=self.n_jobs, backend="loky", verbose=self.verbose)(
|
|
214
|
+
delayed(self._process_single)(v) for v in seq
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
def _filter_fw_bw(self, results: List[Dict[str, Any]]) -> None:
|
|
218
|
+
check = self._rxn_has_both_sides
|
|
219
|
+
for value in results:
|
|
220
|
+
fw = value.get(self.fw_key, [])
|
|
221
|
+
bw = value.get(self.bw_key, [])
|
|
222
|
+
filtered_fw = [r for r in fw if check(r)]
|
|
223
|
+
filtered_bw = [r for r in bw if check(r)]
|
|
224
|
+
if self.verbose >= 3:
|
|
225
|
+
dropped_fw = len(fw) - len(filtered_fw)
|
|
226
|
+
dropped_bw = len(bw) - len(filtered_bw)
|
|
227
|
+
if dropped_fw:
|
|
228
|
+
self.logger.debug(
|
|
229
|
+
"Dropped %d incomplete fw entries for record %r", dropped_fw, fw
|
|
230
|
+
)
|
|
231
|
+
if dropped_bw:
|
|
232
|
+
self.logger.debug(
|
|
233
|
+
"Dropped %d incomplete bw entries for record %r", dropped_bw, bw
|
|
234
|
+
)
|
|
235
|
+
value[self.fw_key] = filtered_fw
|
|
236
|
+
value[self.bw_key] = filtered_bw
|
|
237
|
+
|
|
238
|
+
def process(
|
|
239
|
+
self,
|
|
240
|
+
data: Iterable[Dict[str, Any]],
|
|
241
|
+
*,
|
|
242
|
+
progress: bool = False,
|
|
243
|
+
prefilter: Optional[Callable[[Dict[str, Any]], bool]] = None,
|
|
244
|
+
filter_incomplete_rxn: bool = True,
|
|
245
|
+
) -> List[Dict[str, Any]]:
|
|
246
|
+
"""
|
|
247
|
+
Process reaction entries.
|
|
248
|
+
|
|
249
|
+
:param data: iterable of dicts.
|
|
250
|
+
:param progress: show progress bar if True.
|
|
251
|
+
:param prefilter: predicate to pre-filter entries.
|
|
252
|
+
:param filter_incomplete_rxn: if True, drop incomplete SMILES inside fw/bw.
|
|
253
|
+
:return: processed list with standardized reaction and cleaned fw/bw under their original keys.
|
|
254
|
+
"""
|
|
255
|
+
seq = list(data)
|
|
256
|
+
if prefilter:
|
|
257
|
+
seq = [v for v in seq if prefilter(v)]
|
|
258
|
+
|
|
259
|
+
if self.n_jobs == 1:
|
|
260
|
+
results = self._run_serial(seq, progress)
|
|
261
|
+
else:
|
|
262
|
+
results = self._run_parallel(seq, progress)
|
|
263
|
+
|
|
264
|
+
if filter_incomplete_rxn:
|
|
265
|
+
self._filter_fw_bw(results)
|
|
266
|
+
|
|
267
|
+
return results
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from typing import Union, List, Any
|
|
3
|
+
from synkit.Graph import remove_wildcard_nodes
|
|
4
|
+
from synkit.Graph.Matcher.turbo_iso import TurboISO
|
|
5
|
+
from synkit.Graph.Matcher.sing import SING
|
|
6
|
+
from synkit.Graph.ITS import its_decompose
|
|
7
|
+
from synkit.Graph.ITS.its_reverter import ITSReverter
|
|
8
|
+
from synkit.Graph.Matcher.subgraph_matcher import SubgraphMatch
|
|
9
|
+
from synkit.Graph.Hyrogen._misc import h_to_explicit
|
|
10
|
+
from synkit.IO.chem_converter import detect_its_format
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RuleFilter:
|
|
14
|
+
"""Filter a host graph by a list of transformation rules (patterns),
|
|
15
|
+
keeping only those rules whose (decomposed) pattern appears as a subgraph
|
|
16
|
+
in the host.
|
|
17
|
+
|
|
18
|
+
:param host_graph: The host graph to search within (will be
|
|
19
|
+
converted to explicit H).
|
|
20
|
+
:type host_graph: nx.Graph
|
|
21
|
+
:param rules_list: A list of rule objects to filter against.
|
|
22
|
+
:type rules_list: list
|
|
23
|
+
:param invert: If True, use the "modifier" component of each
|
|
24
|
+
decomposition; otherwise use the normal part.
|
|
25
|
+
:type invert: bool
|
|
26
|
+
:param engine: Matching engine to use: "turbo", "sing", or "nx".
|
|
27
|
+
:type engine: str
|
|
28
|
+
:param node_label: Node attribute(s) for TurboISO to match on.
|
|
29
|
+
:type node_label: str or list
|
|
30
|
+
:param edge_label: Edge attribute(s) for TurboISO to match on.
|
|
31
|
+
:type edge_label: str or list
|
|
32
|
+
:param distance_threshold: Threshold to skip distance filtering in
|
|
33
|
+
TurboISO.
|
|
34
|
+
:type distance_threshold: int
|
|
35
|
+
:param sing_max_path: Maximum path length for SING engine.
|
|
36
|
+
:type sing_max_path: int
|
|
37
|
+
:return: An instance with only the rules that matched.
|
|
38
|
+
:rtype: RuleFilter
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
host_graph: nx.Graph,
|
|
44
|
+
rules_list: List[Any],
|
|
45
|
+
invert: bool = False,
|
|
46
|
+
engine: str = "turbo",
|
|
47
|
+
node_label: Union[str, List[str]] = ["element", "charge"],
|
|
48
|
+
edge_label: Union[str, List[str]] = "order",
|
|
49
|
+
distance_threshold: int = 5000,
|
|
50
|
+
sing_max_path: int = 3,
|
|
51
|
+
) -> None:
|
|
52
|
+
"""Initialize the RuleFilter and perform the filtering pass.
|
|
53
|
+
|
|
54
|
+
:param host_graph: The host graph to search within.
|
|
55
|
+
:type host_graph: nx.Graph
|
|
56
|
+
:param rules_list: A list of rule objects to filter against.
|
|
57
|
+
:type rules_list: list
|
|
58
|
+
:param invert: If True, use the "modifier" component of each
|
|
59
|
+
decomposition.
|
|
60
|
+
:type invert: bool
|
|
61
|
+
:param engine: Matching engine to use.
|
|
62
|
+
:type engine: str
|
|
63
|
+
:param node_label: Node attribute(s) for TurboISO to match on.
|
|
64
|
+
:type node_label: str or list
|
|
65
|
+
:param edge_label: Edge attribute(s) for TurboISO to match on.
|
|
66
|
+
:type edge_label: str or list
|
|
67
|
+
:param distance_threshold: Threshold to skip distance filtering
|
|
68
|
+
in TurboISO.
|
|
69
|
+
:type distance_threshold: int
|
|
70
|
+
:param sing_max_path: Maximum path length for SING engine.
|
|
71
|
+
:type sing_max_path: int
|
|
72
|
+
"""
|
|
73
|
+
# Convert host to explicit hydrogen version once
|
|
74
|
+
self._host = h_to_explicit(host_graph)
|
|
75
|
+
self._rules = list(rules_list)
|
|
76
|
+
self._invert = invert
|
|
77
|
+
self._engine = engine.lower()
|
|
78
|
+
|
|
79
|
+
# Decompose patterns via ITS
|
|
80
|
+
self._patterns = [
|
|
81
|
+
self._decompose_rule(r)[1] if self._invert else self._decompose_rule(r)[0]
|
|
82
|
+
for r in self._rules
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
# Instantiate matcher based on engine
|
|
86
|
+
if self._engine == "turbo":
|
|
87
|
+
self._matcher = TurboISO(
|
|
88
|
+
self._host,
|
|
89
|
+
node_label=node_label,
|
|
90
|
+
edge_label=edge_label,
|
|
91
|
+
distance_threshold=distance_threshold,
|
|
92
|
+
)
|
|
93
|
+
elif self._engine == "sing":
|
|
94
|
+
self._matcher = SING(self._host, max_path_length=sing_max_path)
|
|
95
|
+
elif self._engine == "nx":
|
|
96
|
+
self._matcher = SubgraphMatch()
|
|
97
|
+
else:
|
|
98
|
+
raise ValueError(f"Unknown matching engine '{engine}'")
|
|
99
|
+
|
|
100
|
+
# Perform filtering and collect matched rules
|
|
101
|
+
self._matches = [self._match(p) for p in self._patterns]
|
|
102
|
+
self._new_rules = [r for r, m in zip(self._rules, self._matches) if m]
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def _decompose_rule(rule: nx.Graph) -> tuple[nx.Graph, nx.Graph]:
|
|
106
|
+
"""Return left/right rule fragments for either ITS representation."""
|
|
107
|
+
if detect_its_format(rule) == "tuple":
|
|
108
|
+
reverter = ITSReverter(rule)
|
|
109
|
+
return reverter.to_reactant_graph(), reverter.to_product_graph()
|
|
110
|
+
return its_decompose(rule)
|
|
111
|
+
|
|
112
|
+
def _match(self, pattern: nx.Graph) -> bool:
|
|
113
|
+
"""Test whether the given pattern occurs as a subgraph in the host.
|
|
114
|
+
|
|
115
|
+
:param pattern: The query graph pattern to match.
|
|
116
|
+
:type pattern: nx.Graph
|
|
117
|
+
:return: True if pattern is found, False otherwise.
|
|
118
|
+
:rtype: bool
|
|
119
|
+
"""
|
|
120
|
+
# SynReactor treats wildcard nodes as omitted context during
|
|
121
|
+
# structural matching. A pre-filter must apply the same projection or
|
|
122
|
+
# it can discard a rule that the authoritative matcher accepts.
|
|
123
|
+
pattern = remove_wildcard_nodes(pattern, inplace=False)
|
|
124
|
+
if not pattern:
|
|
125
|
+
return True
|
|
126
|
+
if self._engine == "turbo":
|
|
127
|
+
return bool(self._matcher.search(pattern, prune=True))
|
|
128
|
+
if self._engine == "sing":
|
|
129
|
+
return bool(self._matcher.search(pattern, prune=True))
|
|
130
|
+
if self._engine == "nx":
|
|
131
|
+
return bool(
|
|
132
|
+
self._matcher.subgraph_isomorphism(
|
|
133
|
+
pattern, self._host, check_type="mono"
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
raise ValueError(f"Unknown matching engine '{self._engine}'")
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def host(self) -> nx.Graph:
|
|
140
|
+
"""The explicit host graph.
|
|
141
|
+
|
|
142
|
+
:return: The host graph used for matching.
|
|
143
|
+
:rtype: nx.Graph
|
|
144
|
+
"""
|
|
145
|
+
return self._host
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def rules(self) -> List[Any]:
|
|
149
|
+
"""Original list of rules provided.
|
|
150
|
+
|
|
151
|
+
:return: The list of rules.
|
|
152
|
+
:rtype: list
|
|
153
|
+
"""
|
|
154
|
+
return list(self._rules)
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def patterns(self) -> List[nx.Graph]:
|
|
158
|
+
"""Decomposed subgraph queries used internally.
|
|
159
|
+
|
|
160
|
+
:return: List of ITS-decomposed query graphs.
|
|
161
|
+
:rtype: list of nx.Graph
|
|
162
|
+
"""
|
|
163
|
+
return list(self._patterns)
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def matches(self) -> List[bool]:
|
|
167
|
+
"""Boolean list indicating which patterns were found.
|
|
168
|
+
|
|
169
|
+
:return: List of booleans aligned with `patterns`.
|
|
170
|
+
:rtype: list of bool
|
|
171
|
+
"""
|
|
172
|
+
return list(self._matches)
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def new_rules(self) -> List[Any]:
|
|
176
|
+
"""Subset of rules for which `matches[i]` is True.
|
|
177
|
+
|
|
178
|
+
:return: Filtered list of matching rules.
|
|
179
|
+
:rtype: list
|
|
180
|
+
"""
|
|
181
|
+
return list(self._new_rules)
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def engine(self) -> str:
|
|
185
|
+
"""Matching engine in use.
|
|
186
|
+
|
|
187
|
+
:return: The name of the engine.
|
|
188
|
+
:rtype: str
|
|
189
|
+
"""
|
|
190
|
+
return self._engine
|
|
191
|
+
|
|
192
|
+
def __repr__(self) -> str:
|
|
193
|
+
"""Concise representation of the filter.
|
|
194
|
+
|
|
195
|
+
:return: Representation string.
|
|
196
|
+
:rtype: str
|
|
197
|
+
"""
|
|
198
|
+
return (
|
|
199
|
+
f"<RuleFilter engine={self._engine!r} "
|
|
200
|
+
f"patterns={len(self._patterns)} "
|
|
201
|
+
f"matches={sum(self._matches)}/{len(self._matches)}>"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
def __help__(self) -> str:
|
|
205
|
+
"""Return the class docstring for interactive help.
|
|
206
|
+
|
|
207
|
+
:return: The class documentation.
|
|
208
|
+
:rtype: str
|
|
209
|
+
"""
|
|
210
|
+
return self.__doc__
|
|
File without changes
|