chemicalml 0.1.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 (248) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rubocop.yml +20 -0
  4. data/CHANGELOG.md +21 -0
  5. data/CLAUDE.md +198 -0
  6. data/Gemfile +14 -0
  7. data/LICENSE +24 -0
  8. data/NOTICES.adoc +115 -0
  9. data/README.adoc +87 -0
  10. data/Rakefile +8 -0
  11. data/TODO.align/01-cml-base-mixins.md +122 -0
  12. data/TODO.align/02-real-schema-hierarchies.md +88 -0
  13. data/TODO.align/03-configuration.md +50 -0
  14. data/TODO.align/04-parse-entry-points.md +59 -0
  15. data/TODO.align/05-schema-aware-translator.md +33 -0
  16. data/TODO.align/06-no-respond-to.md +44 -0
  17. data/TODO.align/07-canon-xml-comparison.md +43 -0
  18. data/TODO.align/08-expand-fixtures.md +37 -0
  19. data/TODO.align/09-final-spec-lint.md +29 -0
  20. data/TODO.align/10-role-marker-modules.md +54 -0
  21. data/TODO.align/11-dry-configuration.md +63 -0
  22. data/TODO.align/12-wire-class-macro.md +51 -0
  23. data/TODO.align/13-wire-namespace.md +44 -0
  24. data/TODO.align/14-schema24-correctness.md +37 -0
  25. data/TODO.align/15-canon-fixture-roundtrip.md +38 -0
  26. data/TODO.align/16-schema24-convention-coverage.md +33 -0
  27. data/TODO.align/17-final-spec-lint.md +28 -0
  28. data/TODO.align/README.md +27 -0
  29. data/TODO.align/README.round2.md +24 -0
  30. data/TODO.cml-full/01-reference-docs.md +43 -0
  31. data/TODO.cml-full/02-schema-versioned-model.md +70 -0
  32. data/TODO.cml-full/03-fixtures-scrape.md +52 -0
  33. data/TODO.cml-full/04-convention-framework.md +69 -0
  34. data/TODO.cml-full/05-dictionary-layer.md +77 -0
  35. data/TODO.cml-full/06-extend-canonical-translator.md +60 -0
  36. data/TODO.cml-full/07-attribution-notices.md +42 -0
  37. data/TODO.cml-full/08-autoload-only.md +48 -0
  38. data/TODO.cml-full/09-spec-coverage.md +38 -0
  39. data/TODO.cml-full/README.md +23 -0
  40. data/chemicalml.gemspec +35 -0
  41. data/data/dictionaries/_index.yaml +14 -0
  42. data/data/dictionaries/compchem.yaml +481 -0
  43. data/data/dictionaries/unit_non_si.yaml +53 -0
  44. data/data/dictionaries/unit_si.yaml +87 -0
  45. data/data/dictionaries/unit_type.yaml +113 -0
  46. data/lib/chemicalml/cml/array.rb +10 -0
  47. data/lib/chemicalml/cml/atom.rb +10 -0
  48. data/lib/chemicalml/cml/atom_array.rb +10 -0
  49. data/lib/chemicalml/cml/atom_parity.rb +10 -0
  50. data/lib/chemicalml/cml/base/array.rb +36 -0
  51. data/lib/chemicalml/cml/base/atom.rb +38 -0
  52. data/lib/chemicalml/cml/base/atom_array.rb +22 -0
  53. data/lib/chemicalml/cml/base/atom_parity.rb +24 -0
  54. data/lib/chemicalml/cml/base/bond.rb +28 -0
  55. data/lib/chemicalml/cml/base/bond_array.rb +22 -0
  56. data/lib/chemicalml/cml/base/bond_stereo.rb +28 -0
  57. data/lib/chemicalml/cml/base/cml_module.rb +40 -0
  58. data/lib/chemicalml/cml/base/dictionary.rb +32 -0
  59. data/lib/chemicalml/cml/base/dictionary_entry.rb +34 -0
  60. data/lib/chemicalml/cml/base/document.rb +26 -0
  61. data/lib/chemicalml/cml/base/formula.rb +38 -0
  62. data/lib/chemicalml/cml/base/identifier.rb +26 -0
  63. data/lib/chemicalml/cml/base/label.rb +28 -0
  64. data/lib/chemicalml/cml/base/list.rb +36 -0
  65. data/lib/chemicalml/cml/base/matrix.rb +38 -0
  66. data/lib/chemicalml/cml/base/metadata.rb +30 -0
  67. data/lib/chemicalml/cml/base/metadata_list.rb +28 -0
  68. data/lib/chemicalml/cml/base/molecule.rb +40 -0
  69. data/lib/chemicalml/cml/base/name.rb +26 -0
  70. data/lib/chemicalml/cml/base/parameter.rb +34 -0
  71. data/lib/chemicalml/cml/base/parameter_list.rb +28 -0
  72. data/lib/chemicalml/cml/base/product.rb +22 -0
  73. data/lib/chemicalml/cml/base/product_list.rb +22 -0
  74. data/lib/chemicalml/cml/base/property.rb +34 -0
  75. data/lib/chemicalml/cml/base/property_list.rb +28 -0
  76. data/lib/chemicalml/cml/base/reactant.rb +22 -0
  77. data/lib/chemicalml/cml/base/reactant_list.rb +22 -0
  78. data/lib/chemicalml/cml/base/reaction.rb +32 -0
  79. data/lib/chemicalml/cml/base/reaction_list.rb +22 -0
  80. data/lib/chemicalml/cml/base/scalar.rb +32 -0
  81. data/lib/chemicalml/cml/base/substance.rb +30 -0
  82. data/lib/chemicalml/cml/base/unit.rb +38 -0
  83. data/lib/chemicalml/cml/base/unit_list.rb +30 -0
  84. data/lib/chemicalml/cml/base/unit_type.rb +28 -0
  85. data/lib/chemicalml/cml/base/unit_type_list.rb +30 -0
  86. data/lib/chemicalml/cml/base.rb +51 -0
  87. data/lib/chemicalml/cml/bond.rb +10 -0
  88. data/lib/chemicalml/cml/bond_array.rb +10 -0
  89. data/lib/chemicalml/cml/bond_stereo.rb +10 -0
  90. data/lib/chemicalml/cml/cml_module.rb +10 -0
  91. data/lib/chemicalml/cml/dictionary.rb +10 -0
  92. data/lib/chemicalml/cml/dictionary_entry.rb +10 -0
  93. data/lib/chemicalml/cml/document.rb +10 -0
  94. data/lib/chemicalml/cml/elements.rb +58 -0
  95. data/lib/chemicalml/cml/formula.rb +10 -0
  96. data/lib/chemicalml/cml/identifier.rb +10 -0
  97. data/lib/chemicalml/cml/label.rb +10 -0
  98. data/lib/chemicalml/cml/list.rb +10 -0
  99. data/lib/chemicalml/cml/matrix.rb +10 -0
  100. data/lib/chemicalml/cml/metadata.rb +10 -0
  101. data/lib/chemicalml/cml/metadata_list.rb +10 -0
  102. data/lib/chemicalml/cml/molecule.rb +10 -0
  103. data/lib/chemicalml/cml/name.rb +10 -0
  104. data/lib/chemicalml/cml/namespace.rb +17 -0
  105. data/lib/chemicalml/cml/parameter.rb +10 -0
  106. data/lib/chemicalml/cml/parameter_list.rb +10 -0
  107. data/lib/chemicalml/cml/product.rb +10 -0
  108. data/lib/chemicalml/cml/product_list.rb +10 -0
  109. data/lib/chemicalml/cml/property.rb +10 -0
  110. data/lib/chemicalml/cml/property_list.rb +10 -0
  111. data/lib/chemicalml/cml/reactant.rb +10 -0
  112. data/lib/chemicalml/cml/reactant_list.rb +10 -0
  113. data/lib/chemicalml/cml/reaction.rb +10 -0
  114. data/lib/chemicalml/cml/reaction_list.rb +10 -0
  115. data/lib/chemicalml/cml/role/array.rb +13 -0
  116. data/lib/chemicalml/cml/role/atom.rb +13 -0
  117. data/lib/chemicalml/cml/role/atom_array.rb +13 -0
  118. data/lib/chemicalml/cml/role/atom_parity.rb +13 -0
  119. data/lib/chemicalml/cml/role/bond.rb +13 -0
  120. data/lib/chemicalml/cml/role/bond_array.rb +13 -0
  121. data/lib/chemicalml/cml/role/bond_stereo.rb +13 -0
  122. data/lib/chemicalml/cml/role/cml_module.rb +14 -0
  123. data/lib/chemicalml/cml/role/dictionary.rb +13 -0
  124. data/lib/chemicalml/cml/role/dictionary_entry.rb +13 -0
  125. data/lib/chemicalml/cml/role/document.rb +13 -0
  126. data/lib/chemicalml/cml/role/formula.rb +13 -0
  127. data/lib/chemicalml/cml/role/identifier.rb +13 -0
  128. data/lib/chemicalml/cml/role/label.rb +13 -0
  129. data/lib/chemicalml/cml/role/list.rb +13 -0
  130. data/lib/chemicalml/cml/role/matrix.rb +13 -0
  131. data/lib/chemicalml/cml/role/metadata.rb +13 -0
  132. data/lib/chemicalml/cml/role/metadata_list.rb +13 -0
  133. data/lib/chemicalml/cml/role/molecule.rb +13 -0
  134. data/lib/chemicalml/cml/role/name.rb +13 -0
  135. data/lib/chemicalml/cml/role/parameter.rb +13 -0
  136. data/lib/chemicalml/cml/role/parameter_list.rb +13 -0
  137. data/lib/chemicalml/cml/role/product.rb +13 -0
  138. data/lib/chemicalml/cml/role/product_list.rb +13 -0
  139. data/lib/chemicalml/cml/role/property.rb +13 -0
  140. data/lib/chemicalml/cml/role/property_list.rb +13 -0
  141. data/lib/chemicalml/cml/role/reactant.rb +13 -0
  142. data/lib/chemicalml/cml/role/reactant_list.rb +13 -0
  143. data/lib/chemicalml/cml/role/reaction.rb +13 -0
  144. data/lib/chemicalml/cml/role/reaction_list.rb +13 -0
  145. data/lib/chemicalml/cml/role/scalar.rb +13 -0
  146. data/lib/chemicalml/cml/role/substance.rb +13 -0
  147. data/lib/chemicalml/cml/role/unit.rb +13 -0
  148. data/lib/chemicalml/cml/role/unit_list.rb +13 -0
  149. data/lib/chemicalml/cml/role/unit_type.rb +13 -0
  150. data/lib/chemicalml/cml/role/unit_type_list.rb +13 -0
  151. data/lib/chemicalml/cml/role.rb +54 -0
  152. data/lib/chemicalml/cml/scalar.rb +10 -0
  153. data/lib/chemicalml/cml/schema24/configuration.rb +19 -0
  154. data/lib/chemicalml/cml/schema24.rb +40 -0
  155. data/lib/chemicalml/cml/schema3/configuration.rb +17 -0
  156. data/lib/chemicalml/cml/schema3.rb +40 -0
  157. data/lib/chemicalml/cml/substance.rb +10 -0
  158. data/lib/chemicalml/cml/translator/value_translations.rb +265 -0
  159. data/lib/chemicalml/cml/translator.rb +233 -0
  160. data/lib/chemicalml/cml/unit.rb +10 -0
  161. data/lib/chemicalml/cml/unit_list.rb +10 -0
  162. data/lib/chemicalml/cml/unit_type.rb +10 -0
  163. data/lib/chemicalml/cml/unit_type_list.rb +10 -0
  164. data/lib/chemicalml/cml/visitable.rb +65 -0
  165. data/lib/chemicalml/cml/wire_class_macro.rb +45 -0
  166. data/lib/chemicalml/cml.rb +55 -0
  167. data/lib/chemicalml/context_configuration.rb +127 -0
  168. data/lib/chemicalml/convention/base.rb +48 -0
  169. data/lib/chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list.rb +33 -0
  170. data/lib/chemicalml/convention/compchem/constraints/job_must_contain_initialization.rb +38 -0
  171. data/lib/chemicalml/convention/compchem/constraints.rb +14 -0
  172. data/lib/chemicalml/convention/compchem.rb +28 -0
  173. data/lib/chemicalml/convention/constraint.rb +79 -0
  174. data/lib/chemicalml/convention/dictionary/constraints/entry_ids_unique_within_dictionary.rb +33 -0
  175. data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_id_and_term.rb +34 -0
  176. data/lib/chemicalml/convention/dictionary/constraints.rb +14 -0
  177. data/lib/chemicalml/convention/dictionary.rb +28 -0
  178. data/lib/chemicalml/convention/molecular/constraints/atom_array_must_contain_atoms.rb +30 -0
  179. data/lib/chemicalml/convention/molecular/constraints/atom_ids_unique_within_molecule.rb +42 -0
  180. data/lib/chemicalml/convention/molecular/constraints/bond_must_reference_atoms_in_same_molecule.rb +54 -0
  181. data/lib/chemicalml/convention/molecular/constraints.rb +19 -0
  182. data/lib/chemicalml/convention/molecular.rb +29 -0
  183. data/lib/chemicalml/convention/registry.rb +50 -0
  184. data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb +46 -0
  185. data/lib/chemicalml/convention/unit_dictionary/constraints.rb +12 -0
  186. data/lib/chemicalml/convention/unit_dictionary.rb +27 -0
  187. data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb +34 -0
  188. data/lib/chemicalml/convention/unit_type_dictionary/constraints.rb +12 -0
  189. data/lib/chemicalml/convention/unit_type_dictionary.rb +27 -0
  190. data/lib/chemicalml/convention/violation.rb +36 -0
  191. data/lib/chemicalml/convention.rb +39 -0
  192. data/lib/chemicalml/dictionary/entry.rb +59 -0
  193. data/lib/chemicalml/dictionary/enum.rb +51 -0
  194. data/lib/chemicalml/dictionary/link.rb +32 -0
  195. data/lib/chemicalml/dictionary/loader.rb +60 -0
  196. data/lib/chemicalml/dictionary/model.rb +64 -0
  197. data/lib/chemicalml/dictionary/registry.rb +75 -0
  198. data/lib/chemicalml/dictionary.rb +26 -0
  199. data/lib/chemicalml/errors.rb +7 -0
  200. data/lib/chemicalml/model/atom.rb +40 -0
  201. data/lib/chemicalml/model/bond.rb +33 -0
  202. data/lib/chemicalml/model/cml_array.rb +27 -0
  203. data/lib/chemicalml/model/cml_module.rb +45 -0
  204. data/lib/chemicalml/model/document.rb +29 -0
  205. data/lib/chemicalml/model/formula.rb +34 -0
  206. data/lib/chemicalml/model/identifier.rb +21 -0
  207. data/lib/chemicalml/model/label.rb +21 -0
  208. data/lib/chemicalml/model/matrix.rb +29 -0
  209. data/lib/chemicalml/model/metadata.rb +23 -0
  210. data/lib/chemicalml/model/metadata_list.rb +25 -0
  211. data/lib/chemicalml/model/molecule.rb +38 -0
  212. data/lib/chemicalml/model/name.rb +21 -0
  213. data/lib/chemicalml/model/node.rb +45 -0
  214. data/lib/chemicalml/model/parameter.rb +27 -0
  215. data/lib/chemicalml/model/parameter_list.rb +25 -0
  216. data/lib/chemicalml/model/product.rb +21 -0
  217. data/lib/chemicalml/model/product_list.rb +21 -0
  218. data/lib/chemicalml/model/property.rb +28 -0
  219. data/lib/chemicalml/model/property_list.rb +25 -0
  220. data/lib/chemicalml/model/reactant.rb +21 -0
  221. data/lib/chemicalml/model/reactant_list.rb +21 -0
  222. data/lib/chemicalml/model/reaction.rb +41 -0
  223. data/lib/chemicalml/model/reaction_list.rb +23 -0
  224. data/lib/chemicalml/model/scalar.rb +25 -0
  225. data/lib/chemicalml/model/substance.rb +25 -0
  226. data/lib/chemicalml/model.rb +38 -0
  227. data/lib/chemicalml/schema/definition.rb +41 -0
  228. data/lib/chemicalml/schema/registry.rb +30 -0
  229. data/lib/chemicalml/schema.rb +35 -0
  230. data/lib/chemicalml/version.rb +5 -0
  231. data/lib/chemicalml/versioned_parser.rb +43 -0
  232. data/lib/chemicalml.rb +47 -0
  233. data/lib/tasks/reference_fetch.rake +105 -0
  234. data/lib/tasks/scrape_fixtures.rake +133 -0
  235. data/reference-docs/conventions/compchem.md +141 -0
  236. data/reference-docs/conventions/dictionary.md +119 -0
  237. data/reference-docs/conventions/index.md +56 -0
  238. data/reference-docs/conventions/molecular.md +115 -0
  239. data/reference-docs/conventions/unit-dictionary.md +92 -0
  240. data/reference-docs/conventions/unitType-dictionary.md +51 -0
  241. data/reference-docs/dictionaries/compchem.md +335 -0
  242. data/reference-docs/dictionaries/index.md +52 -0
  243. data/reference-docs/examples/schema24-index.md +50 -0
  244. data/reference-docs/examples/schema3-compchem-index.md +14 -0
  245. data/reference-docs/examples/schema3-molecular-index.md +28 -0
  246. data/reference-docs/schemas/schema24/schema.xsd +10624 -0
  247. data/reference-docs/schemas/schema3/schema.xsd +11459 -0
  248. metadata +306 -0
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ # Dictionary model layer. Canonical, format-agnostic representation
5
+ # of CML dictionaries (the dictionary, unit-dictionary, and
6
+ # unitType-dictionary conventions all share this shape).
7
+ #
8
+ # Built-in dictionaries ship as YAML under `data/dictionaries/` and
9
+ # are loaded into `Chemicalml::Dictionary::Registry` lazily.
10
+ module Dictionary
11
+ autoload :Entry, "chemicalml/dictionary/entry"
12
+ autoload :Enum, "chemicalml/dictionary/enum"
13
+ autoload :Link, "chemicalml/dictionary/link"
14
+ autoload :Loader, "chemicalml/dictionary/loader"
15
+ autoload :Model, "chemicalml/dictionary/model"
16
+ autoload :Registry, "chemicalml/dictionary/registry"
17
+
18
+ BUILTIN_DIR = File.expand_path("../../data/dictionaries", __dir__).freeze
19
+
20
+ # Convenience: load a built-in dictionary by short name
21
+ # (e.g. `:compchem`). Returns a `Chemicalml::Dictionary::Model`.
22
+ def self.load(name)
23
+ Registry.load_builtin(name)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ class Error < StandardError; end
5
+
6
+ class ParseError < Error; end
7
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A chemical atom. Carries every attribute CML's `<atom>` carries
6
+ # that's chemistry-relevant: element symbol, formal charge,
7
+ # isotope, count (multiplicity), hydrogen count, lone pairs,
8
+ # radical electrons, spin multiplicity.
9
+ class Atom < Node
10
+ attr_accessor :id, :element, :formal_charge, :isotope,
11
+ :count, :hydrogen_count, :lone_pairs,
12
+ :radical_electrons, :spin_multiplicity, :title
13
+
14
+ def initialize(element:, id: nil, formal_charge: nil,
15
+ isotope: nil, count: nil, hydrogen_count: nil,
16
+ lone_pairs: nil, radical_electrons: nil,
17
+ spin_multiplicity: nil, title: nil)
18
+ @element = element
19
+ @id = id
20
+ @formal_charge = formal_charge
21
+ @isotope = isotope
22
+ @count = count
23
+ @hydrogen_count = hydrogen_count
24
+ @lone_pairs = lone_pairs
25
+ @radical_electrons = radical_electrons
26
+ @spin_multiplicity = spin_multiplicity
27
+ @title = title
28
+ end
29
+
30
+ def value_attributes
31
+ {
32
+ element: element, id: id, formal_charge: formal_charge,
33
+ isotope: isotope, count: count, hydrogen_count: hydrogen_count,
34
+ lone_pairs: lone_pairs, radical_electrons: radical_electrons,
35
+ spin_multiplicity: spin_multiplicity, title: title
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A bond between two atoms. Endpoint references are string IDs
6
+ # matching `Atom#id`; the kind enum follows CML conventions.
7
+ class Bond < Node
8
+ KINDS = %i[single double triple quadruple aromatic wedge hash
9
+ dative wavy].freeze
10
+
11
+ CML_ORDER = {
12
+ single: "S", double: "D", triple: "T", quadruple: "Q",
13
+ aromatic: "A", wedge: "W", hash: "H", dative: "DG", wavy: "V"
14
+ }.freeze
15
+
16
+ attr_accessor :id, :atom_refs, :kind
17
+
18
+ def initialize(id: nil, atom_refs:, kind: :single)
19
+ @id = id
20
+ @atom_refs = atom_refs
21
+ @kind = kind
22
+ end
23
+
24
+ def value_attributes
25
+ { id: id, atom_refs: atom_refs, kind: kind }
26
+ end
27
+
28
+ def cml_order
29
+ CML_ORDER.fetch(kind, "S")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A one-dimensional array of values.
6
+ class Array < Node
7
+ attr_accessor :id, :title, :dict_ref, :data_type, :units,
8
+ :size, :values
9
+
10
+ def initialize(values:, data_type: nil, units: nil, size: nil,
11
+ id: nil, title: nil, dict_ref: nil)
12
+ @values = values
13
+ @data_type = data_type
14
+ @units = units
15
+ @size = size
16
+ @id = id
17
+ @title = title
18
+ @dict_ref = dict_ref
19
+ end
20
+
21
+ def value_attributes
22
+ { values: values, data_type: data_type, units: units,
23
+ size: size, id: id, title: title, dict_ref: dict_ref }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A generic grouping container (CML `<module>`). The `dict_ref`
6
+ # attribute identifies the module's role (e.g.
7
+ # `compchem:jobList`, `compchem:initialization`).
8
+ class Module < Node
9
+ attr_accessor :id, :title, :dict_ref, :convention,
10
+ :molecules, :modules, :parameter_lists,
11
+ :property_lists, :metadata_lists, :lists
12
+
13
+ def initialize(id: nil, title: nil, dict_ref: nil, convention: nil,
14
+ molecules: [], modules: [],
15
+ parameter_lists: [], property_lists: [],
16
+ metadata_lists: [], lists: [])
17
+ @id = id
18
+ @title = title
19
+ @dict_ref = dict_ref
20
+ @convention = convention
21
+ @molecules = molecules
22
+ @modules = modules
23
+ @parameter_lists = parameter_lists
24
+ @property_lists = property_lists
25
+ @metadata_lists = metadata_lists
26
+ @lists = lists
27
+ end
28
+
29
+ def children
30
+ molecules + modules + parameter_lists + property_lists + metadata_lists + lists
31
+ end
32
+
33
+ def value_attributes
34
+ {
35
+ id: id, title: title, dict_ref: dict_ref, convention: convention,
36
+ molecules: molecules, modules: modules,
37
+ parameter_lists: parameter_lists,
38
+ property_lists: property_lists,
39
+ metadata_lists: metadata_lists,
40
+ lists: lists
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Top-level container: the canonical document. Parallel to
6
+ # `AsciiChem::Model::Formula`. Holds an ordered list of
7
+ # molecules, reactions, and reaction lists.
8
+ class Document < Node
9
+ attr_accessor :molecules, :reactions, :reaction_lists
10
+
11
+ def initialize(molecules: [], reactions: [], reaction_lists: [])
12
+ @molecules = molecules
13
+ @reactions = reactions
14
+ @reaction_lists = reaction_lists
15
+ end
16
+
17
+ def children
18
+ molecules + reactions + reaction_lists
19
+ end
20
+
21
+ def value_attributes
22
+ {
23
+ molecules: molecules, reactions: reactions,
24
+ reaction_lists: reaction_lists
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Canonical formula. Three complementary forms: a structured
6
+ # `atom_array`, a `concise` string (e.g. "C 1 H 4 O 1"), or an
7
+ # `inline` representation (e.g. LaTeX "H_{3}C-OH").
8
+ class Formula < Node
9
+ attr_accessor :id, :concise, :inline, :formal_charge, :count,
10
+ :title, :convention, :dict_ref
11
+
12
+ def initialize(id: nil, concise: nil, inline: nil,
13
+ formal_charge: nil, count: nil, title: nil,
14
+ convention: nil, dict_ref: nil)
15
+ @id = id
16
+ @concise = concise
17
+ @inline = inline
18
+ @formal_charge = formal_charge
19
+ @count = count
20
+ @title = title
21
+ @convention = convention
22
+ @dict_ref = dict_ref
23
+ end
24
+
25
+ def value_attributes
26
+ {
27
+ id: id, concise: concise, inline: inline,
28
+ formal_charge: formal_charge, count: count, title: title,
29
+ convention: convention, dict_ref: dict_ref
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # An external identifier: InChI, SMILES, CAS-RN, etc. The
6
+ # `convention` field tags the identifier kind.
7
+ class Identifier < Node
8
+ attr_accessor :value, :convention, :dict_ref
9
+
10
+ def initialize(value:, convention: nil, dict_ref: nil)
11
+ @value = value
12
+ @convention = convention
13
+ @dict_ref = dict_ref
14
+ end
15
+
16
+ def value_attributes
17
+ { value: value, convention: convention, dict_ref: dict_ref }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A string label with a `dict_ref` pointing to a dictionary entry.
6
+ class Label < Node
7
+ attr_accessor :id, :value, :dict_ref, :convention
8
+
9
+ def initialize(value:, dict_ref:, id: nil, convention: nil)
10
+ @value = value
11
+ @dict_ref = dict_ref
12
+ @id = id
13
+ @convention = convention
14
+ end
15
+
16
+ def value_attributes
17
+ { value: value, dict_ref: dict_ref, id: id, convention: convention }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A two-dimensional rectangular matrix of values.
6
+ class Matrix < Node
7
+ attr_accessor :id, :title, :dict_ref, :data_type, :units,
8
+ :rows, :columns, :values
9
+
10
+ def initialize(values:, rows:, columns:, data_type: nil, units: nil,
11
+ id: nil, title: nil, dict_ref: nil)
12
+ @values = values
13
+ @rows = rows
14
+ @columns = columns
15
+ @data_type = data_type
16
+ @units = units
17
+ @id = id
18
+ @title = title
19
+ @dict_ref = dict_ref
20
+ end
21
+
22
+ def value_attributes
23
+ { values: values, rows: rows, columns: columns,
24
+ data_type: data_type, units: units,
25
+ id: id, title: title, dict_ref: dict_ref }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A single metadata key/value pair.
6
+ class Metadata < Node
7
+ attr_accessor :id, :name, :content, :convention, :title
8
+
9
+ def initialize(name:, content:, id: nil, convention: nil, title: nil)
10
+ @name = name
11
+ @content = content
12
+ @id = id
13
+ @convention = convention
14
+ @title = title
15
+ end
16
+
17
+ def value_attributes
18
+ { name: name, content: content, id: id,
19
+ convention: convention, title: title }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Container for `Metadata` instances.
6
+ class MetadataList < Node
7
+ attr_accessor :id, :title, :dict_ref, :metadata
8
+
9
+ def initialize(metadata: [], id: nil, title: nil, dict_ref: nil)
10
+ @metadata = metadata
11
+ @id = id
12
+ @title = title
13
+ @dict_ref = dict_ref
14
+ end
15
+
16
+ def children
17
+ metadata
18
+ end
19
+
20
+ def value_attributes
21
+ { metadata: metadata, id: id, title: title, dict_ref: dict_ref }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A molecule: ordered atom list + optional bond list + optional
6
+ # names and identifiers + optional count (multiplicity in a
7
+ # larger context).
8
+ class Molecule < Node
9
+ attr_accessor :id, :atoms, :bonds, :names, :identifiers,
10
+ :count, :formal_charge, :title
11
+
12
+ def initialize(id: nil, atoms: [], bonds: [], names: [],
13
+ identifiers: [], count: nil, formal_charge: nil,
14
+ title: nil)
15
+ @id = id
16
+ @atoms = atoms
17
+ @bonds = bonds
18
+ @names = names
19
+ @identifiers = identifiers
20
+ @count = count
21
+ @formal_charge = formal_charge
22
+ @title = title
23
+ end
24
+
25
+ def children
26
+ atoms + bonds + names + identifiers
27
+ end
28
+
29
+ def value_attributes
30
+ {
31
+ id: id, atoms: atoms, bonds: bonds, names: names,
32
+ identifiers: identifiers, count: count,
33
+ formal_charge: formal_charge, title: title
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A molecule name. The `convention` field tags the naming scheme
6
+ # (e.g. `"iupac:systematic"`, `"trivial"`).
7
+ class Name < Node
8
+ attr_accessor :content, :convention, :dict_ref
9
+
10
+ def initialize(content:, convention: nil, dict_ref: nil)
11
+ @content = content
12
+ @convention = convention
13
+ @dict_ref = dict_ref
14
+ end
15
+
16
+ def value_attributes
17
+ { content: content, convention: convention, dict_ref: dict_ref }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Base class for every canonical model node. Mirrors the contract
6
+ # of `AsciiChem::Model::Node` so visitors written against one
7
+ # model work against the other without modification.
8
+ class Node
9
+ def accept(visitor)
10
+ visitor.public_send(:"visit_#{self.class.short_name}", self)
11
+ rescue NoMethodError => e
12
+ raise unless e.name == :"visit_#{self.class.short_name}"
13
+
14
+ raise NotImplementedError,
15
+ "#{visitor.class} does not implement visit_#{self.class.short_name}"
16
+ end
17
+
18
+ def ==(other)
19
+ other.is_a?(self.class) && value_attributes == other.value_attributes
20
+ end
21
+ alias eql? ==
22
+
23
+ def hash
24
+ [self.class, value_attributes].hash
25
+ end
26
+
27
+ def children
28
+ []
29
+ end
30
+
31
+ def value_attributes
32
+ {}
33
+ end
34
+
35
+ def self.short_name
36
+ @short_name ||= begin
37
+ snake = name.split("::").last
38
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
39
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
40
+ snake.downcase
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # An input parameter — same shape as Property, used for inputs.
6
+ class Parameter < Node
7
+ attr_accessor :id, :title, :dict_ref, :convention, :value
8
+
9
+ def initialize(value:, dict_ref:, id: nil, title: nil, convention: nil)
10
+ @value = value
11
+ @dict_ref = dict_ref
12
+ @id = id
13
+ @title = title
14
+ @convention = convention
15
+ end
16
+
17
+ def children
18
+ [value].compact
19
+ end
20
+
21
+ def value_attributes
22
+ { id: id, title: title, dict_ref: dict_ref,
23
+ convention: convention, value: value }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Container for `Parameter` instances.
6
+ class ParameterList < Node
7
+ attr_accessor :id, :title, :dict_ref, :parameters
8
+
9
+ def initialize(parameters: [], id: nil, title: nil, dict_ref: nil)
10
+ @parameters = parameters
11
+ @id = id
12
+ @title = title
13
+ @dict_ref = dict_ref
14
+ end
15
+
16
+ def children
17
+ parameters
18
+ end
19
+
20
+ def value_attributes
21
+ { parameters: parameters, id: id, title: title, dict_ref: dict_ref }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ class Product < Node
6
+ attr_accessor :substance
7
+
8
+ def initialize(substance:)
9
+ @substance = substance
10
+ end
11
+
12
+ def children
13
+ [substance]
14
+ end
15
+
16
+ def value_attributes
17
+ { substance: substance }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ class ProductList < Node
6
+ attr_accessor :products
7
+
8
+ def initialize(products: [])
9
+ @products = products
10
+ end
11
+
12
+ def children
13
+ products
14
+ end
15
+
16
+ def value_attributes
17
+ { products: products }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # A named property that wraps a value (scalar/array/matrix) and
6
+ # points to a dictionary entry via `dict_ref`.
7
+ class Property < Node
8
+ attr_accessor :id, :title, :dict_ref, :convention, :value
9
+
10
+ def initialize(value:, dict_ref:, id: nil, title: nil, convention: nil)
11
+ @value = value
12
+ @dict_ref = dict_ref
13
+ @id = id
14
+ @title = title
15
+ @convention = convention
16
+ end
17
+
18
+ def children
19
+ [value].compact
20
+ end
21
+
22
+ def value_attributes
23
+ { id: id, title: title, dict_ref: dict_ref,
24
+ convention: convention, value: value }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ # Container for `Property` instances.
6
+ class PropertyList < Node
7
+ attr_accessor :id, :title, :dict_ref, :properties
8
+
9
+ def initialize(properties: [], id: nil, title: nil, dict_ref: nil)
10
+ @properties = properties
11
+ @id = id
12
+ @title = title
13
+ @dict_ref = dict_ref
14
+ end
15
+
16
+ def children
17
+ properties
18
+ end
19
+
20
+ def value_attributes
21
+ { properties: properties, id: id, title: title, dict_ref: dict_ref }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ class Reactant < Node
6
+ attr_accessor :substance
7
+
8
+ def initialize(substance:)
9
+ @substance = substance
10
+ end
11
+
12
+ def children
13
+ [substance]
14
+ end
15
+
16
+ def value_attributes
17
+ { substance: substance }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemicalml
4
+ module Model
5
+ class ReactantList < Node
6
+ attr_accessor :reactants
7
+
8
+ def initialize(reactants: [])
9
+ @reactants = reactants
10
+ end
11
+
12
+ def children
13
+ reactants
14
+ end
15
+
16
+ def value_attributes
17
+ { reactants: reactants }
18
+ end
19
+ end
20
+ end
21
+ end