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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74eb61f89b283d3263aa4ead18e9b76061700defcc54232002855af6b1291c0a
4
- data.tar.gz: 228f8f704086b458a73b3f4cb679b25133cf5ee36aa16d58c688a6439abb1974
3
+ metadata.gz: 5aff6a0c43deeff73ff9684286df7c1a7ef97d61fa919415a381e70de217995c
4
+ data.tar.gz: 52237d4db8715d8244b88c124cf3bdc1ad43102b4468d8217099ebdec6b89f1b
5
5
  SHA512:
6
- metadata.gz: ba13a979cce6d48bbef181917107ac9ad24291131e8568652a012698c5e3ebe7f43851f908408478e4b4481d270cb9b83371d9c3f19093700df19a97565af2a9
7
- data.tar.gz: 8557d650ab706936b25031541e256e840cc638d025d5c4b7308a512aa46e27d4223a050ba27b37c7d9c5408c1b1dd7af4974697699af317fec17a3ecfa262f92
6
+ metadata.gz: b9f636c62b495c14f5ab10df0c8fd30e49aa23587731587f2fc9f4d87837376da38db8814df48482e1725751090518722ff3e6ca43ea5197fefb53ab5055183a
7
+ data.tar.gz: c7b42562ce98060bd3ca135d137be215f25a2ae71e2fc2693b70ab7e1030f8c6868744dea7aa9d60d078ba6adc11fc28a7c8d63de4f5f69c0a9b16ff8fe6f65f
@@ -16,13 +16,19 @@ on:
16
16
  Also, you can pass 'skip' to skip 'git tag' and do 'gem push' for the current version
17
17
  required: true
18
18
  default: 'skip'
19
+ acknowledge_breaking_in_patch:
20
+ description: 'Override the patch-release breaking-change guard when the trip is a known false-positive'
21
+ required: false
22
+ type: boolean
23
+ default: false
19
24
  repository_dispatch:
20
25
  types: [ do-release ]
21
26
 
22
27
  jobs:
23
28
  release:
24
- uses: relaton/support/.github/workflows/release.yml@main
29
+ uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
25
30
  with:
26
31
  next_version: ${{ github.event.inputs.next_version }}
32
+ acknowledge_breaking_in_patch: ${{ inputs.acknowledge_breaking_in_patch }}
27
33
  secrets:
28
34
  rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
data/CLAUDE.md CHANGED
@@ -33,23 +33,30 @@ is regenerated by RSpec on every run, and `Gemfile.lock` is development-only.
33
33
 
34
34
  ## Architecture (big picture)
35
35
 
36
- There are **five namespaces** under `Chemicalml`, deliberately kept
36
+ There are **four namespaces** under `Chemicalml`, deliberately kept
37
37
  independent:
38
38
 
39
39
  ```
40
40
  Chemicalml
41
41
  ├── parse(xml, schema: :schema3) # top-level entry point
42
- ├── Model # canonical, format-agnostic chemistry objects
43
- ├── Cml # CML XML wire-format classes
44
- │ ├── Base::* # shared attribute+mapping mixins
45
- │ ├── Schema3::* # Schema 3 wire classes
46
- │ ├── Schema24::* # Schema 2.4 wire classes
47
- └── Translator # the only adapter between Model and Cml
42
+ ├── Cml # CML model (lutaml-model Serializables)
43
+ ├── Base::* # shared attribute + xml-mapping mixins
44
+ │ ├── Schema3::* # Schema 3 classes (121 elements)
45
+ │ ├── Schema24::* # Schema 2.4 classes (121 + 3 legacy)
46
+ │ ├── Role::* # type-marker modules (schema-version-agnostic)
47
+ ├── Visitable # constraint-walker interface
48
+ │ └── WireClassRegistry # (schema, role) → class lookup
48
49
  ├── Schema # version registry
49
50
  ├── Convention # 5 conventions + constraint framework
50
51
  └── Dictionary # dictionary model + YAML store
51
52
  ```
52
53
 
