synkit 0.0.10__tar.gz → 0.0.12__tar.gz

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 (285) hide show
  1. synkit-0.0.12/.github/dependabot.yml +10 -0
  2. synkit-0.0.12/.github/workflows/conda-forge-publish.yml +109 -0
  3. synkit-0.0.12/.github/workflows/docker-publish.yml +46 -0
  4. {synkit-0.0.10 → synkit-0.0.12}/.github/workflows/test-and-lint.yml +1 -1
  5. synkit-0.0.12/.github/workflows/verify-pypi-install.yml +59 -0
  6. {synkit-0.0.10 → synkit-0.0.12}/.gitignore +1 -0
  7. synkit-0.0.12/Dockerfile +45 -0
  8. {synkit-0.0.10 → synkit-0.0.12}/PKG-INFO +29 -8
  9. {synkit-0.0.10 → synkit-0.0.12}/README.md +27 -7
  10. synkit-0.0.12/Test/Chem/Fingerprint/test_fp_calculator.py +69 -0
  11. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Fingerprint/test_transformation_fp.py +4 -4
  12. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_cleanning.py +2 -2
  13. synkit-0.0.10/Test/Chem/Reaction/test_rsmi_utils.py → synkit-0.0.12/Test/Chem/test_utils.py +47 -2
  14. {synkit-0.0.10 → synkit-0.0.12}/doc/api.rst +16 -0
  15. {synkit-0.0.10 → synkit-0.0.12}/doc/conf.py +3 -4
  16. {synkit-0.0.10 → synkit-0.0.12}/doc/getting_started.rst +34 -0
  17. {synkit-0.0.10 → synkit-0.0.12}/pyproject.toml +4 -1
  18. synkit-0.0.12/recipe/meta.yaml +37 -0
  19. synkit-0.0.12/synkit/Chem/Cluster/butina.py +139 -0
  20. synkit-0.0.12/synkit/Chem/Fingerprint/fp_calculator.py +155 -0
  21. synkit-0.0.12/synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
  22. synkit-0.0.12/synkit/Chem/Fingerprint/transformation_fp.py +135 -0
  23. synkit-0.0.12/synkit/Chem/Molecule/standardize.py +167 -0
  24. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/Reaction/__init__.py +6 -1
  25. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/Reaction/aam_validator.py +32 -21
  26. synkit-0.0.12/synkit/Chem/Reaction/balance_check.py +138 -0
  27. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/Reaction/canon_rsmi.py +11 -15
  28. synkit-0.0.12/synkit/Chem/Reaction/cleaning.py +66 -0
  29. synkit-0.0.12/synkit/Chem/Reaction/deionize.py +199 -0
  30. synkit-0.0.12/synkit/Chem/Reaction/fix_aam.py +64 -0
  31. synkit-0.0.12/synkit/Chem/Reaction/neutralize.py +195 -0
  32. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/Reaction/radical_wildcard.py +23 -22
  33. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/Reaction/standardize.py +48 -42
  34. synkit-0.0.12/synkit/Chem/Reaction/tautomerize.py +162 -0
  35. synkit-0.0.12/synkit/Chem/utils.py +276 -0
  36. {synkit-0.0.10 → synkit-0.0.12}/synkit/Data/gen_partial_aam.py +6 -7
  37. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Canon/canon_algs.py +9 -12
  38. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Canon/canon_graph.py +13 -21
  39. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Canon/nauty.py +16 -16
  40. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Context/hier_context.py +22 -20
  41. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Context/radius_expand.py +23 -27
  42. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/graph_descriptors.py +18 -28
  43. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/graph_fps.py +6 -8
  44. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/graph_signature.py +20 -19
  45. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/hash_fps.py +11 -13
  46. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/morgan_fps.py +8 -10
  47. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/path_fps.py +6 -9
  48. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/wl_hash.py +8 -14
  49. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Hyrogen/_misc.py +21 -27
  50. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Hyrogen/hcomplete.py +13 -17
  51. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Hyrogen/hextend.py +7 -10
  52. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/its_builder.py +9 -9
  53. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/its_construction.py +15 -16
  54. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/its_decompose.py +12 -15
  55. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/its_expand.py +12 -10
  56. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/its_relabel.py +16 -21
  57. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/normalize_aam.py +14 -19
  58. synkit-0.0.12/synkit/Graph/ITS/partial_its.py +238 -0
  59. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/MTG/group_comp.py +1 -2
  60. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/MTG/groupoid.py +4 -3
  61. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/MTG/mcs_matcher.py +2 -1
  62. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/MTG/mtg.py +2 -1
  63. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/batch_cluster.py +11 -13
  64. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/graph_cluster.py +10 -11
  65. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/graph_morphism.py +18 -21
  66. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/multi_turbo_iso.py +13 -9
  67. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/sing.py +13 -9
  68. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/subgraph_matcher.py +15 -21
  69. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/turbo_iso.py +3 -1
  70. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Wildcard/fuse_graph.py +5 -7
  71. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/canon_graph.py +13 -21
  72. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/syn_graph.py +10 -21
  73. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/utils.py +6 -10
  74. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/chem_converter.py +81 -58
  75. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/data_io.py +44 -65
  76. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/data_process.py +3 -4
  77. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/debug.py +10 -12
  78. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/dg_to_gml.py +2 -3
  79. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/gml_to_nx.py +19 -20
  80. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/graph_to_mol.py +35 -30
  81. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/mol_to_graph.py +40 -39
  82. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/nx_to_gml.py +36 -34
  83. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/smiles_to_id.py +5 -6
  84. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Apply/reactor_rule.py +10 -11
  85. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Apply/retro_reactor.py +9 -11
  86. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Apply/rule_matcher.py +17 -23
  87. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Apply/rule_rbl.py +3 -3
  88. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Compose/compose_rule.py +16 -18
  89. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Compose/rule_compose.py +12 -16
  90. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Compose/rule_mapping.py +15 -14
  91. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Compose/seq_comp.py +9 -10
  92. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Compose/valence_constrain.py +5 -9
  93. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/implict_rule.py +2 -3
  94. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/longest_path.py +5 -8
  95. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/molecule_rule.py +9 -14
  96. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/prune_templates.py +5 -7
  97. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/rule_utils.py +19 -17
  98. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/Modify/strip_rule.py +10 -7
  99. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/syn_rule.py +4 -4
  100. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/CRN/crn.py +8 -8
  101. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/CRN/dcrn.py +15 -17
  102. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/CRN/mod_crn.py +4 -13
  103. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/MSR/multi_steps.py +7 -9
  104. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/MSR/path_finder.py +21 -19
  105. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Metrics/_base.py +1 -2
  106. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Metrics/_plot.py +5 -6
  107. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Metrics/_ranking.py +20 -21
  108. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/batch_reactor.py +46 -52
  109. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/mod_aam.py +4 -8
  110. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/mod_reactor.py +19 -37
  111. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/partial_engine.py +9 -10
  112. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/rbl_engine.py +20 -21
  113. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/rule_filter.py +25 -31
  114. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/single_predictor.py +9 -15
  115. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/strategy.py +6 -8
  116. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/Reactor/syn_reactor.py +28 -32
  117. {synkit-0.0.10 → synkit-0.0.12}/synkit/Synthesis/reactor_utils.py +18 -21
  118. {synkit-0.0.10 → synkit-0.0.12}/synkit/Utils/utils.py +9 -12
  119. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/embedding.py +9 -16
  120. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/graph_visualizer.py +5 -7
  121. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/pdf_writer.py +8 -10
  122. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/rule_vis.py +8 -14
  123. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/rxn_vis.py +4 -8
  124. synkit-0.0.12/synkit/__init__.py +0 -0
  125. synkit-0.0.10/Makefile +0 -20
  126. synkit-0.0.10/Test/Chem/Fingerprint/test_fp_calculator.py +0 -59
  127. synkit-0.0.10/Test/Chem/Reaction/test_aam_utils.py +0 -52
  128. synkit-0.0.10/make.bat +0 -35
  129. synkit-0.0.10/synkit/Chem/Fingerprint/fp_calculator.py +0 -158
  130. synkit-0.0.10/synkit/Chem/Fingerprint/smiles_featurizer.py +0 -185
  131. synkit-0.0.10/synkit/Chem/Fingerprint/transformation_fp.py +0 -79
  132. synkit-0.0.10/synkit/Chem/Molecule/standardize.py +0 -194
  133. synkit-0.0.10/synkit/Chem/Reaction/aam_utils.py +0 -97
  134. synkit-0.0.10/synkit/Chem/Reaction/balance_check.py +0 -162
  135. synkit-0.0.10/synkit/Chem/Reaction/cleanning.py +0 -67
  136. synkit-0.0.10/synkit/Chem/Reaction/deionize.py +0 -289
  137. synkit-0.0.10/synkit/Chem/Reaction/fix_aam.py +0 -91
  138. synkit-0.0.10/synkit/Chem/Reaction/neutralize.py +0 -256
  139. synkit-0.0.10/synkit/Chem/Reaction/rsmi_utils.py +0 -126
  140. synkit-0.0.10/synkit/Chem/Reaction/tautomerize.py +0 -168
  141. synkit-0.0.10/synkit/Chem/utils.py +0 -187
  142. synkit-0.0.10/synkit/Synthesis/Reactor/core_engine.py +0 -212
  143. {synkit-0.0.10 → synkit-0.0.12}/.github/workflows/build-doc.yml +0 -0
  144. {synkit-0.0.10 → synkit-0.0.12}/.github/workflows/publish-package.yml +0 -0
  145. {synkit-0.0.10 → synkit-0.0.12}/.readthedocs.yml +0 -0
  146. {synkit-0.0.10 → synkit-0.0.12}/Data/Figure/synkit.png +0 -0
  147. {synkit-0.0.10 → synkit-0.0.12}/Data/Testcase/Compose/ComposeRule/data.txt +0 -0
  148. {synkit-0.0.10 → synkit-0.0.12}/Data/Testcase/Compose/SingleRule/R0/0.gml +0 -0
  149. {synkit-0.0.10 → synkit-0.0.12}/Data/Testcase/Compose/SingleRule/R0/1.gml +0 -0
  150. {synkit-0.0.10 → synkit-0.0.12}/Data/Testcase/Compose/SingleRule/R0/2.gml +0 -0
  151. {synkit-0.0.10 → synkit-0.0.12}/LICENSE +0 -0
  152. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Fingerprint/__init__.py +0 -0
  153. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Fingerprint/test_smiles_featurizer.py +0 -0
  154. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Molecule/__init__.py +0 -0
  155. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Molecule/test_standardize.py +0 -0
  156. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/__init__.py +0 -0
  157. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_aam_validator.py +0 -0
  158. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_balance_checker.py +0 -0
  159. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_canon_rsmi.py +0 -0
  160. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_deionize.py +0 -0
  161. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_fix_aam.py +0 -0
  162. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_neutralize.py +0 -0
  163. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_radical_wildcard.py +0 -0
  164. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_standardize.py +0 -0
  165. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/Reaction/test_tautomerize.py +0 -0
  166. {synkit-0.0.10 → synkit-0.0.12}/Test/Chem/__init__.py +0 -0
  167. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Context/__init__.py +0 -0
  168. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Context/test_hier_context.py +0 -0
  169. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Context/test_radius_expand.py +0 -0
  170. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/__init__.py +0 -0
  171. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_graph_descriptors.py +0 -0
  172. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_graph_fps.py +0 -0
  173. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_graph_signature.py +0 -0
  174. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_hash_fps.py +0 -0
  175. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_morgan_fps.py +0 -0
  176. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Feature/test_path_fps.py +0 -0
  177. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Hydrogen/__init__.py +0 -0
  178. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Hydrogen/test_graph_hydrogen.py +0 -0
  179. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Hydrogen/test_hcomplete.py +0 -0
  180. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Hydrogen/test_misc.py +0 -0
  181. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/ITS/__init__.py +0 -0
  182. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/ITS/test_its_construction.py +0 -0
  183. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/ITS/test_its_expand.py +0 -0
  184. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/ITS/test_its_relabel.py +0 -0
  185. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/ITS/test_normalize_aam.py +0 -0
  186. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/MTG/__init__.py +0 -0
  187. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/MTG/test_group_comp.py +0 -0
  188. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/MTG/test_groupoid.py +0 -0
  189. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/MTG/test_mtg.py +0 -0
  190. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/__init__.py +0 -0
  191. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/test_batch_cluster.py +0 -0
  192. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/test_graph_cluster.py +0 -0
  193. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/test_graph_matcher.py +0 -0
  194. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/test_graph_morphism.py +0 -0
  195. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/Matcher/test_subgraph_matcher.py +0 -0
  196. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/__init__.py +0 -0
  197. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/test_canon_graph.py +0 -0
  198. {synkit-0.0.10 → synkit-0.0.12}/Test/Graph/test_syn_graph.py +0 -0
  199. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/__init__.py +0 -0
  200. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_chemical_converter.py +0 -0
  201. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_dg_to_gml.py +0 -0
  202. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_gml_to_nx.py +0 -0
  203. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_graph_to_mol.py +0 -0
  204. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_mol_to_graph.py +0 -0
  205. {synkit-0.0.10 → synkit-0.0.12}/Test/IO/test_nx_to_gml.py +0 -0
  206. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Apply/__init__.py +0 -0
  207. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Apply/test_reactor_rule.py +0 -0
  208. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Apply/test_retro_reactor.py +0 -0
  209. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Apply/test_rule_matcher.py +0 -0
  210. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Apply/test_rule_rbl.py +0 -0
  211. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Compose/__init__.py +0 -0
  212. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Compose/test_rule_compose.py +0 -0
  213. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Compose/test_valance_constrain.py +0 -0
  214. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Modify/__init__.py +0 -0
  215. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Modify/test_molecule_rule.py +0 -0
  216. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/Modify/test_rule_utils.py +0 -0
  217. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/__init__.py +0 -0
  218. {synkit-0.0.10 → synkit-0.0.12}/Test/Rule/test_syn_rule.py +0 -0
  219. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/CRN/__init__.py +0 -0
  220. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/CRN/test_crn.py +0 -0
  221. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/CRN/test_mod_crn.py +0 -0
  222. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/MSR/__init__.py +0 -0
  223. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/MSR/test_multi_steps.py +0 -0
  224. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/MSR/test_path_finder.py +0 -0
  225. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/__init__.py +0 -0
  226. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_core_engine.py +0 -0
  227. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_mod_aam.py +0 -0
  228. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_mod_reactor.py +0 -0
  229. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_partial_engine.py +0 -0
  230. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_rbl_reactor.py +0 -0
  231. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/Reactor/test_strategy.py +0 -0
  232. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/__init__.py +0 -0
  233. {synkit-0.0.10 → synkit-0.0.12}/Test/Synthesis/test_reactor_utils.py +0 -0
  234. {synkit-0.0.10 → synkit-0.0.12}/Test/Vis/__init__.py +0 -0
  235. {synkit-0.0.10 → synkit-0.0.12}/Test/Vis/test_embedding.py +0 -0
  236. {synkit-0.0.10 → synkit-0.0.12}/Test/__init__.py +0 -0
  237. {synkit-0.0.10 → synkit-0.0.12}/build-doc.sh +0 -0
  238. {synkit-0.0.10 → synkit-0.0.12}/doc/changelog.rst +0 -0
  239. {synkit-0.0.10 → synkit-0.0.12}/doc/chem.rst +0 -0
  240. {synkit-0.0.10 → synkit-0.0.12}/doc/figures/aldol.png +0 -0
  241. {synkit-0.0.10 → synkit-0.0.12}/doc/figures/aldol_its.png +0 -0
  242. {synkit-0.0.10 → synkit-0.0.12}/doc/figures/context.png +0 -0
  243. {synkit-0.0.10 → synkit-0.0.12}/doc/figures/mtg.png +0 -0
  244. {synkit-0.0.10 → synkit-0.0.12}/doc/graph.rst +0 -0
  245. {synkit-0.0.10 → synkit-0.0.12}/doc/index.rst +0 -0
  246. {synkit-0.0.10 → synkit-0.0.12}/doc/io.rst +0 -0
  247. {synkit-0.0.10 → synkit-0.0.12}/doc/reference.rst +0 -0
  248. {synkit-0.0.10 → synkit-0.0.12}/doc/refs.bib +0 -0
  249. {synkit-0.0.10 → synkit-0.0.12}/doc/requirements.txt +0 -0
  250. {synkit-0.0.10 → synkit-0.0.12}/doc/rule.rst +0 -0
  251. {synkit-0.0.10 → synkit-0.0.12}/doc/synthesis.rst +0 -0
  252. {synkit-0.0.10 → synkit-0.0.12}/environment.yml +0 -0
  253. {synkit-0.0.10 → synkit-0.0.12}/lint.sh +0 -0
  254. {synkit-0.0.10 → synkit-0.0.12}/pytest.sh +0 -0
  255. {synkit-0.0.10 → synkit-0.0.12}/requirements.txt +0 -0
  256. {synkit-0.0.10/synkit/Chem/Fingerprint → synkit-0.0.12/synkit/Chem/Cluster}/__init__.py +0 -0
  257. {synkit-0.0.10/synkit/Chem/Molecule → synkit-0.0.12/synkit/Chem/Fingerprint}/__init__.py +0 -0
  258. {synkit-0.0.10/synkit/Data → synkit-0.0.12/synkit/Chem/Molecule}/__init__.py +0 -0
  259. {synkit-0.0.10 → synkit-0.0.12}/synkit/Chem/__init__.py +0 -0
  260. {synkit-0.0.10/synkit/Graph/Context → synkit-0.0.12/synkit/Data}/__init__.py +0 -0
  261. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Canon/__init__.py +0 -0
  262. {synkit-0.0.10/synkit/Graph/Hyrogen → synkit-0.0.12/synkit/Graph/Context}/__init__.py +0 -0
  263. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Feature/__init__.py +0 -0
  264. {synkit-0.0.10/synkit/Graph/MTG → synkit-0.0.12/synkit/Graph/Hyrogen}/__init__.py +0 -0
  265. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/ITS/__init__.py +0 -0
  266. {synkit-0.0.10/synkit/Graph/Wildcard → synkit-0.0.12/synkit/Graph/MTG}/__init__.py +0 -0
  267. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/__init__.py +0 -0
  268. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/graph_matcher.py +0 -0
  269. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/mcs_matcher.py +0 -0
  270. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/Matcher/partial_matcher.py +0 -0
  271. {synkit-0.0.10/synkit/Rule/Apply → synkit-0.0.12/synkit/Graph/Wildcard}/__init__.py +0 -0
  272. {synkit-0.0.10 → synkit-0.0.12}/synkit/Graph/__init__.py +0 -0
  273. {synkit-0.0.10 → synkit-0.0.12}/synkit/IO/__init__.py +0 -0
  274. {synkit-0.0.10/synkit/Rule/Compose → synkit-0.0.12/synkit/Rule/Apply}/__init__.py +0 -0
  275. {synkit-0.0.10/synkit/Rule/Modify → synkit-0.0.12/synkit/Rule/Compose}/__init__.py +0 -0
  276. {synkit-0.0.10/synkit/Synthesis/CRN → synkit-0.0.12/synkit/Rule/Modify}/__init__.py +0 -0
  277. {synkit-0.0.10 → synkit-0.0.12}/synkit/Rule/__init__.py +0 -0
  278. {synkit-0.0.10/synkit/Synthesis/MSR → synkit-0.0.12/synkit/Synthesis/CRN}/__init__.py +0 -0
  279. {synkit-0.0.10/synkit/Synthesis/Metrics → synkit-0.0.12/synkit/Synthesis/MSR}/__init__.py +0 -0
  280. {synkit-0.0.10/synkit/Synthesis/Reactor → synkit-0.0.12/synkit/Synthesis/Metrics}/__init__.py +0 -0
  281. {synkit-0.0.10/synkit/Synthesis → synkit-0.0.12/synkit/Synthesis/Reactor}/__init__.py +0 -0
  282. {synkit-0.0.10/synkit/Utils → synkit-0.0.12/synkit/Synthesis}/__init__.py +0 -0
  283. {synkit-0.0.10/synkit → synkit-0.0.12/synkit/Utils}/__init__.py +0 -0
  284. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/__init__.py +0 -0
  285. {synkit-0.0.10 → synkit-0.0.12}/synkit/Vis/chemical_space.py +0 -0
