chemicalml 0.2.0 → 0.3.0

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 (450) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +7 -1
  3. data/.rubocop.yml +23 -0
  4. data/CLAUDE.md +95 -40
  5. data/README.adoc +154 -26
  6. data/TODO.align/36-molecular-convention-coverage.md +46 -0
  7. data/TODO.align/37-compchem-convention-coverage.md +55 -0
  8. data/TODO.align/38-dictionary-convention-coverage.md +34 -0
  9. data/TODO.align/39-unit-dictionary-convention-coverage.md +33 -0
  10. data/TODO.align/40-unit-type-dictionary-convention-coverage.md +28 -0
  11. data/TODO.align/41-expand-canonical-model-layer.md +43 -0
  12. data/TODO.align/42-translator-wire-new-models.md +31 -0
  13. data/TODO.align/43-dictionary-model-no-to-h.md +39 -0
  14. data/TODO.align/44-schema3-only-and-schema24-module.md +44 -0
  15. data/TODO.align/45-documentation-and-final-verification.md +23 -0
  16. data/TODO.align/46-lattice-vector-content.md +24 -0
  17. data/TODO.align/47-molecule-crystal-spectra-property-lists.md +23 -0
  18. data/TODO.align/48-model-list-and-module-lists.md +21 -0
  19. data/TODO.align/49-more-chemistry-models.md +34 -0
  20. data/TODO.align/50-validation-report.md +29 -0
  21. data/TODO.align/51-convention-auto-detection.md +30 -0
  22. data/TODO.align/52-schema24-legacy-elements.md +28 -0
  23. data/TODO.align/53-round-trip-integration-specs.md +30 -0
  24. data/TODO.align/54-document-versioned-parser-shim.md +38 -0
  25. data/TODO.align/55-molecule-missing-attributes.md +20 -0
  26. data/TODO.align/56-geometry-models.md +24 -0
  27. data/TODO.align/57-compchem-models.md +26 -0
  28. data/TODO.align/58-remaining-models.md +24 -0
  29. data/TODO.align/59-wire-new-models-translator.md +18 -0
  30. data/TODO.align/60-docs-and-final-verification.md +19 -0
  31. data/TODO.align/61-parallel-array-attrs.md +54 -0
  32. data/TODO.align/62-per-element-attribute-gaps.md +49 -0
  33. data/TODO.align/63-universal-children-mixin.md +42 -0
  34. data/TODO.align/64-per-element-child-gaps.md +81 -0
  35. data/TODO.align/65-simple-unit-convention.md +40 -0
  36. data/TODO.align/66-schema24-legacy-children.md +32 -0
  37. data/TODO.align/67-final-verification.md +32 -0
  38. data/TODO.align/68-detection-coverage.md +33 -0
  39. data/TODO.align/69-json-yaml-roundtrip.md +27 -0
  40. data/TODO.align/70-iterative-walker.md +40 -0
  41. data/TODO.align/71-violation-value.md +25 -0
  42. data/TODO.align/72-close-child-gaps.md +66 -0
  43. data/TODO.align/73-schema24-parse-limitation.md +64 -0
  44. data/TODO.align/74-final-verification-round18.md +15 -0
  45. data/TODO.align/75-key-value-mappings.md +43 -0
  46. data/TODO.align/76-schema24-workaround.md +57 -0
  47. data/TODO.align/77-convention-coverage-matrix.md +31 -0
  48. data/TODO.align/78-fixture-audit.md +23 -0
  49. data/TODO.align/79-final-verification-round19.md +15 -0
  50. data/TODO.align/80-xsd-enum-constants.md +35 -0
  51. data/TODO.align/81-enum-validation-constraints.md +29 -0
  52. data/TODO.align/82-reference-resolver.md +33 -0
  53. data/TODO.align/83-toml-roundtrip.md +20 -0
  54. data/TODO.align/84-final-verification-round21.md +16 -0
  55. data/TODO.align/85-bond-distinct-atoms.md +25 -0
  56. data/TODO.align/86-references-should-resolve.md +20 -0
  57. data/TODO.align/87-cli-utility.md +26 -0
  58. data/TODO.align/88-diverse-fixtures.md +26 -0
  59. data/TODO.align/89-final-verification-round22.md +15 -0
  60. data/TODO.align/90-bond-stereo-completeness.md +31 -0
  61. data/TODO.align/91-atomparity-distinct.md +21 -0
  62. data/TODO.align/92-unit-dictionary-completeness.md +28 -0
  63. data/TODO.align/93-yard-docs.md +23 -0
  64. data/TODO.align/94-final-verification-round23.md +15 -0
  65. data/TODO.align/README.round17.md +28 -0
  66. data/TODO.align/README.round18.md +37 -0
  67. data/TODO.align/README.round19.md +40 -0
  68. data/TODO.align/README.round20.md +49 -0
  69. data/TODO.align/README.round21.md +35 -0
  70. data/TODO.align/README.round22.md +48 -0
  71. data/TODO.align/README.round23.md +46 -0
  72. data/TODO.align/README.round24.md +53 -0
  73. data/TODO.align/README.round25.md +66 -0
  74. data/TODO.align/README.round26.md +55 -0
  75. data/TODO.align/README.round27.md +51 -0
  76. data/TODO.align/README.round28.md +61 -0
  77. data/TODO.align/README.round29.md +64 -0
  78. data/TODO.align/README.round30.md +50 -0
  79. data/TODO.align/README.round31.md +54 -0
  80. data/TODO.align/README.round32.md +67 -0
  81. data/TODO.align/README.round33.md +62 -0
  82. data/TODO.align/README.round34.md +70 -0
  83. data/docs/constraints.md +161 -0
  84. data/docs/generate_constraint_docs.rb +44 -0
  85. data/exe/chemicalml +6 -0
  86. data/lib/chemicalml/cli/base.rb +68 -0
  87. data/lib/chemicalml/cli/command.rb +43 -0
  88. data/lib/chemicalml/cli/constraints_command.rb +27 -0
  89. data/lib/chemicalml/cli/conventions_command.rb +14 -0
  90. data/lib/chemicalml/cli/dictionaries_command.rb +14 -0
  91. data/lib/chemicalml/cli/elements_command.rb +17 -0
  92. data/lib/chemicalml/cli/enums_command.rb +17 -0
  93. data/lib/chemicalml/cli/info_command.rb +77 -0
  94. data/lib/chemicalml/cli/inspect_command.rb +39 -0
  95. data/lib/chemicalml/cli/validate_command.rb +54 -0
  96. data/lib/chemicalml/cli.rb +43 -0
  97. data/lib/chemicalml/cml/base/abundance.rb +21 -5
  98. data/lib/chemicalml/cml/base/action.rb +44 -6
  99. data/lib/chemicalml/cml/base/action_list.rb +44 -8
  100. data/lib/chemicalml/cml/base/alternative.rb +37 -0
  101. data/lib/chemicalml/cml/base/amount.rb +15 -5
  102. data/lib/chemicalml/cml/base/angle.rb +34 -7
  103. data/lib/chemicalml/cml/base/annotation.rb +38 -0
  104. data/lib/chemicalml/cml/base/any_cml.rb +12 -5
  105. data/lib/chemicalml/cml/base/appinfo.rb +40 -0
  106. data/lib/chemicalml/cml/base/arg.rb +80 -0
  107. data/lib/chemicalml/cml/base/array.rb +51 -8
  108. data/lib/chemicalml/cml/base/array_list.rb +15 -5
  109. data/lib/chemicalml/cml/base/atom.rb +93 -19
  110. data/lib/chemicalml/cml/base/atom_array.rb +77 -2
  111. data/lib/chemicalml/cml/base/atom_parity.rb +18 -2
  112. data/lib/chemicalml/cml/base/atom_set.rb +15 -5
  113. data/lib/chemicalml/cml/base/atom_type.rb +27 -7
  114. data/lib/chemicalml/cml/base/atom_type_list.rb +23 -7
  115. data/lib/chemicalml/cml/base/atomic_basis_function.rb +35 -11
  116. data/lib/chemicalml/cml/base/band.rb +22 -7
  117. data/lib/chemicalml/cml/base/band_list.rb +15 -7
  118. data/lib/chemicalml/cml/base/basis_set.rb +26 -7
  119. data/lib/chemicalml/cml/base/bond.rb +39 -7
  120. data/lib/chemicalml/cml/base/bond_array.rb +41 -2
  121. data/lib/chemicalml/cml/base/bond_set.rb +15 -5
  122. data/lib/chemicalml/cml/base/bond_stereo.rb +25 -4
  123. data/lib/chemicalml/cml/base/bond_type.rb +24 -7
  124. data/lib/chemicalml/cml/base/bond_type_list.rb +23 -7
  125. data/lib/chemicalml/cml/base/cell_parameter.rb +30 -8
  126. data/lib/chemicalml/cml/base/cml_module.rb +36 -11
  127. data/lib/chemicalml/cml/base/common_children.rb +35 -0
  128. data/lib/chemicalml/cml/base/complex_object.rb +37 -0
  129. data/lib/chemicalml/cml/base/condition_list.rb +28 -8
  130. data/lib/chemicalml/cml/base/crystal.rb +27 -9
  131. data/lib/chemicalml/cml/base/definition.rb +12 -5
  132. data/lib/chemicalml/cml/base/description.rb +15 -5
  133. data/lib/chemicalml/cml/base/dictionary.rb +30 -7
  134. data/lib/chemicalml/cml/base/dictionary_entry.rb +67 -8
  135. data/lib/chemicalml/cml/base/dimension.rb +31 -7
  136. data/lib/chemicalml/cml/base/document.rb +18 -8
  137. data/lib/chemicalml/cml/base/documentation.rb +12 -5
  138. data/lib/chemicalml/cml/base/eigen.rb +33 -7
  139. data/lib/chemicalml/cml/base/electron.rb +29 -9
  140. data/lib/chemicalml/cml/base/enumeration.rb +41 -0
  141. data/lib/chemicalml/cml/base/expression.rb +47 -0
  142. data/lib/chemicalml/cml/base/float.rb +52 -0
  143. data/lib/chemicalml/cml/base/float_array.rb +55 -0
  144. data/lib/chemicalml/cml/base/formula.rb +31 -10
  145. data/lib/chemicalml/cml/base/fragment.rb +33 -9
  146. data/lib/chemicalml/cml/base/fragment_list.rb +26 -7
  147. data/lib/chemicalml/cml/base/gradient.rb +19 -6
  148. data/lib/chemicalml/cml/base/identifier.rb +22 -4
  149. data/lib/chemicalml/cml/base/integer.rb +52 -0
  150. data/lib/chemicalml/cml/base/integer_array.rb +55 -0
  151. data/lib/chemicalml/cml/base/isotope.rb +29 -8
  152. data/lib/chemicalml/cml/base/isotope_list.rb +18 -7
  153. data/lib/chemicalml/cml/base/join.rb +28 -6
  154. data/lib/chemicalml/cml/base/kpoint.rb +17 -6
  155. data/lib/chemicalml/cml/base/kpoint_list.rb +15 -7
  156. data/lib/chemicalml/cml/base/label.rb +15 -5
  157. data/lib/chemicalml/cml/base/lattice.rb +36 -9
  158. data/lib/chemicalml/cml/base/lattice_vector.rb +17 -6
  159. data/lib/chemicalml/cml/base/length.rb +31 -7
  160. data/lib/chemicalml/cml/base/line3.rb +21 -5
  161. data/lib/chemicalml/cml/base/link.rb +51 -10
  162. data/lib/chemicalml/cml/base/list.rb +23 -9
  163. data/lib/chemicalml/cml/base/map.rb +38 -5
  164. data/lib/chemicalml/cml/base/matrix.rb +38 -9
  165. data/lib/chemicalml/cml/base/mechanism.rb +20 -7
  166. data/lib/chemicalml/cml/base/mechanism_component.rb +14 -6
  167. data/lib/chemicalml/cml/base/metadata.rb +20 -6
  168. data/lib/chemicalml/cml/base/metadata_list.rb +30 -5
  169. data/lib/chemicalml/cml/base/molecule.rb +95 -21
  170. data/lib/chemicalml/cml/base/molecule_list.rb +27 -7
  171. data/lib/chemicalml/cml/base/name.rb +11 -3
  172. data/lib/chemicalml/cml/base/object.rb +20 -6
  173. data/lib/chemicalml/cml/base/observation.rb +18 -5
  174. data/lib/chemicalml/cml/base/operator.rb +40 -0
  175. data/lib/chemicalml/cml/base/parameter.rb +38 -8
  176. data/lib/chemicalml/cml/base/parameter_list.rb +30 -5
  177. data/lib/chemicalml/cml/base/particle.rb +23 -6
  178. data/lib/chemicalml/cml/base/peak.rb +86 -11
  179. data/lib/chemicalml/cml/base/peak_group.rb +81 -7
  180. data/lib/chemicalml/cml/base/peak_list.rb +25 -8
  181. data/lib/chemicalml/cml/base/peak_structure.rb +47 -6
  182. data/lib/chemicalml/cml/base/plane3.rb +15 -5
  183. data/lib/chemicalml/cml/base/point3.rb +15 -5
  184. data/lib/chemicalml/cml/base/potential.rb +17 -6
  185. data/lib/chemicalml/cml/base/potential_form.rb +31 -6
  186. data/lib/chemicalml/cml/base/potential_list.rb +15 -7
  187. data/lib/chemicalml/cml/base/product.rb +53 -2
  188. data/lib/chemicalml/cml/base/product_list.rb +36 -2
  189. data/lib/chemicalml/cml/base/property.rb +32 -8
  190. data/lib/chemicalml/cml/base/property_list.rb +26 -5
  191. data/lib/chemicalml/cml/base/reactant.rb +53 -2
  192. data/lib/chemicalml/cml/base/reactant_list.rb +36 -2
  193. data/lib/chemicalml/cml/base/reaction.rb +82 -12
  194. data/lib/chemicalml/cml/base/reaction_list.rb +29 -2
  195. data/lib/chemicalml/cml/base/reaction_scheme.rb +48 -8
  196. data/lib/chemicalml/cml/base/reaction_step.rb +33 -9
  197. data/lib/chemicalml/cml/base/reaction_step_list.rb +34 -7
  198. data/lib/chemicalml/cml/base/reactive_centre.rb +31 -6
  199. data/lib/chemicalml/cml/base/region.rb +24 -5
  200. data/lib/chemicalml/cml/base/related_entry.rb +34 -0
  201. data/lib/chemicalml/cml/base/sample.rb +32 -5
  202. data/lib/chemicalml/cml/base/scalar.rb +41 -6
  203. data/lib/chemicalml/cml/base/spectator.rb +26 -5
  204. data/lib/chemicalml/cml/base/spectator_list.rb +20 -7
  205. data/lib/chemicalml/cml/base/spectrum.rb +63 -12
  206. data/lib/chemicalml/cml/base/spectrum_data.rb +20 -8
  207. data/lib/chemicalml/cml/base/spectrum_list.rb +30 -7
  208. data/lib/chemicalml/cml/base/sphere3.rb +15 -5
  209. data/lib/chemicalml/cml/base/stmml.rb +12 -5
  210. data/lib/chemicalml/cml/base/string.rb +40 -0
  211. data/lib/chemicalml/cml/base/string_array.rb +52 -0
  212. data/lib/chemicalml/cml/base/substance.rb +42 -8
  213. data/lib/chemicalml/cml/base/substance_list.rb +32 -7
  214. data/lib/chemicalml/cml/base/symmetry.rb +33 -7
  215. data/lib/chemicalml/cml/base/system.rb +23 -8
  216. data/lib/chemicalml/cml/base/table.rb +43 -8
  217. data/lib/chemicalml/cml/base/table_cell.rb +12 -5
  218. data/lib/chemicalml/cml/base/table_content.rb +20 -8
  219. data/lib/chemicalml/cml/base/table_header.rb +15 -7
  220. data/lib/chemicalml/cml/base/table_header_cell.rb +27 -5
  221. data/lib/chemicalml/cml/base/table_row.rb +15 -7
  222. data/lib/chemicalml/cml/base/table_row_list.rb +15 -7
  223. data/lib/chemicalml/cml/base/tcell.rb +43 -0
  224. data/lib/chemicalml/cml/base/torsion.rb +34 -7
  225. data/lib/chemicalml/cml/base/transform3.rb +12 -5
  226. data/lib/chemicalml/cml/base/transition_state.rb +23 -5
  227. data/lib/chemicalml/cml/base/trow.rb +48 -0
  228. data/lib/chemicalml/cml/base/unit.rb +45 -10
  229. data/lib/chemicalml/cml/base/unit_list.rb +40 -6
  230. data/lib/chemicalml/cml/base/unit_type.rb +32 -5
  231. data/lib/chemicalml/cml/base/unit_type_list.rb +34 -6
  232. data/lib/chemicalml/cml/base/vector3.rb +15 -5
  233. data/lib/chemicalml/cml/base/xaxis.rb +33 -7
  234. data/lib/chemicalml/cml/base/yaxis.rb +33 -7
  235. data/lib/chemicalml/cml/base/z_matrix.rb +26 -5
  236. data/lib/chemicalml/cml/base.rb +139 -121
  237. data/lib/chemicalml/cml/canonical_comparison.rb +54 -0
  238. data/lib/chemicalml/cml/elements.rb +168 -124
  239. data/lib/chemicalml/cml/enums.rb +55 -0
  240. data/lib/chemicalml/cml/namespace.rb +2 -3
  241. data/lib/chemicalml/cml/patterns.rb +33 -0
  242. data/lib/chemicalml/cml/reference_resolver.rb +137 -0
  243. data/lib/chemicalml/cml/role/alternative.rb +10 -0
  244. data/lib/chemicalml/cml/role/annotation.rb +10 -0
  245. data/lib/chemicalml/cml/role/appinfo.rb +10 -0
  246. data/lib/chemicalml/cml/role/arg.rb +10 -0
  247. data/lib/chemicalml/cml/role/cml_module.rb +2 -3
  248. data/lib/chemicalml/cml/role/complex_object.rb +10 -0
  249. data/lib/chemicalml/cml/role/enumeration.rb +10 -0
  250. data/lib/chemicalml/cml/role/expression.rb +10 -0
  251. data/lib/chemicalml/cml/role/float.rb +10 -0
  252. data/lib/chemicalml/cml/role/float_array.rb +10 -0
  253. data/lib/chemicalml/cml/role/integer.rb +10 -0
  254. data/lib/chemicalml/cml/role/integer_array.rb +10 -0
  255. data/lib/chemicalml/cml/role/operator.rb +10 -0
  256. data/lib/chemicalml/cml/role/related_entry.rb +10 -0
  257. data/lib/chemicalml/cml/role/string.rb +10 -0
  258. data/lib/chemicalml/cml/role/string_array.rb +10 -0
  259. data/lib/chemicalml/cml/role/tcell.rb +10 -0
  260. data/lib/chemicalml/cml/role/trow.rb +10 -0
  261. data/lib/chemicalml/cml/role.rb +138 -121
  262. data/lib/chemicalml/cml/schema24/alternative.rb +14 -0
  263. data/lib/chemicalml/cml/schema24/annotation.rb +15 -0
  264. data/lib/chemicalml/cml/schema24/appinfo.rb +15 -0
  265. data/lib/chemicalml/cml/schema24/arg.rb +14 -0
  266. data/lib/chemicalml/cml/schema24/cml_module.rb +18 -0
  267. data/lib/chemicalml/cml/schema24/complex_object.rb +14 -0
  268. data/lib/chemicalml/cml/schema24/configuration.rb +15 -2
  269. data/lib/chemicalml/cml/schema24/enumeration.rb +16 -0
  270. data/lib/chemicalml/cml/schema24/expression.rb +14 -0
  271. data/lib/chemicalml/cml/schema24/float.rb +14 -0
  272. data/lib/chemicalml/cml/schema24/float_array.rb +14 -0
  273. data/lib/chemicalml/cml/schema24/integer.rb +14 -0
  274. data/lib/chemicalml/cml/schema24/integer_array.rb +14 -0
  275. data/lib/chemicalml/cml/schema24/operator.rb +14 -0
  276. data/lib/chemicalml/cml/schema24/related_entry.rb +14 -0
  277. data/lib/chemicalml/cml/schema24/string.rb +14 -0
  278. data/lib/chemicalml/cml/schema24/string_array.rb +14 -0
  279. data/lib/chemicalml/cml/schema24/tcell.rb +14 -0
  280. data/lib/chemicalml/cml/schema24/trow.rb +14 -0
  281. data/lib/chemicalml/cml/schema24.rb +154 -126
  282. data/lib/chemicalml/cml/schema3.rb +123 -123
  283. data/lib/chemicalml/cml/visitable.rb +77 -3
  284. data/lib/chemicalml/cml/wire_class_registry.rb +3 -3
  285. data/lib/chemicalml/cml.rb +164 -132
  286. data/lib/chemicalml/context_configuration.rb +12 -4
  287. data/lib/chemicalml/convention/base.rb +17 -3
  288. data/lib/chemicalml/convention/cascade/constraints/reaction_scheme_must_have_content.rb +33 -0
  289. data/lib/chemicalml/convention/cascade/constraints/reaction_step_list_must_contain_steps.rb +31 -0
  290. data/lib/chemicalml/convention/cascade/constraints/reaction_step_must_have_reaction_or_lists.rb +33 -0
  291. data/lib/chemicalml/convention/cascade/constraints/reactive_centre_atom_refs_should_be_present.rb +34 -0
  292. data/lib/chemicalml/convention/cascade/constraints.rb +18 -0
  293. data/lib/chemicalml/convention/cascade.rb +43 -0
  294. data/lib/chemicalml/convention/compchem/constraints/array_rules.rb +44 -0
  295. data/lib/chemicalml/convention/compchem/constraints/calculation_requires_finalization.rb +28 -0
  296. data/lib/chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list.rb +5 -4
  297. data/lib/chemicalml/convention/compchem/constraints/environment_at_most_one_property_list.rb +26 -0
  298. data/lib/chemicalml/convention/compchem/constraints/environment_must_not_contain_parameter.rb +28 -0
  299. data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_molecule.rb +26 -0
  300. data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_property_list.rb +26 -0
  301. data/lib/chemicalml/convention/compchem/constraints/finalization_must_have_content.rb +44 -0
  302. data/lib/chemicalml/convention/compchem/constraints/finalization_must_not_contain_parameter.rb +27 -0
  303. data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_molecule.rb +26 -0
  304. data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_parameter_list.rb +26 -0
  305. data/lib/chemicalml/convention/compchem/constraints/initialization_must_have_content.rb +54 -0
  306. data/lib/chemicalml/convention/compchem/constraints/initialization_must_not_contain_property.rb +28 -0
  307. data/lib/chemicalml/convention/compchem/constraints/job_list_module_must_have_id.rb +25 -0
  308. data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_environment.rb +25 -0
  309. data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_finalization.rb +25 -0
  310. data/lib/chemicalml/convention/compchem/constraints/job_module_must_have_id.rb +25 -0
  311. data/lib/chemicalml/convention/compchem/constraints/job_must_contain_initialization.rb +7 -9
  312. data/lib/chemicalml/convention/compchem/constraints/matrix_rules.rb +48 -0
  313. data/lib/chemicalml/convention/compchem/constraints/module_predicates.rb +50 -0
  314. data/lib/chemicalml/convention/compchem/constraints/scalar_units.rb +42 -0
  315. data/lib/chemicalml/convention/compchem/constraints.rb +40 -2
  316. data/lib/chemicalml/convention/compchem.rb +20 -2
  317. data/lib/chemicalml/convention/constraint.rb +68 -24
  318. data/lib/chemicalml/convention/coordinator.rb +90 -0
  319. data/lib/chemicalml/convention/detection.rb +39 -0
  320. data/lib/chemicalml/convention/dictionary/constraints/dictionary_must_have_namespace.rb +29 -0
  321. data/lib/chemicalml/convention/dictionary/constraints/dictionary_namespace_should_end_with_slash_or_hash.rb +32 -0
  322. data/lib/chemicalml/convention/dictionary/constraints/entry_id_must_match_pattern.rb +33 -0
  323. data/lib/chemicalml/convention/dictionary/constraints/entry_ids_unique_within_dictionary.rb +4 -4
  324. data/lib/chemicalml/convention/dictionary/constraints/entry_must_contain_definition.rb +29 -0
  325. data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_id_and_term.rb +6 -6
  326. data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_unit_type.rb +31 -0
  327. data/lib/chemicalml/convention/dictionary/constraints/entry_units_co_constraints.rb +44 -0
  328. data/lib/chemicalml/convention/dictionary/constraints.rb +14 -2
  329. data/lib/chemicalml/convention/dictionary.rb +8 -2
  330. data/lib/chemicalml/convention/molecular/constraints/atom_array_must_be_child_of_molecule_or_formula.rb +41 -0
  331. data/lib/chemicalml/convention/molecular/constraints/atom_array_must_contain_atoms.rb +18 -9
  332. data/lib/chemicalml/convention/molecular/constraints/atom_coordinates_must_be_paired.rb +6 -6
  333. data/lib/chemicalml/convention/molecular/constraints/atom_element_type_should_be_in_periodic_table.rb +39 -0
  334. data/lib/chemicalml/convention/molecular/constraints/atom_id_must_match_pattern.rb +7 -6
  335. data/lib/chemicalml/convention/molecular/constraints/atom_ids_unique_within_molecule.rb +3 -2
  336. data/lib/chemicalml/convention/molecular/constraints/atom_must_have_element_type.rb +4 -4
  337. data/lib/chemicalml/convention/molecular/constraints/atom_must_have_id.rb +5 -4
  338. data/lib/chemicalml/convention/molecular/constraints/atom_parity_atom_refs4_should_be_distinct.rb +44 -0
  339. data/lib/chemicalml/convention/molecular/constraints/atom_parity_should_include_parent_atom.rb +65 -0
  340. data/lib/chemicalml/convention/molecular/constraints/bond_array_must_be_child_of_molecule.rb +37 -0
  341. data/lib/chemicalml/convention/molecular/constraints/bond_atom_refs2_should_be_distinct.rb +44 -0
  342. data/lib/chemicalml/convention/molecular/constraints/bond_id_should_match_pattern.rb +38 -0
  343. data/lib/chemicalml/convention/molecular/constraints/bond_ids_unique_within_molecule.rb +44 -0
  344. data/lib/chemicalml/convention/molecular/constraints/bond_must_have_atom_refs2.rb +4 -4
  345. data/lib/chemicalml/convention/molecular/constraints/bond_must_have_order.rb +5 -4
  346. data/lib/chemicalml/convention/molecular/constraints/bond_must_reference_atoms_in_same_molecule.rb +4 -3
  347. data/lib/chemicalml/convention/molecular/constraints/bond_order_other_must_have_dict_ref.rb +34 -0
  348. data/lib/chemicalml/convention/molecular/constraints/bond_order_should_be_in_enum.rb +39 -0
  349. data/lib/chemicalml/convention/molecular/constraints/bond_order_should_not_be_numeric.rb +3 -3
  350. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_atom_refs4_should_be_distinct.rb +43 -0
  351. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_cis_trans_must_have_atom_refs4.rb +45 -0
  352. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_other_must_have_dict_ref.rb +33 -0
  353. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_should_be_in_enum.rb +38 -0
  354. data/lib/chemicalml/convention/molecular/constraints/bond_stereo_wedge_hash_must_have_atom_refs2.rb +45 -0
  355. data/lib/chemicalml/convention/molecular/constraints/dict_ref_should_resolve.rb +59 -0
  356. data/lib/chemicalml/convention/molecular/constraints/molecule_atom_array_mutually_exclusive_with_children.rb +33 -0
  357. data/lib/chemicalml/convention/molecular/constraints/molecule_bond_array_mutually_exclusive_with_children.rb +32 -0
  358. data/lib/chemicalml/convention/molecular/constraints/molecule_chirality_should_be_in_enum.rb +38 -0
  359. data/lib/chemicalml/convention/molecular/constraints/molecule_count_must_not_appear_on_top_level.rb +35 -0
  360. data/lib/chemicalml/convention/molecular/constraints/molecule_id_should_match_pattern.rb +38 -0
  361. data/lib/chemicalml/convention/molecular/constraints/molecule_must_have_id.rb +4 -4
  362. data/lib/chemicalml/convention/molecular/constraints/property_must_have_dict_ref.rb +4 -4
  363. data/lib/chemicalml/convention/molecular/constraints/property_scalar_data_type_matches_dictionary.rb +58 -0
  364. data/lib/chemicalml/convention/molecular/constraints/references_should_resolve.rb +37 -0
  365. data/lib/chemicalml/convention/molecular/constraints/scalar_must_have_data_type.rb +4 -4
  366. data/lib/chemicalml/convention/molecular/constraints.rb +59 -13
  367. data/lib/chemicalml/convention/molecular.rb +25 -2
  368. data/lib/chemicalml/convention/registry.rb +95 -10
  369. data/lib/chemicalml/convention/simple_unit/constraints/root_must_be_unit_list.rb +24 -0
  370. data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_power.rb +32 -0
  371. data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_symbol.rb +31 -0
  372. data/lib/chemicalml/convention/simple_unit/constraints.rb +16 -0
  373. data/lib/chemicalml/convention/simple_unit.rb +37 -0
  374. data/lib/chemicalml/convention/spectroscopy/constraints/peak_list_must_contain_peaks.rb +31 -0
  375. data/lib/chemicalml/convention/spectroscopy/constraints/peak_should_have_values.rb +34 -0
  376. data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_content.rb +31 -0
  377. data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_convention.rb +32 -0
  378. data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_format.rb +31 -0
  379. data/lib/chemicalml/convention/spectroscopy/constraints.rb +20 -0
  380. data/lib/chemicalml/convention/spectroscopy.rb +41 -0
  381. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit.rb +29 -0
  382. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace.rb +36 -0
  383. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition.rb +28 -0
  384. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_id.rb +28 -0
  385. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_multiplier_or_constant_to_si.rb +34 -0
  386. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_parent_si.rb +32 -0
  387. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb +4 -4
  388. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_title.rb +32 -0
  389. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_parent_si_should_resolve.rb +45 -0
  390. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_unit_type_should_resolve.rb +46 -0
  391. data/lib/chemicalml/convention/unit_dictionary/constraints.rb +19 -1
  392. data/lib/chemicalml/convention/unit_dictionary.rb +11 -2
  393. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern.rb +31 -0
  394. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_contain_at_least_one_unit_type.rb +28 -0
  395. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_have_namespace.rb +35 -0
  396. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition.rb +28 -0
  397. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb +6 -6
  398. data/lib/chemicalml/convention/unit_type_dictionary/constraints.rb +9 -1
  399. data/lib/chemicalml/convention/unit_type_dictionary.rb +6 -2
  400. data/lib/chemicalml/convention/validation_report.rb +90 -0
  401. data/lib/chemicalml/convention/violation.rb +9 -3
  402. data/lib/chemicalml/convention.rb +49 -11
  403. data/lib/chemicalml/dictionary/entry.rb +6 -6
  404. data/lib/chemicalml/dictionary/enum.rb +1 -1
  405. data/lib/chemicalml/dictionary/link.rb +3 -3
  406. data/lib/chemicalml/dictionary/loader.rb +19 -19
  407. data/lib/chemicalml/dictionary/model.rb +5 -5
  408. data/lib/chemicalml/dictionary/registry.rb +9 -9
  409. data/lib/chemicalml/dictionary.rb +13 -9
  410. data/lib/chemicalml/logger.rb +47 -0
  411. data/lib/chemicalml/schema/definition.rb +2 -2
  412. data/lib/chemicalml/schema.rb +7 -7
  413. data/lib/chemicalml/version.rb +1 -1
  414. data/lib/chemicalml/versioned_parser.rb +28 -10
  415. data/lib/chemicalml.rb +79 -17
  416. data/lib/tasks/reference_fetch.rake +30 -31
  417. data/lib/tasks/scrape_fixtures.rake +23 -24
  418. metadata +235 -35
  419. data/lib/chemicalml/cml/child_mappings.rb +0 -168
  420. data/lib/chemicalml/cml/translator/value_translations.rb +0 -270
  421. data/lib/chemicalml/cml/translator.rb +0 -484
  422. data/lib/chemicalml/model/atom.rb +0 -64
  423. data/lib/chemicalml/model/atom_parity.rb +0 -21
  424. data/lib/chemicalml/model/bond.rb +0 -39
  425. data/lib/chemicalml/model/bond_stereo.rb +0 -29
  426. data/lib/chemicalml/model/cml_array.rb +0 -27
  427. data/lib/chemicalml/model/cml_module.rb +0 -45
  428. data/lib/chemicalml/model/document.rb +0 -29
  429. data/lib/chemicalml/model/formula.rb +0 -34
  430. data/lib/chemicalml/model/identifier.rb +0 -21
  431. data/lib/chemicalml/model/label.rb +0 -21
  432. data/lib/chemicalml/model/matrix.rb +0 -29
  433. data/lib/chemicalml/model/metadata.rb +0 -23
  434. data/lib/chemicalml/model/metadata_list.rb +0 -25
  435. data/lib/chemicalml/model/molecule.rb +0 -45
  436. data/lib/chemicalml/model/name.rb +0 -21
  437. data/lib/chemicalml/model/node.rb +0 -45
  438. data/lib/chemicalml/model/parameter.rb +0 -27
  439. data/lib/chemicalml/model/parameter_list.rb +0 -25
  440. data/lib/chemicalml/model/product.rb +0 -21
  441. data/lib/chemicalml/model/product_list.rb +0 -21
  442. data/lib/chemicalml/model/property.rb +0 -28
  443. data/lib/chemicalml/model/property_list.rb +0 -25
  444. data/lib/chemicalml/model/reactant.rb +0 -21
  445. data/lib/chemicalml/model/reactant_list.rb +0 -21
  446. data/lib/chemicalml/model/reaction.rb +0 -41
  447. data/lib/chemicalml/model/reaction_list.rb +0 -23
  448. data/lib/chemicalml/model/scalar.rb +0 -25
  449. data/lib/chemicalml/model/substance.rb +0 -25
  450. data/lib/chemicalml/model.rb +0 -40
