chemicalml 0.2.0 → 0.2.1

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 (304) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +7 -1
  3. data/CLAUDE.md +48 -41
  4. data/TODO.align/36-molecular-convention-coverage.md +46 -0
  5. data/TODO.align/37-compchem-convention-coverage.md +55 -0
  6. data/TODO.align/38-dictionary-convention-coverage.md +34 -0
  7. data/TODO.align/39-unit-dictionary-convention-coverage.md +33 -0
  8. data/TODO.align/40-unit-type-dictionary-convention-coverage.md +28 -0
  9. data/TODO.align/41-expand-canonical-model-layer.md +43 -0
  10. data/TODO.align/42-translator-wire-new-models.md +31 -0
  11. data/TODO.align/43-dictionary-model-no-to-h.md +39 -0
  12. data/TODO.align/44-schema3-only-and-schema24-module.md +44 -0
  13. data/TODO.align/45-documentation-and-final-verification.md +23 -0
  14. data/TODO.align/46-lattice-vector-content.md +24 -0
  15. data/TODO.align/47-molecule-crystal-spectra-property-lists.md +23 -0
  16. data/TODO.align/48-model-list-and-module-lists.md +21 -0
  17. data/TODO.align/49-more-chemistry-models.md +34 -0
  18. data/TODO.align/50-validation-report.md +29 -0
  19. data/TODO.align/51-convention-auto-detection.md +30 -0
  20. data/TODO.align/52-schema24-legacy-elements.md +28 -0
  21. data/TODO.align/53-round-trip-integration-specs.md +30 -0
  22. data/TODO.align/54-document-versioned-parser-shim.md +38 -0
  23. data/TODO.align/55-molecule-missing-attributes.md +20 -0
  24. data/TODO.align/56-geometry-models.md +24 -0
  25. data/TODO.align/57-compchem-models.md +26 -0
  26. data/TODO.align/58-remaining-models.md +24 -0
  27. data/TODO.align/59-wire-new-models-translator.md +18 -0
  28. data/TODO.align/60-docs-and-final-verification.md +19 -0
  29. data/lib/chemicalml/cml/base/abundance.rb +6 -0
  30. data/lib/chemicalml/cml/base/action.rb +20 -0
  31. data/lib/chemicalml/cml/base/action_list.rb +18 -0
  32. data/lib/chemicalml/cml/base/alternative.rb +28 -0
  33. data/lib/chemicalml/cml/base/amount.rb +2 -0
  34. data/lib/chemicalml/cml/base/angle.rb +12 -0
  35. data/lib/chemicalml/cml/base/annotation.rb +30 -0
  36. data/lib/chemicalml/cml/base/appinfo.rb +32 -0
  37. data/lib/chemicalml/cml/base/arg.rb +46 -0
  38. data/lib/chemicalml/cml/base/array.rb +22 -0
  39. data/lib/chemicalml/cml/base/array_list.rb +2 -0
  40. data/lib/chemicalml/cml/base/atom.rb +18 -0
  41. data/lib/chemicalml/cml/base/atom_array.rb +38 -0
  42. data/lib/chemicalml/cml/base/atom_parity.rb +8 -0
  43. data/lib/chemicalml/cml/base/atom_set.rb +2 -0
  44. data/lib/chemicalml/cml/base/atom_type.rb +4 -0
  45. data/lib/chemicalml/cml/base/atom_type_list.rb +2 -0
  46. data/lib/chemicalml/cml/base/atomic_basis_function.rb +4 -0
  47. data/lib/chemicalml/cml/base/band.rb +2 -0
  48. data/lib/chemicalml/cml/base/basis_set.rb +4 -0
  49. data/lib/chemicalml/cml/base/bond.rb +6 -0
  50. data/lib/chemicalml/cml/base/bond_array.rb +16 -0
  51. data/lib/chemicalml/cml/base/bond_set.rb +2 -0
  52. data/lib/chemicalml/cml/base/bond_stereo.rb +10 -0
  53. data/lib/chemicalml/cml/base/bond_type.rb +2 -0
  54. data/lib/chemicalml/cml/base/bond_type_list.rb +2 -0
  55. data/lib/chemicalml/cml/base/cell_parameter.rb +4 -0
  56. data/lib/chemicalml/cml/base/complex_object.rb +30 -0
  57. data/lib/chemicalml/cml/base/condition_list.rb +4 -0
  58. data/lib/chemicalml/cml/base/crystal.rb +2 -0
  59. data/lib/chemicalml/cml/base/description.rb +2 -0
  60. data/lib/chemicalml/cml/base/dictionary.rb +6 -0
  61. data/lib/chemicalml/cml/base/dimension.rb +10 -0
  62. data/lib/chemicalml/cml/base/eigen.rb +2 -0
  63. data/lib/chemicalml/cml/base/electron.rb +6 -0
  64. data/lib/chemicalml/cml/base/enumeration.rb +32 -0
  65. data/lib/chemicalml/cml/base/expression.rb +32 -0
  66. data/lib/chemicalml/cml/base/float.rb +40 -0
  67. data/lib/chemicalml/cml/base/float_array.rb +42 -0
  68. data/lib/chemicalml/cml/base/fragment.rb +6 -0
  69. data/lib/chemicalml/cml/base/fragment_list.rb +4 -0
  70. data/lib/chemicalml/cml/base/identifier.rb +8 -0
  71. data/lib/chemicalml/cml/base/integer.rb +40 -0
  72. data/lib/chemicalml/cml/base/integer_array.rb +42 -0
  73. data/lib/chemicalml/cml/base/isotope.rb +2 -0
  74. data/lib/chemicalml/cml/base/isotope_list.rb +2 -0
  75. data/lib/chemicalml/cml/base/join.rb +6 -0
  76. data/lib/chemicalml/cml/base/kpoint.rb +2 -0
  77. data/lib/chemicalml/cml/base/label.rb +2 -0
  78. data/lib/chemicalml/cml/base/lattice.rb +2 -0
  79. data/lib/chemicalml/cml/base/lattice_vector.rb +2 -0
  80. data/lib/chemicalml/cml/base/length.rb +10 -0
  81. data/lib/chemicalml/cml/base/line3.rb +6 -0
  82. data/lib/chemicalml/cml/base/link.rb +20 -0
  83. data/lib/chemicalml/cml/base/list.rb +2 -0
  84. data/lib/chemicalml/cml/base/map.rb +12 -0
  85. data/lib/chemicalml/cml/base/matrix.rb +12 -0
  86. data/lib/chemicalml/cml/base/metadata.rb +4 -0
  87. data/lib/chemicalml/cml/base/metadata_list.rb +6 -0
  88. data/lib/chemicalml/cml/base/molecule.rb +10 -0
  89. data/lib/chemicalml/cml/base/molecule_list.rb +2 -0
  90. data/lib/chemicalml/cml/base/name.rb +2 -0
  91. data/lib/chemicalml/cml/base/object.rb +4 -0
  92. data/lib/chemicalml/cml/base/observation.rb +4 -0
  93. data/lib/chemicalml/cml/base/operator.rb +32 -0
  94. data/lib/chemicalml/cml/base/parameter.rb +10 -0
  95. data/lib/chemicalml/cml/base/parameter_list.rb +6 -0
  96. data/lib/chemicalml/cml/base/particle.rb +6 -0
  97. data/lib/chemicalml/cml/base/peak.rb +30 -0
  98. data/lib/chemicalml/cml/base/peak_group.rb +38 -0
  99. data/lib/chemicalml/cml/base/peak_list.rb +2 -0
  100. data/lib/chemicalml/cml/base/peak_structure.rb +14 -0
  101. data/lib/chemicalml/cml/base/plane3.rb +2 -0
  102. data/lib/chemicalml/cml/base/point3.rb +2 -0
  103. data/lib/chemicalml/cml/base/potential_form.rb +2 -0
  104. data/lib/chemicalml/cml/base/product.rb +16 -0
  105. data/lib/chemicalml/cml/base/product_list.rb +14 -0
  106. data/lib/chemicalml/cml/base/property.rb +6 -0
  107. data/lib/chemicalml/cml/base/property_list.rb +6 -0
  108. data/lib/chemicalml/cml/base/reactant.rb +16 -0
  109. data/lib/chemicalml/cml/base/reactant_list.rb +14 -0
  110. data/lib/chemicalml/cml/base/reaction.rb +16 -0
  111. data/lib/chemicalml/cml/base/reaction_list.rb +12 -0
  112. data/lib/chemicalml/cml/base/reaction_scheme.rb +10 -0
  113. data/lib/chemicalml/cml/base/reaction_step.rb +6 -0
  114. data/lib/chemicalml/cml/base/reaction_step_list.rb +8 -0
  115. data/lib/chemicalml/cml/base/region.rb +8 -0
  116. data/lib/chemicalml/cml/base/related_entry.rb +26 -0
  117. data/lib/chemicalml/cml/base/sample.rb +4 -0
  118. data/lib/chemicalml/cml/base/scalar.rb +18 -0
  119. data/lib/chemicalml/cml/base/spectator.rb +2 -0
  120. data/lib/chemicalml/cml/base/spectrum.rb +12 -0
  121. data/lib/chemicalml/cml/base/spectrum_data.rb +2 -0
  122. data/lib/chemicalml/cml/base/spectrum_list.rb +4 -0
  123. data/lib/chemicalml/cml/base/sphere3.rb +2 -0
  124. data/lib/chemicalml/cml/base/string.rb +32 -0
  125. data/lib/chemicalml/cml/base/string_array.rb +40 -0
  126. data/lib/chemicalml/cml/base/substance.rb +12 -0
  127. data/lib/chemicalml/cml/base/substance_list.rb +6 -0
  128. data/lib/chemicalml/cml/base/symmetry.rb +4 -0
  129. data/lib/chemicalml/cml/base/system.rb +4 -0
  130. data/lib/chemicalml/cml/base/table.rb +10 -0
  131. data/lib/chemicalml/cml/base/table_content.rb +2 -0
  132. data/lib/chemicalml/cml/base/table_header_cell.rb +10 -0
  133. data/lib/chemicalml/cml/base/tcell.rb +34 -0
  134. data/lib/chemicalml/cml/base/torsion.rb +12 -0
  135. data/lib/chemicalml/cml/base/trow.rb +32 -0
  136. data/lib/chemicalml/cml/base/unit.rb +12 -0
  137. data/lib/chemicalml/cml/base/unit_list.rb +12 -0
  138. data/lib/chemicalml/cml/base/unit_type.rb +10 -0
  139. data/lib/chemicalml/cml/base/unit_type_list.rb +10 -0
  140. data/lib/chemicalml/cml/base/vector3.rb +2 -0
  141. data/lib/chemicalml/cml/base/xaxis.rb +6 -0
  142. data/lib/chemicalml/cml/base/yaxis.rb +6 -0
  143. data/lib/chemicalml/cml/base.rb +17 -0
  144. data/lib/chemicalml/cml/elements.rb +39 -4
  145. data/lib/chemicalml/cml/role/alternative.rb +10 -0
  146. data/lib/chemicalml/cml/role/annotation.rb +10 -0
  147. data/lib/chemicalml/cml/role/appinfo.rb +10 -0
  148. data/lib/chemicalml/cml/role/arg.rb +10 -0
  149. data/lib/chemicalml/cml/role/cml_module.rb +2 -3
  150. data/lib/chemicalml/cml/role/complex_object.rb +10 -0
  151. data/lib/chemicalml/cml/role/enumeration.rb +10 -0
  152. data/lib/chemicalml/cml/role/expression.rb +10 -0
  153. data/lib/chemicalml/cml/role/float.rb +10 -0
  154. data/lib/chemicalml/cml/role/float_array.rb +10 -0
  155. data/lib/chemicalml/cml/role/integer.rb +10 -0
  156. data/lib/chemicalml/cml/role/integer_array.rb +10 -0
  157. data/lib/chemicalml/cml/role/operator.rb +10 -0
  158. data/lib/chemicalml/cml/role/related_entry.rb +10 -0
  159. data/lib/chemicalml/cml/role/string.rb +10 -0
  160. data/lib/chemicalml/cml/role/string_array.rb +10 -0
  161. data/lib/chemicalml/cml/role/tcell.rb +10 -0
  162. data/lib/chemicalml/cml/role/trow.rb +10 -0
  163. data/lib/chemicalml/cml/role.rb +17 -0
  164. data/lib/chemicalml/cml/schema24/alternative.rb +14 -0
  165. data/lib/chemicalml/cml/schema24/annotation.rb +15 -0
  166. data/lib/chemicalml/cml/schema24/appinfo.rb +15 -0
  167. data/lib/chemicalml/cml/schema24/arg.rb +14 -0
  168. data/lib/chemicalml/cml/schema24/cml_module.rb +18 -0
  169. data/lib/chemicalml/cml/schema24/complex_object.rb +14 -0
  170. data/lib/chemicalml/cml/schema24/configuration.rb +5 -2
  171. data/lib/chemicalml/cml/schema24/enumeration.rb +16 -0
  172. data/lib/chemicalml/cml/schema24/expression.rb +14 -0
  173. data/lib/chemicalml/cml/schema24/float.rb +14 -0
  174. data/lib/chemicalml/cml/schema24/float_array.rb +14 -0
  175. data/lib/chemicalml/cml/schema24/integer.rb +14 -0
  176. data/lib/chemicalml/cml/schema24/integer_array.rb +14 -0
  177. data/lib/chemicalml/cml/schema24/operator.rb +14 -0
  178. data/lib/chemicalml/cml/schema24/related_entry.rb +14 -0
  179. data/lib/chemicalml/cml/schema24/string.rb +14 -0
  180. data/lib/chemicalml/cml/schema24/string_array.rb +14 -0
  181. data/lib/chemicalml/cml/schema24/tcell.rb +14 -0
  182. data/lib/chemicalml/cml/schema24/trow.rb +14 -0
  183. data/lib/chemicalml/cml/schema24.rb +33 -5
  184. data/lib/chemicalml/cml.rb +1 -3
  185. data/lib/chemicalml/context_configuration.rb +8 -2
  186. data/lib/chemicalml/convention/base.rb +17 -3
  187. data/lib/chemicalml/convention/compchem/constraints/array_rules.rb +44 -0
  188. data/lib/chemicalml/convention/compchem/constraints/calculation_requires_finalization.rb +28 -0
  189. data/lib/chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list.rb +4 -4
  190. data/lib/chemicalml/convention/compchem/constraints/environment_at_most_one_property_list.rb +26 -0
  191. data/lib/chemicalml/convention/compchem/constraints/environment_must_not_contain_parameter.rb +28 -0
  192. data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_molecule.rb +26 -0
  193. data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_property_list.rb +26 -0
  194. data/lib/chemicalml/convention/compchem/constraints/finalization_must_not_contain_parameter.rb +27 -0
  195. data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_molecule.rb +26 -0
  196. data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_parameter_list.rb +26 -0
  197. data/lib/chemicalml/convention/compchem/constraints/initialization_must_not_contain_property.rb +28 -0
  198. data/lib/chemicalml/convention/compchem/constraints/job_list_module_must_have_id.rb +24 -0
  199. data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_environment.rb +25 -0
  200. data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_finalization.rb +25 -0
  201. data/lib/chemicalml/convention/compchem/constraints/job_module_must_have_id.rb +24 -0
  202. data/lib/chemicalml/convention/compchem/constraints/job_must_contain_initialization.rb +6 -9
  203. data/lib/chemicalml/convention/compchem/constraints/matrix_rules.rb +48 -0
  204. data/lib/chemicalml/convention/compchem/constraints/module_predicates.rb +50 -0
  205. data/lib/chemicalml/convention/compchem/constraints/scalar_units.rb +42 -0
  206. data/lib/chemicalml/convention/compchem/constraints.rb +36 -2
  207. data/lib/chemicalml/convention/compchem.rb +16 -0
  208. data/lib/chemicalml/convention/constraint.rb +31 -18
  209. data/lib/chemicalml/convention/coordinator.rb +89 -0
  210. data/lib/chemicalml/convention/detection.rb +33 -0
  211. data/lib/chemicalml/convention/dictionary/constraints/dictionary_must_have_namespace.rb +28 -0
  212. data/lib/chemicalml/convention/dictionary/constraints/dictionary_namespace_should_end_with_slash_or_hash.rb +32 -0
  213. data/lib/chemicalml/convention/dictionary/constraints/entry_id_must_match_pattern.rb +33 -0
  214. data/lib/chemicalml/convention/dictionary/constraints/entry_ids_unique_within_dictionary.rb +3 -3
  215. data/lib/chemicalml/convention/dictionary/constraints/entry_must_contain_definition.rb +28 -0
  216. data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_id_and_term.rb +5 -5
  217. data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_unit_type.rb +30 -0
  218. data/lib/chemicalml/convention/dictionary/constraints/entry_units_co_constraints.rb +44 -0
  219. data/lib/chemicalml/convention/dictionary/constraints.rb +12 -0
  220. data/lib/chemicalml/convention/dictionary.rb +6 -0
  221. data/lib/chemicalml/convention/molecular/constraints/atom_array_must_be_child_of_molecule_or_formula.rb +40 -0
  222. data/lib/chemicalml/convention/molecular/constraints/atom_array_must_contain_atoms.rb +3 -3
  223. data/lib/chemicalml/convention/molecular/constraints/atom_coordinates_must_be_paired.rb +5 -5
  224. data/lib/chemicalml/convention/molecular/constraints/atom_id_must_match_pattern.rb +4 -4
  225. data/lib/chemicalml/convention/molecular/constraints/atom_ids_unique_within_molecule.rb +2 -2
  226. data/lib/chemicalml/convention/molecular/constraints/atom_must_have_element_type.rb +3 -3
  227. data/lib/chemicalml/convention/molecular/constraints/atom_must_have_id.rb +3 -3
  228. data/lib/chemicalml/convention/molecular/constraints/bond_array_must_be_child_of_molecule.rb +36 -0
  229. data/lib/chemicalml/convention/molecular/constraints/bond_ids_unique_within_molecule.rb +43 -0
  230. data/lib/chemicalml/convention/molecular/constraints/bond_must_have_atom_refs2.rb +3 -3
  231. data/lib/chemicalml/convention/molecular/constraints/bond_must_have_order.rb +3 -3
  232. data/lib/chemicalml/convention/molecular/constraints/bond_must_reference_atoms_in_same_molecule.rb +3 -3
  233. data/lib/chemicalml/convention/molecular/constraints/bond_order_other_must_have_dict_ref.rb +33 -0
  234. data/lib/chemicalml/convention/molecular/constraints/bond_order_should_not_be_numeric.rb +2 -2
  235. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_cis_trans_must_have_atom_refs4.rb +45 -0
  236. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_other_must_have_dict_ref.rb +32 -0
  237. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_wedge_hash_must_have_atom_refs2.rb +45 -0
  238. data/lib/chemicalml/convention/molecular/constraints/molecule_atom_array_mutually_exclusive_with_children.rb +32 -0
  239. data/lib/chemicalml/convention/molecular/constraints/molecule_bond_array_mutually_exclusive_with_children.rb +31 -0
  240. data/lib/chemicalml/convention/molecular/constraints/molecule_count_must_not_appear_on_top_level.rb +34 -0
  241. data/lib/chemicalml/convention/molecular/constraints/molecule_must_have_id.rb +3 -3
  242. data/lib/chemicalml/convention/molecular/constraints/property_must_have_dict_ref.rb +3 -3
  243. data/lib/chemicalml/convention/molecular/constraints/scalar_must_have_data_type.rb +3 -3
  244. data/lib/chemicalml/convention/molecular/constraints.rb +20 -0
  245. data/lib/chemicalml/convention/molecular.rb +10 -0
  246. data/lib/chemicalml/convention/registry.rb +17 -0
  247. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit.rb +28 -0
  248. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace.rb +36 -0
  249. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition.rb +27 -0
  250. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_id.rb +27 -0
  251. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb +3 -3
  252. data/lib/chemicalml/convention/unit_dictionary/constraints.rb +9 -1
  253. data/lib/chemicalml/convention/unit_dictionary.rb +4 -0
  254. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern.rb +31 -0
  255. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_contain_at_least_one_unit_type.rb +27 -0
  256. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_have_namespace.rb +35 -0
  257. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition.rb +27 -0
  258. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb +5 -5
  259. data/lib/chemicalml/convention/unit_type_dictionary/constraints.rb +9 -1
  260. data/lib/chemicalml/convention/unit_type_dictionary.rb +4 -0
  261. data/lib/chemicalml/convention/validation_report.rb +63 -0
  262. data/lib/chemicalml/convention.rb +11 -0
  263. data/lib/chemicalml/dictionary/entry.rb +6 -6
  264. data/lib/chemicalml/dictionary/enum.rb +1 -1
  265. data/lib/chemicalml/dictionary/link.rb +3 -3
  266. data/lib/chemicalml/dictionary/loader.rb +19 -19
  267. data/lib/chemicalml/dictionary/model.rb +5 -5
  268. data/lib/chemicalml/dictionary/registry.rb +9 -9
  269. data/lib/chemicalml/version.rb +1 -1
  270. data/lib/chemicalml/versioned_parser.rb +18 -0
  271. data/lib/chemicalml.rb +1 -2
  272. metadata +123 -34
  273. data/lib/chemicalml/cml/child_mappings.rb +0 -168
  274. data/lib/chemicalml/cml/translator/value_translations.rb +0 -270
  275. data/lib/chemicalml/cml/translator.rb +0 -484
  276. data/lib/chemicalml/model/atom.rb +0 -64
  277. data/lib/chemicalml/model/atom_parity.rb +0 -21
  278. data/lib/chemicalml/model/bond.rb +0 -39
  279. data/lib/chemicalml/model/bond_stereo.rb +0 -29
  280. data/lib/chemicalml/model/cml_array.rb +0 -27
  281. data/lib/chemicalml/model/cml_module.rb +0 -45
  282. data/lib/chemicalml/model/document.rb +0 -29
  283. data/lib/chemicalml/model/formula.rb +0 -34
  284. data/lib/chemicalml/model/identifier.rb +0 -21
  285. data/lib/chemicalml/model/label.rb +0 -21
  286. data/lib/chemicalml/model/matrix.rb +0 -29
  287. data/lib/chemicalml/model/metadata.rb +0 -23
  288. data/lib/chemicalml/model/metadata_list.rb +0 -25
  289. data/lib/chemicalml/model/molecule.rb +0 -45
  290. data/lib/chemicalml/model/name.rb +0 -21
  291. data/lib/chemicalml/model/node.rb +0 -45
  292. data/lib/chemicalml/model/parameter.rb +0 -27
  293. data/lib/chemicalml/model/parameter_list.rb +0 -25
  294. data/lib/chemicalml/model/product.rb +0 -21
  295. data/lib/chemicalml/model/product_list.rb +0 -21
  296. data/lib/chemicalml/model/property.rb +0 -28
  297. data/lib/chemicalml/model/property_list.rb +0 -25
  298. data/lib/chemicalml/model/reactant.rb +0 -21
  299. data/lib/chemicalml/model/reactant_list.rb +0 -21
  300. data/lib/chemicalml/model/reaction.rb +0 -41
  301. data/lib/chemicalml/model/reaction_list.rb +0 -23
  302. data/lib/chemicalml/model/scalar.rb +0 -25
  303. data/lib/chemicalml/model/substance.rb +0 -25
  304. data/lib/chemicalml/model.rb +0 -40
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The environment module MUST NOT contain more than one
8
+ # propertyList child.
9
+ class EnvironmentAtMostOnePropertyList < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+
15
+ lists = node.property_lists || []
16
+ return [] if lists.length <= 1
17
+
18
+ [violation(path: path.join('/'),
19
+ message: 'environment module must not contain more than ' \
20
+ "one propertyList (found #{lists.length})")]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The environment module MUST NOT contain parameter or
8
+ # parameterList children directly. It MAY contain a
9
+ # propertyList (which itself can hold parameters).
10
+ class EnvironmentMustNotContainParameter < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Module
12
+ include ModulePredicates
13
+
14
+ def check_node(node, path)
15
+
16
+ violations = []
17
+ unless (node.parameter_lists || []).empty?
18
+ violations << violation(path: path.join('/'),
19
+ message: 'environment module must not contain parameterList children ' \
20
+ '(use propertyList instead)')
21
+ end
22
+ violations
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The finalization module MUST NOT contain more than one
8
+ # molecule child.
9
+ class FinalizationAtMostOneMolecule < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+
15
+ molecules = node.molecules || []
16
+ return [] if molecules.length <= 1
17
+
18
+ [violation(path: path.join('/'),
19
+ message: 'finalization module must not contain more than ' \
20
+ "one molecule (found #{molecules.length})")]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The finalization module MUST NOT contain more than one
8
+ # propertyList child.
9
+ class FinalizationAtMostOnePropertyList < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+
15
+ lists = node.property_lists || []
16
+ return [] if lists.length <= 1
17
+
18
+ [violation(path: path.join('/'),
19
+ message: 'finalization module must not contain more than ' \
20
+ "one propertyList (found #{lists.length})")]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The finalization module MUST NOT contain parameter or
8
+ # parameterList children directly. (Parameters belong in
9
+ # initialization.)
10
+ class FinalizationMustNotContainParameter < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Module
12
+ include ModulePredicates
13
+
14
+ def check_node(node, path)
15
+
16
+ violations = []
17
+ unless (node.parameter_lists || []).empty?
18
+ violations << violation(path: path.join('/'),
19
+ message: 'finalization module must not contain parameterList children')
20
+ end
21
+ violations
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The initialization module MUST NOT contain more than one
8
+ # molecule child.
9
+ class InitializationAtMostOneMolecule < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+
15
+ molecules = node.molecules || []
16
+ return [] if molecules.length <= 1
17
+
18
+ [violation(path: path.join('/'),
19
+ message: 'initialization module must not contain more than ' \
20
+ "one molecule (found #{molecules.length})")]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The initialization module MUST NOT contain more than one
8
+ # parameterList child.
9
+ class InitializationAtMostOneParameterList < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+
15
+ lists = node.parameter_lists || []
16
+ return [] if lists.length <= 1
17
+
18
+ [violation(path: path.join('/'),
19
+ message: 'initialization module must not contain more than ' \
20
+ "one parameterList (found #{lists.length})")]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # The initialization module MUST NOT contain property or
8
+ # propertyList children directly. (Properties belong in
9
+ # finalization.)
10
+ class InitializationMustNotContainProperty < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Module
12
+ include ModulePredicates
13
+
14
+ def check_node(node, path)
15
+
16
+ violations = []
17
+ unless (node.property_lists || []).empty?
18
+ violations << violation(path: path.join('/'),
19
+ message: 'initialization module must not contain propertyList children ' \
20
+ '(properties belong in finalization)')
21
+ end
22
+ violations
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # A jobList module MUST have an `id` unique within the
8
+ # compchem module.
9
+ class JobListModuleMustHaveId < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+ return [] unless node.dict_ref == 'compchem:jobList'
15
+ return [] unless node.id.to_s.empty?
16
+
17
+ [violation(path: path.join('/'),
18
+ message: 'jobList module must have an id unique within the compchem module')]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # A job module MUST contain at most one environment module.
8
+ class JobModuleAtMostOneEnvironment < Chemicalml::Convention::Constraint::NodeConstraint
9
+ applies_to Chemicalml::Cml::Role::Module
10
+ include ModulePredicates
11
+
12
+ def check_node(node, path)
13
+
14
+ environments = child_modules_with(node, 'compchem:environment')
15
+ return [] if environments.length <= 1
16
+
17
+ [violation(path: path.join('/'),
18
+ message: 'job module must contain at most one environment ' \
19
+ "(found #{environments.length})")]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # A job module MUST contain at most one finalization module.
8
+ class JobModuleAtMostOneFinalization < Chemicalml::Convention::Constraint::NodeConstraint
9
+ applies_to Chemicalml::Cml::Role::Module
10
+ include ModulePredicates
11
+
12
+ def check_node(node, path)
13
+
14
+ finalizations = child_modules_with(node, 'compchem:finalization')
15
+ return [] if finalizations.length <= 1
16
+
17
+ [violation(path: path.join('/'),
18
+ message: 'job module must contain at most one finalization ' \
19
+ "(found #{finalizations.length})")]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # A job module MUST have an `id` unique within the compchem
8
+ # module.
9
+ class JobModuleMustHaveId < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
11
+ include ModulePredicates
12
+
13
+ def check_node(node, path)
14
+ return [] unless node.dict_ref == 'compchem:job'
15
+ return [] unless node.id.to_s.empty?
16
+
17
+ [violation(path: path.join('/'),
18
+ message: 'job module must have an id unique within the compchem module')]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -7,29 +7,26 @@ module Chemicalml
7
7
  # A job module MUST contain exactly one initialization module