@@ -0,0 +1,10 @@
1
+ # .github/dependabot.yml
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "pip"
5
+ directory: "/" # location of requirements.txt or pyproject.toml
6
+ target-branch: "staging" # open PRs against staging instead of main
7
+ schedule:
8
+ interval: "weekly" # check for updates once a week
9
+ open-pull-requests-limit: 5 # max concurrent Dependabot PRs
10
+ rebase-strategy: "auto" # auto-rebase PRs when they fall out of date
@@ -0,0 +1,109 @@
1
+ name: Publish to conda-forge
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ branches: [refactor]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ outputs:
16
+ pkg_paths: ${{ steps.build.outputs.paths }}
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v3
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Setup Miniconda
24
+ uses: conda-incubator/setup-miniconda@v2
25
+ with:
26
+ channels: conda-forge
27
+ auto-update-conda: true
28
+ auto-activate-base: true
29
+
30
+ - name: Create & activate build env
31
+ shell: bash -l {0}
32
+ run: |
33
+ conda create -n build python=3.11 'conda-build>=3.21' -c conda-forge -y
34
+ conda activate build
35
+
36
+ - id: build
37
+ name: Build conda package
38
+ shell: bash -l {0}
39
+ env:
40
+ GITHUB_RUN_NUMBER: ${{ github.run_number }}
41
+ run: |
42
+ conda activate build
43
+ rm -rf conda-bld && mkdir conda-bld
44
+
45
+ conda-build recipe --output-folder ./conda-bld
46
+
47
+ echo "DEBUG: Built files:"
48
+ find conda-bld -type f \( -name "*.conda" -o -name "*.tar.bz2" \) -print
49
+
50
+ files=$(find conda-bld -type f \( -name "*.conda" -o -name "*.tar.bz2" \) -print | tr '\n' ' ')
51
+ echo "paths=$files" >> $GITHUB_OUTPUT
52
+
53
+ - name: Upload built packages as artifact
54
+ uses: actions/upload-artifact@v4
55
+ with:
56
+ name: conda-packages
57
+ path: conda-bld/
58
+
59
+ publish_release:
60
+ needs: build
61
+ if: github.event_name == 'release'
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - name: Download built packages
65
+ uses: actions/download-artifact@v4
66
+ with:
67
+ name: conda-packages
68
+ path: conda-bld
69
+
70
+ - name: Install Anaconda Client
71
+ run: python3 -m pip install --upgrade anaconda-client
72
+
73
+ - name: Upload to conda-forge / main
74
+ env:
75
+ ANACONDA_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
76
+ run: |
77
+ for pkg in ${{ needs.build.outputs.pkg_paths }}; do
78
+ anaconda -t "$ANACONDA_TOKEN" upload \
79
+ --user tieulongphan \
80
+ --label main \
81
+ --no-progress \
82
+ "$pkg"
83
+ done
84
+
85
+ publish_beta:
86
+ needs: build
87
+ if: github.event_name == 'push' && github.ref == 'refs/heads/refactor'
88
+ runs-on: ubuntu-latest
89
+ steps:
90
+ - name: Download built packages
91
+ uses: actions/download-artifact@v4
92
+ with:
93
+ name: conda-packages
94
+ path: conda-bld
95
+
96
+ - name: Install Anaconda Client
97
+ run: python3 -m pip install --upgrade anaconda-client
98
+
99
+ - name: Upload to conda-forge / beta
100
+ env:
101
+ ANACONDA_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
102
+ run: |
103
+ for pkg in ${{ needs.build.outputs.pkg_paths }}; do
104
+ anaconda -t "$ANACONDA_TOKEN" upload \
105
+ --user tieulongphan \
106
+ --label beta \
107
+ --no-progress \
108
+ "$pkg"
109
+ done
@@ -0,0 +1,46 @@
1
+ # .github/workflows/docker-publish.yml
2
+ name: Publish SynKit Docker Package
3
+
4
+ on:
5
+ push:
6
+ # Fire on semver tags for real releases…
7
+ tags:
8
+ - 'v*.*.*'
9
+ # …and on any push to the refractor branch for testing
10
+ branches:
11
+ - 'staging'
12
+
13
+ jobs:
14
+ build-and-push:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ packages: write
19
+ id-token: write
20
+
21
+ steps:
22
+ - name: Check out repository
23
+ uses: actions/checkout@v3
24
+
25
+ - name: Set up QEMU (optional, for multi‑arch)
26
+ uses: docker/setup-qemu-action@v3
27
+
28
+ - name: Set up Docker Buildx
29
+ uses: docker/setup-buildx-action@v2
30
+
31
+ - name: Log in to Docker Hub
32
+ uses: docker/login-action@v2
33
+ with:
34
+ username: ${{ secrets.DOCKERHUB_USER }}
35
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
36
+
37
+ - name: Build and push Docker image
38
+ uses: docker/build-push-action@v4
39
+ with:
40
+ context: .
41
+ file: Dockerfile
42
+ platforms: linux/amd64,linux/arm64
43
+ push: true
44
+ tags: |
45
+ tieulongphan/synkit:${{ github.ref_name }}
46
+ tieulongphan/synkit:latest
@@ -2,7 +2,7 @@ name: Test & Lint
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ "main", "dev", "maintain", "refractor" ]
5
+ branches: [ "main", "dev", "staging", "refractor" ]
6
6
  pull_request:
