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
@@ -5,13 +5,13 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class BondMustHaveAtomRefs2 < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Bond
8
9
  def check_node(node, path)
9
- return [] unless node.is_a?(Chemicalml::Cml::Role::Bond)
10
10
 
11
11
  return [] unless node.atom_refs2.to_s.strip.empty?
12
12
 
13
- [violation(path: path.empty? ? "bond" : path.join("/"),
14
- message: "bond must have an atomRefs2 attribute")]
13
+ [violation(path: path.empty? ? 'bond' : path.join('/'),
14
+ message: 'bond must have an atomRefs2 attribute')]
15
15
  end
16
16
  end
17
17
  end
@@ -5,13 +5,13 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class BondMustHaveOrder < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Bond
8
9
  def check_node(node, path)
9
- return [] unless node.is_a?(Chemicalml::Cml::Role::Bond)
10
10
 
11
11
  return [] unless node.order.to_s.strip.empty?
12
12
 
13
- [violation(path: path.empty? ? "bond" : path.join("/"),
14
- message: "bond must have an order attribute")]
13
+ [violation(path: path.empty? ? 'bond' : path.join('/'),
14
+ message: 'bond must have an order attribute')]
15
15
  end
16
16
  end
17
17
  end
@@ -18,7 +18,7 @@ module Chemicalml
18
18
  next if missing.empty?
19
19
 
20
20
  violations << violation(
21
- path: path.empty? ? "molecule[#{node.id}]" : path.join("/"),
21
+ path: path.empty? ? "molecule[#{node.id}]" : path.join('/'),
22
22
  message: "bond #{bond.id.inspect} references atoms not in the same molecule: #{missing.inspect}"
23
23
  )
24
24
  end
@@ -35,7 +35,7 @@ module Chemicalml
35
35
  def atom_ids_within(molecule)
36
36
  return [] unless molecule.atom_array
37
37
 
38
- (molecule.atom_array.atoms || []).map { |a| a.id }
38
+ (molecule.atom_array.atoms || []).map(&:id)
39
39
  end
40
40
 
41
41
  def bonds_within(molecule)
@@ -45,7 +45,7 @@ module Chemicalml
45
45
  end
46
46
 
47
47
  def atom_refs_of(bond)
48
- bond.atom_refs2.to_s.split(" ")
48
+ bond.atom_refs2.to_s.split
49
49
  end
50
50
  end
51
51
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: `<bond>` with `order="other"` MUST
8
+ # have a `dictRef` pointing to the dictionary that defines
9
+ # the order semantics. The warning-level "should not be
10
+ # numeric" rule is separate; this is the hard error.
11
+ class BondOrderOtherMustHaveDictRef < Chemicalml::Convention::Constraint::NodeConstraint
12
+ applies_to Chemicalml::Cml::Role::Bond
13
+ def check_node(node, path)
14
+ return [] unless node.order.to_s.downcase == 'other'
15
+ return [] unless node.dict_ref.to_s.empty?
16
+
17
+ [violation(
18
+ path: (path + [describe(node)]).join('/'),
19
+ message: "bond order 'other' must have a dictRef " \
20
+ 'identifying the dictionary entry that defines it'
21
+ )]
22
+ end
23
+
24
+ private
25
+
26
+ def bond?(node)
27
+ node.is_a?(Chemicalml::Cml::Role::Bond)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -5,17 +5,17 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class BondOrderShouldNotBeNumeric < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Bond
8
9
  VALID_ORDERS = %w[S D T Q A other].freeze
9
10
 
10
11
  def check_node(node, path)
11
- return [] unless node.is_a?(Chemicalml::Cml::Role::Bond)
12
12
 
13
13
  order = node.order.to_s
14
14
  return [] if order.empty?
15
15
 
16
16
  return [] if VALID_ORDERS.include?(order) || node.dict_ref.to_s.size.positive?
17
17
 
