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.
Files changed (636) hide show
  1. synkit/CRN/Benchmark/__init__.py +53 -0
  2. synkit/CRN/Benchmark/crosschecks.py +13 -0
  3. synkit/CRN/Benchmark/kegg.py +12 -0
  4. synkit/CRN/Benchmark/networks.py +13 -0
  5. synkit/CRN/Benchmark/scaling.py +13 -0
  6. synkit/CRN/Benchmark/validate.py +13 -0
  7. synkit/CRN/Construct/__init__.py +16 -0
  8. synkit/CRN/Construct/abstract.py +668 -0
  9. synkit/CRN/Construct/arity.py +36 -0
  10. synkit/CRN/Construct/builder.py +619 -0
  11. synkit/CRN/Construct/derivation.py +63 -0
  12. synkit/CRN/Construct/flattener.py +100 -0
  13. synkit/CRN/Construct/keys.py +14 -0
  14. synkit/CRN/Construct/mixtures.py +117 -0
  15. synkit/CRN/Construct/rdkit_worker.py +69 -0
  16. synkit/CRN/Construct/smiles.py +99 -0
  17. synkit/CRN/Construct/state.py +31 -0
  18. synkit/CRN/Construct/strategy.py +75 -0
  19. synkit/CRN/Construct/worker.py +42 -0
  20. synkit/CRN/IO/__init__.py +36 -0
  21. synkit/CRN/IO/sbml.py +925 -0
  22. synkit/CRN/Pathway/__init__.py +72 -0
  23. synkit/CRN/Pathway/_adapter.py +333 -0
  24. synkit/CRN/Pathway/pathfinder.py +500 -0
  25. synkit/CRN/Pathway/reachability.py +796 -0
  26. synkit/CRN/Pathway/realizability.py +1322 -0
  27. synkit/CRN/Petrinet/__init__.py +93 -0
  28. synkit/CRN/Petrinet/analyzer.py +486 -0
  29. synkit/CRN/Petrinet/minimal_semiflows.py +436 -0
  30. synkit/CRN/Petrinet/net.py +1041 -0
  31. synkit/CRN/Petrinet/persistence.py +97 -0
  32. synkit/CRN/Petrinet/semiflows.py +483 -0
  33. synkit/CRN/Petrinet/siphon_search.py +402 -0
  34. synkit/CRN/Petrinet/structure.py +286 -0
  35. synkit/CRN/Props/__init__.py +130 -0
  36. synkit/CRN/Props/_rank.py +29 -0
  37. synkit/CRN/Props/deficiency.py +953 -0
  38. synkit/CRN/Props/dynamics.py +832 -0
  39. synkit/CRN/Props/helper.py +151 -0
  40. synkit/CRN/Props/stoich.py +751 -0
  41. synkit/CRN/Props/thermo.py +584 -0
  42. synkit/CRN/Query/__init__.py +66 -0
  43. synkit/CRN/Query/cache.py +41 -0
  44. synkit/CRN/Query/kegg_api.py +99 -0
  45. synkit/CRN/Query/kegg_extract.py +714 -0
  46. synkit/CRN/Query/kegg_impute.py +707 -0
  47. synkit/CRN/Query/kegg_parse.py +480 -0
  48. synkit/CRN/Query/to_syncrn.py +290 -0
  49. synkit/CRN/README.md +234 -0
  50. synkit/CRN/Structure/__init__.py +12 -0
  51. synkit/CRN/Structure/_graph_io.py +713 -0
  52. synkit/CRN/Structure/_matrices.py +88 -0
  53. synkit/CRN/Structure/_parse.py +544 -0
  54. synkit/CRN/Structure/reaction.py +237 -0
  55. synkit/CRN/Structure/rule.py +55 -0
  56. synkit/CRN/Structure/species.py +46 -0
  57. synkit/CRN/Structure/syncrn.py +929 -0
  58. synkit/CRN/Symmetry/__init__.py +20 -0
  59. synkit/CRN/Symmetry/_common.py +1059 -0
  60. synkit/CRN/Symmetry/_ir.py +940 -0
  61. synkit/CRN/Symmetry/automorphism.py +472 -0
  62. synkit/CRN/Symmetry/canon.py +441 -0
  63. synkit/CRN/Symmetry/isomorphism.py +412 -0
  64. synkit/CRN/Symmetry/symmetry.py +61 -0
  65. synkit/CRN/Symmetry/wl_canon.py +967 -0
  66. synkit/CRN/Visualize/__init__.py +11 -0
  67. synkit/CRN/Visualize/labels.py +113 -0
  68. synkit/CRN/Visualize/layout.py +708 -0
  69. synkit/CRN/Visualize/palette.py +292 -0
  70. synkit/CRN/Visualize/validation.py +122 -0
  71. synkit/CRN/Visualize/vis.py +1152 -0
  72. synkit/CRN/__init__.py +233 -0
  73. synkit/CRN/_build.py +50 -0
  74. synkit/CRN/_native_build.py +175 -0
  75. synkit/CRN/analysis.py +629 -0
  76. synkit/CRN/backend.py +74 -0
  77. synkit/CRN/cpp/CMakeLists.txt +58 -0
  78. synkit/CRN/cpp/algebra.cpp +46 -0
  79. synkit/CRN/cpp/closure.cpp +29 -0
  80. synkit/CRN/cpp/exact.h +55 -0
  81. synkit/CRN/cpp/pathway.cpp +46 -0
  82. synkit/CRN/cpp/semiflows.cpp +209 -0
  83. synkit/CRN/cpp/structural.cpp +240 -0
  84. synkit/CRN/cpp/symmetry.cpp +45 -0
  85. synkit/CRN/cpp/write_manifest.cmake +28 -0
  86. synkit/CRN/kinds.py +137 -0
  87. synkit/CRN/lib/synkit_crn.dll +0 -0
  88. synkit/CRN/lib/synkit_crn.json +33 -0
  89. synkit/CRN/native.py +388 -0
  90. synkit/CRN/native_analysis.py +459 -0
  91. synkit/Chem/Cluster/__init__.py +0 -0
  92. synkit/Chem/Cluster/butina.py +140 -0
  93. synkit/Chem/Fingerprint/__init__.py +0 -0
  94. synkit/Chem/Fingerprint/fp_calculator.py +155 -0
  95. synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
  96. synkit/Chem/Fingerprint/transformation_fp.py +139 -0
  97. synkit/Chem/Mapper/README.rst +43 -0
  98. synkit/Chem/Mapper/__init__.py +255 -0
  99. synkit/Chem/Mapper/_compat.py +130 -0
  100. synkit/Chem/Mapper/adapters/__init__.py +1 -0
  101. synkit/Chem/Mapper/adapters/prediction.py +126 -0
  102. synkit/Chem/Mapper/adapters/template.py +412 -0
  103. synkit/Chem/Mapper/chem/__init__.py +52 -0
  104. synkit/Chem/Mapper/chem/aam.py +673 -0
  105. synkit/Chem/Mapper/chem/blind.py +160 -0
  106. synkit/Chem/Mapper/chem/its.py +309 -0
  107. synkit/Chem/Mapper/chem/smiles.py +564 -0
  108. synkit/Chem/Mapper/graph/__init__.py +66 -0
  109. synkit/Chem/Mapper/graph/automorphism.py +395 -0
  110. synkit/Chem/Mapper/graph/blockcut.py +98 -0
  111. synkit/Chem/Mapper/graph/labeled_graph.py +104 -0
  112. synkit/Chem/Mapper/graph/refine.py +176 -0
  113. synkit/Chem/Mapper/graph/synkit_adapter.py +110 -0
  114. synkit/Chem/Mapper/io/__init__.py +13 -0
  115. synkit/Chem/Mapper/io/idxmapstr.py +82 -0
  116. synkit/Chem/Mapper/mapper.py +685 -0
  117. synkit/Chem/Mapper/reaction_search.py +554 -0
  118. synkit/Chem/Mapper/reporting/__init__.py +1 -0
  119. synkit/Chem/Mapper/reporting/alternatives.py +451 -0
  120. synkit/Chem/Mapper/reporting/analysis.py +681 -0
  121. synkit/Chem/Mapper/reporting/native_analysis.py +485 -0
  122. synkit/Chem/Mapper/reporting/spectrum.py +642 -0
  123. synkit/Chem/Mapper/solvers/__init__.py +1 -0
  124. synkit/Chem/Mapper/solvers/exact/__init__.py +141 -0
  125. synkit/Chem/Mapper/solvers/exact/assignment/__init__.py +1 -0
  126. synkit/Chem/Mapper/solvers/exact/assignment/assignment_certificate.py +113 -0
  127. synkit/Chem/Mapper/solvers/exact/assignment/assignment_domains.py +162 -0
  128. synkit/Chem/Mapper/solvers/exact/assignment/assignment_verification.py +58 -0
  129. synkit/Chem/Mapper/solvers/exact/assignment/incremental_assignment.py +247 -0
  130. synkit/Chem/Mapper/solvers/exact/certificate.py +128 -0
  131. synkit/Chem/Mapper/solvers/exact/core.py +183 -0
  132. synkit/Chem/Mapper/solvers/exact/distance_search/__init__.py +1 -0
  133. synkit/Chem/Mapper/solvers/exact/distance_search/bounds.py +319 -0
  134. synkit/Chem/Mapper/solvers/exact/distance_search/exhaustive.py +179 -0
  135. synkit/Chem/Mapper/solvers/exact/distance_search/inputs.py +283 -0
  136. synkit/Chem/Mapper/solvers/exact/distance_search/records.py +242 -0
  137. synkit/Chem/Mapper/solvers/exact/distance_search/search.py +1025 -0
  138. synkit/Chem/Mapper/solvers/exact/distance_search/verify.py +378 -0
  139. synkit/Chem/Mapper/solvers/exact/edit_support.py +375 -0
  140. synkit/Chem/Mapper/solvers/exact/hybrid.py +224 -0
  141. synkit/Chem/Mapper/solvers/exact/hydrogen.py +264 -0
  142. synkit/Chem/Mapper/solvers/exact/kernel_solvers/__init__.py +1 -0
  143. synkit/Chem/Mapper/solvers/exact/kernel_solvers/branching.py +499 -0
  144. synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumerate.py +1050 -0
  145. synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumeration_result.py +30 -0
  146. synkit/Chem/Mapper/solvers/exact/kernel_solvers/kernel.py +256 -0
  147. synkit/Chem/Mapper/solvers/exact/kernel_solvers/milp.py +194 -0
  148. synkit/Chem/Mapper/solvers/exact/native/__init__.py +1 -0
  149. synkit/Chem/Mapper/solvers/exact/native/build.py +154 -0
  150. synkit/Chem/Mapper/solvers/exact/native/candidates.py +593 -0
  151. synkit/Chem/Mapper/solvers/exact/native/canonical.py +396 -0
  152. synkit/Chem/Mapper/solvers/exact/native/disk_frontier.py +415 -0
  153. synkit/Chem/Mapper/solvers/exact/native/frontier.py +390 -0
  154. synkit/Chem/Mapper/solvers/exact/native/hydrogen_quotient.py +213 -0
  155. synkit/Chem/Mapper/solvers/exact/native/its.py +528 -0
  156. synkit/Chem/Mapper/solvers/exact/native/native_distance.cpp +2803 -0
  157. synkit/Chem/Mapper/solvers/exact/native/orbit_aggregation.py +328 -0
  158. synkit/Chem/Mapper/solvers/exact/native/parallel.py +205 -0
  159. synkit/Chem/Mapper/solvers/exact/native/pmcd.py +203 -0
  160. synkit/Chem/Mapper/solvers/exact/native/runtime.py +40 -0
  161. synkit/Chem/Mapper/solvers/exact/native/search.py +294 -0
  162. synkit/Chem/Mapper/solvers/exact/native/separator.py +224 -0
  163. synkit/Chem/Mapper/solvers/exact/native_build.py +12 -0
  164. synkit/Chem/Mapper/solvers/exact/pabs/__init__.py +1 -0
  165. synkit/Chem/Mapper/solvers/exact/pabs/cost_lattice.py +43 -0
  166. synkit/Chem/Mapper/solvers/exact/pabs/factor_spectrum.py +110 -0
  167. synkit/Chem/Mapper/solvers/exact/pabs/multi_shell.py +368 -0
  168. synkit/Chem/Mapper/solvers/exact/pabs/propagation.py +679 -0
  169. synkit/Chem/Mapper/solvers/exact/pabs/propagation_bounds.py +436 -0
  170. synkit/Chem/Mapper/solvers/exact/pabs/propagation_limits.py +13 -0
  171. synkit/Chem/Mapper/solvers/exact/pabs/propagation_search.py +856 -0
  172. synkit/Chem/Mapper/solvers/exact/pabs/propagation_symmetry.py +66 -0
  173. synkit/Chem/Mapper/solvers/exact/pabs/residual_typed_bonds.py +136 -0
  174. synkit/Chem/Mapper/solvers/exact/pabs/reward_frontier.py +201 -0
  175. synkit/Chem/Mapper/solvers/exact/pabs/separator_bound.py +258 -0
  176. synkit/Chem/Mapper/solvers/exact/pabs/separator_spectrum.py +308 -0
  177. synkit/Chem/Mapper/solvers/exact/pabs/sparse_reward_bound.py +207 -0
  178. synkit/Chem/Mapper/solvers/exact/pabs/suffix_spectrum.py +299 -0
  179. synkit/Chem/Mapper/solvers/exact/search.py +55 -0
  180. synkit/Chem/Mapper/solvers/exact/seeds/__init__.py +1 -0
  181. synkit/Chem/Mapper/solvers/exact/seeds/seed.py +104 -0
  182. synkit/Chem/Mapper/solvers/exact/seeds/seed_fragments.py +148 -0
  183. synkit/Chem/Mapper/solvers/exact/seeds/seed_relaxation.py +181 -0
  184. synkit/Chem/Mapper/solvers/exact/symmetry.py +223 -0
  185. synkit/Chem/Mapper/solvers/native/__init__.py +4 -0
  186. synkit/Chem/Mapper/solvers/native/assignment.py +99 -0
  187. synkit/Chem/Mapper/solvers/native/astar.py +22 -0
  188. synkit/Chem/Mapper/solvers/native/build.py +385 -0
  189. synkit/Chem/Mapper/solvers/native/classification.py +641 -0
  190. synkit/Chem/Mapper/solvers/native/core.py +378 -0
  191. synkit/Chem/Mapper/solvers/native/cpp/CMakeLists.txt +120 -0
  192. synkit/Chem/Mapper/solvers/native/cpp/examples/map_reaction.cpp +29 -0
  193. synkit/Chem/Mapper/solvers/native/cpp/examples/slap_graph.cpp +63 -0
  194. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/assignment/assignment.h +18 -0
  195. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/astar.h +18 -0
  196. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/bound.h +33 -0
  197. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/pmcd_witness.h +16 -0
  198. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/runtime.h +130 -0
  199. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/hydrogen/hydrogen.h +73 -0
  200. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mapper.h +175 -0
  201. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mces/mces.h +9 -0
  202. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/pabs/seed.h +34 -0
  203. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/reaction/reaction.h +30 -0
  204. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/sepdp/sepdp.h +21 -0
  205. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/slap.h +72 -0
  206. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/solvers/solvers.h +16 -0
  207. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/classification.h +140 -0
  208. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/cpabs.h +33 -0
  209. synkit/Chem/Mapper/solvers/native/cpp/src/assignment/abb.cpp +302 -0
  210. synkit/Chem/Mapper/solvers/native/cpp/src/astar/CMakeLists.txt +12 -0
  211. synkit/Chem/Mapper/solvers/native/cpp/src/astar/README.md +47 -0
  212. synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar.cpp +228 -0
  213. synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar_graph.cpp +37 -0
  214. synkit/Chem/Mapper/solvers/native/cpp/src/astar/bound.cpp +212 -0
  215. synkit/Chem/Mapper/solvers/native/cpp/src/core/dispatch.cpp +272 -0
  216. synkit/Chem/Mapper/solvers/native/cpp/src/core/pmcd_witness.cpp +36 -0
  217. synkit/Chem/Mapper/solvers/native/cpp/src/hydrogen/hydrogen.cpp +380 -0
  218. synkit/Chem/Mapper/solvers/native/cpp/src/mces/README.md +57 -0
  219. synkit/Chem/Mapper/solvers/native/cpp/src/mces/mces.cpp +287 -0
  220. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/bridge.cpp +334 -0
  221. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/chemical_floor.inc +181 -0
  222. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/endpoint_symmetry.inc +104 -0
  223. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/exact_helpers.h +20 -0
  224. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_assignment_certificate.h +165 -0
  225. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_certificate.h +125 -0
  226. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_model.h +365 -0
  227. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_provider.inc +319 -0
  228. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_rounding.inc +170 -0
  229. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_test_hooks.h +342 -0
  230. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/objective_reduction.inc +137 -0
  231. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/overlap_dual.inc +351 -0
  232. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/profile_seed.inc +214 -0
  233. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/seed_heuristics.inc +640 -0
  234. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_embedding.cpp +430 -0
  235. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_root_lp.h +176 -0
  236. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/test_hooks.inc +262 -0
  237. synkit/Chem/Mapper/solvers/native/cpp/src/reaction/reaction.cpp +611 -0
  238. synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/README.md +61 -0
  239. synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/sepdp.cpp +253 -0
  240. synkit/Chem/Mapper/solvers/native/cpp/src/slap.cpp +810 -0
  241. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/formulation.h +138 -0
  242. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/maxsat.cpp +526 -0
  243. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/ortools.cpp +475 -0
  244. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/seed.h +80 -0
  245. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/weighted_cnf.h +256 -0
  246. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/README.md +43 -0
  247. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/dfs.cpp +123 -0
  248. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/edit_support.cpp +224 -0
  249. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification.cpp +553 -0
  250. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_pipeline.cpp +124 -0
  251. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_stream.h +13 -0
  252. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/cpabs.cpp +455 -0
  253. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/edge_deck.cpp +743 -0
  254. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
  255. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
  256. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naugraph.c +732 -0
  257. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.c +94 -0
  258. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.h +49 -0
  259. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.c +1771 -0
  260. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.h +133 -0
  261. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nautil.c +750 -0
  262. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naututil.h +355 -0
  263. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.c +1256 -0
  264. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.h +1544 -0
  265. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.c +1131 -0
  266. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.h +70 -0
  267. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/sorttemplates.c +580 -0
  268. synkit/Chem/Mapper/solvers/native/hydrogen.py +711 -0
  269. synkit/Chem/Mapper/solvers/native/implicit.py +506 -0
  270. synkit/Chem/Mapper/solvers/native/implicit_certificate.py +187 -0
  271. synkit/Chem/Mapper/solvers/native/implicit_preparation.py +309 -0
  272. synkit/Chem/Mapper/solvers/native/lib/synkit_mapper.dll +0 -0
  273. synkit/Chem/Mapper/solvers/native/mces.py +16 -0
  274. synkit/Chem/Mapper/solvers/native/reaction.py +179 -0
  275. synkit/Chem/Mapper/solvers/native/reaction_build.py +277 -0
  276. synkit/Chem/Mapper/solvers/native/reaction_text.py +26 -0
  277. synkit/Chem/Mapper/solvers/native/runtime.py +242 -0
  278. synkit/Chem/Mapper/solvers/native/sepdp.py +47 -0
  279. synkit/Chem/Mapper/solvers/native/slap.py +266 -0
  280. synkit/Chem/Mapper/solvers/native/solvers.py +67 -0
  281. synkit/Chem/Mapper/solvers/native/stereo.py +86 -0
  282. synkit/Chem/Mapper/solvers/native/supporting.py +34 -0
  283. synkit/Chem/Mapper/solvers/native/symmetry.py +91 -0
  284. synkit/Chem/Mapper/solvers/slap/__init__.py +29 -0
  285. synkit/Chem/Mapper/solvers/slap/lap.py +174 -0
  286. synkit/Chem/Mapper/solvers/slap/sequential.py +696 -0
  287. synkit/Chem/Mapper/validation/__init__.py +1 -0
  288. synkit/Chem/Mapper/validation/aam_validator.py +442 -0
  289. synkit/Chem/Mapper/validation/annotations.py +274 -0
  290. synkit/Chem/Mapper/validation/bonds.py +124 -0
  291. synkit/Chem/Mapper/validation/cohorts.py +72 -0
  292. synkit/Chem/Mapper/validation/identifiability.py +150 -0
  293. synkit/Chem/Mapper/validation/numerical_scope.py +36 -0
  294. synkit/Chem/Mapper/validation/orbits.py +137 -0
  295. synkit/Chem/Molecule/__init__.py +0 -0
  296. synkit/Chem/Molecule/_chirality_loci.py +165 -0
  297. synkit/Chem/Molecule/_chirality_types.py +231 -0
  298. synkit/Chem/Molecule/_helical_loci.py +167 -0
  299. synkit/Chem/Molecule/_stereo_axis_evidence.py +202 -0
  300. synkit/Chem/Molecule/_stereo_element_detection.py +193 -0
  301. synkit/Chem/Molecule/_stereo_orientation_constraints.py +511 -0
  302. synkit/Chem/Molecule/_tetrahedral_carriers.py +63 -0
  303. synkit/Chem/Molecule/atom_features.py +379 -0
  304. synkit/Chem/Molecule/chirality.py +1041 -0
  305. synkit/Chem/Molecule/cip_assignment.py +569 -0
  306. synkit/Chem/Molecule/cip_ranking.py +843 -0
  307. synkit/Chem/Molecule/coordinate_stereo.py +503 -0
  308. synkit/Chem/Molecule/derived_stereo_naming.py +165 -0
  309. synkit/Chem/Molecule/descriptors.py +452 -0
  310. synkit/Chem/Molecule/formula.py +249 -0
  311. synkit/Chem/Molecule/global_stereo.py +175 -0
  312. synkit/Chem/Molecule/graph_annotator.py +300 -0
  313. synkit/Chem/Molecule/standardize.py +817 -0
  314. synkit/Chem/Molecule/stereo_evidence.py +179 -0
  315. synkit/Chem/Molecule/stereo_perception.py +1032 -0
  316. synkit/Chem/Molecule/valence.py +123 -0
  317. synkit/Chem/Reaction/Mapper/__init__.py +44 -0
  318. synkit/Chem/Reaction/__init__.py +20 -0
  319. synkit/Chem/Reaction/aam_validator.py +5 -0
  320. synkit/Chem/Reaction/balance_check.py +138 -0
  321. synkit/Chem/Reaction/canon_rsmi.py +249 -0
  322. synkit/Chem/Reaction/cleaning.py +58 -0
  323. synkit/Chem/Reaction/deionize.py +199 -0
  324. synkit/Chem/Reaction/explicit_h_audit.py +232 -0
  325. synkit/Chem/Reaction/fix_aam.py +64 -0
  326. synkit/Chem/Reaction/neutralize.py +207 -0
  327. synkit/Chem/Reaction/radical_wildcard.py +224 -0
  328. synkit/Chem/Reaction/standardize.py +203 -0
  329. synkit/Chem/Reaction/tautomerize.py +205 -0
  330. synkit/Chem/__init__.py +1 -0
  331. synkit/Chem/utils.py +315 -0
  332. synkit/Data/__init__.py +0 -0
  333. synkit/Data/aldol.json.gz +1 -0
  334. synkit/Data/gen_partial_aam.py +147 -0
  335. synkit/Data/paracetamol.json.gz +1 -0
  336. synkit/Graph/Canon/__init__.py +16 -0
  337. synkit/Graph/Canon/_native/__init__.py +13 -0
  338. synkit/Graph/Canon/_native/build.py +93 -0
  339. synkit/Graph/Canon/_native/lib/synkit_canon.dll +0 -0
  340. synkit/Graph/Canon/_native/prepare.py +49 -0
  341. synkit/Graph/Canon/_native/runtime.py +140 -0
  342. synkit/Graph/Canon/_native/search.py +137 -0
  343. synkit/Graph/Canon/canon_algs.py +228 -0
  344. synkit/Graph/Canon/canon_graph.py +531 -0
  345. synkit/Graph/Canon/cpp/CMakeLists.txt +42 -0
  346. synkit/Graph/Canon/cpp/README.md +123 -0
  347. synkit/Graph/Canon/cpp/examples/canonical_graph.cpp +16 -0
  348. synkit/Graph/Canon/cpp/include/synkit_canon/canon.h +85 -0
  349. synkit/Graph/Canon/cpp/src/canonical.cpp +391 -0
  350. synkit/Graph/Canon/cpp/src/symmetry.h +83 -0
  351. synkit/Graph/Canon/cpp/tests/symmetry.cpp +93 -0
  352. synkit/Graph/Canon/exact.py +1020 -0
  353. synkit/Graph/Canon/exact_refinement.py +368 -0
  354. synkit/Graph/Canon/nauty.py +143 -0
  355. synkit/Graph/Context/__init__.py +0 -0
  356. synkit/Graph/Context/hier_context.py +244 -0
  357. synkit/Graph/Context/radius_expand.py +252 -0
  358. synkit/Graph/FG/__init__.py +19 -0
  359. synkit/Graph/FG/api.py +39 -0
  360. synkit/Graph/FG/audit.py +155 -0
  361. synkit/Graph/FG/catalog.py +919 -0
  362. synkit/Graph/FG/detector.py +288 -0
  363. synkit/Graph/FG/model.py +97 -0
  364. synkit/Graph/FG/recognizers.py +274 -0
  365. synkit/Graph/FG/ring_system.py +154 -0
  366. synkit/Graph/Feature/Descriptors/topology.py +857 -0
  367. synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
  368. synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +222 -0
  369. synkit/Graph/Feature/__init__.py +5 -0
  370. synkit/Graph/Feature/graph_descriptors.py +323 -0
  371. synkit/Graph/Feature/graph_fps.py +96 -0
  372. synkit/Graph/Feature/graph_signature.py +239 -0
  373. synkit/Graph/Feature/hash_fps.py +133 -0
  374. synkit/Graph/Feature/morgan_fps.py +88 -0
  375. synkit/Graph/Feature/path_fps.py +81 -0
  376. synkit/Graph/Feature/wl_hash.py +134 -0
  377. synkit/Graph/Fusion/__init__.py +85 -0
  378. synkit/Graph/Fusion/candidate.py +559 -0
  379. synkit/Graph/Fusion/constructor.py +877 -0
  380. synkit/Graph/Fusion/identity.py +184 -0
  381. synkit/Graph/Fusion/interface.py +700 -0
  382. synkit/Graph/Fusion/search.py +241 -0
  383. synkit/Graph/Hyrogen/__init__.py +6 -0
  384. synkit/Graph/Hyrogen/_misc.py +591 -0
  385. synkit/Graph/Hyrogen/hcomplete.py +995 -0
  386. synkit/Graph/Hyrogen/hcomplete_legacy.py +368 -0
  387. synkit/Graph/Hyrogen/hcompletion_algorithms.py +713 -0
  388. synkit/Graph/Hyrogen/hextend.py +570 -0
  389. synkit/Graph/Hyrogen/hextend_legacy.py +215 -0
  390. synkit/Graph/ITS/__init__.py +4 -0
  391. synkit/Graph/ITS/its_builder.py +120 -0
  392. synkit/Graph/ITS/its_construction.py +719 -0
  393. synkit/Graph/ITS/its_decompose.py +572 -0
  394. synkit/Graph/ITS/its_destruction.py +331 -0
  395. synkit/Graph/ITS/its_expand.py +1251 -0
  396. synkit/Graph/ITS/its_relabel.py +187 -0
  397. synkit/Graph/ITS/its_reverter.py +356 -0
  398. synkit/Graph/ITS/normalize_aam.py +145 -0
  399. synkit/Graph/ITS/partial_its.py +238 -0
  400. synkit/Graph/ITS/rc_extractor.py +656 -0
  401. synkit/Graph/ITS/stereo.py +74 -0
  402. synkit/Graph/MTG/__init__.py +107 -0
  403. synkit/Graph/MTG/gluing.py +451 -0
  404. synkit/Graph/MTG/history.py +928 -0
  405. synkit/Graph/MTG/inventory.py +118 -0
  406. synkit/Graph/MTG/local.py +447 -0
  407. synkit/Graph/MTG/mcs_matcher.py +246 -0
  408. synkit/Graph/MTG/mtg.py +611 -0
  409. synkit/Graph/MTG/mtg_explore.py +74 -0
  410. synkit/Graph/MTG/observation.py +209 -0
  411. synkit/Graph/MTG/process.py +577 -0
  412. synkit/Graph/MTG/queries.py +66 -0
  413. synkit/Graph/MTG/realization.py +95 -0
  414. synkit/Graph/MTG/series_parallel.py +107 -0
  415. synkit/Graph/MTG/utils.py +424 -0
  416. synkit/Graph/Matcher/__init__.py +10 -0
  417. synkit/Graph/Matcher/approx_mcs.py +1264 -0
  418. synkit/Graph/Matcher/auto_est.py +736 -0
  419. synkit/Graph/Matcher/automorphism.py +314 -0
  420. synkit/Graph/Matcher/batch_cluster.py +224 -0
  421. synkit/Graph/Matcher/dedup_matches.py +247 -0
  422. synkit/Graph/Matcher/graph_cluster.py +191 -0
  423. synkit/Graph/Matcher/graph_matcher.py +312 -0
  424. synkit/Graph/Matcher/graph_morphism.py +421 -0
  425. synkit/Graph/Matcher/mcs_matcher.py +804 -0
  426. synkit/Graph/Matcher/multi_turbo_iso.py +186 -0
  427. synkit/Graph/Matcher/orbit.py +284 -0
  428. synkit/Graph/Matcher/partial_matcher.py +694 -0
  429. synkit/Graph/Matcher/sing.py +544 -0
  430. synkit/Graph/Matcher/subgraph_matcher.py +812 -0
  431. synkit/Graph/Matcher/turbo_iso.py +272 -0
  432. synkit/Graph/Matcher/wl_sel.py +537 -0
  433. synkit/Graph/Mech/__init__.py +26 -0
  434. synkit/Graph/Mech/conversion.py +1466 -0
  435. synkit/Graph/Mech/conversion_debug.py +237 -0
  436. synkit/Graph/Mech/electron_accounting.py +200 -0
  437. synkit/Graph/Mech/lwg_editor.py +406 -0
  438. synkit/Graph/Mech/lwg_ops.py +313 -0
  439. synkit/Graph/Morphism/__init__.py +99 -0
  440. synkit/Graph/Morphism/constraints.py +460 -0
  441. synkit/Graph/Morphism/llg.py +999 -0
  442. synkit/Graph/Morphism/morphism.py +349 -0
  443. synkit/Graph/Morphism/stereo.py +258 -0
  444. synkit/Graph/Morphism/stereo_morphism.py +383 -0
  445. synkit/Graph/Morphism/stereo_morphism_helpers.py +957 -0
  446. synkit/Graph/Morphism/stereo_morphism_types.py +117 -0
  447. synkit/Graph/Stereo/__init__.py +376 -0
  448. synkit/Graph/Stereo/_descriptor_core.py +207 -0
  449. synkit/Graph/Stereo/_descriptor_serialization.py +138 -0
  450. synkit/Graph/Stereo/canonical.py +648 -0
  451. synkit/Graph/Stereo/changes.py +964 -0
  452. synkit/Graph/Stereo/composition.py +391 -0
  453. synkit/Graph/Stereo/configured.py +946 -0
  454. synkit/Graph/Stereo/couplings.py +245 -0
  455. synkit/Graph/Stereo/descriptors.py +1030 -0
  456. synkit/Graph/Stereo/enumeration.py +597 -0
  457. synkit/Graph/Stereo/extended_descriptors.py +406 -0
  458. synkit/Graph/Stereo/global_configured.py +152 -0
  459. synkit/Graph/Stereo/global_stereo.py +304 -0
  460. synkit/Graph/Stereo/identity.py +648 -0
  461. synkit/Graph/Stereo/interchange.py +496 -0
  462. synkit/Graph/Stereo/legacy.py +460 -0
  463. synkit/Graph/Stereo/matching.py +899 -0
  464. synkit/Graph/Stereo/native.py +154 -0
  465. synkit/Graph/Stereo/orbits.py +668 -0
  466. synkit/Graph/Stereo/outcomes.py +99 -0
  467. synkit/Graph/Stereo/pairwise.py +350 -0
  468. synkit/Graph/Stereo/rdkit_adapter.py +662 -0
  469. synkit/Graph/Stereo/rdkit_identity.py +118 -0
  470. synkit/Graph/Stereo/rdkit_resonance.py +140 -0
  471. synkit/Graph/Stereo/reaction_interchange.py +266 -0
  472. synkit/Graph/Stereo/semantics.py +296 -0
  473. synkit/Graph/Stereo/supports.py +257 -0
  474. synkit/Graph/Stereo/wire.py +339 -0
  475. synkit/Graph/Wildcard/__init__.py +0 -0
  476. synkit/Graph/Wildcard/fuse_graph.py +156 -0
  477. synkit/Graph/Wildcard/graph_wc.py +303 -0
  478. synkit/Graph/Wildcard/its_merge.py +857 -0
  479. synkit/Graph/Wildcard/radwc.py +114 -0
  480. synkit/Graph/Wildcard/wc_matcher.py +576 -0
  481. synkit/Graph/Wildcard/wildcard.py +225 -0
  482. synkit/Graph/__init__.py +17 -0
  483. synkit/Graph/canon_graph.py +14 -0
  484. synkit/Graph/syn_graph.py +199 -0
  485. synkit/Graph/utils.py +324 -0
  486. synkit/IO/__init__.py +4 -0
  487. synkit/IO/chem_converter.py +1059 -0
  488. synkit/IO/combinatorial/__init__.py +8 -0
  489. synkit/IO/combinatorial/gml_to_graph.py +223 -0
  490. synkit/IO/combinatorial/graph_to_gml.py +280 -0
  491. synkit/IO/combinatorial/graph_to_smarts.py +186 -0
  492. synkit/IO/combinatorial/smarts_expander.py +147 -0
  493. synkit/IO/combinatorial/smarts_generalizer.py +133 -0
  494. synkit/IO/combinatorial/smarts_to_graph.py +179 -0
  495. synkit/IO/conversion.py +42 -0
  496. synkit/IO/data_io.py +269 -0
  497. synkit/IO/data_process.py +143 -0
  498. synkit/IO/debug.py +73 -0
  499. synkit/IO/gml_to_nx.py +150 -0
  500. synkit/IO/graph_to_mol.py +199 -0
  501. synkit/IO/mol_to_graph.py +1105 -0
  502. synkit/IO/mol_to_graph_chemistry.py +545 -0
  503. synkit/IO/nx_to_gml.py +209 -0
  504. synkit/IO/smiles_to_id.py +123 -0
  505. synkit/Mechanism/__init__.py +151 -0
  506. synkit/Mechanism/adapters.py +136 -0
  507. synkit/Mechanism/audit.py +323 -0
  508. synkit/Mechanism/benchmark.py +638 -0
  509. synkit/Mechanism/compatibility.py +13 -0
  510. synkit/Mechanism/drawing.py +85 -0
  511. synkit/Mechanism/electron_models.py +725 -0
  512. synkit/Mechanism/equivalence.py +521 -0
  513. synkit/Mechanism/evidence.py +262 -0
  514. synkit/Mechanism/interchange.py +141 -0
  515. synkit/Mechanism/model.py +918 -0
  516. synkit/Mechanism/neighbor_stereo.py +312 -0
  517. synkit/Mechanism/radical_data.py +740 -0
  518. synkit/Mechanism/replay.py +986 -0
  519. synkit/Mechanism/schema.py +264 -0
  520. synkit/Mechanism/stereo_state.py +416 -0
  521. synkit/Mechanism/symbols.py +91 -0
  522. synkit/Rule/Apply/__init__.py +35 -0
  523. synkit/Rule/Apply/conditions.py +45 -0
  524. synkit/Rule/Apply/dpo.py +998 -0
  525. synkit/Rule/Apply/rule_matcher.py +218 -0
  526. synkit/Rule/Apply/validation.py +354 -0
  527. synkit/Rule/Compose/__init__.py +106 -0
  528. synkit/Rule/Compose/_identity.py +43 -0
  529. synkit/Rule/Compose/composition.py +976 -0
  530. synkit/Rule/Compose/laws.py +439 -0
  531. synkit/Rule/Compose/search.py +771 -0
  532. synkit/Rule/Compose/synrule.py +170 -0
  533. synkit/Rule/Modify/__init__.py +0 -0
  534. synkit/Rule/Modify/implict_rule.py +56 -0
  535. synkit/Rule/Modify/longest_path.py +92 -0
  536. synkit/Rule/Modify/molecule_rule.py +115 -0
  537. synkit/Rule/Modify/prune_templates.py +78 -0
  538. synkit/Rule/Modify/rule_utils.py +194 -0
  539. synkit/Rule/Modify/strip_rule.py +97 -0
  540. synkit/Rule/__init__.py +28 -0
  541. synkit/Rule/generic_stereo.py +884 -0
  542. synkit/Rule/stereo_identity.py +271 -0
  543. synkit/Rule/syn_rule.py +1090 -0
  544. synkit/Synthesis/MSR/__init__.py +0 -0
  545. synkit/Synthesis/MSR/path_finder.py +239 -0
  546. synkit/Synthesis/Metrics/__init__.py +0 -0
  547. synkit/Synthesis/Metrics/_base.py +52 -0
  548. synkit/Synthesis/Metrics/_plot.py +129 -0
  549. synkit/Synthesis/Metrics/_ranking.py +179 -0
  550. synkit/Synthesis/RBL/__init__.py +80 -0
  551. synkit/Synthesis/RBL/engine.py +1249 -0
  552. synkit/Synthesis/RBL/matching.py +652 -0
  553. synkit/Synthesis/RBL/overlap.py +336 -0
  554. synkit/Synthesis/RBL/pipeline.py +376 -0
  555. synkit/Synthesis/RBL/policy.py +139 -0
  556. synkit/Synthesis/RBL/proof.py +370 -0
  557. synkit/Synthesis/RBL/reaction.py +506 -0
  558. synkit/Synthesis/RBL/state.py +169 -0
  559. synkit/Synthesis/RBL/validation.py +1060 -0
  560. synkit/Synthesis/Reactor/__init__.py +60 -0
  561. synkit/Synthesis/Reactor/core/__init__.py +1 -0
  562. synkit/Synthesis/Reactor/core/engine.py +967 -0
  563. synkit/Synthesis/Reactor/core/product.py +621 -0
  564. synkit/Synthesis/Reactor/core/rewrite.py +561 -0
  565. synkit/Synthesis/Reactor/core/strategy.py +44 -0
  566. synkit/Synthesis/Reactor/matching/__init__.py +1 -0
  567. synkit/Synthesis/Reactor/matching/mixin.py +920 -0
  568. synkit/Synthesis/Reactor/matching/policy.py +345 -0
  569. synkit/Synthesis/Reactor/matching/symmetry.py +309 -0
  570. synkit/Synthesis/Reactor/output/__init__.py +1 -0
  571. synkit/Synthesis/Reactor/output/deduplication.py +703 -0
  572. synkit/Synthesis/Reactor/output/policy.py +16 -0
  573. synkit/Synthesis/Reactor/output/serialization.py +485 -0
  574. synkit/Synthesis/Reactor/output/structural.py +893 -0
  575. synkit/Synthesis/Reactor/stereo/__init__.py +1 -0
  576. synkit/Synthesis/Reactor/stereo/assignment.py +35 -0
  577. synkit/Synthesis/Reactor/stereo/mixin.py +780 -0
  578. synkit/Synthesis/Reactor/variants/__init__.py +1 -0
  579. synkit/Synthesis/Reactor/variants/imbalanced.py +180 -0
  580. synkit/Synthesis/Reactor/variants/partial.py +84 -0
  581. synkit/Synthesis/Reactor/workflow/__init__.py +1 -0
  582. synkit/Synthesis/Reactor/workflow/batch.py +550 -0
  583. synkit/Synthesis/Reactor/workflow/benchmark.py +143 -0
  584. synkit/Synthesis/Reactor/workflow/postprocess.py +267 -0
  585. synkit/Synthesis/Reactor/workflow/rule_filter.py +210 -0
  586. synkit/Synthesis/__init__.py +0 -0
  587. synkit/Synthesis/reactor_utils.py +316 -0
  588. synkit/Utils/__init__.py +0 -0
  589. synkit/Utils/utils.py +172 -0
  590. synkit/Vis/__init__.py +91 -0
  591. synkit/Vis/crn/__init__.py +40 -0
  592. synkit/Vis/epd/__init__.py +20 -0
  593. synkit/Vis/epd/arrows.py +425 -0
  594. synkit/Vis/epd/chem.py +197 -0
  595. synkit/Vis/epd/constants.py +83 -0
  596. synkit/Vis/epd/layout.py +283 -0
  597. synkit/Vis/epd/mapping.py +51 -0
  598. synkit/Vis/epd/models.py +136 -0
  599. synkit/Vis/epd/render.py +543 -0
  600. synkit/Vis/epd/utils.py +108 -0
  601. synkit/Vis/epd/visualizer.py +811 -0
  602. synkit/Vis/graph_visualizer.py +375 -0
  603. synkit/Vis/its/__init__.py +19 -0
  604. synkit/Vis/its/drawer.py +615 -0
  605. synkit/Vis/its_drawer.py +35 -0
  606. synkit/Vis/molecule/__init__.py +31 -0
  607. synkit/Vis/molecule/drawer.py +563 -0
  608. synkit/Vis/molecule/reaction.py +285 -0
  609. synkit/Vis/molecule_drawer.py +33 -0
  610. synkit/Vis/mtg/__init__.py +17 -0
  611. synkit/Vis/mtg/drawer.py +769 -0
  612. synkit/Vis/mtg_drawer.py +34 -0
  613. synkit/Vis/pdf_writer.py +146 -0
  614. synkit/Vis/reaction/__init__.py +19 -0
  615. synkit/Vis/reaction/rule.py +141 -0
  616. synkit/Vis/reaction/rxn.py +532 -0
  617. synkit/Vis/reaction_drawer.py +41 -0
  618. synkit/Vis/space/__init__.py +17 -0
  619. synkit/Vis/space/chemical.py +80 -0
  620. synkit/Vis/space/embedding.py +87 -0
  621. synkit/Vis/vis_synedu/Vis/__init__.py +7 -0
  622. synkit/Vis/vis_synedu/Vis/dpo.py +862 -0
  623. synkit/Vis/vis_synedu/rxn_vis.py +377 -0
  624. synkit/Vis/vis_synedu/vis.py +501 -0
  625. synkit/Vis/visual_drawer.py +215 -0
  626. synkit/Vis/visual_model.py +520 -0
  627. synkit/__init__.py +3 -0
  628. synkit/_native.py +91 -0
  629. synkit/examples.py +50 -0
  630. synkit/version.py +23 -0
  631. synkit-1.6.5.dist-info/METADATA +156 -0
  632. synkit-1.6.5.dist-info/RECORD +636 -0
  633. synkit-1.6.5.dist-info/WHEEL +4 -0
  634. synkit-1.6.5.dist-info/licenses/LICENSE +21 -0
  635. synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
  636. 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,572 @@