@@ -8,142 +8,174 @@ module Chemicalml
8
8
  # and are included by both schema-versioned class hierarchies.
9
9
  module Cml
10
10
  # Structural modules (each in its own file, loaded independently).
11
- autoload :Base, "chemicalml/cml/base"
12
- autoload :ChildMappings, "chemicalml/cml/child_mappings"
13
- autoload :Elements, "chemicalml/cml/elements"
14
- autoload :Namespace, "chemicalml/cml/namespace"
15
- autoload :Role, "chemicalml/cml/role"
16
- autoload :Schema3, "chemicalml/cml/schema3"
17
- autoload :Schema24, "chemicalml/cml/schema24"
18
- autoload :Translator, "chemicalml/cml/translator"
19
- autoload :Visitable, "chemicalml/cml/visitable"
20
- autoload :WireClassRegistry, "chemicalml/cml/wire_class_registry"
11
+ autoload :Base, 'chemicalml/cml/base'
12
+ autoload :CanonicalComparison, 'chemicalml/cml/canonical_comparison'
13
+ autoload :Elements, 'chemicalml/cml/elements'
14
+ autoload :Enums, 'chemicalml/cml/enums'
15
+ autoload :Namespace, 'chemicalml/cml/namespace'
16
+ autoload :Patterns, 'chemicalml/cml/patterns'
17
+ autoload :ReferenceResolver, 'chemicalml/cml/reference_resolver'
18
+ autoload :Role, 'chemicalml/cml/role'
19
+ autoload :Schema3, 'chemicalml/cml/schema3'
20
+ autoload :Schema24, 'chemicalml/cml/schema24'
21
+ autoload :Visitable, 'chemicalml/cml/visitable'
22
+ autoload :WireClassRegistry, 'chemicalml/cml/wire_class_registry'
21
23
 