8
8
  # child per the compchem convention.
9
9
  class JobMustContainInitialization < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Module
10
11
  def check_node(node, path)
11
- return [] unless job_module?(node)
12
+ return [] unless node.dict_ref == 'compchem:job'
12
13
 
13
14
  modules = node.modules || []
14
- inits = modules.select { |m| m.dict_ref == "compchem:initialization" }
15
+ inits = modules.select { |m| m.dict_ref == 'compchem:initialization' }
15
16
  return [] if inits.length == 1
16
17
 
17
18
  message = if inits.empty?
18
- "job module must contain exactly one initialization module (found 0)"
19
+ 'job module must contain exactly one initialization module (found 0)'
19
20
  else
20
21
  "job module must contain exactly one initialization module (found #{inits.length})"
21
22
  end
22
- [violation(path: path.join("/"), message: message)]
23
+ [violation(path: path.join('/'), message: message)]
23
24
  end
24
25
 
25
26
  private
26
27
 
27
28
  def job_module?(node)
28
- module?(node) && node.dict_ref == "compchem:job"
29
- end
30
-
31
- def module?(node)
32
- node.is_a?(Chemicalml::Cml::Role::Module)
29
+ node.is_a?(Chemicalml::Cml::Role::Module) && node.dict_ref == 'compchem:job'
33
30
  end