1
+ import re
2
+ import networkx as nx
3
+ from typing import Optional, List, Any
4
+
5
+ from rdkit import Chem
6
+ from rdkit.Chem.MolStandardize import rdMolStandardize
7
+
8
+ __all__ = ["get_rc", "its_decompose"]
9
+
10
+
11
+ # def get_rc(
12
+ # ITS: nx.Graph,
13
+ # element_key: List[str] = ["element", "charge", "typesGH", "atom_map"],
14
+ # bond_key: str = "order",
15
+ # standard_key: str = "standard_order",
16
+ # disconnected: bool = False,
17
+ # ) -> nx.Graph:
18
+ # """Extract the reaction-center (RC) subgraph from an ITS graph.
19
+
20
+ # This function identifies:
21
+ # 1. All bonds whose standard order (difference between ITS orders) is non-zero.
22
+ # 2. All H–H bonds, ensuring they are included even if no order change is detected.
23
+ # 3. (Optional) Additional nodes with charge changes and reconnection of edges
24
+ # if `disconnected=True`.
25
+
26
+ # :param ITS: The integrated transition-state graph with composite node/edge attributes.
27
+ # :type ITS: nx.Graph
28
+ # :param element_key: List of node‐attribute keys to copy into the RC graph.
29
+ # :type element_key: List[str]
30
+ # :param bond_key: Edge attribute key representing the tuple of bond orders.
31
+ # :type bond_key: str
32
+ # :param standard_key: Edge attribute key for the computed standard_order.
33
+ # :type standard_key: str
34
+ # :param disconnected: If True, also include nodes with charge changes and
35
+ # reconnect any ITS edges between RC nodes.
36
+ # :type disconnected: bool
37
+ # :returns: A new graph containing only the reaction-center nodes and edges.
38
+ # :rtype: nx.Graph
39
+
40
+ # :example:
41
+ # >>> ITS = nx.Graph()
42
+ # >>> # ... populate ITS with 'order', 'standard_order', 'typesGH', etc. ...
43
+ # >>> RC = get_rc(ITS, disconnected=True)
44
+ # >>> isinstance(RC, nx.Graph)
45
+ # True
46
+ # """
47
+ # rc = nx.Graph()
48
+ # _add_bond_order_changes(ITS, rc, element_key, bond_key, standard_key)
49
+
50
+ # # 1.5) H-H bonds (force inclusion, with fallback typesGH)
51
+ # for u, v, data in ITS.edges(data=True):
52
+ # elem_u = ITS.nodes[u].get("element")
53
+ # elem_v = ITS.nodes[v].get("element")
54
+ # if elem_u == "H" and elem_v == "H":
55
+ # for n in (u, v):
56
+ # node_data = dict(ITS.nodes[n])
57
+ # if "typesGH" not in node_data:
58
+ # node_data["typesGH"] = (
59
+ # ("H", False, 0, 0, []),
60
+ # ("*", False, 0, 0, []),
61
+ # )
62
+ # # Ensure typesGH is available even if not in original element_key
63
+ # final_attrs = {k: node_data[k] for k in element_key if k in node_data}
64
+ # final_attrs["typesGH"] = node_data["typesGH"]
65
+ # rc.add_node(n, **final_attrs)
66
+
67
+ # rc.add_edge(
68
+ # u,
69
+ # v,
70
+ # **{
71
+ # bond_key: data.get(bond_key),
72
+ # standard_key: data.get(standard_key),
73
+ # },
74
+ # )
75
+ # if disconnected:
76
+ # _add_charge_change_nodes(ITS, rc, element_key)
77
+ # _reconnect_rc_edges(ITS, rc, bond_key, standard_key)
78
+
79
+ # return rc
80
+
81
+
82
+ # def get_rc(
83
+ # ITS: nx.Graph,
84
+ # element_key: list[str] = ["element", "charge", "typesGH", "atom_map"],
85
+ # bond_key: str = "order",
86
+ # standard_key: str = "standard_order",
87
+ # disconnected: bool = False,
88
+ # keep_mtg: bool = False,
89
+ # ) -> nx.Graph:
90
+ # """
91
+ # Extract the reaction-center (RC) subgraph from an ITS graph.
92
+
93
+ # This function identifies:
94
+ # 1. All bonds whose standard order is non-zero.
95
+ # 2. (Optional) All bonds labeled with 'is_mtg=True' if keep_mtg is True.
96
+ # 3. All H-H bonds, ensuring they are included even if no order change is detected.
97
+ # 4. (Optional) Additional nodes with charge changes and reconnection of edges
98
+ # if `disconnected=True`.
99
+
100
+ # :param ITS: The integrated transition-state graph with composite node/edge attributes.
101
+ # :type ITS: nx.Graph
102
+ # :param element_key: List of node-attribute keys to copy into the RC graph.
103
+ # :type element_key: List[str]
104
+ # :param bond_key: Edge attribute key representing the tuple of bond orders.
105
+ # :type bond_key: str
106
+ # :param standard_key: Edge attribute key for the computed standard_order.
107
+ # :type standard_key: str
108
+ # :param disconnected: If True, also include nodes with charge changes and
109
+ # reconnect any ITS edges between RC nodes.
110
+ # :type disconnected: bool
111
+ # :param keep_mtg: If True, also include edges where 'is_mtg' attribute is True.
112
+ # :type keep_mtg: bool
113
+ # :returns: A new graph containing only the reaction-center nodes and edges.
114
+ # :rtype: nx.Graph
115
+ # """
116
+ # rc = nx.Graph()
117
+ # # 1) Bonds with standard order change or mechanistic transition
118
+ # for u, v, data in ITS.edges(data=True):
119
+ # std = data.get(standard_key)
120
+ # is_mtg_attr = data.get("is_mtg", False)
121
+ # include = False
122
+ # if isinstance(std, (int, float)) and std != 0:
123
+ # include = True
124
+ # if keep_mtg and is_mtg_attr:
125
+ # include = True
126
+ # if not include:
127
+ # continue
128
+ # # add nodes
129
+ # for n in (u, v):
130
+ # if not rc.has_node(n):
131
+ # node_data = dict(ITS.nodes[n])
132
+ # final_attrs = {k: node_data[k] for k in element_key if k in node_data}
133
+ # rc.add_node(n, **final_attrs)
134
+ # # add edge
135
+ # edge_attrs = {
136
+ # bond_key: data.get(bond_key),
137
+ # standard_key: std,
138
+ # "is_mtg": is_mtg_attr,
139
+ # }
140
+ # rc.add_edge(u, v, **edge_attrs)
141
+
142
+ # # 2) H-H bonds (force inclusion, with fallback typesGH)
143
+ # for u, v, data in ITS.edges(data=True):
144
+ # elem_u = ITS.nodes[u].get("element")
145
+ # elem_v = ITS.nodes[v].get("element")
146
+ # if elem_u == "H" and elem_v == "H":
147
+ # for n in (u, v):
148
+ # if not rc.has_node(n):
149
+ # node_data = dict(ITS.nodes[n])
150
+ # if "typesGH" not in node_data:
151
+ # node_data["typesGH"] = (
152
+ # ("H", False, 0, 0, []),
153
+ # ("*", False, 0, 0, []),
154
+ # )
155
+ # final_attrs = {
156
+ # k: node_data[k] for k in element_key if k in node_data
157
+ # }
158
+ # final_attrs["typesGH"] = node_data["typesGH"]
159
+ # rc.add_node(n, **final_attrs)
160
+ # if not rc.has_edge(u, v):
161
+ # rc.add_edge(
162
+ # u,
163
+ # v,
164
+ # **{
165
+ # bond_key: data.get(bond_key),
166
+ # standard_key: data.get(standard_key),
167
+ # "is_mtg": data.get("is_mtg", False),
168
+ # },
169
+ # )
170
+
171
+ # if disconnected:
172
+ # _add_charge_change_nodes(ITS, rc, element_key)
173
+ # _reconnect_rc_edges(ITS, rc, bond_key, standard_key)
174
+
175
+ # return rc
176
+
177
+ # import networkx as nx
178
+ # from typing import List, Any
179
+
180
+
181
+ def get_rc(
182
+ ITS: nx.Graph,
183
+ element_key: List[str] = ["element", "charge", "typesGH", "atom_map"],
184
+ bond_key: str = "order",
185
+ standard_key: str = "standard_order",
186
+ disconnected: bool = False,
187
+ keep_mtg: bool = False,
188
+ ) -> nx.Graph:
189
+ """
190
+ Extract the reaction-center (RC) subgraph from an ITS graph.
191
+ """
192
+ rc = nx.Graph()
193
+ _add_changed_bonds(ITS, rc, element_key, bond_key, standard_key, keep_mtg)
194
+ _add_hh_bonds(ITS, rc, element_key, bond_key, standard_key)
195
+ if disconnected:
196
+ _add_charge_change_nodes(ITS, rc, element_key)
197
+ _reconnect_rc_edges(ITS, rc, bond_key, standard_key)
198
+ return rc
199
+
200
+
201
+ def _add_changed_bonds(
202
+ ITS: nx.Graph,
203
+ rc: nx.Graph,
204
+ element_key: List[str],
205
+ bond_key: str,
206
+ standard_key: str,
207
+ keep_mtg: bool,
208
+ ) -> None:
209
+ """
210
+ Add bonds with non-zero standard order or mechanistic transitions.
211
+ """
212
+ for u, v, data in ITS.edges(data=True):
213
+ std = data.get(standard_key)
214
+ is_mtg_attr = data.get("is_mtg", False)
215
+ if not _should_include_edge(std, is_mtg_attr, keep_mtg):
216
+ continue
217
+ _ensure_node(rc, ITS, u, element_key)
218
+ _ensure_node(rc, ITS, v, element_key)
219
+ rc.add_edge(
220
+ u,
221
+ v,
222
+ **{bond_key: data.get(bond_key), standard_key: std, "is_mtg": is_mtg_attr},
223
+ )
224
+
225
+
226
+ def _add_hh_bonds(
227
+ ITS: nx.Graph,
228
+ rc: nx.Graph,
229
+ element_key: List[str],
230
+ bond_key: str,
231
+ standard_key: str,
232
+ ) -> None:
233
+ """
234
+ Force inclusion of H-H bonds, with fallback for typesGH.
235
+ """
236
+ for u, v, data in ITS.edges(data=True):
237
+ if _is_hh_pair(ITS, u, v):
238
+ for n in (u, v):
239
+ _ensure_node_hh(rc, ITS, n, element_key)
240
+ if not rc.has_edge(u, v):
241
+ rc.add_edge(
242
+ u,
243
+ v,
244
+ **{
245
+ bond_key: data.get(bond_key),
246
+ standard_key: data.get(standard_key),
247
+ "is_mtg": data.get("is_mtg", False),
248
+ },
249
+ )
250
+
251
+
252
+ def _should_include_edge(
253
+ std: Any,
254
+ is_mtg_attr: bool,
255
+ keep_mtg: bool,
256
+ ) -> bool:
257
+ """
258
+ Determine if an edge should be included based on standard order and mechanistic flag.
259
+ """
260
+ if isinstance(std, (int, float)) and std != 0:
261
+ return True
262
+ if keep_mtg and is_mtg_attr:
263
+ return True
264
+ return False
265
+
266
+
267
+ def _is_hh_pair(ITS: nx.Graph, u: Any, v: Any) -> bool:
268
+ """
269
+ Check if both nodes of an edge are hydrogen.
270
+ """
271
+ return ITS.nodes[u].get("element") == "H" and ITS.nodes[v].get("element") == "H"
272
+
273
+
274
+ def _ensure_node(
275
+ rc: nx.Graph,
276
+ ITS: nx.Graph,
277
+ node: Any,
278
+ element_key: List[str],
279
+ ) -> None:
280
+ """
281
+ Add a node to RC with selected attributes if not already present.
282
+ """
283
+ if not rc.has_node(node):
284
+ node_data = ITS.nodes[node]
285
+ final_attrs = {k: node_data[k] for k in element_key if k in node_data}
286
+ rc.add_node(node, **final_attrs)
287
+
288
+
289
+ def _ensure_node_hh(
290
+ rc: nx.Graph,
291
+ ITS: nx.Graph,
292
+ node: Any,
293
+ element_key: List[str],
294
+ ) -> None:
295
+ """
296
+ Add H node to RC, ensuring typesGH fallback if missing.
297
+ """
298
+ if not rc.has_node(node):
299
+ node_data = dict(ITS.nodes[node])
300
+ if "typesGH" not in node_data:
301
+ node_data["typesGH"] = (("H", False, 0, 0, []), ("*", False, 0, 0, []))
302
+ final_attrs = {k: node_data[k] for k in element_key if k in node_data}
303
+ final_attrs["typesGH"] = node_data["typesGH"]
304
+ rc.add_node(node, **final_attrs)
305
+
306
+
307
+ def _carry_node_attrs(src: nx.Graph, dst: nx.Graph, n: int, keys: List[str]) -> None:
308
+ """Copy node *n* from *src* to *dst* with only *keys* attributes."""
309
+ if dst.has_node(n):
310
+ return
311
+ attrs = {k: src.nodes[n][k] for k in keys if k in src.nodes[n]}
312
+ dst.add_node(n, **attrs)
313
+
314
+
315
+ def _add_charge_change_nodes(
316
+ ITS: nx.Graph,
317
+ rc: nx.Graph,
318
+ keys: List[str],
319
+ ) -> None:
320
+ """Step 3a – add nodes whose *typesGH* shows a charge change."""
321
+ for n, data in ITS.nodes(data=True):
322
+ gh = data.get("typesGH")
323
+ if (
324
+ isinstance(gh, (list, tuple))
325
+ and len(gh) >= 2
326
+ and gh[0][3] != gh[1][3]
327
+ and not rc.has_node(n)
328
+ ):
329
+ _carry_node_attrs(ITS, rc, n, keys)
330
+
331
+
332
+ def _reconnect_rc_edges(
333
+ ITS: nx.Graph,
334
+ rc: nx.Graph,
335
+ bond_key: str,
336
+ standard_key: str,
337
+ ) -> None:
338
+ """Step 3b – re-add any original ITS edge between nodes already in RC."""
339
+ for u, v, data in ITS.edges(data=True):
340
+ if rc.has_node(u) and rc.has_node(v) and not rc.has_edge(u, v):
341
+ rc.add_edge(
342
+ u,
343
+ v,
344
+ **{bond_key: data.get(bond_key), standard_key: data.get(standard_key)},
345
+ )
346
+
347
+
348
+ def _add_bond_order_changes(
349
+ ITS: nx.Graph,
350
+ rc: nx.Graph,
351
+ keys: List[str],
352
+ bond_key: str,
353
+ standard_key: str,
354
+ ) -> None:
355
+ """Step 1 – bond-order-change edges and their nodes."""
356
+ for u, v, data in ITS.edges(data=True):
357
+ old, new = data.get(bond_key, (None, None))
358
+ if old == new:
359
+ continue
360
+ for n in (u, v):
361
+ _carry_node_attrs(ITS, rc, n, keys)
362
+ rc.add_edge(
363
+ u, v, **{bond_key: data[bond_key], standard_key: data.get(standard_key)}
364
+ )
365
+
366
+
367
+ def its_decompose(its_graph: nx.Graph, nodes_share="typesGH", edges_share="order"):
368
+ """Decompose an ITS graph into two separate reactant (G) and product (H)
369
+ graphs.
370
+
371
+ Nodes and edges in `its_graph` carry composite attributes:
372
+ - Each node has `its_graph.nodes[nodes_share] = (node_attrs_G, node_attrs_H)`.
373
+ - Each edge has `its_graph.edges[edges_share] = (order_G, order_H)`.
374
+
375
+ This function splits those tuples to reconstruct the original G and H graphs.
376
+
377
+ :param its_graph: The ITS graph with composite node/edge attributes.
378
+ :type its_graph: nx.Graph
379
+ :param nodes_share: Node attribute key storing (G_attrs, H_attrs) tuples.
380
+ :type nodes_share: str
381
+ :param edges_share: Edge attribute key storing (order_G, order_H) tuples.
382
+ :type edges_share: str
383
+ :return: A tuple of two graphs (G, H) reconstructed from the ITS.
384
+ :rtype: Tuple[nx.Graph, nx.Graph]
385
+
386
+ .. rubric:: Examples
387
+
388
+ >>> its = nx.Graph()
389
+ >>> # ... set its.nodes[n]['typesGH'] and its.edges[e]['order'] ...
390
+ >>> G, H = its_decompose(its)
391
+ >>> isinstance(G, nx.Graph) and isinstance(H, nx.Graph)
392
+ True
393
+ """
394
+ G = nx.Graph()
395
+ H = nx.Graph()
396
+
397
+ # Decompose nodes
398
+ for node, data in its_graph.nodes(data=True):
399
+ if nodes_share in data:
400
+ node_attr_g, node_attr_h = data[nodes_share]
401
+ # Unpack node attributes for G
402
+ G.add_node(
403
+ node,
404
+ element=node_attr_g[0],
405
+ aromatic=node_attr_g[1],
406
+ hcount=node_attr_g[2],
407
+ charge=node_attr_g[3],
408
+ # neighbors=node_attr_g[4],
409
+ atom_map=node,
410
+ )
411
+ if len(node_attr_h) > 0:
412
+ # Unpack node attributes for H
413
+ H.add_node(
414
+ node,
415
+ element=node_attr_h[0],
416
+ aromatic=node_attr_h[1],
417
+ hcount=node_attr_h[2],
418
+ charge=node_attr_h[3],
419
+ # neighbors=node_attr_h[4],
420
+ atom_map=node,
421
+ )
422
+
423
+ # Decompose edges
424
+ for u, v, data in its_graph.edges(data=True):
425
+ if edges_share in data:
426
+ order_g, order_h = data[edges_share]
427
+ if order_g > 0: # Assuming 0 means no edge in G
428
+ G.add_edge(u, v, order=order_g)
429
+ if order_h > 0: # Assuming 0 means no edge in H
430
+ H.add_edge(u, v, order=order_h)
431
+
432
+ return G, H
433
+
434
+
435
+ def compare_graphs(
436
+ graph1: nx.Graph,
437
+ graph2: nx.Graph,
438
+ node_attrs: list = ["element", "aromatic", "hcount", "charge", "neighbors"],
439
+ edge_attrs: list = ["order"],
440
+ ) -> bool:
441
+ """Compare two graphs based on specified node and edge attributes.
442
+
443
+ :param graph1: The first graph to compare.
444
+ :type graph1: nx.Graph
445
+ :param graph2: The second graph to compare.
446
+ :type graph2: nx.Graph
447
+ :param node_attrs: A list of node attribute names to include in the comparison.
448
+ :type node_attrs: list
449
+ :param edge_attrs: A list of edge attribute names to include in the comparison.
450
+ :type edge_attrs: list
451
+
452
+ :return: True if both graphs are identical with respect to the specified attributes, otherwise False.
453
+ :rtype: bool
454
+ """
455
+ # Compare node sets
456
+ if set(graph1.nodes()) != set(graph2.nodes()):
457
+ return False
458
+
459
+ # Compare nodes based on attributes
460
+ for node in graph1.nodes():
461
+ if node not in graph2:
462
+ return False
463
+ node_data1 = {attr: graph1.nodes[node].get(attr, None) for attr in node_attrs}
464
+ node_data2 = {attr: graph2.nodes[node].get(attr, None) for attr in node_attrs}
465
+ if node_data1 != node_data2:
466
+ return False
467
+
468
+ # Compare edge sets with sorted tuples
469
+ if set(tuple(sorted(edge)) for edge in graph1.edges()) != set(
470
+ tuple(sorted(edge)) for edge in graph2.edges()
471
+ ):
472
+ return False
473
+
474
+ # Compare edges based on attributes
475
+ for edge in graph1.edges():
476
+ # Sort the edge for consistent comparison
477
+ sorted_edge = tuple(sorted(edge))
478
+ if sorted_edge not in graph2.edges():
479
+ return False
480
+ edge_data1 = {attr: graph1.edges[edge].get(attr, None) for attr in edge_attrs}
481
+ edge_data2 = {
482
+ attr: graph2.edges[sorted_edge].get(attr, None) for attr in edge_attrs
483
+ }
484
+ if edge_data1 != edge_data2:
485
+ return False
486
+
487
+ return True
488
+
489
+
490
+ def enumerate_tautomers(reaction_smiles: str) -> Optional[List[str]]:
491
+ """Enumerates possible tautomers for reactants while canonicalizing the
492
+ products in a reaction SMILES string. This function first splits the
493
+ reaction SMILES string into reactants and products. It then generates all
494
+ possible tautomers for the reactants and canonicalizes the product
495
+ molecule. The function returns a list of reaction SMILES strings for each
496
+ tautomer of the reactants combined with the canonical product.
497
+
498
+ :param reaction_smiles: A SMILES string of the reaction formatted as
499
+ 'reactants>>products'.
500
+ :type reaction_smiles: str
501
+
502
+ :return: Reaction SMILES for each reactant tautomer combined with the
503
+ canonicalized products, or ``None`` for invalid input.
504
+ :rtype: List[str] | None
505
+
506
+ :raises ValueError: If the SMILES strings cannot be converted to molecules.
507
+ """
508
+ try:
509
+ # Split the input reaction SMILES string into reactants and products
510
+ reactants_smiles, products_smiles = reaction_smiles.split(">>")
511
+
512
+ # Convert SMILES strings to molecule objects
513
+ reactants_mol = Chem.MolFromSmiles(reactants_smiles)
514
+ products_mol = Chem.MolFromSmiles(products_smiles)
515
+
516
+ if reactants_mol is None or products_mol is None:
517
+ raise ValueError(
518
+ "Invalid SMILES string provided for reactants or products."
519
+ )
520
+
521
+ # Initialize tautomer enumerator
522
+
523
+ enumerator = rdMolStandardize.TautomerEnumerator()
524
+
525
+ # Enumerate tautomers for the reactants and canonicalize the products
526
+ try:
527
+ reactants_can = enumerator.Enumerate(reactants_mol)
528
+ except Exception as e:
529
+ print(f"An error occurred: {e}")
530
+ reactants_can = [reactants_mol]
531
+ products_can = products_mol
532
+
533
+ # Convert molecule objects back to SMILES strings
534
+ reactants_can_smiles = [Chem.MolToSmiles(i) for i in reactants_can]
535
+ products_can_smiles = Chem.MolToSmiles(products_can)
536
+
537
+ # Combine each reactant tautomer with the canonical product in SMILES format
538
+ rsmi_list = [i + ">>" + products_can_smiles for i in reactants_can_smiles]
539
+ if len(rsmi_list) == 0:
540
+ return [reaction_smiles]
541
+ else:
542
+ # rsmi_list.remove(reaction_smiles)
543
+ rsmi_list.insert(0, reaction_smiles)
544
+ return rsmi_list
545
+
546
+ except Exception as e:
547
+ print(f"An error occurred: {e}")
548
+ return [reaction_smiles]
549
+
550
+
551
+ def mapping_success_rate(list_mapping_data):
552
+ """Calculate the success rate of entries containing atom mappings in a list
553
+ of data strings.
554
+
555
+ :param list_mapping_data: Strings to search for atom mappings.
556
+ :type list_mapping_data: list[str]
557
+
558
+ :return: The success rate of finding atom mappings in the list as a percentage.
559
+ :rtype: float
560
+
561
+ :raises ValueError: If the input list is empty.
562
+ """
563
+ atom_map_pattern = re.compile(r":\d+")
564
+ if not list_mapping_data:
565
+ raise ValueError("The input list is empty, cannot calculate success rate.")
566
+
567
+ success = sum(
568
+ 1 for entry in list_mapping_data if re.search(atom_map_pattern, entry)
569
+ )
570
+ rate = 100 * (success / len(list_mapping_data))
571
+
572
+ return round(rate, 2)