22
- # Backward-compatible aliases (Cml::Foo = Schema3::Foo). All 36
24
+ class << self
25
+ # Look up a wire class by XML element name.
26
+ #
27
+ # @param xml_name [String, Symbol] the XML element name, e.g. "atomArray".
28
+ # @param schema [Symbol] `:schema3` (default) or `:schema24`.
29
+ # @return [Class, nil] the matching wire class, or nil if not found.
30
+ def for_xml_name(xml_name, schema: :schema3)
31
+ class_name = Elements::XML_TO_CLASS[xml_name.to_s]
32
+ return nil unless class_name
33
+
34
+ parent = schema == :schema24 ? Schema24 : Schema3
35
+ parent.const_get(class_name)
36
+ rescue NameError
37
+ nil
38
+ end
39
+
40
+ # Enumerate every wire class for a schema version.
41
+ #
42
+ # @param schema [Symbol] `:schema3` or `:schema24`.
43
+ # @return [Array<Class>] the wire classes.
44
+ def wire_classes(schema: :schema3)
45
+ parent = schema == :schema24 ? Schema24 : Schema3
46
+ Elements::ALL.keys.map do |class_name|
47
+ parent.const_get(class_name)
48
+ rescue NameError
49
+ nil
50
+ end.compact
51
+ end
52
+ end
53
+
54
+ # Backward-compatible aliases (Cml::Foo = Schema3::Foo). All 121
23
55
  # aliases load from a single file via autoload — the file loads