34
31
  end
35
32
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # CompChem `matrix` value-container rules: MUST have `rows`
8
+ # and `columns` attributes (each ≥ 1); `dataType` MUST be
9
+ # integer or double; MUST have `units`.
10
+ class MatrixRules < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Matrix
12
+ include ModulePredicates
13
+
14
+ ALLOWED_TYPES = %w[xsd:integer xsd:double].freeze
15
+
16
+ def check_node(node, path)
17
+
18
+ violations = []
19
+ if node.rows.to_s.empty? || node.rows.to_i < 1
20
+ violations << violation(path: path.join('/'),
21
+ message: 'matrix must have a rows attribute (minimum 1)')
22
+ end
23
+ if node.columns.to_s.empty? || node.columns.to_i < 1
24
+ violations << violation(path: path.join('/'),
25
+ message: 'matrix must have a columns attribute (minimum 1)')
26
+ end
27
+ unless ALLOWED_TYPES.include?(node.data_type.to_s)
28
+ violations << violation(path: path.join('/'),
29
+ message: 'matrix dataType must be xsd:integer or xsd:double ' \
30
+ "(got #{node.data_type.inspect})")
31
+ end
32
+ if node.units.to_s.empty?
33
+ violations << violation(path: path.join('/'),
34
+ message: 'matrix must have units (even if dimensionless)')
35
+ end
36
+ violations
37
+ end
38
+
39
+ private
40
+
41
+ def matrix?(node)
42
+ node.is_a?(Chemicalml::Cml::Role::Matrix)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # Internal: helpers shared by every compchem constraint. Mixed
8
+ # into each constraint class so the role + dictRef checks
9
+ # live in one place (DRY).
10
+ module ModulePredicates
11
+ def cml_module?(node)
12
+ node.is_a?(Chemicalml::Cml::Role::Module)
13
+ end
14
+
15
+ def compchem_root?(node)
16
+ cml_module?(node) && node.convention == 'convention:compchem'
17
+ end
18
+
19
+ def job_list_module?(node)
20
+ cml_module?(node) && node.dict_ref == 'compchem:jobList'
21
+ end
22
+
23
+ def job_module?(node)
24
+ cml_module?(node) && node.dict_ref == 'compchem:job'
25
+ end
26
+
27
+ def initialization_module?(node)
28
+ cml_module?(node) && node.dict_ref == 'compchem:initialization'
29
+ end
30
+
31
+ def calculation_module?(node)
32
+ cml_module?(node) && node.dict_ref == 'compchem:calculation'
33
+ end
34
+
35
+ def finalization_module?(node)
36
+ cml_module?(node) && node.dict_ref == 'compchem:finalization'
37
+ end
38
+
39
+ def environment_module?(node)
40
+ cml_module?(node) && node.dict_ref == 'compchem:environment'
41
+ end
42
+
43
+ def child_modules_with(node, dict_ref)
44
+ (node.modules || []).select { |m| m.dict_ref == dict_ref }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # CompChem value-container rules: `scalar` with dataType
8
+ # `xsd:integer` or `xsd:double` MUST have `units`; `scalar`
9
+ # with dataType `xsd:string` MUST NOT have `units`.
10
+ class ScalarUnits < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Scalar
12
+ include ModulePredicates
13
+
14
+ NUMERIC_TYPES = %w[xsd:integer xsd:double].freeze
15
+
16
+ def check_node(node, path)
17
+
18
+ data_type = node.data_type.to_s
19
+ units = node.units.to_s
20
+ violations = []
21
+
22
+ if NUMERIC_TYPES.include?(data_type) && units.empty?
23
+ violations << violation(path: path.join('/'),
24
+ message: "scalar with dataType #{data_type.inspect} must have units")
25
+ end
26
+ if data_type == 'xsd:string' && !units.empty?
27
+ violations << violation(path: path.join('/'),
28
+ message: "scalar with dataType 'xsd:string' must not have units")
29
+ end
30
+ violations
31
+ end
32
+
33
+ private
34
+
35
+ def scalar?(node)
36
+ node.is_a?(Chemicalml::Cml::Role::Scalar)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,10 +4,44 @@ module Chemicalml
4
4
  module Convention