7
7
  branches: [ "main" ]
8
8
 
@@ -0,0 +1,59 @@
1
+ # .github/workflows/verify-synkit-pypi-install.yml
2
+ name: Verify SynKit PyPI install
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ branches:
8
+ type: string
9
+ required: true
10
+ default: refractor
11
+
12
+ # Scheduled test every Monday at 03:00 UTC
13
+ schedule:
14
+ - cron: '0 3 * * 1'
15
+
16
+ jobs:
17
+ verify:
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - name: Setup Python
22
+ uses: actions/setup-python@v4
23
+ with:
24
+ python-version: '3.x'
25
+
26
+ - name: Create & activate virtualenv, upgrade pip, install SynKit
27
+ run: |
28
+ python -m venv venv
29
+ source venv/bin/activate
30
+ python -m pip install --upgrade pip
31
+ pip install synkit[all]
32
+
33
+ - name: Show installed SynKit version
34
+ run: |
35
+ source venv/bin/activate
36
+ python -c "import importlib.metadata as m; print('SynKit version:', m.version('synkit'))"
37
+
38
+ - name: Write smoke-test script
39
+ run: |
40
+ cat << 'EOF' > test_synkit.py
41
+ from synkit.IO import rsmi_to_rsmarts
42
+
43
+ template = (
44
+ '[C:2]=[O:3].[C:4]([H:7])[H:8]'
45
+ '>>'
46
+ '[C:2]=[C:4].[O:3]([H:7])[H:8]'
47
+ )
48
+
49
+ smart = rsmi_to_rsmarts(template)
50
+ print("Reaction SMARTS:", smart)
51
+ EOF
52
+
53
+ - name: Run smoke-test
54
+ run: |
55
+ source venv/bin/activate
56
+ python test_synkit.py
57
+
58
+ - name: Success message
59
+ run: echo "✅ synkit[all] installed and smoke-test passed"
@@ -21,3 +21,4 @@ Data/Benchmark/*
21
21
  run.sh
22
22
  docs/*
23
23
  run_rdcanon.py
24
+ Data/Fragment/*
@@ -0,0 +1,45 @@
1
+ ############################################
2
+ # STAGE 1: Build your package wheel
3
+ ############################################
4
+ FROM python:3.11-slim AS builder
5
+
6
+ # 1. Install system build tools (for any C extensions)
7
+ RUN apt-get update \
8
+ && apt-get install -y --no-install-recommends build-essential \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # 2. Upgrade pip/setuptools/wheel and install PEP 517 tooling + Hatchling backend
12
+ RUN pip install --upgrade pip setuptools wheel \
13
+ && pip install --no-cache-dir build hatchling
14
+
15
+ # 3. Set working directory inside builder
16
+ WORKDIR /build
17
+
18
+ # 4. Copy project metadata (including README so Hatchling can find it)
19
+ COPY pyproject.toml README.md ./
20
+ # If you have a lockfile, uncomment:
21
+ # COPY poetry.lock ./
22
+
23
+ # 5. Copy your library source
24
+ COPY synkit/ ./synkit
25
+
26
+ # 6. Build the wheel
27
+ RUN python -m build --wheel --no-isolation
28
+
29
+ ############################################
30
+ # STAGE 2: Create the “release” image
31
+ ############################################
32
+ FROM python:3.11-slim
33
+
34
+ # 7. Set a clean workdir
35
+ WORKDIR /opt/synkit
36
+
37
+ # 8. Copy in the built wheel from the builder stage
38
+ COPY --from=builder /build/dist/*.whl ./
39
+
40
+ # 9. Install your package (and its dependencies), then remove the wheel
41
+ RUN pip install --no-cache-dir *.whl \
42
+ && rm *.whl
43
+
44
+ # 10. Sanity check: print the installed synkit version
45
+ CMD ["python", "-c", "import importlib.metadata as m; print(m.version('synkit'))"]
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synkit
3
- Version: 0.0.10
3
+ Version: 0.0.12
4
4
  Summary: Utility for reaction modeling using graph grammar
5
5
  Project-URL: homepage, https://github.com/TieuLongPhan/SynKit
6
6
  Project-URL: source, https://github.com/TieuLongPhan/SynKit
7
7
  Project-URL: issues, https://github.com/TieuLongPhan/SynKit/issues
8
8
  Project-URL: documentation, https://tieulongphan.github.io/SynKit/
9
9
  Author-email: Tieu Long Phan <tieu@bioinf.uni-leipzig.de>
10
+ License: MIT
10
11
  License-File: LICENSE
11
12
  Classifier: License :: OSI Approved :: MIT License
12
13
  Classifier: Operating System :: OS Independent
@@ -40,7 +41,14 @@ Our tools are tailored to assist researchers and chemists in navigating complex
40
41
 
41
42
  For more details on each utility within the repository, please refer to the documentation provided in the respective folders.
42
43
 
43
- ## Step-by-Step Installation Guide
44
+ ## Table of Contents
45
+ - [Installation](#installation)
46
+ - [Contribute to `SynKit`](#contribute)
47
+ - [Contributing](#contributing)
48
+ - [License](#license)
49
+ - [Acknowledgments](#acknowledgments)
50
+
51
+ ## Installation
44
52
 
45
53
  1. **Python Installation:**
46
54
  Ensure that Python 3.11 or later is installed on your system. You can download it from [python.org](https://www.python.org/downloads/).
@@ -71,7 +79,20 @@ For more details on each utility within the repository, please refer to the docu
71
79
  pip install synkit[all]
72
80
  ```
73
81
 
74
- ## For contributors
82
+ 4. **Install via Docker**
83
+ Pull the image:
84
+
85
+ ```bash
86
+ docker pull tieulongphan/synkit:latest
87
+ # or a specific version:
88
+ docker pull tieulongphan/synkit:0.1.0
89
+ ```
90
+ Run a container (sanity check):
91
+ ```
92
+ docker run --rm tieulongphan/synkit:latest
93
+ ```
94
+
95
+ ## Contribute
75
96
 
76
97
  We're welcoming new contributors to build this project better. Please not hesitate to inquire me via [email][tieu@bioinf.uni-leipzig.de].
77
98
 
@@ -82,7 +103,7 @@ git checkout main
82
103
  git pull
83
104
  ```
84
105
 
85
- ## Working on New Features
106
+ ### Working on New Features
86
107
 
87
108
  1. **Create a New Branch**:
88
109
  For every new feature or bug fix, create a new branch from the `main` branch. Name your branch meaningfully, related to the feature or fix you are working on.
@@ -108,7 +129,7 @@ git pull
108
129
 
109
130
  Fix any issues or errors highlighted by these checks.
110
131
 
111
- ## Integrating Changes
132
+ ### Integrating Changes
112
133
 
113
134
  1. **Rebase onto Staging**:
114
135
  Once your feature is complete and tests pass, rebase your changes onto the `staging` branch to prepare for integration.
@@ -128,16 +149,16 @@ git pull
128
149
  ```
129
150
 
130
151
  3. **Create a Pull Request**:
131
- Open a pull request from your feature branch to the `stagging` branch. Ensure the pull request description clearly describes the changes and any additional context necessary for review.
152
+ Open a pull request from your feature branch to the `staging` branch. Ensure the pull request description clearly describes the changes and any additional context necessary for review.
132
153
 
133
154
  ## Contributing
134
155
  - [Tieu-Long Phan](https://tieulongphan.github.io/)
135
156
  - [Klaus Weinbauer](https://github.com/klausweinbauer)
136
157
  - [Phuoc-Chung Nguyen Van](https://github.com/phuocchung123)
137
158
 
138
- ## Deployment timeline
159
+ ## Publication
139
160
 
140
- We plan to update new version quarterly.
161
+ [**SynKit**: An Advanced Cheminformatics Python Library for Efficient Manipulation and Analysis of Chemical Reaction Data]()
141
162
 
142
163
 
143
164
  ## License
@@ -10,7 +10,14 @@ Our tools are tailored to assist researchers and chemists in navigating complex
10
10
 
11
11
  For more details on each utility within the repository, please refer to the documentation provided in the respective folders.
12
12
 
13
- ## Step-by-Step Installation Guide
13
+ ## Table of Contents
14
+ - [Installation](#installation)
15
+ - [Contribute to `SynKit`](#contribute)
16
+ - [Contributing](#contributing)
17
+ - [License](#license)
18
+ - [Acknowledgments](#acknowledgments)
19
+
20
+ ## Installation
14
21
 
15
22
  1. **Python Installation:**
16
23
  Ensure that Python 3.11 or later is installed on your system. You can download it from [python.org](https://www.python.org/downloads/).
@@ -41,7 +48,20 @@ For more details on each utility within the repository, please refer to the docu
41
48
  pip install synkit[all]
42
49
  ```
43
50
 
44
- ## For contributors
51
+ 4. **Install via Docker**
52
+ Pull the image:
53
+
54
+ ```bash
55
+ docker pull tieulongphan/synkit:latest
56
+ # or a specific version:
57
+ docker pull tieulongphan/synkit:0.1.0
58
+ ```
59
+ Run a container (sanity check):
60
+ ```
61
+ docker run --rm tieulongphan/synkit:latest
62
+ ```
63
+
64
+ ## Contribute
45
65
 
46
66
  We're welcoming new contributors to build this project better. Please not hesitate to inquire me via [email][tieu@bioinf.uni-leipzig.de].
47
67
 
@@ -52,7 +72,7 @@ git checkout main
52
72
  git pull
53
73
  ```
54
74
 
55
- ## Working on New Features
75
+ ### Working on New Features
56
76
 
57
77
  1. **Create a New Branch**:
58
78
  For every new feature or bug fix, create a new branch from the `main` branch. Name your branch meaningfully, related to the feature or fix you are working on.
@@ -78,7 +98,7 @@ git pull
78
98
 
79
99
  Fix any issues or errors highlighted by these checks.
80
100
 
81
- ## Integrating Changes
101
+ ### Integrating Changes
82
102
 
83
103
  1. **Rebase onto Staging**:
84
104
  Once your feature is complete and tests pass, rebase your changes onto the `staging` branch to prepare for integration.
@@ -98,16 +118,16 @@ git pull
98
118
  ```
99
119
 
100
120
  3. **Create a Pull Request**:
101
- Open a pull request from your feature branch to the `stagging` branch. Ensure the pull request description clearly describes the changes and any additional context necessary for review.
121
+ Open a pull request from your feature branch to the `staging` branch. Ensure the pull request description clearly describes the changes and any additional context necessary for review.
102
122
 
103
123
  ## Contributing
104
124
  - [Tieu-Long Phan](https://tieulongphan.github.io/)
105
125
  - [Klaus Weinbauer](https://github.com/klausweinbauer)
106
126
  - [Phuoc-Chung Nguyen Van](https://github.com/phuocchung123)
107
127
 
108
- ## Deployment timeline
128
+ ## Publication
109
129
 
110
- We plan to update new version quarterly.
130
+ [**SynKit**: An Advanced Cheminformatics Python Library for Efficient Manipulation and Analysis of Chemical Reaction Data]()
111
131
 
112
132
 
113
133
  ## License
@@ -0,0 +1,69 @@
1
+ import io
2
+ import unittest
3
+ from contextlib import redirect_stdout
4
+
5
+ from synkit.Chem.Fingerprint.fp_calculator import FPCalculator
6
+
7
+
8
+ class TestFPCalculator(unittest.TestCase):
9
+ def setUp(self):
10
+ # Sample single reaction dict
11
+ self.single = {"rsmi": "CCO>>CC=O"}
12
+ # List of dicts for parallel
13
+ self.batch = [
14
+ {"rsmi": "CCO>>CC=O"},
15
+ {"rsmi": "CC(Cl)C>>CCCl"},
16
+ ]
17
+ self.rsmi_key = "rsmi"
18
+ self.fp_type = "ecfp4"
19
+ self.calc = FPCalculator(n_jobs=2, verbose=0)
20
+
21
+ def test_constructor_assigns_attributes(self):
22
+ self.assertEqual(self.calc.n_jobs, 2)
23
+ self.assertEqual(self.calc.verbose, 0)
24
+
25
+ def test_validate_fp_type_accepts_supported(self):
26
+ # Should not raise
27
+ for ft in FPCalculator.VALID_FP_TYPES:
28
+ self.calc._validate_fp_type(ft)
29
+
30
+ def test_validate_fp_type_rejects_unsupported(self):
31
+ with self.assertRaises(ValueError):
32
+ self.calc._validate_fp_type("invalid_fp")
33
+
34
+ def test_dict_process_missing_key_raises(self):
35
+ with self.assertRaises(ValueError):
36
+ FPCalculator.dict_process({}, self.rsmi_key, fp_type=self.fp_type)
37
+
38
+ def test_dict_process_adds_fingerprint(self):
39
+ data = {"rsmi": "CCO>>CC=O"}
40
+ out = FPCalculator.dict_process(data, "rsmi", fp_type="ecfp4")
41
+ self.assertIn("ecfp4", out)
42
+ # Check it's a list/vector (not None)
43
+ self.assertIsNotNone(out["ecfp4"])
44
+
45
+ def test_parallel_process_returns_list_of_dicts(self):
46
+ results = self.calc.parallel_process(self.batch, "rsmi", fp_type="ecfp4")
47
+ self.assertIsInstance(results, list)
48
+ self.assertEqual(len(results), 2)
49
+ for d in results:
50
+ self.assertIn("ecfp4", d)
51
+
52
+ def test_str_and_help_output(self):
53
+ s = str(self.calc)
54
+ self.assertIn("FPCalculator", s)
55
+ buf = io.StringIO()
56
+ with redirect_stdout(buf):
57
+ self.calc.help()
58
+ help_out = buf.getvalue()
59
+
60
+ # The help text starts with this exact line
61
+ self.assertIn(
62
+ "FPCalculator supports the following fingerprint types:", help_out
63
+ )
64
+ # And lists our parallel jobs config
65
+ self.assertIn(f"Configured for {self.calc.n_jobs} parallel jobs", help_out)
66
+
67
+
68
+ if __name__ == "__main__":
69
+ unittest.main()
@@ -22,13 +22,13 @@ class TestTransformationFP(unittest.TestCase):
22
22
  abs_val = True
23
23
 
24
24
  # Test with return_array=True
25
- reaction_fp_array = TransformationFP.fit(
25
+ reaction_fp_array = TransformationFP().fit(
26
26
  reaction_smiles, symbols, fp_type, abs_val
27
27
  )
28
28
  self.assertIsInstance(reaction_fp_array, np.ndarray)
29
29
 
30
30
  # Test with return_array=False
31
- reaction_fp_bitvect = TransformationFP.fit(
31
+ reaction_fp_bitvect = TransformationFP().fit(
32
32
  reaction_smiles, symbols, fp_type, abs_val, return_array=False
33
33
  )
34
34
  self.assertIsInstance(reaction_fp_bitvect, cDataStructs.ExplicitBitVect)
@@ -40,7 +40,7 @@ class TestTransformationFP(unittest.TestCase):
40
40
  fp_type = "maccs"
41
41
  abs_val = True
42
42
  with self.assertRaises(Exception):
43
- _ = TransformationFP.fit(reaction_smiles, symbols, fp_type, abs_val)
43
+ _ = TransformationFP().fit(reaction_smiles, symbols, fp_type, abs_val)
44
44
 
45
45
  def test_fit_reaction_split(self):
46
46
  """Test handling of SMILES split by symbols and impact on results"""
@@ -48,7 +48,7 @@ class TestTransformationFP(unittest.TestCase):
48
48
  symbols = ">>"
49
49
  fp_type = "maccs"
50
50
  abs_val = False # without taking absolute values
51
- reaction_fp = TransformationFP.fit(reaction_smiles, symbols, fp_type, abs_val)
51
+ reaction_fp = TransformationFP().fit(reaction_smiles, symbols, fp_type, abs_val)
52
52
  self.assertIsInstance(reaction_fp, np.ndarray)
53
53
 
54
54
 
@@ -1,11 +1,11 @@
1
1
  import unittest
2
- from synkit.Chem.Reaction.cleanning import Cleanning
2
+ from synkit.Chem.Reaction.cleaning import Cleaning
3
3
 
4
4
 
5
5
  class TestCleaning(unittest.TestCase):
6
6
 
7
7
  def setUp(self):
8
- self.cleaner = Cleanning()
8
+ self.cleaner = Cleaning()
9
9
 
10
10
  def test_remove_duplicates(self):
11
11
  input_smiles = ["CC>>CC", "CC>>CC"]
@@ -1,5 +1,8 @@
1
1
  import unittest
2
- from synkit.Chem.Reaction.rsmi_utils import (
2
+ from rdkit import Chem
3
+ from synkit.Chem.utils import (
4
+ enumerate_tautomers,
5
+ mapping_success_rate,
3
6
  remove_common_reagents,
4
7
  reverse_reaction,
5
8
  remove_duplicates,
@@ -8,7 +11,49 @@ from synkit.Chem.Reaction.rsmi_utils import (
8
11
  )
9
12
 
10
13
 
11
- class TestChemicalReactions(unittest.TestCase):
14
+ class TestChemUtils(unittest.TestCase):
15
+ def test_enumerate_tautomers_simple(self):
16
+ # A simple keto-enol tautomerism: acetylacetone (CC(=O)CC=O) -> same product
17
+ reaction = "CC(=O)CC=O>>O"
18
+ tautomers = enumerate_tautomers(reaction)
19
+ # Should return a list with at least the original reaction
20
+ self.assertIsInstance(tautomers, list)
21
+ self.assertIn(reaction, tautomers)
22
+ # Each entry should be a valid reaction SMILES
23
+ for rsmi in tautomers:
24
+ self.assertIsInstance(rsmi, str)
25
+ parts = rsmi.split(">>")
26
+ self.assertEqual(len(parts), 2)
27
+ # Reactant and product part parseable by RDKit
28
+ self.assertIsNotNone(Chem.MolFromSmiles(parts[0]))
29
+ self.assertIsNotNone(Chem.MolFromSmiles(parts[1]))
30
+
31
+ def test_enumerate_tautomers_invalid(self):
32
+ # Invalid SMILES input should raise ValueError
33
+ bad = "INVALID>>SMILES"
34
+ with self.assertRaises(ValueError) as cm:
35
+ enumerate_tautomers(bad)
36
+ self.assertIn("Invalid reactant or product SMILES", str(cm.exception))
37
+
38
+ def test_mapping_success_rate_normal(self):
39
+ data = ["C:1CC", "CCC", "O:3=O", ":5", "N"]
40
+ rate = mapping_success_rate(data)
41
+ # Entries with mapping: 'C:1CC', 'O:3=O', ':5' => 3/5 = 60.0%
42
+ self.assertEqual(rate, 60.0)
43
+
44
+ def test_mapping_success_rate_empty(self):
45
+ with self.assertRaises(ValueError):
46
+ mapping_success_rate([])
47
+
48
+ def test_mapping_success_rate_all(self):
49
+ data = [":1C", ":2", "N:3"]
50
+ rate = mapping_success_rate(data)
51
+ self.assertEqual(rate, 100.0)
52
+
53
+ def test_mapping_success_rate_none(self):
54
+ data = ["C", "O", "N"]
55
+ rate = mapping_success_rate(data)
56
+ self.assertEqual(rate, 0.0)
12
57
 
13
58
  def test_remove_common_reagents_no_common(self):
14
59
  reaction = "A.B.C>>D.E.F"
@@ -21,6 +21,22 @@ The `Chem` module provides tools for handling input and output operations relate
21
21
  :undoc-members:
22
22
  :show-inheritance:
23
23
 
24
+ .. automodule:: synkit.Chem.Reaction.balance_check
25
+ :members:
26
+ :undoc-members:
27
+ :show-inheritance:
28
+
29
+ .. automodule:: synkit.Chem.Fingerprint.fp_calculator
30
+ :members:
31
+ :undoc-members:
32
+ :show-inheritance:
33
+
34
+ .. automodule:: synkit.Chem.Cluster.butina
35
+ :members:
36
+ :undoc-members:
37
+ :show-inheritance:
38
+
39
+
24
40
  Synthesis Module
25
41
  ================
26
42
 
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import sys
3
+ import importlib.metadata as m
3
4
  from importlib.metadata import version as _get_version, PackageNotFoundError
4
5
 
5
6
  # -- Path setup --------------------------------------------------------------
@@ -15,12 +16,10 @@ try:
15
16
  release = _get_version("synkit")
16
17
  except PackageNotFoundError:
17
18
  try:
18
- import synkit
19
-
20
- release = synkit.__version__
19
+ release = m.version("synkit")
21
20
  except (ImportError, AttributeError):
22
21
  # Fallback default
23
- release = "0.0.10"
22
+ release = "0.0.11"
24
23
  # Use only major.minor for short version
25
24
  version = ".".join(release.split(".")[:2])
26
25