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,296 @@
|
|
|
1
|
+
"""Normative information axes and typed refusals for reaction stereo.
|
|
2
|
+
|
|
3
|
+
The values in this module describe assertions. They do not perceive
|
|
4
|
+
stereochemistry, select a mechanism, or infer a product population. In
|
|
5
|
+
particular, a descriptor whose orientation is unknown is not a racemic
|
|
6
|
+
population.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import Any, Mapping
|
|
14
|
+
|
|
15
|
+
from .orbits import StereoRelationKind
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class StereoLifecycle(str, Enum):
|
|
19
|
+
"""Configuration-aware lifecycle of one reaction-local stereo locus."""
|
|
20
|
+
|
|
21
|
+
RETAINED = "RETAINED"
|
|
22
|
+
INVERTED = "INVERTED"
|
|
23
|
+
FORMED = "FORMED"
|
|
24
|
+
BROKEN = "BROKEN"
|
|
25
|
+
FLEETING = "FLEETING"
|
|
26
|
+
UNSPECIFIED = "UNSPECIFIED"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class StereoPopulation(str, Enum):
|
|
30
|
+
"""Population assertion for the products of one declared operation."""
|
|
31
|
+
|
|
32
|
+
SINGLE = "SINGLE"
|
|
33
|
+
RACEMIC = "RACEMIC"
|
|
34
|
+
ENANTIOMERIC_MIXTURE = "ENANTIOMERIC_MIXTURE"
|
|
35
|
+
DIASTEREOMER_SET = "DIASTEREOMER_SET"
|
|
36
|
+
MESO = "MESO"
|
|
37
|
+
ACHIRAL = "ACHIRAL"
|
|
38
|
+
UNKNOWN = "UNKNOWN"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StereoDeterminacy(str, Enum):
|
|
42
|
+
"""Strength of the supplied reaction-stereo outcome assertion."""
|
|
43
|
+
|
|
44
|
+
STEREOSPECIFIC = "STEREOSPECIFIC"
|
|
45
|
+
STEREOSELECTIVE = "STEREOSELECTIVE"
|
|
46
|
+
NON_STEREOSPECIFIC = "NON_STEREOSPECIFIC"
|
|
47
|
+
UNDERDETERMINED = "UNDERDETERMINED"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class StereoEvidenceKind(str, Enum):
|
|
51
|
+
"""Provenance class that authorizes a reaction-stereo assertion."""
|
|
52
|
+
|
|
53
|
+
SOURCE_DECLARED = "SOURCE_DECLARED"
|
|
54
|
+
RULE_DECLARED = "RULE_DECLARED"
|
|
55
|
+
MECHANISM_CONSTRAINED = "MECHANISM_CONSTRAINED"
|
|
56
|
+
CONTEXT_REQUIRED = "CONTEXT_REQUIRED"
|
|
57
|
+
UNSUPPORTED = "UNSUPPORTED"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class StereoRefusalCode(str, Enum):
|
|
61
|
+
"""Stable categories for fail-closed reaction-stereo decisions."""
|
|
62
|
+
|
|
63
|
+
INVALID_REFERENCE = "INVALID_REFERENCE"
|
|
64
|
+
UNSUPPORTED_GEOMETRY = "UNSUPPORTED_GEOMETRY"
|
|
65
|
+
AMBIGUOUS_ALIGNMENT = "AMBIGUOUS_ALIGNMENT"
|
|
66
|
+
LOSSY_PROJECTION = "LOSSY_PROJECTION"
|
|
67
|
+
MISSING_CONTEXT = "MISSING_CONTEXT"
|
|
68
|
+
ASSIGNMENT_LIMIT = "ASSIGNMENT_LIMIT"
|
|
69
|
+
BRANCH_LIMIT = "BRANCH_LIMIT"
|
|
70
|
+
IRREVERSIBLE_INFORMATION_LOSS = "IRREVERSIBLE_INFORMATION_LOSS"
|
|
71
|
+
CONTRADICTORY_ASSERTION = "CONTRADICTORY_ASSERTION"
|
|
72
|
+
INVALID_COUPLING = "INVALID_COUPLING"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
_RELATION_REQUIRED = frozenset({StereoLifecycle.RETAINED, StereoLifecycle.INVERTED})
|
|
76
|
+
_RELATION_FREE = frozenset(
|
|
77
|
+
{
|
|
78
|
+
StereoLifecycle.FORMED,
|
|
79
|
+
StereoLifecycle.BROKEN,
|
|
80
|
+
StereoLifecycle.FLEETING,
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass(frozen=True)
|
|
86
|
+
class StereoReactionSemantics:
|
|
87
|
+
"""One normalized, evidence-bearing reaction-stereo assertion.
|
|
88
|
+
|
|
89
|
+
``descriptor_class`` describes the local geometry (for example
|
|
90
|
+
``"tetrahedral"`` or ``"planar_bond"``). It is deliberately not the
|
|
91
|
+
historical MechanismBench ``local_geometry`` field, whose values describe
|
|
92
|
+
change across the arrow.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
descriptor_class: str
|
|
96
|
+
lifecycle: StereoLifecycle
|
|
97
|
+
relation: StereoRelationKind | None
|
|
98
|
+
population: StereoPopulation = StereoPopulation.SINGLE
|
|
99
|
+
determinacy: StereoDeterminacy = StereoDeterminacy.STEREOSPECIFIC
|
|
100
|
+
evidence: StereoEvidenceKind = StereoEvidenceKind.SOURCE_DECLARED
|
|
101
|
+
context: tuple[str, ...] = ()
|
|
102
|
+
provenance: str | None = None
|
|
103
|
+
|
|
104
|
+
def __post_init__(self) -> None:
|
|
105
|
+
descriptor_class = self.descriptor_class.strip().lower()
|
|
106
|
+
if not descriptor_class:
|
|
107
|
+
raise ValueError("Reaction stereo requires a local geometry class.")
|
|
108
|
+
object.__setattr__(self, "descriptor_class", descriptor_class)
|
|
109
|
+
object.__setattr__(self, "lifecycle", StereoLifecycle(self.lifecycle))
|
|
110
|
+
object.__setattr__(
|
|
111
|
+
self,
|
|
112
|
+
"population",
|
|
113
|
+
StereoPopulation(self.population),
|
|
114
|
+
)
|
|
115
|
+
object.__setattr__(
|
|
116
|
+
self,
|
|
117
|
+
"determinacy",
|
|
118
|
+
StereoDeterminacy(self.determinacy),
|
|
119
|
+
)
|
|
120
|
+
object.__setattr__(self, "evidence", StereoEvidenceKind(self.evidence))
|
|
121
|
+
if self.relation is not None:
|
|
122
|
+
object.__setattr__(
|
|
123
|
+
self,
|
|
124
|
+
"relation",
|
|
125
|
+
StereoRelationKind(self.relation),
|
|
126
|
+
)
|
|
127
|
+
object.__setattr__(
|
|
128
|
+
self,
|
|
129
|
+
"context",
|
|
130
|
+
tuple(sorted(set(str(item) for item in self.context))),
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if self.lifecycle in _RELATION_REQUIRED and self.relation is None:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
f"{self.lifecycle.value} requires a transported "
|
|
136
|
+
"configuration relation."
|
|
137
|
+
)
|
|
138
|
+
if self.lifecycle in _RELATION_FREE and self.relation is not None:
|
|
139
|
+
raise ValueError(
|
|
140
|
+
f"{self.lifecycle.value} does not compare two endpoint "
|
|
141
|
+
"configurations."
|
|
142
|
+
)
|
|
143
|
+
if self.lifecycle is StereoLifecycle.UNSPECIFIED and self.relation not in {
|
|
144
|
+
None,
|
|
145
|
+
StereoRelationKind.UNSPECIFIED,
|
|
146
|
+
StereoRelationKind.UNRELATED,
|
|
147
|
+
}:
|
|
148
|
+
raise ValueError(
|
|
149
|
+
"UNSPECIFIED lifecycle cannot carry a definitive relation."
|
|
150
|
+
)
|
|
151
|
+
if (
|
|
152
|
+
self.population is StereoPopulation.UNKNOWN
|
|
153
|
+
and self.determinacy is not StereoDeterminacy.UNDERDETERMINED
|
|
154
|
+
):
|
|
155
|
+
raise ValueError("An unknown product population must be underdetermined.")
|
|
156
|
+
if (
|
|
157
|
+
self.evidence is StereoEvidenceKind.CONTEXT_REQUIRED
|
|
158
|
+
and self.determinacy is not StereoDeterminacy.UNDERDETERMINED
|
|
159
|
+
):
|
|
160
|
+
raise ValueError(
|
|
161
|
+
"A context-required assertion must remain underdetermined."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def to_dict(self) -> dict[str, Any]:
|
|
165
|
+
"""Return a deterministic JSON-compatible representation."""
|
|
166
|
+
return {
|
|
167
|
+
"descriptor_class": self.descriptor_class,
|
|
168
|
+
"lifecycle": self.lifecycle.value,
|
|
169
|
+
"relation": (self.relation.value if self.relation is not None else None),
|
|
170
|
+
"population": self.population.value,
|
|
171
|
+
"determinacy": self.determinacy.value,
|
|
172
|
+
"evidence": self.evidence.value,
|
|
173
|
+
"context": list(self.context),
|
|
174
|
+
"provenance": self.provenance,
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@classmethod
|
|
178
|
+
def from_dict(
|
|
179
|
+
cls,
|
|
180
|
+
value: Mapping[str, Any],
|
|
181
|
+
) -> "StereoReactionSemantics":
|
|
182
|
+
"""Read one normalized assertion."""
|
|
183
|
+
return cls(
|
|
184
|
+
descriptor_class=str(value["descriptor_class"]),
|
|
185
|
+
lifecycle=StereoLifecycle(value["lifecycle"]),
|
|
186
|
+
relation=(
|
|
187
|
+
StereoRelationKind(value["relation"])
|
|
188
|
+
if value.get("relation") is not None
|
|
189
|
+
else None
|
|
190
|
+
),
|
|
191
|
+
population=StereoPopulation(value.get("population", "SINGLE")),
|
|
192
|
+
determinacy=StereoDeterminacy(value.get("determinacy", "STEREOSPECIFIC")),
|
|
193
|
+
evidence=StereoEvidenceKind(value.get("evidence", "SOURCE_DECLARED")),
|
|
194
|
+
context=tuple(str(item) for item in value.get("context", ())),
|
|
195
|
+
provenance=value.get("provenance"),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dataclass(frozen=True)
|
|
200
|
+
class StereoRefusal:
|
|
201
|
+
"""One typed reason that a stereo assertion was not accepted."""
|
|
202
|
+
|
|
203
|
+
code: StereoRefusalCode
|
|
204
|
+
detail: str
|
|
205
|
+
targets: tuple[str, ...] = ()
|
|
206
|
+
required_context: tuple[str, ...] = ()
|
|
207
|
+
|
|
208
|
+
def __post_init__(self) -> None:
|
|
209
|
+
object.__setattr__(self, "code", StereoRefusalCode(self.code))
|
|
210
|
+
detail = self.detail.strip()
|
|
211
|
+
if not detail:
|
|
212
|
+
raise ValueError("A stereo refusal requires explanatory detail.")
|
|
213
|
+
object.__setattr__(self, "detail", detail)
|
|
214
|
+
object.__setattr__(
|
|
215
|
+
self,
|
|
216
|
+
"targets",
|
|
217
|
+
tuple(sorted(set(str(item) for item in self.targets))),
|
|
218
|
+
)
|
|
219
|
+
object.__setattr__(
|
|
220
|
+
self,
|
|
221
|
+
"required_context",
|
|
222
|
+
tuple(sorted(set(str(item) for item in self.required_context))),
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
def to_dict(self) -> dict[str, Any]:
|
|
226
|
+
"""Return a deterministic JSON-compatible representation."""
|
|
227
|
+
return {
|
|
228
|
+
"code": self.code.value,
|
|
229
|
+
"detail": self.detail,
|
|
230
|
+
"targets": list(self.targets),
|
|
231
|
+
"required_context": list(self.required_context),
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def from_dict(cls, value: Mapping[str, Any]) -> "StereoRefusal":
|
|
236
|
+
"""Read one typed refusal."""
|
|
237
|
+
return cls(
|
|
238
|
+
StereoRefusalCode(value["code"]),
|
|
239
|
+
str(value["detail"]),
|
|
240
|
+
tuple(str(item) for item in value.get("targets", ())),
|
|
241
|
+
tuple(str(item) for item in value.get("required_context", ())),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@dataclass(frozen=True)
|
|
246
|
+
class StereoReactionDecision:
|
|
247
|
+
"""Exactly one accepted assertion or one fail-closed refusal."""
|
|
248
|
+
|
|
249
|
+
assertion: StereoReactionSemantics | None = None
|
|
250
|
+
refusal: StereoRefusal | None = None
|
|
251
|
+
|
|
252
|
+
def __post_init__(self) -> None:
|
|
253
|
+
if (self.assertion is None) == (self.refusal is None):
|
|
254
|
+
raise ValueError(
|
|
255
|
+
"A reaction-stereo decision requires exactly one assertion "
|
|
256
|
+
"or refusal."
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def accepted(self) -> bool:
|
|
261
|
+
"""Whether this decision carries an accepted assertion."""
|
|
262
|
+
return self.assertion is not None
|
|
263
|
+
|
|
264
|
+
def to_dict(self) -> dict[str, Any]:
|
|
265
|
+
"""Return the explicit decision discriminator and payload."""
|
|
266
|
+
if self.assertion is not None:
|
|
267
|
+
return {
|
|
268
|
+
"status": "accepted",
|
|
269
|
+
"assertion": self.assertion.to_dict(),
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
"status": "refused",
|
|
273
|
+
"refusal": self.refusal.to_dict(), # type: ignore[union-attr]
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@classmethod
|
|
277
|
+
def from_dict(cls, value: Mapping[str, Any]) -> "StereoReactionDecision":
|
|
278
|
+
"""Read an accepted or refused decision without guessing its kind."""
|
|
279
|
+
status = value.get("status")
|
|
280
|
+
if status == "accepted":
|
|
281
|
+
return cls(assertion=StereoReactionSemantics.from_dict(value["assertion"]))
|
|
282
|
+
if status == "refused":
|
|
283
|
+
return cls(refusal=StereoRefusal.from_dict(value["refusal"]))
|
|
284
|
+
raise ValueError(f"Unsupported reaction-stereo decision status: {status!r}.")
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
__all__ = [
|
|
288
|
+
"StereoDeterminacy",
|
|
289
|
+
"StereoEvidenceKind",
|
|
290
|
+
"StereoLifecycle",
|
|
291
|
+
"StereoPopulation",
|
|
292
|
+
"StereoReactionDecision",
|
|
293
|
+
"StereoReactionSemantics",
|
|
294
|
+
"StereoRefusal",
|
|
295
|
+
"StereoRefusalCode",
|
|
296
|
+
]
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""Typed, immutable supports for relative stereochemical descriptors.
|
|
2
|
+
|
|
3
|
+
Support answers *where* a stereo element lives. It deliberately does not
|
|
4
|
+
encode configuration, CIP labels, provenance, or configurational stability.
|
|
5
|
+
Those are separate concerns of configured descriptors and their consumers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from typing import Mapping
|
|
12
|
+
|
|
13
|
+
Reference = int | str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _relabel_reference(value: Reference, mapping: Mapping[int, int]) -> Reference:
|
|
17
|
+
"""Relabel material references and owner-scoped virtual references."""
|
|
18
|
+
if type(value) is int:
|
|
19
|
+
return mapping.get(value, value)
|
|
20
|
+
for prefix in ("@H:", "@LP:"):
|
|
21
|
+
if value.startswith(prefix):
|
|
22
|
+
try:
|
|
23
|
+
owner = int(value[len(prefix) :])
|
|
24
|
+
except ValueError:
|
|
25
|
+
return value
|
|
26
|
+
return f"{prefix}{mapping.get(owner, owner)}"
|
|
27
|
+
return value
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class StereoDescriptor:
|
|
31
|
+
"""Marker base for configured stereo elements."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AtomCenteredStereo(StereoDescriptor):
|
|
35
|
+
"""Configured stereo supported by one atom."""
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def support(self) -> "AtomStereoSupport":
|
|
39
|
+
return AtomStereoSupport(self.center) # type: ignore[attr-defined]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class BondCenteredStereo(StereoDescriptor):
|
|
43
|
+
"""Configured stereo supported by one bond."""
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def support(self) -> "BondStereoSupport":
|
|
47
|
+
left, right = self.atoms[2:4] # type: ignore[attr-defined]
|
|
48
|
+
return BondStereoSupport(left, right)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class AxisStereo(StereoDescriptor):
|
|
52
|
+
"""Configured stereo supported by an ordered axis and terminal frames."""
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class PlaneStereo(StereoDescriptor):
|
|
56
|
+
"""Configured stereo supported by an oriented molecular plane."""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class PathStereo(StereoDescriptor):
|
|
60
|
+
"""Configured stereo supported by an ordered molecular path."""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GlobalStereo(StereoDescriptor):
|
|
64
|
+
"""Configured stereo whose support is a whole connected component."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class StereoSupport:
|
|
68
|
+
"""Marker base for immutable stereo-support values."""
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def dependencies(self) -> frozenset[int]:
|
|
72
|
+
raise NotImplementedError
|
|
73
|
+
|
|
74
|
+
def relabel(self, mapping: Mapping[int, int]) -> "StereoSupport":
|
|
75
|
+
raise NotImplementedError
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class AtomStereoSupport(StereoSupport):
|
|
80
|
+
center: int
|
|
81
|
+
|
|
82
|
+
def __post_init__(self) -> None:
|
|
83
|
+
if type(self.center) is not int:
|
|
84
|
+
raise TypeError("Atom stereo support requires an integer center.")
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def dependencies(self) -> frozenset[int]:
|
|
88
|
+
return frozenset({self.center})
|
|
89
|
+
|
|
90
|
+
def relabel(self, mapping: Mapping[int, int]) -> "AtomStereoSupport":
|
|
91
|
+
return AtomStereoSupport(mapping.get(self.center, self.center))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass(frozen=True)
|
|
95
|
+
class BondStereoSupport(StereoSupport):
|
|
96
|
+
left: int
|
|
97
|
+
right: int
|
|
98
|
+
|
|
99
|
+
def __post_init__(self) -> None:
|
|
100
|
+
if type(self.left) is not int or type(self.right) is not int:
|
|
101
|
+
raise TypeError("Bond stereo support requires integer endpoints.")
|
|
102
|
+
if self.left == self.right:
|
|
103
|
+
raise ValueError("Bond stereo support endpoints must be distinct.")
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def endpoints(self) -> tuple[int, int]:
|
|
107
|
+
return self.left, self.right
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def dependencies(self) -> frozenset[int]:
|
|
111
|
+
return frozenset(self.endpoints)
|
|
112
|
+
|
|
113
|
+
def relabel(self, mapping: Mapping[int, int]) -> "BondStereoSupport":
|
|
114
|
+
return BondStereoSupport(
|
|
115
|
+
mapping.get(self.left, self.left),
|
|
116
|
+
mapping.get(self.right, self.right),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(frozen=True)
|
|
121
|
+
class AxisStereoSupport(StereoSupport):
|
|
122
|
+
path: tuple[int, ...]
|
|
123
|
+
terminal_frames: tuple[
|
|
124
|
+
tuple[Reference, Reference],
|
|
125
|
+
tuple[Reference, Reference],
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
def __post_init__(self) -> None:
|
|
129
|
+
object.__setattr__(self, "path", tuple(self.path))
|
|
130
|
+
object.__setattr__(
|
|
131
|
+
self,
|
|
132
|
+
"terminal_frames",
|
|
133
|
+
tuple(tuple(frame) for frame in self.terminal_frames),
|
|
134
|
+
)
|
|
135
|
+
if len(self.path) < 2 or any(type(atom) is not int for atom in self.path):
|
|
136
|
+
raise ValueError("Axis stereo support requires at least two integer atoms.")
|
|
137
|
+
if len(set(self.path)) != len(self.path):
|
|
138
|
+
raise ValueError("Axis stereo support paths must not repeat atoms.")
|
|
139
|
+
if len(self.terminal_frames) != 2 or any(
|
|
140
|
+
len(frame) != 2 for frame in self.terminal_frames
|
|
141
|
+
):
|
|
142
|
+
raise ValueError("Axis stereo support requires two two-reference frames.")
|
|
143
|
+
if any(len(set(frame)) != 2 for frame in self.terminal_frames):
|
|
144
|
+
raise ValueError("References within each terminal frame must be distinct.")
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def endpoints(self) -> tuple[int, int]:
|
|
148
|
+
return self.path[0], self.path[-1]
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def dependencies(self) -> frozenset[int]:
|
|
152
|
+
material = {
|
|
153
|
+
reference
|
|
154
|
+
for frame in self.terminal_frames
|
|
155
|
+
for reference in frame
|
|
156
|
+
if type(reference) is int
|
|
157
|
+
}
|
|
158
|
+
return frozenset((*self.path, *material))
|
|
159
|
+
|
|
160
|
+
def relabel(self, mapping: Mapping[int, int]) -> "AxisStereoSupport":
|
|
161
|
+
return AxisStereoSupport(
|
|
162
|
+
tuple(mapping.get(atom, atom) for atom in self.path),
|
|
163
|
+
tuple(
|
|
164
|
+
tuple(_relabel_reference(reference, mapping) for reference in frame)
|
|
165
|
+
for frame in self.terminal_frames
|
|
166
|
+
), # type: ignore[arg-type]
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@dataclass(frozen=True)
|
|
171
|
+
class PlaneStereoSupport(StereoSupport):
|
|
172
|
+
plane_atoms: tuple[int, ...]
|
|
173
|
+
|
|
174
|
+
def __post_init__(self) -> None:
|
|
175
|
+
object.__setattr__(self, "plane_atoms", tuple(self.plane_atoms))
|
|
176
|
+
if len(self.plane_atoms) < 3 or any(
|
|
177
|
+
type(atom) is not int for atom in self.plane_atoms
|
|
178
|
+
):
|
|
179
|
+
raise ValueError("Plane stereo support requires at least three atoms.")
|
|
180
|
+
if len(set(self.plane_atoms)) != len(self.plane_atoms):
|
|
181
|
+
raise ValueError("Plane stereo support atoms must be distinct.")
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def dependencies(self) -> frozenset[int]:
|
|
185
|
+
return frozenset(self.plane_atoms)
|
|
186
|
+
|
|
187
|
+
def relabel(self, mapping: Mapping[int, int]) -> "PlaneStereoSupport":
|
|
188
|
+
return PlaneStereoSupport(
|
|
189
|
+
tuple(mapping.get(atom, atom) for atom in self.plane_atoms)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass(frozen=True)
|
|
194
|
+
class PathStereoSupport(StereoSupport):
|
|
195
|
+
path: tuple[int, ...]
|
|
196
|
+
cyclic: bool = False
|
|
197
|
+
|
|
198
|
+
def __post_init__(self) -> None:
|
|
199
|
+
object.__setattr__(self, "path", tuple(self.path))
|
|
200
|
+
if len(self.path) < 2 or any(type(atom) is not int for atom in self.path):
|
|
201
|
+
raise ValueError("Path stereo support requires at least two atoms.")
|
|
202
|
+
if len(set(self.path)) != len(self.path):
|
|
203
|
+
raise ValueError("Path stereo support atoms must be distinct.")
|
|
204
|
+
if type(self.cyclic) is not bool:
|
|
205
|
+
raise TypeError("Path stereo cyclic state must be boolean.")
|
|
206
|
+
if self.cyclic and len(self.path) < 3:
|
|
207
|
+
raise ValueError(
|
|
208
|
+
"Cyclic path stereo support requires at least three atoms."
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def dependencies(self) -> frozenset[int]:
|
|
213
|
+
return frozenset(self.path)
|
|
214
|
+
|
|
215
|
+
def relabel(self, mapping: Mapping[int, int]) -> "PathStereoSupport":
|
|
216
|
+
return PathStereoSupport(
|
|
217
|
+
tuple(mapping.get(atom, atom) for atom in self.path),
|
|
218
|
+
self.cyclic,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@dataclass(frozen=True)
|
|
223
|
+
class GlobalStereoSupport(StereoSupport):
|
|
224
|
+
atoms: frozenset[int]
|
|
225
|
+
|
|
226
|
+
def __post_init__(self) -> None:
|
|
227
|
+
object.__setattr__(self, "atoms", frozenset(self.atoms))
|
|
228
|
+
if not self.atoms or any(type(atom) is not int for atom in self.atoms):
|
|
229
|
+
raise ValueError("Global stereo support requires integer component atoms.")
|
|
230
|
+
|
|
231
|
+
@property
|
|
232
|
+
def dependencies(self) -> frozenset[int]:
|
|
233
|
+
return self.atoms
|
|
234
|
+
|
|
235
|
+
def relabel(self, mapping: Mapping[int, int]) -> "GlobalStereoSupport":
|
|
236
|
+
return GlobalStereoSupport(
|
|
237
|
+
frozenset(mapping.get(atom, atom) for atom in self.atoms)
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
__all__ = [
|
|
242
|
+
"AtomCenteredStereo",
|
|
243
|
+
"AtomStereoSupport",
|
|
244
|
+
"AxisStereo",
|
|
245
|
+
"AxisStereoSupport",
|
|
246
|
+
"BondCenteredStereo",
|
|
247
|
+
"BondStereoSupport",
|
|
248
|
+
"GlobalStereo",
|
|
249
|
+
"GlobalStereoSupport",
|
|
250
|
+
"PathStereo",
|
|
251
|
+
"PathStereoSupport",
|
|
252
|
+
"PlaneStereo",
|
|
253
|
+
"PlaneStereoSupport",
|
|
254
|
+
"Reference",
|
|
255
|
+
"StereoDescriptor",
|
|
256
|
+
"StereoSupport",
|
|
257
|
+
]
|