5
5
  module Compchem
6
6
  module Constraints
7
+ autoload :ModulePredicates,
8
+ 'chemicalml/convention/compchem/constraints/module_predicates'
7
9
  autoload :CompchemModuleMustContainJobList,
8
- "chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list"
10
+ 'chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list'
9
11
  autoload :JobMustContainInitialization,
10
- "chemicalml/convention/compchem/constraints/job_must_contain_initialization"
12
+ 'chemicalml/convention/compchem/constraints/job_must_contain_initialization'
13
+ autoload :JobListModuleMustHaveId,
14
+ 'chemicalml/convention/compchem/constraints/job_list_module_must_have_id'
15
+ autoload :JobModuleMustHaveId,
16
+ 'chemicalml/convention/compchem/constraints/job_module_must_have_id'
17
+ autoload :JobModuleAtMostOneFinalization,
18
+ 'chemicalml/convention/compchem/constraints/job_module_at_most_one_finalization'
19
+ autoload :JobModuleAtMostOneEnvironment,
20
+ 'chemicalml/convention/compchem/constraints/job_module_at_most_one_environment'
21
+ autoload :CalculationRequiresFinalization,
22
+ 'chemicalml/convention/compchem/constraints/calculation_requires_finalization'
23
+ autoload :InitializationAtMostOneMolecule,
24
+ 'chemicalml/convention/compchem/constraints/initialization_at_most_one_molecule'
25
+ autoload :InitializationAtMostOneParameterList,
26
+ 'chemicalml/convention/compchem/constraints/initialization_at_most_one_parameter_list'
27
+ autoload :InitializationMustNotContainProperty,
28
+ 'chemicalml/convention/compchem/constraints/initialization_must_not_contain_property'
29
+ autoload :FinalizationAtMostOneMolecule,
30
+ 'chemicalml/convention/compchem/constraints/finalization_at_most_one_molecule'
31
+ autoload :FinalizationAtMostOnePropertyList,
32
+ 'chemicalml/convention/compchem/constraints/finalization_at_most_one_property_list'
33
+ autoload :FinalizationMustNotContainParameter,
34
+ 'chemicalml/convention/compchem/constraints/finalization_must_not_contain_parameter'
35
+ autoload :EnvironmentAtMostOnePropertyList,
36
+ 'chemicalml/convention/compchem/constraints/environment_at_most_one_property_list'
37
+ autoload :EnvironmentMustNotContainParameter,
38
+ 'chemicalml/convention/compchem/constraints/environment_must_not_contain_parameter'
39
+ autoload :ScalarUnits,
40
+ 'chemicalml/convention/compchem/constraints/scalar_units'
41
+ autoload :ArrayRules,
42
+ 'chemicalml/convention/compchem/constraints/array_rules'
43
+ autoload :MatrixRules,
44
+ 'chemicalml/convention/compchem/constraints/matrix_rules'
11
45
  end