54
+ The Cml classes ARE the model — every one is a
55
+ `Lutaml::Model::Serializable` subclass with `attribute` declarations
56
+ and an `xml do ... end` mapping block. lutaml-model handles XML
57
+ parsing and serialization directly. There is no separate "canonical"
58
+ layer and no translator.
59
+
53
60
  ### Schema-versioned wire classes (mirrors `mml` V3/V4 pattern)
54
61
 
55
62
  Both Schema 3 and Schema 2.4 have **real, distinct** class hierarchies
@@ -83,43 +90,41 @@ Chemicalml::Cml::Schema3.parse(xml) # version-specific
83
90
  Chemicalml::Cml::Schema24.parse(xml) # version-specific
84
91
  ```
85
92
 
86
- ### The canonical model (`Chemicalml::Model::*`)
87
-
88
- Plain Ruby `Node` subclasses. **No XML, no JSON, no YAML**. Format-agnostic.
89
- Every adapter speaks this model; adapters never talk to each other directly.
90
- `Node` provides `accept(visitor)`, `value_attributes`, `children`, and
91
- class-level `short_name` so visitors written against the canonical model
92
- work across every adapter.
93
+ ### The CML model (`Chemicalml::Cml::*`)
93
94
 
94
- ### The CML wire layer (`Chemicalml::Cml::*`)
95
+ Every CML element is a `Lutaml::Model::Serializable` subclass — these
96
+ ARE the model. lutaml-model is format-agnostic (XML/JSON/YAML/TOML
97
+ via adapters), so the same class supports whatever serialization
98
+ lutaml-model supports. Each class includes three mixins:
95
99
 
96
- Every CML element is a `Lutaml::Model::Serializable` subclass that
97
- includes three mixins: a `Base::*` module (shared declarations +
98
- xml mapping + `namespace Chemicalml::Cml::Namespace`), a
99
- `Role::*` marker module (type identity used by constraints and the
100
- translator independent of which schema version's class it is), and
101
- `Cml::Visitable` (uniform interface for the constraint walker —
102
- `wire_children`, `node_id`, `element_name`).
100
+ - a `Base::*` module (shared `attribute` declarations + `xml do ... end`
101
+ mapping block + `namespace Chemicalml::Cml::Namespace`)
102
+ - a `Role::*` marker module (type identity used by constraints —
103
+ independent of which schema version's class it is)
104
+ - `Cml::Visitable` (uniform interface for the constraint walker
105
+ `wire_children`, `node_id`, `element_name`)
103
106
 
104
107
  Wire classes are generated in-place by each schema module from the
105
- shared `Chemicalml::Cml::Elements::ALL` table — no 70+ boilerplate
106
- files. Adding a new CML element = adding one entry to `Elements::ALL`,
107
- one `Base::*` mixin, and one `Role::*` module. Both `Schema3::*` and
108
- `Schema24::*` pick up the new element automatically (unless it's
109
- listed in `Elements::SCHEMA3_ONLY`).
108
+ shared `Chemicalml::Cml::Elements::ALL` table — 121 entries spanning
109
+ the entire Schema 3 XSD. Adding a new CML element = adding one entry
110
+ to `Elements::ALL`, one `Base::*` mixin, and one `Role::*` module.
111
+ Both `Schema3::*` and `Schema24::*` pick up the new element
112
+ automatically unless it's listed in `Elements::SCHEMA3_ONLY`
113
+ (currently `%i[AnyCml]` — the only element in Schema 3 that Schema 2.4
114
+ lacks; verified by direct XSD diff).
115
+
116
+ Schema 2.4 actually declares 137 elements (a superset of Schema 3 in
117
+ most respects); 17 legacy elements (`alternative`, `annotation`,
118
+ `appinfo`, `arg`, `complexObject`, `enumeration`, `expression`,
119
+ `float`, `floatArray`, `integer`, `integerArray`, `operator`,
120
+ `relatedEntry`, `string`, `stringArray`, `tcell`, `trow`) are
121
+ Schema-2.4-only. Three of them (`annotation`, `appinfo`,
122
+ `enumeration`) are explicitly modeled in `Elements::SCHEMA24_ONLY`
123
+ because they carry semantic meaning; the rest are redundant with
124
+ Schema 3's unified `scalar`/`array`/`table` machinery.
110
125
 
111
126
  The framework handles (de)serialization; **never** add `def to_xml` /
112
- `def from_xml` /
113
- `def to_h` to these classes.
114
-
115
- ### The translator (`Chemicalml::Cml::Translator`)
116
-
117
- Pure transformation. `to_canonical(wire_doc)` accepts either Schema3
118
- or Schema24 wire documents (dispatches via `is_a?`).
119
- `from_canonical(model_doc, schema: :schema3)` produces the requested
120
- schema's wire format. It is the **only** place that imports both
121
- `Chemicalml::Model` and `Chemicalml::Cml`. Adding a new CML element
122
- means updating translator rules — the two namespaces stay decoupled.
127
+ `def from_xml` / `def to_h` to these classes.
123
128
 
124
129
  ### Schema versions
125
130
 
@@ -172,9 +177,11 @@ These are non-negotiable and apply in addition to the user's global rules:
172
177
  or `respond_to?` for type checks.** Use `is_a?` or design the type
173
178
  hierarchy so the check isn't needed.
174
179
 
175
- 5. **One concern, one place (MECE).** Adding a CML element = adding one
176
- model class + one Cml class + one translator rule + specs. Don't
177
- entangle them.
180
+ 5. **One concern, one place (MECE).** Adding a CML element = adding
181
+ one `Base::*` mixin + one `Role::*` module + one entry to
182
+ `Elements::ALL` + (if needed) one entry to `SCHEMA3_ONLY` or
183
+ `SCHEMA24_ONLY`. Both Schema3::* and Schema24::* pick it up
184
+ automatically.
178
185
 
179
186
  ## Reference docs (in-tree)
180
187
 
@@ -0,0 +1,46 @@
1
+ # 36 — Molecular convention: full upstream constraint coverage
2
+
3
+ ## Why
4
+
5
+ `reference-docs/conventions/molecular.md` mandates more rules than the
6
+ gem currently enforces. The walker framework already exists; this is
7
+ purely additive constraint registration.
8
+
9
+ ## Current constraints (13)
10
+
11
+ AtomArrayMustContainAtoms, AtomIdsUniqueWithinMolecule,
12
+ BondMustReferenceAtomsInSameMolecule, AtomMustHaveId,
13
+ AtomMustHaveElementType, BondMustHaveAtomRefs2, BondMustHaveOrder,
14
+ MoleculeMustHaveId, AtomCoordinatesMustBePaired,
15
+ PropertyMustHaveDictRef, ScalarMustHaveDataType,
16
+ BondOrderShouldNotBeNumeric, AtomIdMustMatchPattern.
17
+
18
+ ## Missing rules per upstream spec
19
+
20
+ - `count` attribute MUST NOT appear on top-level molecules (only on
21
+ children of another molecule).
22
+ - `atomArray` — at most one per molecule; mutually exclusive with
23
+ child `<molecule>` elements.
24
+ - `bondArray` — at most one per molecule; mutually exclusive with
25
+ child `<molecule>` elements.
26
+ - `bondStereo` value `W` or `H` MUST have `atomRefs2`, MUST NOT have
27
+ `atomRefs4`.
28
+ - `bondStereo` value `C` or `T` MUST have `atomRefs4`, MUST NOT have
29
+ `atomRefs2`.
30
+ - `bondStereo` value `other` MUST have `dictRef`.
31
+ - `bond` `id` MUST be unique within the eldest containing molecule.
32
+ - `bond` with `order="other"` MUST have `dictRef`.
33
+ - `atomArray` MUST be a child of `molecule` or `formula`.
34
+ - `bondArray` MUST be a child of `molecule`.
35
+
36
+ ## Implementation
37
+
38
+ Each rule → one Constraint subclass + `register` call in
39
+ `lib/chemicalml/convention/molecular.rb`. New files autoloaded from
40
+ `lib/chemicalml/convention/molecular/constraints.rb`.
41
+
42
+ ## Acceptance
43
+
44
+ - 10 new constraint classes registered.
45
+ - Per-class spec under `spec/chemicalml/convention/molecular/`.
46
+ - Full suite still green.
@@ -0,0 +1,55 @@
1
+ # 37 — CompChem convention: full upstream constraint coverage
2
+
3
+ ## Why
4
+
5
+ `reference-docs/conventions/compchem.md` defines a deep module
6
+ structure (jobList → job → initialization/calculation/finalization/
7
+ environment) and value-container rules. The gem currently ships only
8
+ 2 of the ~19 rules.
9
+
10
+ ## Current constraints (2)
11
+
12
+ CompchemModuleMustContainJobList, JobMustContainInitialization.
13
+
14
+ ## Missing structural rules
15
+
16
+ - `jobList` module MUST have `id` unique within compchem module.
17
+ - `job` module MUST have `id` unique within compchem module.
18
+ - `job` module MUST contain at most one `finalization`.
19
+ - `job` module MUST contain at most one `environment`.
20
+ - If a `calculation` is present in a `job`, a `finalization` MUST
21
+ also be present (co-constraint).
22
+ - `initialization` module MUST NOT contain `property`/`propertyList`.
23
+ - `initialization` module MUST NOT contain more than one `molecule`.
24
+ - `initialization` module MUST NOT contain more than one
25
+ `parameterList`.
26
+ - `finalization` module MUST NOT contain `parameter`/`parameterList`.
27
+ - `finalization` module MUST NOT contain more than one `molecule`.
28
+ - `finalization` module MUST NOT contain more than one `propertyList`.
29
+ - `environment` module MUST NOT contain more than one `propertyList`.
30
+ - `environment` module MUST NOT contain `parameter`/`parameterList`
31
+ directly.
32
+
33
+ ## Missing value-container rules
34
+
35
+ - `scalar` with `dataType` `xsd:integer` or `xsd:double` MUST have
36
+ `units`.
37
+ - `scalar` with `dataType` `xsd:string` MUST NOT have `units`.
38
+ - `array` MUST have `size` ≥ 1; `dataType` MUST be integer or double;
39
+ MUST have `units`.
40
+ - `matrix` MUST have `rows` ≥ 1 and `columns` ≥ 1; `dataType` MUST
41
+ be integer or double; MUST have `units`.
42
+
43
+ ## Implementation
44
+
45
+ Use `DocumentConstraint` for cross-node rules (calculation→finalization
46
+ co-constraint), `NodeConstraint` for single-node rules.
47
+
48
+ CompChem modules are `<module dictRef="compchem:*">`. Match by
49
+ `node.is_a?(Chemicalml::Cml::Role::Module)` then check `dict_ref`.
50
+
51
+ ## Acceptance
52
+
53
+ - 17 new constraint classes registered.
54
+ - Per-class spec under `spec/chemicalml/convention/compchem/`.
55
+ - Full suite still green.
@@ -0,0 +1,34 @@
1
+ # 38 — Dictionary convention: full upstream constraint coverage
2
+
3
+ ## Why
4
+
5
+ `reference-docs/conventions/dictionary.md` requires namespace,
6
+ definition children, id patterns, and unitType/units co-constraints.
7
+ Currently 2 of 7 rules enforced.
8
+
9
+ ## Current constraints (2)
10
+
11
+ EntryMustHaveIdAndTerm, EntryIdsUniqueWithinDictionary.
12
+
13
+ ## Missing rules
14
+
15
+ - `dictionary` MUST have `namespace` attribute.
16
+ - `dictionary` `namespace` SHOULD end with `/` or `#` (warning).
17
+ - `entry` MUST contain a single `definition` child.
18
+ - `entry` `id` MUST match `[A-Za-z][A-Za-z0-9._-]*`.
19
+ - `entry` MUST have `unitType` attribute.
20
+ - If `unitType` is `unknown`, `units` MUST NOT be present.
21
+ - If `unitType` is `none`, `units` MUST be present and point to
22
+ `http://www.xml-cml.org/unit/si#none`.
23
+
24
+ ## Implementation
25
+
26
+ New files under
27
+ `lib/chemicalml/convention/dictionary/constraints/`, registered in
28
+ `lib/chemicalml/convention/dictionary.rb`.
29
+
30
+ ## Acceptance
31
+
32
+ - 7 new constraint classes registered.
33
+ - Per-class spec under `spec/chemicalml/convention/dictionary/`.
34
+ - Full suite still green.
@@ -0,0 +1,33 @@
1
+ # 39 — Unit-dictionary convention: full upstream constraint coverage
2
+
3
+ ## Why
4
+
5
+ `reference-docs/conventions/unit-dictionary.md` requires 8 attributes
6
+ on every `<unit>`. The gem currently ships 1 rule.
7
+
8
+ ## Current constraints (1)
9
+
10
+ UnitMustHaveSymbolAndUnitType.
11
+
12
+ ## Missing rules
13
+
14
+ - `unitList` MUST have `namespace` attribute.
15
+ - `unit` MUST have `id` (unique within unitList — already implied by
16
+ pattern rules but enforce presence).
17
+ - `unit` MUST have `title` attribute.
18
+ - `unit` MUST have `parentSI` attribute.
19
+ - `unit` MUST have at least one of `multiplierToSI` or `constantToSI`.
20
+ - `unit` MUST contain a single `definition` child.
21
+ - `unitList` MUST contain at least one `unit` child.
22
+
23
+ ## Implementation
24
+
25
+ NodeConstraint subclasses. Register in
26
+ `lib/chemicalml/convention/unit_dictionary.rb`.
27
+
28
+ ## Acceptance
29
+
30
+ - 7 new constraint classes registered (some may consolidate with
31
+ existing UnitMustHaveSymbolAndUnitType).
32
+ - Per-class spec under `spec/chemicalml/convention/unit_dictionary/`.
33
+ - Full suite still green.
@@ -0,0 +1,28 @@
1
+ # 40 — UnitType-dictionary convention: full upstream constraint coverage
2
+
3
+ ## Why
4
+
5
+ `reference-docs/conventions/unitType-dictionary.md` requires
6
+ namespace, definition child, and id pattern. The gem ships 1 rule.
7
+
8
+ ## Current constraints (1)
9
+
10
+ UnitTypeMustHaveIdAndName.
11
+
12
+ ## Missing rules
13
+
14
+ - `unitTypeList` MUST have `namespace` attribute.
15
+ - `unitType` MUST contain a single `definition` child.
16
+ - `unitType` `id` MUST match `[A-Za-z][A-Za-z0-9._-]*`.
17
+ - `unitTypeList` MUST contain at least one `unitType` child.
18
+
19
+ ## Implementation
20
+
21
+ NodeConstraint subclasses. Register in
22
+ `lib/chemicalml/convention/unit_type_dictionary.rb`.
23
+
24
+ ## Acceptance
25
+
26
+ - 4 new constraint classes registered.
27
+ - Per-class spec under `spec/chemicalml/convention/unit_type_dictionary/`.
28
+ - Full suite still green.
@@ -0,0 +1,43 @@
1
+ # 41 — Expand canonical Model layer for chemistry completeness
2
+
3
+ ## Why
4
+
5
+ The canonical `Model::*` layer has 28 classes but the CML wire layer
6
+ has 121. Many chemistry concepts (crystallography, spectroscopy,
7
+ z-matrix, isotopes, samples, reaction schemes) have no canonical
8
+ representation, forcing callers to use wire classes directly —
9
+ breaking the "all adapters speak the canonical model" invariant.
10
+
11
+ ## New Model classes
12
+
13
+ - `Model::Lattice` — `lattice_type`, `a/b/c/alpha/beta/gamma`,
14
+ children: cell_parameters, lattice_vectors
15
+ - `Model::Crystal` — wraps lattice + scalar/array geometry
16
+ - `Model::ZMatrix` — internal coordinates (atomRefs + lengths/angles)
17
+ - `Model::Isotope` — number, spin, abundance, mass
18
+ - `Model::IsotopeList` — collection
19
+ - `Model::Sample` — sample metadata (state, amount, count)
20
+ - `Model::Spectrum` — `id`, `title`, `dict_ref`, xaxis/yaxis,
21
+ spectrum_data
22
+ - `Model::Peak` — `atomRefs`, `xValue`, `yValue`, `multiplicity`,
23
+ `peakShape`
24
+ - `Model::PeakList` — collection
25
+ - `Model::ReactionScheme` — `id`, `name`, reaction_step_list
26
+ - `Model::ReactionStep` — `atoms`, `reactiveCentre`, `type`
27
+ - `Model::Spectator` / `Model::SpectatorList`
28
+ - `Model::MoleculeList` — collection (distinct from `molecule[]`)
29
+ - `Model::Observation` — observation record
30
+
31
+ ## Implementation pattern
32
+
33
+ Each class subclasses `Model::Node` and provides:
34
+ - `attr_accessor` for every value
35
+ - `initialize` with keyword args + sensible defaults
36
+ - `children` returning child Model nodes
37
+ - `value_attributes` returning the equality/hash snapshot
38
+
39
+ ## Acceptance
40
+
41
+ - 14 new Model classes.
42
+ - Per-class spec under `spec/chemicalml/model/`.
43
+ - Full suite still green.
@@ -0,0 +1,31 @@
1
+ # 42 — Wire new Model classes through the translator
2
+
3
+ ## Why
4
+
5
+ New `Model::*` classes from TODO 41 are inert until the translator
6
+ maps them to/from CML wire format.
7
+
8
+ ## Translator additions
9
+
10
+ - `molecule_to_canonical`: include `crystal`, `spectra`,
11
+ `spectra_lists`, `z_matrix`, `isotope_list`, `sample` fields.
12
+ - `molecule_from_canonical`: reverse of above.
13
+ - New helpers: `crystal_to/from_canonical`,
14
+ `lattice_to/from_canonical`, `spectrum_to/from_canonical`,
15
+ `peak_to/from_canonical`, `z_matrix_to/from_canonical`,
16
+ `isotope_to/from_canonical`, `sample_to/from_canonical`,
17
+ `reaction_scheme_to/from_canonical`, `spectator_to/from_canonical`.
18
+ - `module_to_canonical`: stop hardcoding `lists: []` — collect
19
+ `<list>` children into Model::List collection.
20
+
21
+ ## Implementation
22
+
23
+ All schema-aware (take `schema:` keyword). Use `WireClassRegistry`
24
+ for every wire class lookup. Add to existing
25
+ `translator.rb` + `translator/value_translations.rb`.
26
+
27
+ ## Acceptance
28
+
29
+ - Round-trip spec: parse CML with crystal/spectrum/zMatrix →
30
+ Model → serialize → same CML (canon-compared).
31
+ - Full suite still green.
@@ -0,0 +1,39 @@
1
+ # 43 — Refactor Dictionary::Model away from hand-rolled `to_h`
2
+
3
+ ## Why
4
+
5
+ `lib/chemicalml/dictionary/model.rb`, `entry.rb`, `enum.rb`, `link.rb`
6
+ define `def to_h` — hand-rolled serialization. The project's coding
7
+ standard #2 forbids this. The Loader uses `to_h` to round-trip YAML,
8
+ but the canonical Model layer uses `value_attributes` for the same
9
+ purpose. Align Dictionary with the rest of the codebase.
10
+
11
+ ## Current state
12
+
13
+ ```ruby
14
+ class Model
15
+ def to_h
16
+ { namespace: ..., prefix: ..., title: ...,
17
+ description: ..., entries: entries.map(&:to_h) }
18
+ end
19
+ end
20
+ ```
21
+
22
+ Same pattern in Entry, Enum, Link.
23
+
24
+ ## Target
25
+
26
+ - Drop `def to_h`.
27
+ - `value_attributes` returns the same shape (used by Loader to dump
28
+ YAML, by `==`/`hash` for equality).
29
+ - Loader's `dump_to_hash` calls `model.value_attributes`.
30
+
31
+ If Loader needs a specific YAML shape (string keys vs symbol keys),
32
+ add a thin `as_yaml` adapter — but the model itself only exposes
33
+ `value_attributes`.
34
+
35
+ ## Acceptance
36
+
37
+ - No `def to_h` / `to_hash` anywhere in `lib/chemicalml/dictionary/`.
38
+ - Loader round-trip still works (specs pass).
39
+ - Full suite still green.
@@ -0,0 +1,44 @@
1
+ # 44 — Fix SCHEMA3_ONLY and add Schema24 Module class
2
+
3
+ ## Why
4
+
5
+ Actual XSD diff (via `grep '<xsd:element name='`):
6
+
7
+ - Schema3 has **121** elements. Our `Elements::ALL` matches.
8
+ - Schema24 has **137** elements (a superset of Schema3 for most parts).
9
+ - **`anyCml` is in Schema3 but NOT Schema24** → must be in
10
+ `SCHEMA3_ONLY`.
11
+ - `module` is in BOTH schemas → currently listed in SCHEMA3_ONLY
12
+ is **wrong**.
13
+
14
+ Current `SCHEMA3_ONLY = %i[Module]` is incorrect and Schema24 is
15
+ missing its `cml_module.rb` wire class entirely.
16
+
17
+ ## Fix
18
+
19
+ 1. `lib/chemicalml/cml/elements.rb`:
20
+ `SCHEMA3_ONLY = %i[AnyCml].freeze`
21
+ 2. Create `lib/chemicalml/cml/schema24/cml_module.rb` mirroring
22
+ `schema3/cml_module.rb`.
23
+ 3. Update Schema24 autoload list to include `cml_module`.
24
+ 4. Update translator comment ("Schema 3 only — Schema 2.4 lacks
25
+ `<module>`") — no longer accurate.
26
+ 5. Verify Schema24 Configuration registers Module.
27
+
28
+ ## Schema24-only elements (not modeled yet)
29
+
30
+ Schema24 has 16 elements not in Schema3: alternative, annotation,
31
+ appinfo, arg, complexObject, enumeration, expression, float,
32
+ floatArray, integer, integerArray, operator, relatedEntry, string,
33
+ stringArray, tcell, trow.
34
+
35
+ These are Schema-2.4-only legacy elements. They're outside the
36
+ gem's current scope (the gem focuses on Schema 3 + intersection).
37
+ Document them in CLAUDE.md so future contributors know.
38
+
39
+ ## Acceptance
40
+
41
+ - SCHEMA3_ONLY = %i[AnyCml].
42
+ - Schema24::CmlModule wire class exists, parses, serializes.
43
+ - Translator's module_from_canonical works for schema24.
44
+ - Full suite still green.
@@ -0,0 +1,23 @@
1
+ # 45 — Documentation cleanup and final spec verification
2
+
3
+ ## Why
4
+
5
+ Stale comments and docs rot fast. After TODOs 36–44 land, sweep the
6
+ codebase for outdated references and run the full suite end-to-end.
7
+
8
+ ## Updates
9
+
10
+ - `lib/chemicalml/cml.rb`: comment says "All 36 aliases load from a
11
+ single file" — actually 121 now.
12
+ - `CLAUDE.md`: refresh any counts (121 elements, ~45 constraints,
13
+ 14 model classes added, etc.).
14
+ - `CLAUDE.md`: note Schema24-only legacy elements not modeled.
15
+ - Verify `bundle exec rspec` is fully green.
16
+ - Verify `bundle exec rubocop` is clean (or autocorrect what's
17
+ safe).
18
+
19
+ ## Acceptance
20
+
21
+ - All counts in docs match the actual codebase.
22
+ - Full rspec suite passes.
23
+ - Rubocop reports no new offenses.
@@ -0,0 +1,24 @@
1
+ # 46 — Fix LatticeVector content attribute
2
+
3
+ ## Why
4
+
5
+ `<latticeVector>1 0 0</latticeVector>` carries vector components as
6
+ element content. `lib/chemicalml/cml/base/lattice_vector.rb` declares
7
+ only id/title/dictRef/convention/units — **no content attribute**.
8
+ The translator's workaround maps `lv.content` ↔ wire `units` —
9
+ semantically wrong (units ≠ vector components).
10
+
11
+ ## Fix
12
+
13
+ 1. Add `attribute :content, :string` + `map_content` to Base::LatticeVector.
14
+ 2. Update Model::LatticeVector to carry `units` and `content` as
15
+ independent fields.
16
+ 3. Update translator `lattice_vector_to/from_canonical` to map both.
17
+ 4. Spec round-trip.
18
+
19
+ ## Acceptance
20
+
21
+ - `<latticeVector units="unit:nm">1 0 0</latticeVector>` round-trips
22
+ with units and content preserved.
23
+ - Translator spec covers the fix.
24
+ - Full suite green.
@@ -0,0 +1,23 @@
1
+ # 47 — Wire Molecule#crystal/spectra/property_lists through translator
2
+
3
+ ## Why
4
+
5
+ `Base::Molecule` declares `crystal`, `spectra`, `property_lists`
6
+ children, but `Model::Molecule` doesn't have those fields and
7
+ `molecule_to_canonical/from_canonical` silently drops them. Silent
8
+ data loss.
9
+
10
+ ## Fix
11
+
12
+ 1. Add `crystal`, `spectra`, `property_lists` accessors to
13
+ `Model::Molecule`.
14
+ 2. Wire through `molecule_to_canonical` (read wire, build Model) and
15
+ `molecule_from_canonical` (read Model, build wire).
16
+ 3. Update `Model::Molecule#children` and `#value_attributes`.
17
+ 4. Spec round-trip with a molecule containing crystal + propertyList.
18
+
19
+ ## Acceptance
20
+
21
+ - A molecule with `<crystal>` and `<propertyList>` children round-trips
22
+ through canonical without loss.
23
+ - Full suite green.
@@ -0,0 +1,21 @@
1
+ # 48 — Add Model::List and wire Module#lists
2
+
3
+ ## Why
4
+
5
+ `Model::Module` has a `lists` accessor but `module_to_canonical`
6
+ hardcodes `lists: []`. There is no `Model::List` canonical class, so
7
+ wire `<list>` children of `<module>` are silently dropped.
8
+
9
+ ## Fix
10
+
11
+ 1. Add `Model::List` mirroring `Base::List` shape: id/title/dictRef/
12
+ convention + scalar/array/matrix/list children.
13
+ 2. Wire `module_to_canonical` to map `wire_module.lists` (drop the
14
+ hardcoded `[]`).
15
+ 3. Wire `module_from_canonical` reverse.
16
+ 4. Spec round-trip.
17
+
18
+ ## Acceptance
19
+
20
+ - A `<module>` containing a `<list>` child round-trips without loss.
21
+ - Full suite green.
@@ -0,0 +1,34 @@
1
+ # 49 — Add more chemistry Model classes
2
+
3
+ ## Why
4
+
5
+ Several chemically-meaningful CML elements still lack canonical Model
6
+ classes, forcing callers to use wire classes directly and breaking the
7
+ "all adapters speak canonical" invariant.
8
+
9
+ ## New Model classes
10
+
11
+ - `Model::Torsion` — `<torsion>` (4-atom dihedral)
12
+ - `Model::Angle` — `<angle>` (3-atom angle)
13
+ - `Model::Length` — `<length>` (2-atom distance)
14
+ - `Model::Action` / `Model::ActionList` — `<action>` / `<actionList>`
15
+ - `Model::Map` — `<map>` (atom mapping across reaction)
16
+ - `Model::Fragment` / `Model::FragmentList` — substructure references
17
+ - `Model::ReactionStepList` — list of `<reactionStep>`
18
+ - `Model::ReactiveCentre` — `<reactiveCentre>`
19
+ - `Model::TransitionState` — `<transitionState>`
20
+ - `Model::PeakGroup` — `<peakGroup>`
21
+ - `Model::SpectrumList` — `<spectrumList>`
22
+ - `Model::SpectrumData` — `<spectrumData>`
23
+ - `Model::Region` — `<region>`
24
+
25
+ ## Wire translator mappings
26
+
27
+ For each new Model class, add `*_to_canonical` / `*_from_canonical`
28
+ helpers. Most are simple (id/title/dictRef/convention).
29
+
30
+ ## Acceptance
31
+
32
+ - Each new Model class has instantiation + value_attributes specs.
33
+ - Translator mappings round-trip.
34
+ - Full suite green.