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,545 @@
|
|
|
1
|
+
"""Chemical bookkeeping helpers mixed into :class:`MolToGraph`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
from rdkit import Chem
|
|
8
|
+
|
|
9
|
+
from synkit.IO.debug import setup_logging
|
|
10
|
+
|
|
11
|
+
logger = setup_logging()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MolToGraphChemistryMixin:
|
|
15
|
+
@staticmethod
|
|
16
|
+
def _safe_atom_map(atom: Chem.Atom) -> int:
|
|
17
|
+
"""Return atom-map number or ``0``.
|
|
18
|
+
|
|
19
|
+
:param atom: RDKit atom.
|
|
20
|
+
:type atom: Chem.Atom
|
|
21
|
+
:return: Atom-map number.
|
|
22
|
+
:rtype: int
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
return int(atom.GetAtomMapNum())
|
|
26
|
+
except Exception:
|
|
27
|
+
return 0
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def _safe_bond_order_sum(atom: Chem.Atom) -> float:
|
|
31
|
+
"""Return raw RDKit bond-order sum.
|
|
32
|
+
|
|
33
|
+
:param atom: RDKit atom.
|
|
34
|
+
:type atom: Chem.Atom
|
|
35
|
+
:return: Incident bond-order sum.
|
|
36
|
+
:rtype: float
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
return float(sum(bond.GetBondTypeAsDouble() for bond in atom.GetBonds()))
|
|
40
|
+
except Exception:
|
|
41
|
+
return 0.0
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def _safe_valence_electrons(atom: Chem.Atom) -> int:
|
|
45
|
+
"""Return outer-shell valence electron count.
|
|
46
|
+
|
|
47
|
+
:param atom: RDKit atom.
|
|
48
|
+
:type atom: Chem.Atom
|
|
49
|
+
:return: Valence electron count, or ``0`` on failure.
|
|
50
|
+
:rtype: int
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
pt = Chem.GetPeriodicTable()
|
|
54
|
+
return int(pt.GetNOuterElecs(atom.GetAtomicNum()))
|
|
55
|
+
except Exception:
|
|
56
|
+
return 0
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def _explicit_h_neighbor_count(atom: Chem.Atom) -> int:
|
|
60
|
+
"""Count explicit hydrogen neighbors.
|
|
61
|
+
|
|
62
|
+
:param atom: RDKit atom.
|
|
63
|
+
:type atom: Chem.Atom
|
|
64
|
+
:return: Number of explicit hydrogen neighbors.
|
|
65
|
+
:rtype: int
|
|
66
|
+
"""
|
|
67
|
+
try:
|
|
68
|
+
return sum(1 for nb in atom.GetNeighbors() if nb.GetAtomicNum() == 1)
|
|
69
|
+
except Exception:
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def _non_neighbor_h_count(atom: Chem.Atom) -> int:
|
|
74
|
+
"""Count hydrogens not represented as explicit neighbors.
|
|
75
|
+
|
|
76
|
+
:param atom: RDKit atom.
|
|
77
|
+
:type atom: Chem.Atom
|
|
78
|
+
:return: Non-neighbor hydrogen count.
|
|
79
|
+
:rtype: int
|
|
80
|
+
"""
|
|
81
|
+
try:
|
|
82
|
+
return int(atom.GetTotalNumHs(includeNeighbors=False))
|
|
83
|
+
except TypeError:
|
|
84
|
+
try:
|
|
85
|
+
return int(atom.GetTotalNumHs())
|
|
86
|
+
except Exception:
|
|
87
|
+
return 0
|
|
88
|
+
except Exception:
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def _total_h_count(atom: Chem.Atom) -> int:
|
|
93
|
+
"""Count explicit-neighbor and non-neighbor hydrogens.
|
|
94
|
+
|
|
95
|
+
:param atom: RDKit atom.
|
|
96
|
+
:type atom: Chem.Atom
|
|
97
|
+
:return: Total hydrogen count.
|
|
98
|
+
:rtype: int
|
|
99
|
+
"""
|
|
100
|
+
return MolToGraphChemistryMixin._explicit_h_neighbor_count(
|
|
101
|
+
atom
|
|
102
|
+
) + MolToGraphChemistryMixin._non_neighbor_h_count(atom)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def _heavy_neighbor_count(atom: Chem.Atom) -> int:
|
|
106
|
+
"""Count non-hydrogen neighbors.
|
|
107
|
+
|
|
108
|
+
:param atom: RDKit atom.
|
|
109
|
+
:type atom: Chem.Atom
|
|
110
|
+
:return: Heavy-neighbor count.
|
|
111
|
+
:rtype: int
|
|
112
|
+
"""
|
|
113
|
+
try:
|
|
114
|
+
return sum(1 for nb in atom.GetNeighbors() if nb.GetAtomicNum() != 1)
|
|
115
|
+
except Exception:
|
|
116
|
+
return 0
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def _make_kekule_copy(mol: Chem.Mol) -> Optional[Chem.Mol]:
|
|
120
|
+
"""Return a kekulized copy, or ``None`` on failure.
|
|
121
|
+
|
|
122
|
+
:param mol: RDKit molecule.
|
|
123
|
+
:type mol: Chem.Mol
|
|
124
|
+
:return: Kekulized molecule copy or ``None``.
|
|
125
|
+
:rtype: Optional[Chem.Mol]
|
|
126
|
+
"""
|
|
127
|
+
try:
|
|
128
|
+
kek = Chem.Mol(mol)
|
|
129
|
+
Chem.Kekulize(kek, clearAromaticFlags=True)
|
|
130
|
+
return kek
|
|
131
|
+
except Exception as exc:
|
|
132
|
+
logger.debug("Failed to create kekulized copy: %s", exc)
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
# ------------------------------------------------------------------
|
|
136
|
+
# Lone-pair estimation
|
|
137
|
+
# ------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
@classmethod
|
|
140
|
+
def _is_aromatic_lone_pair_donor(cls, atom: Chem.Atom) -> bool:
|
|
141
|
+
"""Detect aromatic heteroatoms whose lone pair contributes to aromaticity.
|
|
142
|
+
|
|
143
|
+
:param atom: RDKit atom.
|
|
144
|
+
:type atom: Chem.Atom
|
|
145
|
+
:return: ``True`` if aromatic bonds should be counted as sigma bonds
|
|
146
|
+
for lone-pair bookkeeping.
|
|
147
|
+
:rtype: bool
|
|
148
|
+
"""
|
|
149
|
+
try:
|
|
150
|
+
if not atom.GetIsAromatic():
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
atomic_num = int(atom.GetAtomicNum())
|
|
154
|
+
formal_charge = int(atom.GetFormalCharge())
|
|
155
|
+
total_h = cls._total_h_count(atom)
|
|
156
|
+
heavy_degree = cls._heavy_neighbor_count(atom)
|
|
157
|
+
|
|
158
|
+
if atomic_num == 7:
|
|
159
|
+
aromatic_bonds = 0
|
|
160
|
+
nonaromatic_heavy_sigma_bonds = 0
|
|
161
|
+
for bond in atom.GetBonds():
|
|
162
|
+
other = bond.GetOtherAtom(atom)
|
|
163
|
+
if bond.GetIsAromatic():
|
|
164
|
+
aromatic_bonds += 1
|
|
165
|
+
elif (
|
|
166
|
+
other.GetAtomicNum() != 1
|
|
167
|
+
and float(bond.GetBondTypeAsDouble()) <= 1.1
|
|
168
|
+
):
|
|
169
|
+
nonaromatic_heavy_sigma_bonds += 1
|
|
170
|
+
|
|
171
|
+
if formal_charge <= 0 and aromatic_bonds >= 2:
|
|
172
|
+
if total_h > 0 and heavy_degree == 2:
|
|
173
|
+
return True
|
|
174
|
+
if (
|
|
175
|
+
total_h == 0
|
|
176
|
+
and heavy_degree == 3
|
|
177
|
+
and nonaromatic_heavy_sigma_bonds >= 1
|
|
178
|
+
):
|
|
179
|
+
return True
|
|
180
|
+
|
|
181
|
+
if formal_charge < 0 and heavy_degree <= 2:
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
if atomic_num in {8, 16, 34, 52}:
|
|
187
|
+
if formal_charge <= 0 and heavy_degree <= 2:
|
|
188
|
+
return True
|
|
189
|
+
|
|
190
|
+
if atomic_num == 15:
|
|
191
|
+
if formal_charge <= 0 and total_h > 0 and heavy_degree == 2:
|
|
192
|
+
return True
|
|
193
|
+
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
except Exception:
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
@classmethod
|
|
200
|
+
def _bond_order_sum_for_lone_pairs(cls, atom: Chem.Atom) -> float:
|
|
201
|
+
"""Return bond-order sum used for lone-pair bookkeeping.
|
|
202
|
+
|
|
203
|
+
:param atom: RDKit atom.
|
|
204
|
+
:type atom: Chem.Atom
|
|
205
|
+
:return: Corrected lone-pair bond-order sum.
|
|
206
|
+
:rtype: float
|
|
207
|
+
"""
|
|
208
|
+
try:
|
|
209
|
+
if atom.GetIsAromatic():
|
|
210
|
+
# Lone-pair bookkeeping needs the Kekule heavy-atom valence,
|
|
211
|
+
# not presentation bond orders such as three aromatic 1.5 bonds.
|
|
212
|
+
return float(atom.GetTotalValence() - cls._non_neighbor_h_count(atom))
|
|
213
|
+
|
|
214
|
+
aromatic_lp_donor = cls._is_aromatic_lone_pair_donor(atom)
|
|
215
|
+
total = 0.0
|
|
216
|
+
|
|
217
|
+
for bond in atom.GetBonds():
|
|
218
|
+
try:
|
|
219
|
+
if aromatic_lp_donor and bond.GetIsAromatic():
|
|
220
|
+
total += 1.0
|
|
221
|
+
else:
|
|
222
|
+
total += float(bond.GetBondTypeAsDouble())
|
|
223
|
+
except Exception:
|
|
224
|
+
total += 1.0
|
|
225
|
+
|
|
226
|
+
return total
|
|
227
|
+
|
|
228
|
+
except Exception:
|
|
229
|
+
return 0.0
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def estimate_lone_pairs(cls, atom: Chem.Atom) -> int:
|
|
233
|
+
"""Estimate total lone-pair count.
|
|
234
|
+
|
|
235
|
+
:param atom: RDKit atom.
|
|
236
|
+
:type atom: Chem.Atom
|
|
237
|
+
:return: Estimated total lone-pair count.
|
|
238
|
+
:rtype: int
|
|
239
|
+
|
|
240
|
+
.. code-block:: python
|
|
241
|
+
|
|
242
|
+
mol = Chem.MolFromSmiles("c1cc[nH]c1")
|
|
243
|
+
n_atom = next(a for a in mol.GetAtoms() if a.GetSymbol() == "N")
|
|
244
|
+
print(MolToGraph.estimate_lone_pairs(n_atom))
|
|
245
|
+
"""
|
|
246
|
+
try:
|
|
247
|
+
valence_electrons = float(cls._safe_valence_electrons(atom))
|
|
248
|
+
formal_charge = float(int(atom.GetFormalCharge()))
|
|
249
|
+
radical_electrons = float(int(atom.GetNumRadicalElectrons()))
|
|
250
|
+
bond_order_sum = float(cls._bond_order_sum_for_lone_pairs(atom))
|
|
251
|
+
non_neighbor_h = float(cls._non_neighbor_h_count(atom))
|
|
252
|
+
|
|
253
|
+
nonbonding_electrons = (
|
|
254
|
+
valence_electrons
|
|
255
|
+
- formal_charge
|
|
256
|
+
- radical_electrons
|
|
257
|
+
- bond_order_sum
|
|
258
|
+
- non_neighbor_h
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
lone_pairs = int((nonbonding_electrons + 1e-8) // 2)
|
|
262
|
+
return max(0, lone_pairs)
|
|
263
|
+
|
|
264
|
+
except Exception:
|
|
265
|
+
return 0
|
|
266
|
+
|
|
267
|
+
@classmethod
|
|
268
|
+
def estimate_available_lone_pairs(cls, atom: Chem.Atom) -> int:
|
|
269
|
+
"""Estimate lone pairs locally available for ``LP-/B+`` donation.
|
|
270
|
+
|
|
271
|
+
:param atom: RDKit atom.
|
|
272
|
+
:type atom: Chem.Atom
|
|
273
|
+
:return: Locally available lone-pair count.
|
|
274
|
+
:rtype: int
|
|
275
|
+
"""
|
|
276
|
+
total_lp = cls.estimate_lone_pairs(atom)
|
|
277
|
+
|
|
278
|
+
if total_lp <= 0:
|
|
279
|
+
return 0
|
|
280
|
+
|
|
281
|
+
try:
|
|
282
|
+
atomic_num = int(atom.GetAtomicNum())
|
|
283
|
+
formal_charge = int(atom.GetFormalCharge())
|
|
284
|
+
total_h = cls._total_h_count(atom)
|
|
285
|
+
|
|
286
|
+
if formal_charge > 0:
|
|
287
|
+
return 0
|
|
288
|
+
|
|
289
|
+
if atom.GetIsAromatic():
|
|
290
|
+
if atomic_num == 7 and total_h > 0:
|
|
291
|
+
return 0
|
|
292
|
+
if atomic_num in {8, 16, 34, 52}:
|
|
293
|
+
return max(0, total_lp - 1)
|
|
294
|
+
|
|
295
|
+
return total_lp
|
|
296
|
+
|
|
297
|
+
except Exception:
|
|
298
|
+
return total_lp
|
|
299
|
+
|
|
300
|
+
# ------------------------------------------------------------------
|
|
301
|
+
# Oxidation-state estimation
|
|
302
|
+
# ------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
@classmethod
|
|
305
|
+
def _bond_order_for_oxidation_state(
|
|
306
|
+
cls,
|
|
307
|
+
bond: Chem.Bond,
|
|
308
|
+
kek_bond: Optional[Chem.Bond] = None,
|
|
309
|
+
*,
|
|
310
|
+
prefer_kekule: bool = True,
|
|
311
|
+
) -> float:
|
|
312
|
+
"""Return bond order for oxidation-state bookkeeping.
|
|
313
|
+
|
|
314
|
+
:param bond: Original RDKit bond.
|
|
315
|
+
:type bond: Chem.Bond
|
|
316
|
+
:param kek_bond: Matching bond from a kekulized copy.
|
|
317
|
+
:type kek_bond: Optional[Chem.Bond]
|
|
318
|
+
:param prefer_kekule: Whether to use ``kek_bond`` when available.
|
|
319
|
+
:type prefer_kekule: bool
|
|
320
|
+
:return: Bond order.
|
|
321
|
+
:rtype: float
|
|
322
|
+
"""
|
|
323
|
+
try:
|
|
324
|
+
if prefer_kekule and kek_bond is not None:
|
|
325
|
+
return float(kek_bond.GetBondTypeAsDouble())
|
|
326
|
+
return float(bond.GetBondTypeAsDouble())
|
|
327
|
+
except Exception:
|
|
328
|
+
return 1.0
|
|
329
|
+
|
|
330
|
+
@classmethod
|
|
331
|
+
def estimate_oxidation_states(
|
|
332
|
+
cls,
|
|
333
|
+
mol: Chem.Mol,
|
|
334
|
+
*,
|
|
335
|
+
kek_mol: Optional[Chem.Mol] = None,
|
|
336
|
+
prefer_kekule: bool = True,
|
|
337
|
+
en_tie_threshold: float = 0.05,
|
|
338
|
+
) -> Dict[int, float]:
|
|
339
|
+
"""Estimate atom oxidation states.
|
|
340
|
+
|
|
341
|
+
For each bond, bond electrons are assigned to the more electronegative
|
|
342
|
+
atom. Formal charge is used as the starting value.
|
|
343
|
+
|
|
344
|
+
:param mol: RDKit molecule.
|
|
345
|
+
:type mol: Chem.Mol
|
|
346
|
+
:param kek_mol: Optional kekulized copy of ``mol``.
|
|
347
|
+
:type kek_mol: Optional[Chem.Mol]
|
|
348
|
+
:param prefer_kekule: Whether to prefer kekulized bond orders.
|
|
349
|
+
:type prefer_kekule: bool
|
|
350
|
+
:param en_tie_threshold: Electronegativity-difference threshold for
|
|
351
|
+
treating a bond as a tie.
|
|
352
|
+
:type en_tie_threshold: float
|
|
353
|
+
:return: Oxidation states keyed by RDKit atom index.
|
|
354
|
+
:rtype: Dict[int, float]
|
|
355
|
+
"""
|
|
356
|
+
ox: Dict[int, float] = {}
|
|
357
|
+
|
|
358
|
+
try:
|
|
359
|
+
for atom in mol.GetAtoms():
|
|
360
|
+
ox[atom.GetIdx()] = float(atom.GetFormalCharge())
|
|
361
|
+
|
|
362
|
+
for bond in mol.GetBonds():
|
|
363
|
+
a = bond.GetBeginAtom()
|
|
364
|
+
b = bond.GetEndAtom()
|
|
365
|
+
|
|
366
|
+
i = a.GetIdx()
|
|
367
|
+
j = b.GetIdx()
|
|
368
|
+
|
|
369
|
+
elem_i = a.GetSymbol()
|
|
370
|
+
elem_j = b.GetSymbol()
|
|
371
|
+
|
|
372
|
+
en_i = cls.PAULING_EN.get(elem_i)
|
|
373
|
+
en_j = cls.PAULING_EN.get(elem_j)
|
|
374
|
+
|
|
375
|
+
if en_i is None or en_j is None:
|
|
376
|
+
continue
|
|
377
|
+
|
|
378
|
+
kek_bond: Optional[Chem.Bond] = None
|
|
379
|
+
if kek_mol is not None:
|
|
380
|
+
try:
|
|
381
|
+
kek_bond = kek_mol.GetBondWithIdx(bond.GetIdx())
|
|
382
|
+
except Exception:
|
|
383
|
+
kek_bond = None
|
|
384
|
+
|
|
385
|
+
order = cls._bond_order_for_oxidation_state(
|
|
386
|
+
bond,
|
|
387
|
+
kek_bond=kek_bond,
|
|
388
|
+
prefer_kekule=prefer_kekule,
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
if abs(order) < 1e-12:
|
|
392
|
+
continue
|
|
393
|
+
|
|
394
|
+
diff = float(en_i) - float(en_j)
|
|
395
|
+
|
|
396
|
+
if abs(diff) <= en_tie_threshold:
|
|
397
|
+
continue
|
|
398
|
+
|
|
399
|
+
if diff > 0:
|
|
400
|
+
ox[i] -= order
|
|
401
|
+
ox[j] += order
|
|
402
|
+
else:
|
|
403
|
+
ox[i] += order
|
|
404
|
+
ox[j] -= order
|
|
405
|
+
|
|
406
|
+
return ox
|
|
407
|
+
|
|
408
|
+
except Exception as exc:
|
|
409
|
+
logger.debug("Oxidation-state estimation failed: %s", exc)
|
|
410
|
+
return ox
|
|
411
|
+
|
|
412
|
+
@classmethod
|
|
413
|
+
def oxidation_states_by_atom_map(
|
|
414
|
+
cls,
|
|
415
|
+
mol: Chem.Mol,
|
|
416
|
+
*,
|
|
417
|
+
kek_mol: Optional[Chem.Mol] = None,
|
|
418
|
+
prefer_kekule: bool = True,
|
|
419
|
+
en_tie_threshold: float = 0.05,
|
|
420
|
+
) -> Dict[int, Dict[str, Any]]:
|
|
421
|
+
"""Return oxidation states keyed by non-zero atom-map number.
|
|
422
|
+
|
|
423
|
+
:param mol: Mapped RDKit molecule.
|
|
424
|
+
:type mol: Chem.Mol
|
|
425
|
+
:param kek_mol: Optional kekulized copy.
|
|
426
|
+
:type kek_mol: Optional[Chem.Mol]
|
|
427
|
+
:param prefer_kekule: Whether to prefer kekulized bond orders.
|
|
428
|
+
:type prefer_kekule: bool
|
|
429
|
+
:param en_tie_threshold: Electronegativity tie threshold.
|
|
430
|
+
:type en_tie_threshold: float
|
|
431
|
+
:return: Oxidation-state records keyed by atom-map number.
|
|
432
|
+
:rtype: Dict[int, Dict[str, Any]]
|
|
433
|
+
"""
|
|
434
|
+
if kek_mol is None:
|
|
435
|
+
kek_mol = cls._make_kekule_copy(mol)
|
|
436
|
+
|
|
437
|
+
ox = cls.estimate_oxidation_states(
|
|
438
|
+
mol,
|
|
439
|
+
kek_mol=kek_mol,
|
|
440
|
+
prefer_kekule=prefer_kekule,
|
|
441
|
+
en_tie_threshold=en_tie_threshold,
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
out: Dict[int, Dict[str, Any]] = {}
|
|
445
|
+
|
|
446
|
+
for atom in mol.GetAtoms():
|
|
447
|
+
amap = cls._safe_atom_map(atom)
|
|
448
|
+
if amap == 0:
|
|
449
|
+
continue
|
|
450
|
+
|
|
451
|
+
out[amap] = {
|
|
452
|
+
"atom_idx": atom.GetIdx(),
|
|
453
|
+
"element": atom.GetSymbol(),
|
|
454
|
+
"charge": atom.GetFormalCharge(),
|
|
455
|
+
"oxidation_state": ox.get(atom.GetIdx(), 0.0),
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return out
|
|
459
|
+
|
|
460
|
+
@classmethod
|
|
461
|
+
def reaction_oxidation_state_delta_from_rsmi(
|
|
462
|
+
cls,
|
|
463
|
+
rsmi: str,
|
|
464
|
+
*,
|
|
465
|
+
threshold: float = 0.5,
|
|
466
|
+
prefer_kekule: bool = True,
|
|
467
|
+
en_tie_threshold: float = 0.05,
|
|
468
|
+
) -> Dict[int, Dict[str, Any]]:
|
|
469
|
+
"""Compute oxidation-state changes for mapped reaction SMILES.
|
|
470
|
+
|
|
471
|
+
Positive ``delta`` means oxidation; negative ``delta`` means reduction.
|
|
472
|
+
|
|
473
|
+
:param rsmi: Mapped reaction SMILES containing ``">>"``.
|
|
474
|
+
:type rsmi: str
|
|
475
|
+
:param threshold: Minimum absolute delta to report.
|
|
476
|
+
:type threshold: float
|
|
477
|
+
:param prefer_kekule: Whether to prefer kekulized bond orders.
|
|
478
|
+
:type prefer_kekule: bool
|
|
479
|
+
:param en_tie_threshold: Electronegativity tie threshold.
|
|
480
|
+
:type en_tie_threshold: float
|
|
481
|
+
:return: Significant oxidation-state changes keyed by atom map.
|
|
482
|
+
:rtype: Dict[int, Dict[str, Any]]
|
|
483
|
+
:raises ValueError: If ``rsmi`` lacks ``">>"``.
|
|
484
|
+
|
|
485
|
+
.. code-block:: python
|
|
486
|
+
|
|
487
|
+
rsmi = "[CH3:1][OH:2]>>[CH2:1]=[O:2]"
|
|
488
|
+
print(MolToGraph.reaction_oxidation_state_delta_from_rsmi(rsmi))
|
|
489
|
+
"""
|
|
490
|
+
if ">>" not in rsmi:
|
|
491
|
+
raise ValueError("Expected mapped reaction SMILES containing '>>'.")
|
|
492
|
+
|
|
493
|
+
reactants_smi, products_smi = rsmi.split(">>", 1)
|
|
494
|
+
|
|
495
|
+
def _side_maps(side_smi: str) -> Dict[int, Dict[str, Any]]:
|
|
496
|
+
merged: Dict[int, Dict[str, Any]] = {}
|
|
497
|
+
|
|
498
|
+
for smi in side_smi.split("."):
|
|
499
|
+
smi = smi.strip()
|
|
500
|
+
if not smi:
|
|
501
|
+
continue
|
|
502
|
+
|
|
503
|
+
mol = Chem.MolFromSmiles(smi)
|
|
504
|
+
if mol is None:
|
|
505
|
+
continue
|
|
506
|
+
|
|
507
|
+
merged.update(
|
|
508
|
+
cls.oxidation_states_by_atom_map(
|
|
509
|
+
mol,
|
|
510
|
+
prefer_kekule=prefer_kekule,
|
|
511
|
+
en_tie_threshold=en_tie_threshold,
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
return merged
|
|
516
|
+
|
|
517
|
+
r_by_map = _side_maps(reactants_smi)
|
|
518
|
+
p_by_map = _side_maps(products_smi)
|
|
519
|
+
|
|
520
|
+
changes: Dict[int, Dict[str, Any]] = {}
|
|
521
|
+
|
|
522
|
+
for amap in sorted(set(r_by_map) | set(p_by_map)):
|
|
523
|
+
r = r_by_map.get(amap)
|
|
524
|
+
p = p_by_map.get(amap)
|
|
525
|
+
|
|
526
|
+
if r is None or p is None:
|
|
527
|
+
changes[amap] = {
|
|
528
|
+
"reactant": r,
|
|
529
|
+
"product": p,
|
|
530
|
+
"reason": "atom_map_missing_on_one_side",
|
|
531
|
+
}
|
|
532
|
+
continue
|
|
533
|
+
|
|
534
|
+
delta = float(p["oxidation_state"]) - float(r["oxidation_state"])
|
|
535
|
+
|
|
536
|
+
if abs(delta) >= threshold:
|
|
537
|
+
changes[amap] = {
|
|
538
|
+
"element": (r["element"], p["element"]),
|
|
539
|
+
"reactant_os": round(float(r["oxidation_state"]), 3),
|
|
540
|
+
"product_os": round(float(p["oxidation_state"]), 3),
|
|
541
|
+
"delta": round(delta, 3),
|
|
542
|
+
"classification": "oxidized" if delta > 0 else "reduced",
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return changes
|