24
56
  # lazily when the first alias is referenced, then defines all of
25
57
  # them via const_set (aliasing existing Schema3 classes, not
26
58
  # creating new ones).
27
- autoload :Array, "chemicalml/cml/aliases"
28
- autoload :Atom, "chemicalml/cml/aliases"
29
- autoload :AtomArray, "chemicalml/cml/aliases"
30
- autoload :AtomParity, "chemicalml/cml/aliases"
31
- autoload :Bond, "chemicalml/cml/aliases"
32
- autoload :BondArray, "chemicalml/cml/aliases"
33
- autoload :BondStereo, "chemicalml/cml/aliases"
34
- autoload :Dictionary, "chemicalml/cml/aliases"
35
- autoload :DictionaryEntry, "chemicalml/cml/aliases"
36
- autoload :Document, "chemicalml/cml/aliases"
37
- autoload :Formula, "chemicalml/cml/aliases"
38
- autoload :Identifier, "chemicalml/cml/aliases"
39
- autoload :Label, "chemicalml/cml/aliases"
40
- autoload :List, "chemicalml/cml/aliases"
41
- autoload :Matrix, "chemicalml/cml/aliases"
42
- autoload :Metadata, "chemicalml/cml/aliases"
43
- autoload :MetadataList, "chemicalml/cml/aliases"
44
- autoload :Module, "chemicalml/cml/aliases"
45
- autoload :Molecule, "chemicalml/cml/aliases"
46
- autoload :Name, "chemicalml/cml/aliases"
47
- autoload :Parameter, "chemicalml/cml/aliases"
48
- autoload :ParameterList, "chemicalml/cml/aliases"
49
- autoload :Product, "chemicalml/cml/aliases"
50
- autoload :ProductList, "chemicalml/cml/aliases"
51
- autoload :Property, "chemicalml/cml/aliases"
52
- autoload :PropertyList, "chemicalml/cml/aliases"
53
- autoload :Reaction, "chemicalml/cml/aliases"
54
- autoload :ReactionList, "chemicalml/cml/aliases"
55
- autoload :Reactant, "chemicalml/cml/aliases"
56
- autoload :ReactantList, "chemicalml/cml/aliases"
57
- autoload :Scalar, "chemicalml/cml/aliases"
58
- autoload :Substance, "chemicalml/cml/aliases"
59
- autoload :Unit, "chemicalml/cml/aliases"
60
- autoload :UnitList, "chemicalml/cml/aliases"
61
- autoload :UnitType, "chemicalml/cml/aliases"
62
- autoload :UnitTypeList, "chemicalml/cml/aliases"
63
- autoload :Abundance, "chemicalml/cml/aliases"
64
- autoload :Action, "chemicalml/cml/aliases"
65
- autoload :ActionList, "chemicalml/cml/aliases"
66
- autoload :Amount, "chemicalml/cml/aliases"
67
- autoload :Angle, "chemicalml/cml/aliases"
68
- autoload :AnyCml, "chemicalml/cml/aliases"
69
- autoload :ArrayList, "chemicalml/cml/aliases"
70
- autoload :AtomSet, "chemicalml/cml/aliases"
71
- autoload :AtomType, "chemicalml/cml/aliases"
72
- autoload :AtomTypeList, "chemicalml/cml/aliases"
73
- autoload :AtomicBasisFunction, "chemicalml/cml/aliases"
74
- autoload :Band, "chemicalml/cml/aliases"
75
- autoload :BandList, "chemicalml/cml/aliases"
76
- autoload :BasisSet, "chemicalml/cml/aliases"
77
- autoload :BondSet, "chemicalml/cml/aliases"
78
- autoload :BondType, "chemicalml/cml/aliases"
79
- autoload :BondTypeList, "chemicalml/cml/aliases"
80
- autoload :CellParameter, "chemicalml/cml/aliases"
81
- autoload :ConditionList, "chemicalml/cml/aliases"
82
- autoload :Crystal, "chemicalml/cml/aliases"
83
- autoload :Definition, "chemicalml/cml/aliases"
84
- autoload :Description, "chemicalml/cml/aliases"
85
- autoload :Dimension, "chemicalml/cml/aliases"
86
- autoload :Documentation, "chemicalml/cml/aliases"
87
- autoload :Eigen, "chemicalml/cml/aliases"
88
- autoload :Electron, "chemicalml/cml/aliases"
89
- autoload :Fragment, "chemicalml/cml/aliases"
90
- autoload :FragmentList, "chemicalml/cml/aliases"
91
- autoload :Gradient, "chemicalml/cml/aliases"
92
- autoload :Isotope, "chemicalml/cml/aliases"
93
- autoload :IsotopeList, "chemicalml/cml/aliases"
94
- autoload :Join, "chemicalml/cml/aliases"
95
- autoload :Kpoint, "chemicalml/cml/aliases"
96
- autoload :KpointList, "chemicalml/cml/aliases"
97
- autoload :Lattice, "chemicalml/cml/aliases"
98
- autoload :LatticeVector, "chemicalml/cml/aliases"
99
- autoload :Length, "chemicalml/cml/aliases"
100
- autoload :Line3, "chemicalml/cml/aliases"
101
- autoload :Link, "chemicalml/cml/aliases"
102
- autoload :Map, "chemicalml/cml/aliases"
103
- autoload :Mechanism, "chemicalml/cml/aliases"
104
- autoload :MechanismComponent, "chemicalml/cml/aliases"
105
- autoload :MoleculeList, "chemicalml/cml/aliases"
106
- autoload :Object, "chemicalml/cml/aliases"
107
- autoload :Observation, "chemicalml/cml/aliases"
108
- autoload :Particle, "chemicalml/cml/aliases"
109
- autoload :Peak, "chemicalml/cml/aliases"
110
- autoload :PeakGroup, "chemicalml/cml/aliases"
111
- autoload :PeakList, "chemicalml/cml/aliases"
112
- autoload :PeakStructure, "chemicalml/cml/aliases"
113
- autoload :Plane3, "chemicalml/cml/aliases"
114
- autoload :Point3, "chemicalml/cml/aliases"
115
- autoload :Potential, "chemicalml/cml/aliases"
116
- autoload :PotentialForm, "chemicalml/cml/aliases"
117
- autoload :PotentialList, "chemicalml/cml/aliases"
118
- autoload :ReactionScheme, "chemicalml/cml/aliases"
119
- autoload :ReactionStep, "chemicalml/cml/aliases"
120
- autoload :ReactionStepList, "chemicalml/cml/aliases"
121
- autoload :ReactiveCentre, "chemicalml/cml/aliases"
122
- autoload :Region, "chemicalml/cml/aliases"
123
- autoload :Sample, "chemicalml/cml/aliases"
124
- autoload :Spectator, "chemicalml/cml/aliases"
125
- autoload :SpectatorList, "chemicalml/cml/aliases"
126
- autoload :Spectrum, "chemicalml/cml/aliases"
127
- autoload :SpectrumData, "chemicalml/cml/aliases"
128
- autoload :SpectrumList, "chemicalml/cml/aliases"
129
- autoload :Sphere3, "chemicalml/cml/aliases"
130
- autoload :Stmml, "chemicalml/cml/aliases"
131
- autoload :SubstanceList, "chemicalml/cml/aliases"
132
- autoload :Symmetry, "chemicalml/cml/aliases"
133
- autoload :System, "chemicalml/cml/aliases"
134
- autoload :Table, "chemicalml/cml/aliases"
135
- autoload :TableCell, "chemicalml/cml/aliases"
136
- autoload :TableContent, "chemicalml/cml/aliases"
137
- autoload :TableHeader, "chemicalml/cml/aliases"
138
- autoload :TableHeaderCell, "chemicalml/cml/aliases"
139
- autoload :TableRow, "chemicalml/cml/aliases"
140
- autoload :TableRowList, "chemicalml/cml/aliases"
141
- autoload :Torsion, "chemicalml/cml/aliases"
142
- autoload :Transform3, "chemicalml/cml/aliases"
143
- autoload :TransitionState, "chemicalml/cml/aliases"
144
- autoload :Vector3, "chemicalml/cml/aliases"
145
- autoload :Xaxis, "chemicalml/cml/aliases"
146
- autoload :Yaxis, "chemicalml/cml/aliases"
147
- autoload :ZMatrix, "chemicalml/cml/aliases"
59
+ autoload :Array, 'chemicalml/cml/aliases'
60
+ autoload :Atom, 'chemicalml/cml/aliases'
61
+ autoload :AtomArray, 'chemicalml/cml/aliases'
62
+ autoload :AtomParity, 'chemicalml/cml/aliases'
63
+ autoload :Bond, 'chemicalml/cml/aliases'
64
+ autoload :BondArray, 'chemicalml/cml/aliases'
65
+ autoload :BondStereo, 'chemicalml/cml/aliases'
66
+ autoload :Dictionary, 'chemicalml/cml/aliases'
67
+ autoload :DictionaryEntry, 'chemicalml/cml/aliases'
68
+ autoload :Document, 'chemicalml/cml/aliases'
69
+ autoload :Formula, 'chemicalml/cml/aliases'
70
+ autoload :Identifier, 'chemicalml/cml/aliases'
71
+ autoload :Label, 'chemicalml/cml/aliases'
72
+ autoload :List, 'chemicalml/cml/aliases'
73
+ autoload :Matrix, 'chemicalml/cml/aliases'
74
+ autoload :Metadata, 'chemicalml/cml/aliases'
75
+ autoload :MetadataList, 'chemicalml/cml/aliases'
76
+ autoload :Module, 'chemicalml/cml/aliases'
77
+ autoload :Molecule, 'chemicalml/cml/aliases'
78
+ autoload :Name, 'chemicalml/cml/aliases'
79
+ autoload :Parameter, 'chemicalml/cml/aliases'
80
+ autoload :ParameterList, 'chemicalml/cml/aliases'
81
+ autoload :Product, 'chemicalml/cml/aliases'
82
+ autoload :ProductList, 'chemicalml/cml/aliases'
83
+ autoload :Property, 'chemicalml/cml/aliases'
84
+ autoload :PropertyList, 'chemicalml/cml/aliases'
85
+ autoload :Reaction, 'chemicalml/cml/aliases'
86
+ autoload :ReactionList, 'chemicalml/cml/aliases'
87
+ autoload :Reactant, 'chemicalml/cml/aliases'
88
+ autoload :ReactantList, 'chemicalml/cml/aliases'
89
+ autoload :Scalar, 'chemicalml/cml/aliases'
90
+ autoload :Substance, 'chemicalml/cml/aliases'
91
+ autoload :Unit, 'chemicalml/cml/aliases'
92
+ autoload :UnitList, 'chemicalml/cml/aliases'
93
+ autoload :UnitType, 'chemicalml/cml/aliases'
94
+ autoload :UnitTypeList, 'chemicalml/cml/aliases'
95
+ autoload :Abundance, 'chemicalml/cml/aliases'
96
+ autoload :Action, 'chemicalml/cml/aliases'
97
+ autoload :ActionList, 'chemicalml/cml/aliases'
98
+ autoload :Amount, 'chemicalml/cml/aliases'
99
+ autoload :Angle, 'chemicalml/cml/aliases'
100
+ autoload :AnyCml, 'chemicalml/cml/aliases'
101
+ autoload :ArrayList, 'chemicalml/cml/aliases'
102
+ autoload :AtomSet, 'chemicalml/cml/aliases'
103
+ autoload :AtomType, 'chemicalml/cml/aliases'
104
+ autoload :AtomTypeList, 'chemicalml/cml/aliases'
105
+ autoload :AtomicBasisFunction, 'chemicalml/cml/aliases'
106
+ autoload :Band, 'chemicalml/cml/aliases'
107
+ autoload :BandList, 'chemicalml/cml/aliases'
108
+ autoload :BasisSet, 'chemicalml/cml/aliases'
109
+ autoload :BondSet, 'chemicalml/cml/aliases'
110
+ autoload :BondType, 'chemicalml/cml/aliases'
111
+ autoload :BondTypeList, 'chemicalml/cml/aliases'
112
+ autoload :CellParameter, 'chemicalml/cml/aliases'
113
+ autoload :ConditionList, 'chemicalml/cml/aliases'
114
+ autoload :Crystal, 'chemicalml/cml/aliases'
115
+ autoload :Definition, 'chemicalml/cml/aliases'
116
+ autoload :Description, 'chemicalml/cml/aliases'
117
+ autoload :Dimension, 'chemicalml/cml/aliases'
118
+ autoload :Documentation, 'chemicalml/cml/aliases'
119
+ autoload :Eigen, 'chemicalml/cml/aliases'
120
+ autoload :Electron, 'chemicalml/cml/aliases'
121
+ autoload :Fragment, 'chemicalml/cml/aliases'
122
+ autoload :FragmentList, 'chemicalml/cml/aliases'
123
+ autoload :Gradient, 'chemicalml/cml/aliases'
124
+ autoload :Isotope, 'chemicalml/cml/aliases'
125
+ autoload :IsotopeList, 'chemicalml/cml/aliases'
126
+ autoload :Join, 'chemicalml/cml/aliases'
127
+ autoload :Kpoint, 'chemicalml/cml/aliases'
128
+ autoload :KpointList, 'chemicalml/cml/aliases'
129
+ autoload :Lattice, 'chemicalml/cml/aliases'
130
+ autoload :LatticeVector, 'chemicalml/cml/aliases'
131
+ autoload :Length, 'chemicalml/cml/aliases'
132
+ autoload :Line3, 'chemicalml/cml/aliases'
133
+ autoload :Link, 'chemicalml/cml/aliases'
134
+ autoload :Map, 'chemicalml/cml/aliases'
135
+ autoload :Mechanism, 'chemicalml/cml/aliases'
136
+ autoload :MechanismComponent, 'chemicalml/cml/aliases'
137
+ autoload :MoleculeList, 'chemicalml/cml/aliases'
138
+ autoload :Object, 'chemicalml/cml/aliases'
139
+ autoload :Observation, 'chemicalml/cml/aliases'
140
+ autoload :Particle, 'chemicalml/cml/aliases'
141
+ autoload :Peak, 'chemicalml/cml/aliases'
142
+ autoload :PeakGroup, 'chemicalml/cml/aliases'
143
+ autoload :PeakList, 'chemicalml/cml/aliases'
144
+ autoload :PeakStructure, 'chemicalml/cml/aliases'
145
+ autoload :Plane3, 'chemicalml/cml/aliases'
146
+ autoload :Point3, 'chemicalml/cml/aliases'
147
+ autoload :Potential, 'chemicalml/cml/aliases'
148
+ autoload :PotentialForm, 'chemicalml/cml/aliases'
149
+ autoload :PotentialList, 'chemicalml/cml/aliases'
150
+ autoload :ReactionScheme, 'chemicalml/cml/aliases'
151
+ autoload :ReactionStep, 'chemicalml/cml/aliases'
152
+ autoload :ReactionStepList, 'chemicalml/cml/aliases'
153
+ autoload :ReactiveCentre, 'chemicalml/cml/aliases'
154
+ autoload :Region, 'chemicalml/cml/aliases'
155
+ autoload :Sample, 'chemicalml/cml/aliases'
156
+ autoload :Spectator, 'chemicalml/cml/aliases'
157
+ autoload :SpectatorList, 'chemicalml/cml/aliases'
158
+ autoload :Spectrum, 'chemicalml/cml/aliases'
159
+ autoload :SpectrumData, 'chemicalml/cml/aliases'
160
+ autoload :SpectrumList, 'chemicalml/cml/aliases'
161
+ autoload :Sphere3, 'chemicalml/cml/aliases'
162
+ autoload :Stmml, 'chemicalml/cml/aliases'
163
+ autoload :SubstanceList, 'chemicalml/cml/aliases'
164
+ autoload :Symmetry, 'chemicalml/cml/aliases'
165
+ autoload :System, 'chemicalml/cml/aliases'
166
+ autoload :Table, 'chemicalml/cml/aliases'
167
+ autoload :TableCell, 'chemicalml/cml/aliases'
168
+ autoload :TableContent, 'chemicalml/cml/aliases'
169
+ autoload :TableHeader, 'chemicalml/cml/aliases'
170
+ autoload :TableHeaderCell, 'chemicalml/cml/aliases'
171
+ autoload :TableRow, 'chemicalml/cml/aliases'
172
+ autoload :TableRowList, 'chemicalml/cml/aliases'
173
+ autoload :Torsion, 'chemicalml/cml/aliases'
174
+ autoload :Transform3, 'chemicalml/cml/aliases'
175
+ autoload :TransitionState, 'chemicalml/cml/aliases'
176
+ autoload :Vector3, 'chemicalml/cml/aliases'
177
+ autoload :Xaxis, 'chemicalml/cml/aliases'
178
+ autoload :Yaxis, 'chemicalml/cml/aliases'
179
+ autoload :ZMatrix, 'chemicalml/cml/aliases'
148
180
  end
