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,199 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from itertools import combinations, permutations
|
|
3
|
+
from joblib import Parallel, delayed
|
|
4
|
+
from typing import List, Tuple, Callable, Dict, Any
|
|
5
|
+
|
|
6
|
+
from rdkit import Chem
|
|
7
|
+
from rdkit.Chem.MolStandardize import rdMolStandardize
|
|
8
|
+
|
|
9
|
+
from synkit.Chem.Reaction.balance_check import BalanceReactionCheck
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Deionize:
|
|
13
|
+
"""Neutralize ionic species and mixtures of ions in reactions.
|
|
14
|
+
|
|
15
|
+
Provides methods to group ions into neutral combinations, uncharge
|
|
16
|
+
individual anions/cations, and apply these corrections to SMILES
|
|
17
|
+
strings or entire reaction dictionaries.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def random_pair_ions(
|
|
22
|
+
charges: List[int], smiles: List[str]
|
|
23
|
+
) -> Tuple[List[List[str]], List[List[int]]]:
|
|
24
|
+
"""Identify non‑overlapping groups of ions whose charges sum to zero.
|
|
25
|
+
|
|
26
|
+
:param charges: List of integer formal charges for each ion.
|
|
27
|
+
:type charges: List[int]
|
|
28
|
+
:param smiles: Corresponding SMILES strings for each ion.
|
|
29
|
+
:type smiles: List[str]
|
|
30
|
+
:return: A tuple of two lists:
|
|
31
|
+
- groups of SMILES strings forming neutral sets,
|
|
32
|
+
- groups of their corresponding charges.
|
|
33
|
+
:rtype: Tuple[List[List[str]], List[List[int]]]
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def find_groups(indices: List[int], size: int) -> Tuple[int, ...]:
|
|
37
|
+
for group in combinations(indices, size):
|
|
38
|
+
if sum(charges[i] for i in group) == 0:
|
|
39
|
+
return group
|
|
40
|
+
return ()
|
|
41
|
+
|
|
42
|
+
indices = list(range(len(charges)))
|
|
43
|
+
random.shuffle(indices)
|
|
44
|
+
used = set()
|
|
45
|
+
grouped_smiles: List[List[str]] = []
|
|
46
|
+
grouped_charges: List[List[int]] = []
|
|
47
|
+
|
|
48
|
+
for group_size in (2, 3, 4):
|
|
49
|
+
while True:
|
|
50
|
+
available = [i for i in indices if i not in used]
|
|
51
|
+
group = find_groups(available, group_size)
|
|
52
|
+
if not group:
|
|
53
|
+
break
|
|
54
|
+
grouped_smiles.append([smiles[i] for i in group])
|
|
55
|
+
grouped_charges.append([charges[i] for i in group])
|
|
56
|
+
used.update(group)
|
|
57
|
+
|
|
58
|
+
return grouped_smiles, grouped_charges
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def uncharge_anion(smiles: str, charges: int = -1) -> str:
|
|
62
|
+
"""Neutralize an anionic SMILES string.
|
|
63
|
+
|
|
64
|
+
:param smiles: SMILES of the anion to neutralize.
|
|
65
|
+
:type smiles: str
|
|
66
|
+
:param charges: Formal charge of the ion (negative integer).
|
|
67
|
+
Defaults to -1.
|
|
68
|
+
:type charges: int
|
|
69
|
+
:return: SMILES of the uncharged molecule.
|
|
70
|
+
:rtype: str
|
|
71
|
+
"""
|
|
72
|
+
if smiles == "[N-]=[N+]=[N-]":
|
|
73
|
+
return "[N-]=[N+]=[N]"
|
|
74
|
+
if charges == -1:
|
|
75
|
+
mol = Chem.MolFromSmiles(smiles)
|
|
76
|
+
uncharger = rdMolStandardize.Uncharger()
|
|
77
|
+
uncharged = uncharger.uncharge(mol)
|
|
78
|
+
return Chem.MolToSmiles(uncharged)
|
|
79
|
+
# for multi‐charged anions
|
|
80
|
+
return smiles.replace(f"{charges}", "").replace("[", "").replace("]", "")
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def uncharge_cation(smiles: str, charges: int = 1) -> str:
|
|
84
|
+
"""Neutralize a cationic SMILES string.
|
|
85
|
+
|
|
86
|
+
:param smiles: SMILES of the cation to neutralize.
|
|
87
|
+
:type smiles: str
|
|
88
|
+
:param charges: Formal charge of the ion (positive integer).
|
|
89
|
+
Defaults to 1.
|
|
90
|
+
:type charges: int
|
|
91
|
+
:return: SMILES of the uncharged molecule.
|
|
92
|
+
:rtype: str
|
|
93
|
+
"""
|
|
94
|
+
if charges == 1:
|
|
95
|
+
return smiles.replace("+", "")
|
|
96
|
+
return smiles.replace(f"+{charges}", "")
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def uncharge_smiles(charge_smiles: str) -> str:
|
|
100
|
+
"""Neutralize all ionic components in a dot‑separated SMILES string.
|
|
101
|
+
|
|
102
|
+
Splits into components, identifies ionic species, groups
|
|
103
|
+
them into neutral sets via `random_pair_ions`, then
|
|
104
|
+
applies `uncharge_anion` or `uncharge_cation` and recombines.
|
|
105
|
+
|
|
106
|
+
:param charge_smiles: SMILES string with ionic and non‑ionic parts.
|
|
107
|
+
:type charge_smiles: str
|
|
108
|
+
:return: SMILES string with charges neutralized.
|
|
109
|
+
:rtype: str
|
|
110
|
+
"""
|
|
111
|
+
parts = charge_smiles.split(".")
|
|
112
|
+
charges = [Chem.rdmolops.GetFormalCharge(Chem.MolFromSmiles(p)) for p in parts]
|
|
113
|
+
if all(c == 0 for c in charges):
|
|
114
|
+
return charge_smiles
|
|
115
|
+
|
|
116
|
+
non_ionic, ionic_parts, ionic_charges = [], [], []
|
|
117
|
+
for p, c in zip(parts, charges):
|
|
118
|
+
if c == 0:
|
|
119
|
+
non_ionic.append(p)
|
|
120
|
+
else:
|
|
121
|
+
ionic_parts.append(p)
|
|
122
|
+
ionic_charges.append(c)
|
|
123
|
+
|
|
124
|
+
valid = non_ionic.copy()
|
|
125
|
+
groups, group_chs = Deionize.random_pair_ions(ionic_charges, ionic_parts)
|
|
126
|
+
for smiles_group, charge_group in zip(groups, group_chs):
|
|
127
|
+
candidates = []
|
|
128
|
+
for smi, ch in zip(smiles_group, charge_group):
|
|
129
|
+
if ch > 0:
|
|
130
|
+
candidates.append(Deionize.uncharge_cation(smi, ch))
|
|
131
|
+
else:
|
|
132
|
+
candidates.append(Deionize.uncharge_anion(smi, ch))
|
|
133
|
+
# try permutations for valid SMILES
|
|
134
|
+
for perm in permutations(candidates):
|
|
135
|
+
combo = "".join(perm)
|
|
136
|
+
if Chem.MolFromSmiles(combo):
|
|
137
|
+
valid.append(Chem.CanonSmiles(combo))
|
|
138
|
+
break
|
|
139
|
+
else:
|
|
140
|
+
valid.extend(smiles_group)
|
|
141
|
+
return ".".join(valid)
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def ammonia_hydroxide_standardize(reaction_smiles: str) -> str:
|
|
145
|
+
"""Simplify ammonium hydroxide pairs in a reaction SMILES.
|
|
146
|
+
|
|
147
|
+
:param reaction_smiles: Reaction SMILES string.
|
|
148
|
+
:type reaction_smiles: str
|
|
149
|
+
:return: Reaction SMILES with '[NH4+].[OH-]' replaced by 'N.O'
|
|
150
|
+
or 'O.N'.
|
|
151
|
+
:rtype: str
|
|
152
|
+
"""
|
|
153
|
+
return reaction_smiles.replace("[NH4+].[OH-]", "N.O").replace(
|
|
154
|
+
"[OH-].[NH4+]", "O.N"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
@classmethod
|
|
158
|
+
def apply_uncharge_smiles_to_reactions(
|
|
159
|
+
cls,
|
|
160
|
+
reactions: List[Dict[str, Any]],
|
|
161
|
+
uncharge_smiles_func: Callable[[str], str],
|
|
162
|
+
n_jobs: int = 4,
|
|
163
|
+
) -> List[Dict[str, Any]]:
|
|
164
|
+
"""Apply a neutralization function to each reaction’s
|
|
165
|
+
reactants/products in parallel.
|
|
166
|
+
|
|
167
|
+
Adds keys 'new_reactants', 'new_products', and 'standardized_reactions'
|
|
168
|
+
based on uncharged SMILES and verifies formula balance.
|
|
169
|
+
|
|
170
|
+
:param reactions: List of reaction dicts with 'reactants' and 'products' keys.
|
|
171
|
+
:type reactions: List[Dict[str, Any]]
|
|
172
|
+
:param uncharge_smiles_func: Function to neutralize a SMILES string.
|
|
173
|
+
:type uncharge_smiles_func: Callable[[str], str]
|
|
174
|
+
:param n_jobs: Number of parallel jobs to run. Defaults to 4.
|
|
175
|
+
:type n_jobs: int
|
|
176
|
+
:return: List of updated reaction dicts with:
|
|
177
|
+
- 'success': bool indicating formula match
|
|
178
|
+
- 'new_reactants' / 'new_products'
|
|
179
|
+
- 'standardized_reactions'
|
|
180
|
+
:rtype: List[Dict[str, Any]]
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
def process(reaction: Dict[str, Any]) -> Dict[str, Any]:
|
|
184
|
+
# pre‐standardize ammonia hydroxide
|
|
185
|
+
r_fix = cls.ammonia_hydroxide_standardize(reaction["reactants"])
|
|
186
|
+
p_fix = cls.ammonia_hydroxide_standardize(reaction["products"])
|
|
187
|
+
ur = uncharge_smiles_func(r_fix)
|
|
188
|
+
up = uncharge_smiles_func(p_fix)
|
|
189
|
+
r_formula = BalanceReactionCheck().get_combined_molecular_formula(ur)
|
|
190
|
+
p_formula = BalanceReactionCheck().get_combined_molecular_formula(up)
|
|
191
|
+
reaction["success"] = r_formula == p_formula
|
|
192
|
+
reaction["new_reactants"] = ur if reaction["success"] else r_fix
|
|
193
|
+
reaction["new_products"] = up if reaction["success"] else p_fix
|
|
194
|
+
reaction["standardized_reactions"] = (
|
|
195
|
+
f"{reaction['new_reactants']}>>{reaction['new_products']}"
|
|
196
|
+
)
|
|
197
|
+
return reaction
|
|
198
|
+
|
|
199
|
+
return Parallel(n_jobs=n_jobs)(delayed(process)(rxn) for rxn in reactions)
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""Selection gate for mapped reactions with hydrogen in the reaction center.
|
|
2
|
+
|
|
3
|
+
This module deliberately uses a narrow definition suitable for regression and
|
|
4
|
+
conformance data. An accepted reaction must be fully atom mapped, conserve
|
|
5
|
+
mapped atom identities, molecular formula, and total formal charge, and contain
|
|
6
|
+
at least one explicit mapped hydrogen incident to a changed bond.
|
|
7
|
+
|
|
8
|
+
The check is stricter than merely searching for ``"[H:"``. A mapped hydrogen
|
|
9
|
+
which is present but remote from every bond change does not qualify.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from collections import Counter
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
|
|
17
|
+
from rdkit import Chem
|
|
18
|
+
from rdkit.Chem.rdMolDescriptors import CalcMolFormula
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True, order=True)
|
|
22
|
+
class MappedBondChange:
|
|
23
|
+
"""One mapped bond before and after a reaction."""
|
|
24
|
+
|
|
25
|
+
atom_maps: tuple[int, int]
|
|
26
|
+
before: float
|
|
27
|
+
after: float
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def kind(self) -> str:
|
|
31
|
+
if self.before == 0.0:
|
|
32
|
+
return "FORMED"
|
|
33
|
+
if self.after == 0.0:
|
|
34
|
+
return "BROKEN"
|
|
35
|
+
return "ORDER_CHANGED"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class ExplicitHydrogenReactionAudit:
|
|
40
|
+
"""Structured result returned by :func:`audit_explicit_h_reaction`."""
|
|
41
|
+
|
|
42
|
+
reaction: str
|
|
43
|
+
errors: tuple[str, ...] = ()
|
|
44
|
+
reactant_formula: str | None = None
|
|
45
|
+
product_formula: str | None = None
|
|
46
|
+
reactant_charge: int | None = None
|
|
47
|
+
product_charge: int | None = None
|
|
48
|
+
atom_maps: tuple[int, ...] = ()
|
|
49
|
+
explicit_hydrogen_maps: tuple[int, ...] = ()
|
|
50
|
+
changed_hydrogen_maps: tuple[int, ...] = ()
|
|
51
|
+
reaction_center_maps: tuple[int, ...] = ()
|
|
52
|
+
changed_bonds: tuple[MappedBondChange, ...] = ()
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def accepted(self) -> bool:
|
|
56
|
+
"""Whether the reaction satisfies every strict selection criterion."""
|
|
57
|
+
|
|
58
|
+
return not self.errors
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class _ReactionSide:
|
|
63
|
+
formula: str
|
|
64
|
+
elemental_composition: tuple[tuple[tuple[int, int], int], ...]
|
|
65
|
+
charge: int
|
|
66
|
+
atoms_by_map: dict[int, tuple[int, int]]
|
|
67
|
+
bonds_by_maps: dict[tuple[int, int], float]
|
|
68
|
+
unmapped_atoms: tuple[int, ...]
|
|
69
|
+
duplicate_maps: tuple[int, ...]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def reaction_smiles_from_annotated_text(text: str) -> str:
|
|
73
|
+
"""Return the reaction token from legacy ``SMIRKS arrow-code`` text.
|
|
74
|
+
|
|
75
|
+
SynKit's polar and radical CSV files append electron-flow notation after a
|
|
76
|
+
space. Ordinary reaction SMILES contains no whitespace, so the first token
|
|
77
|
+
is the complete reaction in both the annotated and unannotated forms.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
stripped = str(text).strip()
|
|
81
|
+
return stripped.split(maxsplit=1)[0] if stripped else ""
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _parse_side(smiles: str) -> _ReactionSide | None:
|
|
85
|
+
parser = Chem.SmilesParserParams()
|
|
86
|
+
parser.removeHs = False
|
|
87
|
+
molecule = Chem.MolFromSmiles(smiles, parser)
|
|
88
|
+
if molecule is None:
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
atoms_by_map: dict[int, tuple[int, int]] = {}
|
|
92
|
+
unmapped_atoms = []
|
|
93
|
+
duplicate_maps = []
|
|
94
|
+
for atom in molecule.GetAtoms():
|
|
95
|
+
atom_map = int(atom.GetAtomMapNum())
|
|
96
|
+
if atom_map <= 0:
|
|
97
|
+
unmapped_atoms.append(atom.GetIdx())
|
|
98
|
+
continue
|
|
99
|
+
if atom_map in atoms_by_map:
|
|
100
|
+
duplicate_maps.append(atom_map)
|
|
101
|
+
continue
|
|
102
|
+
# Charge, radical state, and hydrogen count may legitimately change.
|
|
103
|
+
# Element and isotope may not change under an atom mapping.
|
|
104
|
+
atoms_by_map[atom_map] = (atom.GetAtomicNum(), atom.GetIsotope())
|
|
105
|
+
|
|
106
|
+
bonds_by_maps = {}
|
|
107
|
+
for bond in molecule.GetBonds():
|
|
108
|
+
begin_map = int(bond.GetBeginAtom().GetAtomMapNum())
|
|
109
|
+
end_map = int(bond.GetEndAtom().GetAtomMapNum())
|
|
110
|
+
if begin_map <= 0 or end_map <= 0:
|
|
111
|
+
continue
|
|
112
|
+
key = tuple(sorted((begin_map, end_map)))
|
|
113
|
+
bonds_by_maps[key] = float(bond.GetBondTypeAsDouble())
|
|
114
|
+
|
|
115
|
+
# CalcMolFormula includes a charge suffix (for example ``H4N+``). Keep
|
|
116
|
+
# that human-readable value in the report, but compare mass balance using
|
|
117
|
+
# an isotope-aware elemental inventory so charge has its own error code.
|
|
118
|
+
composition: Counter[tuple[int, int]] = Counter()
|
|
119
|
+
for atom in molecule.GetAtoms():
|
|
120
|
+
composition[(atom.GetAtomicNum(), atom.GetIsotope())] += 1
|
|
121
|
+
if atom.GetAtomicNum() != 1:
|
|
122
|
+
hydrogen_count = atom.GetTotalNumHs(includeNeighbors=False)
|
|
123
|
+
if hydrogen_count:
|
|
124
|
+
composition[(1, 0)] += int(hydrogen_count)
|
|
125
|
+
|
|
126
|
+
return _ReactionSide(
|
|
127
|
+
formula=CalcMolFormula(molecule),
|
|
128
|
+
elemental_composition=tuple(sorted(composition.items())),
|
|
129
|
+
charge=int(Chem.GetFormalCharge(molecule)),
|
|
130
|
+
atoms_by_map=atoms_by_map,
|
|
131
|
+
bonds_by_maps=bonds_by_maps,
|
|
132
|
+
unmapped_atoms=tuple(unmapped_atoms),
|
|
133
|
+
duplicate_maps=tuple(sorted(set(duplicate_maps))),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def audit_explicit_h_reaction(text: str) -> ExplicitHydrogenReactionAudit:
|
|
138
|
+
"""Audit a mapped reaction for strict explicit-H-center suitability.
|
|
139
|
+
|
|
140
|
+
:param text: A mapped reaction SMILES, optionally followed by SynKit's legacy
|
|
141
|
+
whitespace-separated electron-flow annotation.
|
|
142
|
+
|
|
143
|
+
:return: A report with stable error codes and the detected mapped bond changes.
|
|
144
|
+
:rtype: ExplicitHydrogenReactionAudit
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
reaction = reaction_smiles_from_annotated_text(text)
|
|
148
|
+
if reaction.count(">>") != 1:
|
|
149
|
+
return ExplicitHydrogenReactionAudit(
|
|
150
|
+
reaction,
|
|
151
|
+
errors=("INVALID_REACTION_SEPARATOR",),
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
reactant_text, product_text = reaction.split(">>", 1)
|
|
155
|
+
reactants = _parse_side(reactant_text)
|
|
156
|
+
products = _parse_side(product_text)
|
|
157
|
+
if reactants is None or products is None:
|
|
158
|
+
errors = []
|
|
159
|
+
if reactants is None:
|
|
160
|
+
errors.append("REACTANT_PARSE_FAILED")
|
|
161
|
+
if products is None:
|
|
162
|
+
errors.append("PRODUCT_PARSE_FAILED")
|
|
163
|
+
return ExplicitHydrogenReactionAudit(reaction, errors=tuple(errors))
|
|
164
|
+
|
|
165
|
+
errors = []
|
|
166
|
+
if reactants.unmapped_atoms:
|
|
167
|
+
errors.append("UNMAPPED_REACTANT_ATOM")
|
|
168
|
+
if products.unmapped_atoms:
|
|
169
|
+
errors.append("UNMAPPED_PRODUCT_ATOM")
|
|
170
|
+
if reactants.duplicate_maps:
|
|
171
|
+
errors.append("DUPLICATE_REACTANT_MAP")
|
|
172
|
+
if products.duplicate_maps:
|
|
173
|
+
errors.append("DUPLICATE_PRODUCT_MAP")
|
|
174
|
+
|
|
175
|
+
reactant_maps = set(reactants.atoms_by_map)
|
|
176
|
+
product_maps = set(products.atoms_by_map)
|
|
177
|
+
if reactant_maps != product_maps:
|
|
178
|
+
errors.append("MAP_INVENTORY_MISMATCH")
|
|
179
|
+
elif reactants.atoms_by_map != products.atoms_by_map:
|
|
180
|
+
errors.append("MAPPED_ATOM_IDENTITY_MISMATCH")
|
|
181
|
+
|
|
182
|
+
if reactants.elemental_composition != products.elemental_composition:
|
|
183
|
+
errors.append("FORMULA_IMBALANCE")
|
|
184
|
+
if reactants.charge != products.charge:
|
|
185
|
+
errors.append("CHARGE_IMBALANCE")
|
|
186
|
+
|
|
187
|
+
changed_bonds = []
|
|
188
|
+
all_bonds = set(reactants.bonds_by_maps) | set(products.bonds_by_maps)
|
|
189
|
+
for atom_maps in sorted(all_bonds):
|
|
190
|
+
before = reactants.bonds_by_maps.get(atom_maps, 0.0)
|
|
191
|
+
after = products.bonds_by_maps.get(atom_maps, 0.0)
|
|
192
|
+
if before != after:
|
|
193
|
+
changed_bonds.append(MappedBondChange(atom_maps, before, after))
|
|
194
|
+
|
|
195
|
+
hydrogen_maps = tuple(
|
|
196
|
+
sorted(
|
|
197
|
+
atom_map
|
|
198
|
+
for atom_map, identity in reactants.atoms_by_map.items()
|
|
199
|
+
if identity[0] == 1
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
if not hydrogen_maps:
|
|
203
|
+
errors.append("NO_EXPLICIT_MAPPED_HYDROGEN")
|
|
204
|
+
|
|
205
|
+
center_maps = tuple(
|
|
206
|
+
sorted({atom_map for change in changed_bonds for atom_map in change.atom_maps})
|
|
207
|
+
)
|
|
208
|
+
changed_hydrogen_maps = tuple(sorted(set(hydrogen_maps) & set(center_maps)))
|
|
209
|
+
if not changed_hydrogen_maps:
|
|
210
|
+
errors.append("NO_CHANGED_EXPLICIT_HYDROGEN")
|
|
211
|
+
|
|
212
|
+
return ExplicitHydrogenReactionAudit(
|
|
213
|
+
reaction=reaction,
|
|
214
|
+
errors=tuple(errors),
|
|
215
|
+
reactant_formula=reactants.formula,
|
|
216
|
+
product_formula=products.formula,
|
|
217
|
+
reactant_charge=reactants.charge,
|
|
218
|
+
product_charge=products.charge,
|
|
219
|
+
atom_maps=tuple(sorted(reactant_maps & product_maps)),
|
|
220
|
+
explicit_hydrogen_maps=hydrogen_maps,
|
|
221
|
+
changed_hydrogen_maps=changed_hydrogen_maps,
|
|
222
|
+
reaction_center_maps=center_maps,
|
|
223
|
+
changed_bonds=tuple(changed_bonds),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
__all__ = [
|
|
228
|
+
"ExplicitHydrogenReactionAudit",
|
|
229
|
+
"MappedBondChange",
|
|
230
|
+
"audit_explicit_h_reaction",
|
|
231
|
+
"reaction_smiles_from_annotated_text",
|
|
232
|
+
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from rdkit import Chem
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FixAAM:
|
|
6
|
+
"""Utilities for incrementing and correcting atom‐atom mapping (AAM)
|
|
7
|
+
numbers in molecules and reaction SMILES.
|
|
8
|
+
|
|
9
|
+
Provides methods to:
|
|
10
|
+
- Increment AAM on all atoms of an RDKit Mol.
|
|
11
|
+
- Adjust AAM numbers in a standalone SMILES string.
|
|
12
|
+
- Apply the same adjustment to both sides of a reaction SMILES (RSMI).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def increment_atom_mapping(mol: Chem.Mol) -> Chem.Mol:
|
|
17
|
+
"""Increment the atom‐map number of each atom in an RDKit Mol by 1.
|
|
18
|
+
|
|
19
|
+
:param mol: RDKit molecule with existing atom‐map annotations.
|
|
20
|
+
:type mol: Chem.Mol
|
|
21
|
+
:return: The same Mol object with each atom’s map number
|
|
22
|
+
increased by one.
|
|
23
|
+
:rtype: Chem.Mol
|
|
24
|
+
"""
|
|
25
|
+
for atom in mol.GetAtoms():
|
|
26
|
+
atom.SetAtomMapNum(atom.GetAtomMapNum() + 1)
|
|
27
|
+
return mol
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def fix_aam_smiles(smiles: str) -> str:
|
|
31
|
+
"""Parse a SMILES string, increment all atom map numbers, and return
|
|
32
|
+
updated SMILES.
|
|
33
|
+
|
|
34
|
+
:param smiles: SMILES string containing atom‐map annotations.
|
|
35
|
+
:type smiles: str
|
|
36
|
+
:return: SMILES string with every atom‐map number increased by
|
|
37
|
+
one.
|
|
38
|
+
:rtype: str
|
|
39
|
+
:raises ValueError: If the input SMILES cannot be parsed into an
|
|
40
|
+
RDKit Mol.
|
|
41
|
+
"""
|
|
42
|
+
mol: Optional[Chem.Mol] = Chem.MolFromSmiles(smiles, sanitize=False)
|
|
43
|
+
if mol is None:
|
|
44
|
+
raise ValueError(f"Invalid SMILES string: {smiles!r}")
|
|
45
|
+
Chem.SanitizeMol(mol)
|
|
46
|
+
FixAAM.increment_atom_mapping(mol)
|
|
47
|
+
return Chem.MolToSmiles(mol)
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def fix_aam_rsmi(rsmi: str) -> str:
|
|
51
|
+
"""Apply atom‐map increment to both reactant and product sides of a
|
|
52
|
+
reaction SMILES.
|
|
53
|
+
|
|
54
|
+
:param rsmi: Reaction SMILES in 'reactants>>products' format
|
|
55
|
+
with atom‐map tags.
|
|
56
|
+
:type rsmi: str
|
|
57
|
+
:return: New reaction SMILES string where each atom‐map number
|
|
58
|
+
in both halves is increased by one.
|
|
59
|
+
:rtype: str
|
|
60
|
+
"""
|
|
61
|
+
react, prod = rsmi.split(">>")
|
|
62
|
+
new_react = FixAAM.fix_aam_smiles(react)
|
|
63
|
+
new_prod = FixAAM.fix_aam_smiles(prod)
|
|
64
|
+
return f"{new_react}>>{new_prod}"
|