18
- [violation(path: path.empty? ? "bond" : path.join("/"),
18
+ [violation(path: path.empty? ? 'bond' : path.join('/'),
19
19
  message: "bond order #{order.inspect} is not recommended " \
20
20
  "(use S/D/T/Q/A or 'other' with dictRef)",
21
21
  severity: :warning)]
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: `<bondStereo>` value C (cis) or T
8
+ # (trans) MUST have `atomRefs4` and MUST NOT have `atomRefs2`.
9
+ class BondStereoCisTransMustHaveAtomRefs4 < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::BondStereo
11
+ CIS_TRANS_VALUES = %w[C T].freeze
12
+
13
+ def check_node(node, path)
14
+
15
+ value = node.content.to_s.upcase
16
+ return [] unless CIS_TRANS_VALUES.include?(value)
17
+
18
+ violations = []
19
+ if node.atom_refs4.to_s.strip.empty?
20
+ violations << violation(
21
+ path: (path + [describe(node)]).join('/'),
22
+ message: "bondStereo value #{value.inspect} must have atomRefs4 " \
23
+ '(four atom ids; two must match the parent bond)'
24
+ )
25
+ end
26
+ unless node.atom_refs2.to_s.strip.empty?
27
+ violations << violation(
28
+ path: (path + [describe(node)]).join('/'),
29
+ message: "bondStereo value #{value.inspect} must not have atomRefs2 " \
30
+ '(only W/H wedge/hatch values use atomRefs2)'
31
+ )
32
+ end
33
+ violations
34
+ end
35
+
36
+ private
37
+
38
+ def bond_stereo?(node)
39
+ node.is_a?(Chemicalml::Cml::Role::BondStereo)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: `<bondStereo>` with value `other`
8
+ # MUST have a `dictRef` pointing to the convention that
9
+ # defines the stereo semantics.
10
+ class BondStereoOtherMustHaveDictRef < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::BondStereo
12
+ def check_node(node, path)
13
+ return [] unless node.content.to_s.downcase == 'other'
14
+ return [] unless node.dict_ref.to_s.empty?
15
+
16
+ [violation(
17
+ path: (path + [describe(node)]).join('/'),
18
+ message: "bondStereo value 'other' must have a dictRef " \
19
+ 'identifying the convention that defines it'
20
+ )]
21
+ end
22
+
23
+ private
24
+
25
+ def bond_stereo?(node)
26
+ node.is_a?(Chemicalml::Cml::Role::BondStereo)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: `<bondStereo>` value W (wedge) or H
8
+ # (hatch) MUST have `atomRefs2` and MUST NOT have `atomRefs4`.
9
+ class BondStereoWedgeHashMustHaveAtomRefs2 < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::BondStereo
11
+ WEDGE_HASH_VALUES = %w[W H].freeze
12
+
13
+ def check_node(node, path)
14
+
15
+ value = node.content.to_s.upcase
16
+ return [] unless WEDGE_HASH_VALUES.include?(value)
17
+
18
+ violations = []
19
+ if node.atom_refs2.to_s.strip.empty?
20
+ violations << violation(
21
+ path: (path + [describe(node)]).join('/'),
22
+ message: "bondStereo value #{value.inspect} must have atomRefs2 " \
23
+ '(first atom = sharp end, second = blunt end)'
24
+ )
25
+ end
26
+ unless node.atom_refs4.to_s.strip.empty?
27
+ violations << violation(
28
+ path: (path + [describe(node)]).join('/'),
29
+ message: "bondStereo value #{value.inspect} must not have atomRefs4 " \
30
+ '(only C/T cis-trans values use atomRefs4)'
31
+ )
32
+ end
33
+ violations
34
+ end
35
+
36
+ private
37
+
38
+ def bond_stereo?(node)
39
+ node.is_a?(Chemicalml::Cml::Role::BondStereo)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: a `<molecule>` MAY hold an `atomArray`
8
+ # OR child `<molecule>` elements, but not both. The two are
9
+ # mutually exclusive ways of describing composition.
10
+ class MoleculeAtomArrayMutuallyExclusiveWithChildren < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Molecule
12
+ def check_node(node, path)
13
+ return [] if node.atom_array.nil?
14
+ return [] if (node.molecules || []).empty?
15
+
16
+ [violation(
17
+ path: (path + [describe(node)]).join('/'),
18
+ message: "molecule #{node.id.inspect} has both an atomArray " \
19
+ 'and child molecule elements — these are mutually exclusive'
20
+ )]
21
+ end
22
+
23
+ private
24
+
25
+ def molecule?(node)
26
+ node.is_a?(Chemicalml::Cml::Role::Molecule)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: a `<molecule>` MAY hold a `bondArray`
8
+ # OR child `<molecule>` elements, but not both.
9
+ class MoleculeBondArrayMutuallyExclusiveWithChildren < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Molecule
11
+ def check_node(node, path)
12
+ return [] if node.bond_array.nil?
13
+ return [] if (node.molecules || []).empty?
14
+
15
+ [violation(
16
+ path: (path + [describe(node)]).join('/'),
17
+ message: "molecule #{node.id.inspect} has both a bondArray " \
18
+ 'and child molecule elements — these are mutually exclusive'
19
+ )]
20
+ end
21
+
22
+ private
23
+
24
+ def molecule?(node)
25
+ node.is_a?(Chemicalml::Cml::Role::Molecule)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Molecular
6
+ module Constraints
7
+ # Molecular convention: `count` MUST NOT appear on top-level
8
+ # molecules (direct children of `<cml>`). It is REQUIRED on
9
+ # molecules nested inside another `<molecule>`.
10
+ class MoleculeCountMustNotAppearOnTopLevel < Chemicalml::Convention::Constraint::DocumentConstraint
11
+ def check(document)
12
+ violations = []
13
+ top_level_molecules(document).each do |mol, path|
14
+ next if mol.count.to_s.empty?
15
+
16
+ violations << violation(
17
+ path: (path + [describe(mol)]).join('/'),
18
+ message: "top-level molecule #{mol.id.inspect} must not have " \
19
+ 'a count attribute (only nested molecules may carry count)'
20
+ )
21
+ end
22
+ violations
23
+ end
24
+
25
+ private
26
+
27
+ def top_level_molecules(document)
28
+ (document.molecules || []).map { |m| [m, []] }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -5,13 +5,13 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class MoleculeMustHaveId < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Molecule
8
9
  def check_node(node, path)
9
- return [] unless node.is_a?(Chemicalml::Cml::Role::Molecule)
10
10
 
11
11
  return [] unless node.id.to_s.empty?
12
12
 
13
- [violation(path: path.empty? ? "molecule" : path.join("/"),
14
- message: "molecule must have an id attribute")]
13
+ [violation(path: path.empty? ? 'molecule' : path.join('/'),
14
+ message: 'molecule must have an id attribute')]
15
15
  end
16
16
  end
17
17
  end
@@ -5,13 +5,13 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class PropertyMustHaveDictRef < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Property
8
9
  def check_node(node, path)
9
- return [] unless node.is_a?(Chemicalml::Cml::Role::Property)
10
10
 
11
11
  return [] unless node.dict_ref.to_s.empty?
12
12
 
13
- [violation(path: path.empty? ? "property" : path.join("/"),
14
- message: "property must have a dictRef attribute")]
13
+ [violation(path: path.empty? ? 'property' : path.join('/'),
14
+ message: 'property must have a dictRef attribute')]
15
15
  end
16
16
  end
17
17
  end
@@ -5,13 +5,13 @@ module Chemicalml
5
5
  module Molecular
6
6
  module Constraints
7
7
  class ScalarMustHaveDataType < Chemicalml::Convention::Constraint::NodeConstraint
8
+ applies_to Chemicalml::Cml::Role::Scalar
8
9
  def check_node(node, path)
9
- return [] unless node.is_a?(Chemicalml::Cml::Role::Scalar)
10
10
 
11
11
  return [] unless node.data_type.to_s.empty?
12
12
 
13
- [violation(path: path.empty? ? "scalar" : path.join("/"),
14
- message: "scalar must have a dataType attribute")]
13
+ [violation(path: path.empty? ? 'scalar' : path.join('/'),
14
+ message: 'scalar must have a dataType attribute')]
15
15
  end
16
16
  end
17
17
  end
@@ -30,6 +30,26 @@ module Chemicalml
30
30
  "chemicalml/convention/molecular/constraints/bond_order_should_not_be_numeric"
31
31
  autoload :AtomIdMustMatchPattern,
32
32
  "chemicalml/convention/molecular/constraints/atom_id_must_match_pattern"
33
+ autoload :MoleculeCountMustNotAppearOnTopLevel,
34
+ "chemicalml/convention/molecular/constraints/molecule_count_must_not_appear_on_top_level"
35
+ autoload :MoleculeAtomArrayMutuallyExclusiveWithChildren,
36
+ "chemicalml/convention/molecular/constraints/molecule_atom_array_mutually_exclusive_with_children"
37
+ autoload :MoleculeBondArrayMutuallyExclusiveWithChildren,
38
+ "chemicalml/convention/molecular/constraints/molecule_bond_array_mutually_exclusive_with_children"
39
+ autoload :BondStereoWedgeHashMustHaveAtomRefs2,
40
+ "chemicalml/convention/molecular/constraints/bond_stereo_wedge_hash_must_have_atom_refs2"
41
+ autoload :BondStereoCisTransMustHaveAtomRefs4,
42
+ "chemicalml/convention/molecular/constraints/bond_stereo_cis_trans_must_have_atom_refs4"
43
+ autoload :BondStereoOtherMustHaveDictRef,
44
+ "chemicalml/convention/molecular/constraints/bond_stereo_other_must_have_dict_ref"
45
+ autoload :BondIdsUniqueWithinMolecule,
46
+ "chemicalml/convention/molecular/constraints/bond_ids_unique_within_molecule"
47
+ autoload :BondOrderOtherMustHaveDictRef,
48
+ "chemicalml/convention/molecular/constraints/bond_order_other_must_have_dict_ref"
49
+ autoload :AtomArrayMustBeChildOfMoleculeOrFormula,
50
+ "chemicalml/convention/molecular/constraints/atom_array_must_be_child_of_molecule_or_formula"
51
+ autoload :BondArrayMustBeChildOfMolecule,
52
+ "chemicalml/convention/molecular/constraints/bond_array_must_be_child_of_molecule"
33
53
  end
34
54
  end
35
55
  end
@@ -34,6 +34,16 @@ module Chemicalml
34
34
  register Constraints::ScalarMustHaveDataType
35
35
  register Constraints::BondOrderShouldNotBeNumeric
36
36
  register Constraints::AtomIdMustMatchPattern
37
+ register Constraints::MoleculeCountMustNotAppearOnTopLevel
38
+ register Constraints::MoleculeAtomArrayMutuallyExclusiveWithChildren
39
+ register Constraints::MoleculeBondArrayMutuallyExclusiveWithChildren
40
+ register Constraints::BondStereoWedgeHashMustHaveAtomRefs2
41
+ register Constraints::BondStereoCisTransMustHaveAtomRefs4
42
+ register Constraints::BondStereoOtherMustHaveDictRef
43
+ register Constraints::BondIdsUniqueWithinMolecule
44
+ register Constraints::BondOrderOtherMustHaveDictRef
45
+ register Constraints::AtomArrayMustBeChildOfMoleculeOrFormula
46
+ register Constraints::BondArrayMustBeChildOfMolecule
37
47
  end
38
48
  end
39
49
  end
@@ -23,6 +23,23 @@ module Chemicalml
23
23
  convention.validate(document)
24
24
  end
25
25
 
26
+ def self.validate_report(document, qname:)
27
+ convention = lookup(qname)
28
+ raise ArgumentError, "unknown convention: #{qname.inspect}" unless convention
29
+
30
+ convention.validate_report(document)
31
+ end
32
+
33
+ # Detect the convention from the document's root `convention`
34
+ # attribute and validate. Raises ArgumentError if the document
35
+ # declares no convention or an unknown one.
36
+ def self.detect_and_validate(document)
37
+ qname = Convention::Detection.convention_of(document)
38
+ raise ArgumentError, "document declares no convention attribute" unless qname
39
+
40
+ validate_report(document, qname: qname)
41
+ end
42
+
26
43
  def self.builtin_qnames
27
44
  load_cache.keys.sort
28
45
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module UnitDictionary
6
+ module Constraints
7
+ # A `<unitList>` element MUST contain one or more `<unit>`
8
+ # children, and MUST NOT contain any other CML-namespace
9
+ # child elements.
10
+ class UnitListMustContainAtLeastOneUnit < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::UnitList
12
+ def check_node(node, path)
13
+ return [] if (node.units || []).length.positive?
14
+
15
+ [violation(path: path.join('/'),
16
+ message: 'unitList must contain at least one unit child')]
17
+ end
18
+
19
+ private
20
+
21
+ def unit_list?(node)
22
+ node.is_a?(Chemicalml::Cml::Role::UnitList)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module UnitDictionary
6
+ module Constraints
7
+ # A `<unitList>` element MUST have a `namespace` attribute
8
+ # whose value is a valid URI defining the scope within which
9
+ # the unit ids are unique. SHOULD end with `/` or `#`.
10
+ class UnitListMustHaveNamespace < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::UnitList
12
+ def check_node(node, path)
13
+
14
+ violations = []
15
+ ns = node.namespace.to_s
16
+ if ns.empty?
17
+ violations << violation(path: path.join('/'),
18
+ message: 'unitList must have a namespace attribute')
19
+ elsif !ns.end_with?('/', '#')
20
+ violations << violation(path: path.join('/'),
21
+ message: "unitList namespace #{ns.inspect} should end with / or #",
22
+ severity: :warning)
23
+ end
24
+ violations
25
+ end
26
+
27
+ private
28
+
29
+ def unit_list?(node)
30
+ node.is_a?(Chemicalml::Cml::Role::UnitList)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module UnitDictionary
6
+ module Constraints
7
+ # A `<unit>` element MUST contain a single `<definition>`
8
+ # child element with XHTML content.
9
+ class UnitMustContainDefinition < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Unit
11
+ def check_node(node, path)
12
+ return [] unless node.definition.to_s.strip.empty?
13
+
14
+ [violation(path: path.join('/'),
15
+ message: "unit #{node.id.inspect} must contain a single definition child")]
16
+ end
17
+
18
+ private
19
+
20
+ def unit?(node)
21
+ node.is_a?(Chemicalml::Cml::Role::Unit)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module UnitDictionary
6
+ module Constraints
7
+ # A `<unit>` element MUST have an `id` attribute, unique
8
+ # within the unitList.
9
+ class UnitMustHaveId < Chemicalml::Convention::Constraint::NodeConstraint
10
+ applies_to Chemicalml::Cml::Role::Unit
11
+ def check_node(node, path)
12
+ return [] unless node.id.to_s.empty?
13
+
14
+ [violation(path: path.join('/'),
15
+ message: 'unit must have an id attribute unique within the unitList')]
16
+ end
17
+
18
+ private
19
+
20
+ def unit?(node)
21
+ node.is_a?(Chemicalml::Cml::Role::Unit)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -8,22 +8,22 @@ module Chemicalml
8
8
  # at least one of `multiplierToSI`/`constantToSI`, and
9
9
  # `unitType` per the unit-dictionary convention.
10
10
  class UnitMustHaveSymbolAndUnitType < Chemicalml::Convention::Constraint::NodeConstraint
11
+ applies_to Chemicalml::Cml::Role::Unit
11
12
  REQUIRED = %i[title symbol parent_si unit_type].freeze
12
13
 
13
14
  def check_node(node, path)
14
- return [] unless unit?(node)
15
15
 
16
16
  violations = []
17
17
  REQUIRED.each do |attr|
18
18
  val = node.public_send(attr)
19
19
  next unless val.to_s.empty?
20
20
 
21
- violations << violation(path: path.join("/"),
21
+ violations << violation(path: path.join('/'),
22
22
  message: "unit must have #{attr} (id=#{node.id.inspect})")
23
23
  end
24
24
 
25
25
  unless has_si_conversion?(node)
26
- violations << violation(path: path.join("/"),
26
+ violations << violation(path: path.join('/'),
27
27
  message: "unit must have multiplierToSI or constantToSI (id=#{node.id.inspect})")
28
28
  end
29
29
 
@@ -5,7 +5,15 @@ module Chemicalml
5
5
  module UnitDictionary
6
6
  module Constraints
7
7
  autoload :UnitMustHaveSymbolAndUnitType,
8
- "chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type"
8
+ 'chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type'
9
+ autoload :UnitMustHaveId,
10
+ 'chemicalml/convention/unit_dictionary/constraints/unit_must_have_id'
11
+ autoload :UnitMustContainDefinition,
12
+ 'chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition'
13
+ autoload :UnitListMustHaveNamespace,
14
+ 'chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace'
15
+ autoload :UnitListMustContainAtLeastOneUnit,
16
+ 'chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit'
9
17
  end
10
18
  end
11
19
  end
@@ -22,6 +22,10 @@ module Chemicalml
22
22
  end
23
23
 
24
24
  register Constraints::UnitMustHaveSymbolAndUnitType
25
+ register Constraints::UnitMustHaveId
26
+ register Constraints::UnitMustContainDefinition
27
+ register Constraints::UnitListMustHaveNamespace
28
+ register Constraints::UnitListMustContainAtLeastOneUnit
25
29
  end
26
30
  end
27
31
  end