12
46
  end
13
47
  end
@@ -23,6 +23,22 @@ module Chemicalml
23
23
 
24
24
  register Constraints::CompchemModuleMustContainJobList
25
25
  register Constraints::JobMustContainInitialization
26
+ register Constraints::JobListModuleMustHaveId
27
+ register Constraints::JobModuleMustHaveId
28
+ register Constraints::JobModuleAtMostOneFinalization
29
+ register Constraints::JobModuleAtMostOneEnvironment
30
+ register Constraints::CalculationRequiresFinalization
31
+ register Constraints::InitializationAtMostOneMolecule
32
+ register Constraints::InitializationAtMostOneParameterList
33
+ register Constraints::InitializationMustNotContainProperty
34
+ register Constraints::FinalizationAtMostOneMolecule
35
+ register Constraints::FinalizationAtMostOnePropertyList
36
+ register Constraints::FinalizationMustNotContainParameter
37
+ register Constraints::EnvironmentAtMostOnePropertyList
38
+ register Constraints::EnvironmentMustNotContainParameter
39
+ register Constraints::ScalarUnits
40
+ register Constraints::ArrayRules
41
+ register Constraints::MatrixRules
26
42
  end
27
43
  end
28
44
  end
@@ -3,26 +3,37 @@
3
3
  module Chemicalml