149
181
  end
@@ -40,10 +40,16 @@ module Chemicalml
40
40
  # each class on the parent (schema) module, and register it. Pass
41
41
  # `except:` to skip specific elements (used by Schema 2.4 which
42
42
  # lacks `<module>`).
43
- def register_elements!(except: [])
43
+ def register_elements!(except: [], only: nil)
44
44
  parent = version_parent_module
45
45
  skip = except.to_set
46
- Chemicalml::Cml::Elements::ALL.each do |class_name, element_id|
46
+ source =
47
+ if only
48
+ Chemicalml::Cml::Elements::SCHEMA24_ONLY
49
+ else
50
+ Chemicalml::Cml::Elements::ALL
51
+ end
52
+ source.each do |class_name, element_id|
47
53
  next if skip.include?(class_name)
48
54
  next unless parent.const_defined?(class_name)
49
55
 
@@ -68,7 +74,9 @@ module Chemicalml
68
74
  def create_context(id:, registry: nil, fallback_to: [context_id])
69
75
  normalized_id = id.to_sym
70
76
  ensure_version_registered
71
- Lutaml::Model::GlobalContext.unregister_context(normalized_id) if Lutaml::Model::GlobalContext.context(normalized_id)
77
+ if Lutaml::Model::GlobalContext.context(normalized_id)
78
+ Lutaml::Model::GlobalContext.unregister_context(normalized_id)
79
+ end
72
80
  Lutaml::Model::GlobalContext.create_context(
73
81
  id: normalized_id,
74
82
  registry: registry || Lutaml::Model::TypeRegistry.new,
@@ -116,7 +124,7 @@ module Chemicalml
116
124
  def version_parent_module
117
125
  return nil unless name
118
126
 
119
- parent_const_name = name.split("::")[0..-2].join("::")
127
+ parent_const_name = name.split('::')[0..-2].join('::')
120
128
  return nil if parent_const_name.empty?
121
129
 
122
130
  Object.const_get(parent_const_name)
@@ -27,13 +27,20 @@ module Chemicalml
27
27
 
28
28
  def register(constraint_class)
29
29
  constraints << constraint_class unless constraints.include?(constraint_class)
30
+ @coordinator = nil # invalidate cached coordinator
30
31
  self
31
32
  end
32
33
 
34
+ # Single-pass validation via Convention::Coordinator. The
35
+ # coordinator builds a role-dispatch table from the declared
36
+ # `applies_to` on each constraint, walks the tree once, and
37
+ # dispatches each node only to applicable constraints.
33
38
  def validate(document)
34
- constraints.flat_map do |klass|
35
- klass.new.check(document)
36
- end
39
+ coordinator.validate(document)
40
+ end
41
+
42
+ def validate_report(document)
43
+ ValidationReport.new(validate(document))
37
44
  end
38
45
 
39
46
  def constraint_count
@@ -42,6 +49,13 @@ module Chemicalml
42
49
 
43
50
  def reset_constraints!
44
51
  @constraints = []
52
+ @coordinator = nil
53
+ end
54
+
55
+ private
56
+
57
+ def coordinator
58
+ @coordinator ||= Coordinator.new(constraints)
45
59
  end
46
60
  end
47
61
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Cascade
6
+ module Constraints
7
+ # A `<reactionScheme>` MUST contain at least one
8
+ # `<reactionStepList>` or `<reaction>` child. An empty scheme
9
+ # carries no cascade information.
10
+ class ReactionSchemeMustHaveContent < Chemicalml::Convention::Constraint::NodeConstraint
11
+ self.description = 'A `<reactionScheme>` MUST contain at least one `<reactionStepList>` or `<reaction>` child. An empty scheme carries no cascade information.'
12
+ applies_to Chemicalml::Cml::Role::ReactionScheme
13
+
14
+ def check_node(node, _path)
15
+ return [] unless (node.reaction_step_lists || []).empty? &&
16
+ (node.reactions || []).empty?
17
+
18
+ [violation(path: yield_path(node),
19
+ message: "reactionScheme #{node.id.inspect} must contain at least one " \
20
+ 'reactionStepList or reaction')]
21
+ end
22
+
23
+ private
24
+
25
+ def yield_path(node)
26
+ id = node.node_id
27
+ id ? "reactionScheme[#{id}]" : 'reactionScheme'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Cascade
6
+ module Constraints
7
+ # A `<reactionStepList>` MUST contain at least one
8
+ # `<reactionStep>` child. An empty step list breaks the
9
+ # cascade chain.
10
+ class ReactionStepListMustContainSteps < Chemicalml::Convention::Constraint::NodeConstraint
11
+ self.description = 'A `<reactionStepList>` MUST contain at least one `<reactionStep>` child. An empty step list breaks the cascade chain.'
12
+ applies_to Chemicalml::Cml::Role::ReactionStepList
13
+
14
+ def check_node(node, _path)
15
+ return [] unless (node.reaction_steps || []).empty?
16
+
17
+ [violation(path: yield_path(node),
18
+ message: 'reactionStepList must contain at least one reactionStep')]
19
+ end
20
+
21
+ private
22
+
23
+ def yield_path(node)
24
+ id = node.node_id
25
+ id ? "reactionStepList[#{id}]" : 'reactionStepList'
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Cascade
6
+ module Constraints
7
+ # A `<reactionStep>` MUST contain either a `<reaction>` child
8
+ # or explicit `<reactantList>` + `<productList>` children. An
9
+ # empty step is a dead-end in the cascade.
10
+ class ReactionStepMustHaveReactionOrLists < Chemicalml::Convention::Constraint::NodeConstraint
11
+ self.description = 'A `<reactionStep>` MUST contain either a `<reaction>` child or explicit `<reactantList>` + `<productList>` children. An empty step is a dead-end in the cascade.'
12
+ applies_to Chemicalml::Cml::Role::ReactionStep
13
+
14
+ def check_node(node, _path)
15
+ return [] if node.reaction
16
+ return [] if node.reactant_list && node.product_list
17
+
18
+ [violation(path: yield_path(node),
19
+ message: "reactionStep #{node.id.inspect} must contain a reaction " \
20
+ 'or both reactantList and productList')]
21
+ end
22
+
23
+ private
24
+
25
+ def yield_path(node)
26
+ id = node.node_id
27
+ id ? "reactionStep[#{id}]" : 'reactionStep'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Cascade
6
+ module Constraints
7
+ # A `<reactiveCentre>` SHOULD declare its `atomRefs` attribute.
8
+ # Without atom references the reactive centre is
9
+ # indistinguishable from a placeholder. Warning severity —
10
+ # consumers may use `ref` or external context instead.
11
+ class ReactiveCentreAtomRefsShouldBePresent < Chemicalml::Convention::Constraint::NodeConstraint
12
+ self.description = 'A `<reactiveCentre>` SHOULD declare its `atomRefs` attribute. Without atom references the reactive centre is indistinguishable from a placeholder. Warning severity —'
13
+ applies_to Chemicalml::Cml::Role::ReactiveCentre
14
+
15
+ def check_node(node, _path)
16
+ return [] unless node.atomRefs.to_s.empty?
17
+
18
+ [violation(path: yield_path(node),
19
+ message: "reactiveCentre #{node.id.inspect} should declare atomRefs " \
20
+ 'to identify the reacting atoms',
21
+ severity: :warning)]
22
+ end
23
+
24
+ private
25
+
26
+ def yield_path(node)
27
+ id = node.node_id
28
+ id ? "reactiveCentre[#{id}]" : 'reactiveCentre'
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Cascade
6
+ module Constraints
7
+ autoload :ReactionSchemeMustHaveContent,
8
+ 'chemicalml/convention/cascade/constraints/reaction_scheme_must_have_content'
9
+ autoload :ReactionStepListMustContainSteps,
10
+ 'chemicalml/convention/cascade/constraints/reaction_step_list_must_contain_steps'
11
+ autoload :ReactionStepMustHaveReactionOrLists,
12
+ 'chemicalml/convention/cascade/constraints/reaction_step_must_have_reaction_or_lists'
13
+ autoload :ReactiveCentreAtomRefsShouldBePresent,
14
+ 'chemicalml/convention/cascade/constraints/reactive_centre_atom_refs_should_be_present'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ # The Cascade convention. A chemicalml-specific convention for CML
6
+ # reaction cascades — multi-step reaction networks encoded via
7
+ # `<reactionScheme>`, `<reactionStepList>`, `<reactionStep>`,
8
+ # `<reaction>`, and `<reactiveCentre>`.
9
+ #
10
+ # Upstream CML does not publish a dedicated cascade convention; the
11
+ # wire elements exist in the XSD but no constraints guard their
12
+ # well-formedness. This convention covers the gaps:
13
+ #
14
+ # - reactionScheme MUST contain at least one reactionStepList or
15
+ # reaction (an empty scheme carries no cascade)
16
+ # - reactionStepList MUST contain at least one reactionStep
17
+ # - reactionStep MUST contain a reaction or explicit reactant/product
18
+ # lists (an empty step is a dead-end in the cascade)
19
+ # - reactiveCentre atomRefs SHOULD be parseable atom references
20
+ # (warning — gracefully degrades when context is missing)
21
+ module Cascade
22
+ extend Base
23
+
24
+ autoload :Constraints, 'chemicalml/convention/cascade/constraints'
25
+
26
+ QNAME = 'convention:cascade'
27
+ NAMESPACE_URI = "#{Chemicalml::Convention::CONVENTION_NAMESPACE}cascade".freeze
28
+
29
+ def self.qname
30
+ QNAME
31
+ end
32
+
33
+ def self.namespace_uri
34
+ NAMESPACE_URI
35
+ end
36
+
37
+ register Constraints::ReactionSchemeMustHaveContent
38
+ register Constraints::ReactionStepListMustContainSteps
39
+ register Constraints::ReactionStepMustHaveReactionOrLists
40
+ register Constraints::ReactiveCentreAtomRefsShouldBePresent
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Convention
5
+ module Compchem
6
+ module Constraints
7
+ # CompChem `array` value-container rules: MUST have `size`
8
+ # attribute (≥ 1); `dataType` MUST be integer or double;
9
+ # MUST have `units`.
10
+ class ArrayRules < Chemicalml::Convention::Constraint::NodeConstraint
11
+ self.description = 'CompChem `array` value-container rules: MUST have `size` attribute (≥ 1); `dataType` MUST be integer or double; MUST have `units`.'
12
+ applies_to Chemicalml::Cml::Role::Array
13
+ include ModulePredicates
14
+
15
+ ALLOWED_TYPES = %w[xsd:integer xsd:double].freeze
16
+
17
+ def check_node(node, path)
18
+ violations = []
19
+ if node.size.to_s.empty? || node.size.to_i < 1
20
+ violations << violation(path: path.join('/'),
21
+ message: 'array must have a size attribute (minimum 1)')
22
+ end
23
+ unless ALLOWED_TYPES.include?(node.data_type.to_s)
24
+ violations << violation(path: path.join('/'),
25
+ message: 'array dataType must be xsd:integer or xsd:double ' \
26
+ "(got #{node.data_type.inspect})")
27
+ end
28
+ if node.units.to_s.empty?
29
+ violations << violation(path: path.join('/'),
30
+ message: 'array must have units (even if dimensionless)')
31
+ end
32
+ violations
33
+ end
34
+
35
+ private
36
+
37
+ def array?(node)
38
+ node.is_a?(Chemicalml::Cml::Role::Array)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end