4
4
  module Convention
5
5
  # Abstract base class for a single constraint. Subclasses implement
6
- # `check_node` (one node at a time) or `check_document` (whole
7
- # document at once). The base class provides traversal and
8
- # collection plumbing.
6
+ # `check_node` (one node at a time) or `check` (whole document).
9
7
  #
10
- # To add a new constraint:
11
- #
12
- # 1. Subclass `Constraint::NodeConstraint` or
13
- # `Constraint::DocumentConstraint`
14
- # 2. Implement `check_node` / `check_document`
15
- # 3. Register it on the convention: `register(MyConstraint)`
16
- #
17
- # No framework code changes.
8
+ # A constraint subclass MAY declare `applies_to` — one or more
9
+ # `Cml::Role::*` modules. When it does, the Coordinator only
10
+ # invokes `check_node` for nodes matching that role. Without
11
+ # `applies_to`, the constraint receives every node (legacy
12
+ # behaviour). Declaring `applies_to` is the fast path: the
13
+ # dispatch is O(node.ancestors) per node, not O(constraint_count).
18
14
  class Constraint
19
- def self.name_for_display
20
- to_s.split("::").last
15
+ class << self
16
+ # Returns the Role module(s) this constraint applies to, or
17
+ # nil if it must run for every node.
18
+ def applies_to_roles
19
+ @applies_to_roles
20
+ end
21
+
22
+ # Declare one or more Role modules this constraint handles.
23
+ # applies_to Chemicalml::Cml::Role::Atom
24
+ # applies_to Chemicalml::Cml::Role::Bond, Chemicalml::Cml::Role::AtomParity
25
+ def applies_to(*roles)
26
+ @applies_to_roles = roles.flatten.freeze
27
+ end
28
+ end
29
+
30
+ def initialize
31
+ freeze
21
32
  end
22
33
 
23
34
  def check(_document)
24
35
  raise NotImplementedError,
25
- "#{self.class.name_for_display} must implement #check(document)"
36
+ "#{self.class} must implement #check(document)"
26
37
  end
27
38
 
28
39
  protected
@@ -54,8 +65,9 @@ module Chemicalml
54
65
  id_value ? "#{node.element_name}[#{id_value}]" : node.element_name
55
66
  end
56
67
 
57
- # Constraint that walks the document tree once per node and calls
58
- # `check_node(node, path)`. Subclasses get traversal for free.
68
+ # NodeConstraint: walks the document tree once per node and
69
+ # calls `check_node(node, path)`. Subclasses get traversal for
70
+ # free plus declarative role dispatch via `applies_to`.
59
71
  class NodeConstraint < Constraint
60
72
  def check(document)
61
73
  violations = []
@@ -70,8 +82,9 @@ module Chemicalml
70
82
  end
71
83
  end
72
84
 
73
- # Constraint that operates on the whole document at once — used
74
- # for cross-cutting rules like "atom ids unique within molecule".
85
+ # DocumentConstraint: operates on the whole document at once —
86
+ # used for cross-cutting rules like "atom ids unique within
87
+ # molecule". Walks the tree itself; not subject to dispatch.
75
88
  class DocumentConstraint < Constraint
76
89
  end
77
90
  end