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.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +7 -1
- data/.rubocop.yml +23 -0
- data/CLAUDE.md +95 -40
- data/README.adoc +154 -26
- data/TODO.align/36-molecular-convention-coverage.md +46 -0
- data/TODO.align/37-compchem-convention-coverage.md +55 -0
- data/TODO.align/38-dictionary-convention-coverage.md +34 -0
- data/TODO.align/39-unit-dictionary-convention-coverage.md +33 -0
- data/TODO.align/40-unit-type-dictionary-convention-coverage.md +28 -0
- data/TODO.align/41-expand-canonical-model-layer.md +43 -0
- data/TODO.align/42-translator-wire-new-models.md +31 -0
- data/TODO.align/43-dictionary-model-no-to-h.md +39 -0
- data/TODO.align/44-schema3-only-and-schema24-module.md +44 -0
- data/TODO.align/45-documentation-and-final-verification.md +23 -0
- data/TODO.align/46-lattice-vector-content.md +24 -0
- data/TODO.align/47-molecule-crystal-spectra-property-lists.md +23 -0
- data/TODO.align/48-model-list-and-module-lists.md +21 -0
- data/TODO.align/49-more-chemistry-models.md +34 -0
- data/TODO.align/50-validation-report.md +29 -0
- data/TODO.align/51-convention-auto-detection.md +30 -0
- data/TODO.align/52-schema24-legacy-elements.md +28 -0
- data/TODO.align/53-round-trip-integration-specs.md +30 -0
- data/TODO.align/54-document-versioned-parser-shim.md +38 -0
- data/TODO.align/55-molecule-missing-attributes.md +20 -0
- data/TODO.align/56-geometry-models.md +24 -0
- data/TODO.align/57-compchem-models.md +26 -0
- data/TODO.align/58-remaining-models.md +24 -0
- data/TODO.align/59-wire-new-models-translator.md +18 -0
- data/TODO.align/60-docs-and-final-verification.md +19 -0
- data/TODO.align/61-parallel-array-attrs.md +54 -0
- data/TODO.align/62-per-element-attribute-gaps.md +49 -0
- data/TODO.align/63-universal-children-mixin.md +42 -0
- data/TODO.align/64-per-element-child-gaps.md +81 -0
- data/TODO.align/65-simple-unit-convention.md +40 -0
- data/TODO.align/66-schema24-legacy-children.md +32 -0
- data/TODO.align/67-final-verification.md +32 -0
- data/TODO.align/68-detection-coverage.md +33 -0
- data/TODO.align/69-json-yaml-roundtrip.md +27 -0
- data/TODO.align/70-iterative-walker.md +40 -0
- data/TODO.align/71-violation-value.md +25 -0
- data/TODO.align/72-close-child-gaps.md +66 -0
- data/TODO.align/73-schema24-parse-limitation.md +64 -0
- data/TODO.align/74-final-verification-round18.md +15 -0
- data/TODO.align/75-key-value-mappings.md +43 -0
- data/TODO.align/76-schema24-workaround.md +57 -0
- data/TODO.align/77-convention-coverage-matrix.md +31 -0
- data/TODO.align/78-fixture-audit.md +23 -0
- data/TODO.align/79-final-verification-round19.md +15 -0
- data/TODO.align/80-xsd-enum-constants.md +35 -0
- data/TODO.align/81-enum-validation-constraints.md +29 -0
- data/TODO.align/82-reference-resolver.md +33 -0
- data/TODO.align/83-toml-roundtrip.md +20 -0
- data/TODO.align/84-final-verification-round21.md +16 -0
- data/TODO.align/85-bond-distinct-atoms.md +25 -0
- data/TODO.align/86-references-should-resolve.md +20 -0
- data/TODO.align/87-cli-utility.md +26 -0
- data/TODO.align/88-diverse-fixtures.md +26 -0
- data/TODO.align/89-final-verification-round22.md +15 -0
- data/TODO.align/90-bond-stereo-completeness.md +31 -0
- data/TODO.align/91-atomparity-distinct.md +21 -0
- data/TODO.align/92-unit-dictionary-completeness.md +28 -0
- data/TODO.align/93-yard-docs.md +23 -0
- data/TODO.align/94-final-verification-round23.md +15 -0
- data/TODO.align/README.round17.md +28 -0
- data/TODO.align/README.round18.md +37 -0
- data/TODO.align/README.round19.md +40 -0
- data/TODO.align/README.round20.md +49 -0
- data/TODO.align/README.round21.md +35 -0
- data/TODO.align/README.round22.md +48 -0
- data/TODO.align/README.round23.md +46 -0
- data/TODO.align/README.round24.md +53 -0
- data/TODO.align/README.round25.md +66 -0
- data/TODO.align/README.round26.md +55 -0
- data/TODO.align/README.round27.md +51 -0
- data/TODO.align/README.round28.md +61 -0
- data/TODO.align/README.round29.md +64 -0
- data/TODO.align/README.round30.md +50 -0
- data/TODO.align/README.round31.md +54 -0
- data/TODO.align/README.round32.md +67 -0
- data/TODO.align/README.round33.md +62 -0
- data/TODO.align/README.round34.md +70 -0
- data/docs/constraints.md +161 -0
- data/docs/generate_constraint_docs.rb +44 -0
- data/exe/chemicalml +6 -0
- data/lib/chemicalml/cli/base.rb +68 -0
- data/lib/chemicalml/cli/command.rb +43 -0
- data/lib/chemicalml/cli/constraints_command.rb +27 -0
- data/lib/chemicalml/cli/conventions_command.rb +14 -0
- data/lib/chemicalml/cli/dictionaries_command.rb +14 -0
- data/lib/chemicalml/cli/elements_command.rb +17 -0
- data/lib/chemicalml/cli/enums_command.rb +17 -0
- data/lib/chemicalml/cli/info_command.rb +77 -0
- data/lib/chemicalml/cli/inspect_command.rb +39 -0
- data/lib/chemicalml/cli/validate_command.rb +54 -0
- data/lib/chemicalml/cli.rb +43 -0
- data/lib/chemicalml/cml/base/abundance.rb +21 -5
- data/lib/chemicalml/cml/base/action.rb +44 -6
- data/lib/chemicalml/cml/base/action_list.rb +44 -8
- data/lib/chemicalml/cml/base/alternative.rb +37 -0
- data/lib/chemicalml/cml/base/amount.rb +15 -5
- data/lib/chemicalml/cml/base/angle.rb +34 -7
- data/lib/chemicalml/cml/base/annotation.rb +38 -0
- data/lib/chemicalml/cml/base/any_cml.rb +12 -5
- data/lib/chemicalml/cml/base/appinfo.rb +40 -0
- data/lib/chemicalml/cml/base/arg.rb +80 -0
- data/lib/chemicalml/cml/base/array.rb +51 -8
- data/lib/chemicalml/cml/base/array_list.rb +15 -5
- data/lib/chemicalml/cml/base/atom.rb +93 -19
- data/lib/chemicalml/cml/base/atom_array.rb +77 -2
- data/lib/chemicalml/cml/base/atom_parity.rb +18 -2
- data/lib/chemicalml/cml/base/atom_set.rb +15 -5
- data/lib/chemicalml/cml/base/atom_type.rb +27 -7
- data/lib/chemicalml/cml/base/atom_type_list.rb +23 -7
- data/lib/chemicalml/cml/base/atomic_basis_function.rb +35 -11
- data/lib/chemicalml/cml/base/band.rb +22 -7
- data/lib/chemicalml/cml/base/band_list.rb +15 -7
- data/lib/chemicalml/cml/base/basis_set.rb +26 -7
- data/lib/chemicalml/cml/base/bond.rb +39 -7
- data/lib/chemicalml/cml/base/bond_array.rb +41 -2
- data/lib/chemicalml/cml/base/bond_set.rb +15 -5
- data/lib/chemicalml/cml/base/bond_stereo.rb +25 -4
- data/lib/chemicalml/cml/base/bond_type.rb +24 -7
- data/lib/chemicalml/cml/base/bond_type_list.rb +23 -7
- data/lib/chemicalml/cml/base/cell_parameter.rb +30 -8
- data/lib/chemicalml/cml/base/cml_module.rb +36 -11
- data/lib/chemicalml/cml/base/common_children.rb +35 -0
- data/lib/chemicalml/cml/base/complex_object.rb +37 -0
- data/lib/chemicalml/cml/base/condition_list.rb +28 -8
- data/lib/chemicalml/cml/base/crystal.rb +27 -9
- data/lib/chemicalml/cml/base/definition.rb +12 -5
- data/lib/chemicalml/cml/base/description.rb +15 -5
- data/lib/chemicalml/cml/base/dictionary.rb +30 -7
- data/lib/chemicalml/cml/base/dictionary_entry.rb +67 -8
- data/lib/chemicalml/cml/base/dimension.rb +31 -7
- data/lib/chemicalml/cml/base/document.rb +18 -8
- data/lib/chemicalml/cml/base/documentation.rb +12 -5
- data/lib/chemicalml/cml/base/eigen.rb +33 -7
- data/lib/chemicalml/cml/base/electron.rb +29 -9
- data/lib/chemicalml/cml/base/enumeration.rb +41 -0
- data/lib/chemicalml/cml/base/expression.rb +47 -0
- data/lib/chemicalml/cml/base/float.rb +52 -0
- data/lib/chemicalml/cml/base/float_array.rb +55 -0
- data/lib/chemicalml/cml/base/formula.rb +31 -10
- data/lib/chemicalml/cml/base/fragment.rb +33 -9
- data/lib/chemicalml/cml/base/fragment_list.rb +26 -7
- data/lib/chemicalml/cml/base/gradient.rb +19 -6
- data/lib/chemicalml/cml/base/identifier.rb +22 -4
- data/lib/chemicalml/cml/base/integer.rb +52 -0
- data/lib/chemicalml/cml/base/integer_array.rb +55 -0
- data/lib/chemicalml/cml/base/isotope.rb +29 -8
- data/lib/chemicalml/cml/base/isotope_list.rb +18 -7
- data/lib/chemicalml/cml/base/join.rb +28 -6
- data/lib/chemicalml/cml/base/kpoint.rb +17 -6
- data/lib/chemicalml/cml/base/kpoint_list.rb +15 -7
- data/lib/chemicalml/cml/base/label.rb +15 -5
- data/lib/chemicalml/cml/base/lattice.rb +36 -9
- data/lib/chemicalml/cml/base/lattice_vector.rb +17 -6
- data/lib/chemicalml/cml/base/length.rb +31 -7
- data/lib/chemicalml/cml/base/line3.rb +21 -5
- data/lib/chemicalml/cml/base/link.rb +51 -10
- data/lib/chemicalml/cml/base/list.rb +23 -9
- data/lib/chemicalml/cml/base/map.rb +38 -5
- data/lib/chemicalml/cml/base/matrix.rb +38 -9
- data/lib/chemicalml/cml/base/mechanism.rb +20 -7
- data/lib/chemicalml/cml/base/mechanism_component.rb +14 -6
- data/lib/chemicalml/cml/base/metadata.rb +20 -6
- data/lib/chemicalml/cml/base/metadata_list.rb +30 -5
- data/lib/chemicalml/cml/base/molecule.rb +95 -21
- data/lib/chemicalml/cml/base/molecule_list.rb +27 -7
- data/lib/chemicalml/cml/base/name.rb +11 -3
- data/lib/chemicalml/cml/base/object.rb +20 -6
- data/lib/chemicalml/cml/base/observation.rb +18 -5
- data/lib/chemicalml/cml/base/operator.rb +40 -0
- data/lib/chemicalml/cml/base/parameter.rb +38 -8
- data/lib/chemicalml/cml/base/parameter_list.rb +30 -5
- data/lib/chemicalml/cml/base/particle.rb +23 -6
- data/lib/chemicalml/cml/base/peak.rb +86 -11
- data/lib/chemicalml/cml/base/peak_group.rb +81 -7
- data/lib/chemicalml/cml/base/peak_list.rb +25 -8
- data/lib/chemicalml/cml/base/peak_structure.rb +47 -6
- data/lib/chemicalml/cml/base/plane3.rb +15 -5
- data/lib/chemicalml/cml/base/point3.rb +15 -5
- data/lib/chemicalml/cml/base/potential.rb +17 -6
- data/lib/chemicalml/cml/base/potential_form.rb +31 -6
- data/lib/chemicalml/cml/base/potential_list.rb +15 -7
- data/lib/chemicalml/cml/base/product.rb +53 -2
- data/lib/chemicalml/cml/base/product_list.rb +36 -2
- data/lib/chemicalml/cml/base/property.rb +32 -8
- data/lib/chemicalml/cml/base/property_list.rb +26 -5
- data/lib/chemicalml/cml/base/reactant.rb +53 -2
- data/lib/chemicalml/cml/base/reactant_list.rb +36 -2
- data/lib/chemicalml/cml/base/reaction.rb +82 -12
- data/lib/chemicalml/cml/base/reaction_list.rb +29 -2
- data/lib/chemicalml/cml/base/reaction_scheme.rb +48 -8
- data/lib/chemicalml/cml/base/reaction_step.rb +33 -9
- data/lib/chemicalml/cml/base/reaction_step_list.rb +34 -7
- data/lib/chemicalml/cml/base/reactive_centre.rb +31 -6
- data/lib/chemicalml/cml/base/region.rb +24 -5
- data/lib/chemicalml/cml/base/related_entry.rb +34 -0
- data/lib/chemicalml/cml/base/sample.rb +32 -5
- data/lib/chemicalml/cml/base/scalar.rb +41 -6
- data/lib/chemicalml/cml/base/spectator.rb +26 -5
- data/lib/chemicalml/cml/base/spectator_list.rb +20 -7
- data/lib/chemicalml/cml/base/spectrum.rb +63 -12
- data/lib/chemicalml/cml/base/spectrum_data.rb +20 -8
- data/lib/chemicalml/cml/base/spectrum_list.rb +30 -7
- data/lib/chemicalml/cml/base/sphere3.rb +15 -5
- data/lib/chemicalml/cml/base/stmml.rb +12 -5
- data/lib/chemicalml/cml/base/string.rb +40 -0
- data/lib/chemicalml/cml/base/string_array.rb +52 -0
- data/lib/chemicalml/cml/base/substance.rb +42 -8
- data/lib/chemicalml/cml/base/substance_list.rb +32 -7
- data/lib/chemicalml/cml/base/symmetry.rb +33 -7
- data/lib/chemicalml/cml/base/system.rb +23 -8
- data/lib/chemicalml/cml/base/table.rb +43 -8
- data/lib/chemicalml/cml/base/table_cell.rb +12 -5
- data/lib/chemicalml/cml/base/table_content.rb +20 -8
- data/lib/chemicalml/cml/base/table_header.rb +15 -7
- data/lib/chemicalml/cml/base/table_header_cell.rb +27 -5
- data/lib/chemicalml/cml/base/table_row.rb +15 -7
- data/lib/chemicalml/cml/base/table_row_list.rb +15 -7
- data/lib/chemicalml/cml/base/tcell.rb +43 -0
- data/lib/chemicalml/cml/base/torsion.rb +34 -7
- data/lib/chemicalml/cml/base/transform3.rb +12 -5
- data/lib/chemicalml/cml/base/transition_state.rb +23 -5
- data/lib/chemicalml/cml/base/trow.rb +48 -0
- data/lib/chemicalml/cml/base/unit.rb +45 -10
- data/lib/chemicalml/cml/base/unit_list.rb +40 -6
- data/lib/chemicalml/cml/base/unit_type.rb +32 -5
- data/lib/chemicalml/cml/base/unit_type_list.rb +34 -6
- data/lib/chemicalml/cml/base/vector3.rb +15 -5
- data/lib/chemicalml/cml/base/xaxis.rb +33 -7
- data/lib/chemicalml/cml/base/yaxis.rb +33 -7
- data/lib/chemicalml/cml/base/z_matrix.rb +26 -5
- data/lib/chemicalml/cml/base.rb +139 -121
- data/lib/chemicalml/cml/canonical_comparison.rb +54 -0
- data/lib/chemicalml/cml/elements.rb +168 -124
- data/lib/chemicalml/cml/enums.rb +55 -0
- data/lib/chemicalml/cml/namespace.rb +2 -3
- data/lib/chemicalml/cml/patterns.rb +33 -0
- data/lib/chemicalml/cml/reference_resolver.rb +137 -0
- data/lib/chemicalml/cml/role/alternative.rb +10 -0
- data/lib/chemicalml/cml/role/annotation.rb +10 -0
- data/lib/chemicalml/cml/role/appinfo.rb +10 -0
- data/lib/chemicalml/cml/role/arg.rb +10 -0
- data/lib/chemicalml/cml/role/cml_module.rb +2 -3
- data/lib/chemicalml/cml/role/complex_object.rb +10 -0
- data/lib/chemicalml/cml/role/enumeration.rb +10 -0
- data/lib/chemicalml/cml/role/expression.rb +10 -0
- data/lib/chemicalml/cml/role/float.rb +10 -0
- data/lib/chemicalml/cml/role/float_array.rb +10 -0
- data/lib/chemicalml/cml/role/integer.rb +10 -0
- data/lib/chemicalml/cml/role/integer_array.rb +10 -0
- data/lib/chemicalml/cml/role/operator.rb +10 -0
- data/lib/chemicalml/cml/role/related_entry.rb +10 -0
- data/lib/chemicalml/cml/role/string.rb +10 -0
- data/lib/chemicalml/cml/role/string_array.rb +10 -0
- data/lib/chemicalml/cml/role/tcell.rb +10 -0
- data/lib/chemicalml/cml/role/trow.rb +10 -0
- data/lib/chemicalml/cml/role.rb +138 -121
- data/lib/chemicalml/cml/schema24/alternative.rb +14 -0
- data/lib/chemicalml/cml/schema24/annotation.rb +15 -0
- data/lib/chemicalml/cml/schema24/appinfo.rb +15 -0
- data/lib/chemicalml/cml/schema24/arg.rb +14 -0
- data/lib/chemicalml/cml/schema24/cml_module.rb +18 -0
- data/lib/chemicalml/cml/schema24/complex_object.rb +14 -0
- data/lib/chemicalml/cml/schema24/configuration.rb +15 -2
- data/lib/chemicalml/cml/schema24/enumeration.rb +16 -0
- data/lib/chemicalml/cml/schema24/expression.rb +14 -0
- data/lib/chemicalml/cml/schema24/float.rb +14 -0
- data/lib/chemicalml/cml/schema24/float_array.rb +14 -0
- data/lib/chemicalml/cml/schema24/integer.rb +14 -0
- data/lib/chemicalml/cml/schema24/integer_array.rb +14 -0
- data/lib/chemicalml/cml/schema24/operator.rb +14 -0
- data/lib/chemicalml/cml/schema24/related_entry.rb +14 -0
- data/lib/chemicalml/cml/schema24/string.rb +14 -0
- data/lib/chemicalml/cml/schema24/string_array.rb +14 -0
- data/lib/chemicalml/cml/schema24/tcell.rb +14 -0
- data/lib/chemicalml/cml/schema24/trow.rb +14 -0
- data/lib/chemicalml/cml/schema24.rb +154 -126
- data/lib/chemicalml/cml/schema3.rb +123 -123
- data/lib/chemicalml/cml/visitable.rb +77 -3
- data/lib/chemicalml/cml/wire_class_registry.rb +3 -3
- data/lib/chemicalml/cml.rb +164 -132
- data/lib/chemicalml/context_configuration.rb +12 -4
- data/lib/chemicalml/convention/base.rb +17 -3
- data/lib/chemicalml/convention/cascade/constraints/reaction_scheme_must_have_content.rb +33 -0
- data/lib/chemicalml/convention/cascade/constraints/reaction_step_list_must_contain_steps.rb +31 -0
- data/lib/chemicalml/convention/cascade/constraints/reaction_step_must_have_reaction_or_lists.rb +33 -0
- data/lib/chemicalml/convention/cascade/constraints/reactive_centre_atom_refs_should_be_present.rb +34 -0
- data/lib/chemicalml/convention/cascade/constraints.rb +18 -0
- data/lib/chemicalml/convention/cascade.rb +43 -0
- data/lib/chemicalml/convention/compchem/constraints/array_rules.rb +44 -0
- data/lib/chemicalml/convention/compchem/constraints/calculation_requires_finalization.rb +28 -0
- data/lib/chemicalml/convention/compchem/constraints/compchem_module_must_contain_job_list.rb +5 -4
- data/lib/chemicalml/convention/compchem/constraints/environment_at_most_one_property_list.rb +26 -0
- data/lib/chemicalml/convention/compchem/constraints/environment_must_not_contain_parameter.rb +28 -0
- data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_molecule.rb +26 -0
- data/lib/chemicalml/convention/compchem/constraints/finalization_at_most_one_property_list.rb +26 -0
- data/lib/chemicalml/convention/compchem/constraints/finalization_must_have_content.rb +44 -0
- data/lib/chemicalml/convention/compchem/constraints/finalization_must_not_contain_parameter.rb +27 -0
- data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_molecule.rb +26 -0
- data/lib/chemicalml/convention/compchem/constraints/initialization_at_most_one_parameter_list.rb +26 -0
- data/lib/chemicalml/convention/compchem/constraints/initialization_must_have_content.rb +54 -0
- data/lib/chemicalml/convention/compchem/constraints/initialization_must_not_contain_property.rb +28 -0
- data/lib/chemicalml/convention/compchem/constraints/job_list_module_must_have_id.rb +25 -0
- data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_environment.rb +25 -0
- data/lib/chemicalml/convention/compchem/constraints/job_module_at_most_one_finalization.rb +25 -0
- data/lib/chemicalml/convention/compchem/constraints/job_module_must_have_id.rb +25 -0
- data/lib/chemicalml/convention/compchem/constraints/job_must_contain_initialization.rb +7 -9
- data/lib/chemicalml/convention/compchem/constraints/matrix_rules.rb +48 -0
- data/lib/chemicalml/convention/compchem/constraints/module_predicates.rb +50 -0
- data/lib/chemicalml/convention/compchem/constraints/scalar_units.rb +42 -0
- data/lib/chemicalml/convention/compchem/constraints.rb +40 -2
- data/lib/chemicalml/convention/compchem.rb +20 -2
- data/lib/chemicalml/convention/constraint.rb +68 -24
- data/lib/chemicalml/convention/coordinator.rb +90 -0
- data/lib/chemicalml/convention/detection.rb +39 -0
- data/lib/chemicalml/convention/dictionary/constraints/dictionary_must_have_namespace.rb +29 -0
- data/lib/chemicalml/convention/dictionary/constraints/dictionary_namespace_should_end_with_slash_or_hash.rb +32 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_id_must_match_pattern.rb +33 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_ids_unique_within_dictionary.rb +4 -4
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_contain_definition.rb +29 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_id_and_term.rb +6 -6
- data/lib/chemicalml/convention/dictionary/constraints/entry_must_have_unit_type.rb +31 -0
- data/lib/chemicalml/convention/dictionary/constraints/entry_units_co_constraints.rb +44 -0
- data/lib/chemicalml/convention/dictionary/constraints.rb +14 -2
- data/lib/chemicalml/convention/dictionary.rb +8 -2
- data/lib/chemicalml/convention/molecular/constraints/atom_array_must_be_child_of_molecule_or_formula.rb +41 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_array_must_contain_atoms.rb +18 -9
- data/lib/chemicalml/convention/molecular/constraints/atom_coordinates_must_be_paired.rb +6 -6
- data/lib/chemicalml/convention/molecular/constraints/atom_element_type_should_be_in_periodic_table.rb +39 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_id_must_match_pattern.rb +7 -6
- data/lib/chemicalml/convention/molecular/constraints/atom_ids_unique_within_molecule.rb +3 -2
- data/lib/chemicalml/convention/molecular/constraints/atom_must_have_element_type.rb +4 -4
- data/lib/chemicalml/convention/molecular/constraints/atom_must_have_id.rb +5 -4
- data/lib/chemicalml/convention/molecular/constraints/atom_parity_atom_refs4_should_be_distinct.rb +44 -0
- data/lib/chemicalml/convention/molecular/constraints/atom_parity_should_include_parent_atom.rb +65 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_array_must_be_child_of_molecule.rb +37 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_atom_refs2_should_be_distinct.rb +44 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_id_should_match_pattern.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_ids_unique_within_molecule.rb +44 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_must_have_atom_refs2.rb +4 -4
- data/lib/chemicalml/convention/molecular/constraints/bond_must_have_order.rb +5 -4
- data/lib/chemicalml/convention/molecular/constraints/bond_must_reference_atoms_in_same_molecule.rb +4 -3
- data/lib/chemicalml/convention/molecular/constraints/bond_order_other_must_have_dict_ref.rb +34 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_order_should_be_in_enum.rb +39 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_order_should_not_be_numeric.rb +3 -3
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_atom_refs4_should_be_distinct.rb +43 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_cis_trans_must_have_atom_refs4.rb +45 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_other_must_have_dict_ref.rb +33 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_should_be_in_enum.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/bond_stereo_wedge_hash_must_have_atom_refs2.rb +45 -0
- data/lib/chemicalml/convention/molecular/constraints/dict_ref_should_resolve.rb +59 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_atom_array_mutually_exclusive_with_children.rb +33 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_bond_array_mutually_exclusive_with_children.rb +32 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_chirality_should_be_in_enum.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_count_must_not_appear_on_top_level.rb +35 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_id_should_match_pattern.rb +38 -0
- data/lib/chemicalml/convention/molecular/constraints/molecule_must_have_id.rb +4 -4
- data/lib/chemicalml/convention/molecular/constraints/property_must_have_dict_ref.rb +4 -4
- data/lib/chemicalml/convention/molecular/constraints/property_scalar_data_type_matches_dictionary.rb +58 -0
- data/lib/chemicalml/convention/molecular/constraints/references_should_resolve.rb +37 -0
- data/lib/chemicalml/convention/molecular/constraints/scalar_must_have_data_type.rb +4 -4
- data/lib/chemicalml/convention/molecular/constraints.rb +59 -13
- data/lib/chemicalml/convention/molecular.rb +25 -2
- data/lib/chemicalml/convention/registry.rb +95 -10
- data/lib/chemicalml/convention/simple_unit/constraints/root_must_be_unit_list.rb +24 -0
- data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_power.rb +32 -0
- data/lib/chemicalml/convention/simple_unit/constraints/unit_must_have_symbol.rb +31 -0
- data/lib/chemicalml/convention/simple_unit/constraints.rb +16 -0
- data/lib/chemicalml/convention/simple_unit.rb +37 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/peak_list_must_contain_peaks.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/peak_should_have_values.rb +34 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_content.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_convention.rb +32 -0
- data/lib/chemicalml/convention/spectroscopy/constraints/spectrum_must_have_format.rb +31 -0
- data/lib/chemicalml/convention/spectroscopy/constraints.rb +20 -0
- data/lib/chemicalml/convention/spectroscopy.rb +41 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit.rb +29 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace.rb +36 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition.rb +28 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_id.rb +28 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_multiplier_or_constant_to_si.rb +34 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_parent_si.rb +32 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb +4 -4
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_title.rb +32 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_parent_si_should_resolve.rb +45 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints/unit_unit_type_should_resolve.rb +46 -0
- data/lib/chemicalml/convention/unit_dictionary/constraints.rb +19 -1
- data/lib/chemicalml/convention/unit_dictionary.rb +11 -2
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern.rb +31 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_contain_at_least_one_unit_type.rb +28 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_have_namespace.rb +35 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition.rb +28 -0
- data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb +6 -6
- data/lib/chemicalml/convention/unit_type_dictionary/constraints.rb +9 -1
- data/lib/chemicalml/convention/unit_type_dictionary.rb +6 -2
- data/lib/chemicalml/convention/validation_report.rb +90 -0
- data/lib/chemicalml/convention/violation.rb +9 -3
- data/lib/chemicalml/convention.rb +49 -11
- data/lib/chemicalml/dictionary/entry.rb +6 -6
- data/lib/chemicalml/dictionary/enum.rb +1 -1
- data/lib/chemicalml/dictionary/link.rb +3 -3
- data/lib/chemicalml/dictionary/loader.rb +19 -19
- data/lib/chemicalml/dictionary/model.rb +5 -5
- data/lib/chemicalml/dictionary/registry.rb +9 -9
- data/lib/chemicalml/dictionary.rb +13 -9
- data/lib/chemicalml/logger.rb +47 -0
- data/lib/chemicalml/schema/definition.rb +2 -2
- data/lib/chemicalml/schema.rb +7 -7
- data/lib/chemicalml/version.rb +1 -1
- data/lib/chemicalml/versioned_parser.rb +28 -10
- data/lib/chemicalml.rb +79 -17
- data/lib/tasks/reference_fetch.rake +30 -31
- data/lib/tasks/scrape_fixtures.rake +23 -24
- metadata +235 -35
- data/lib/chemicalml/cml/child_mappings.rb +0 -168
- data/lib/chemicalml/cml/translator/value_translations.rb +0 -270
- data/lib/chemicalml/cml/translator.rb +0 -484
- data/lib/chemicalml/model/atom.rb +0 -64
- data/lib/chemicalml/model/atom_parity.rb +0 -21
- data/lib/chemicalml/model/bond.rb +0 -39
- data/lib/chemicalml/model/bond_stereo.rb +0 -29
- data/lib/chemicalml/model/cml_array.rb +0 -27
- data/lib/chemicalml/model/cml_module.rb +0 -45
- data/lib/chemicalml/model/document.rb +0 -29
- data/lib/chemicalml/model/formula.rb +0 -34
- data/lib/chemicalml/model/identifier.rb +0 -21
- data/lib/chemicalml/model/label.rb +0 -21
- data/lib/chemicalml/model/matrix.rb +0 -29
- data/lib/chemicalml/model/metadata.rb +0 -23
- data/lib/chemicalml/model/metadata_list.rb +0 -25
- data/lib/chemicalml/model/molecule.rb +0 -45
- data/lib/chemicalml/model/name.rb +0 -21
- data/lib/chemicalml/model/node.rb +0 -45
- data/lib/chemicalml/model/parameter.rb +0 -27
- data/lib/chemicalml/model/parameter_list.rb +0 -25
- data/lib/chemicalml/model/product.rb +0 -21
- data/lib/chemicalml/model/product_list.rb +0 -21
- data/lib/chemicalml/model/property.rb +0 -28
- data/lib/chemicalml/model/property_list.rb +0 -25
- data/lib/chemicalml/model/reactant.rb +0 -21
- data/lib/chemicalml/model/reactant_list.rb +0 -21
- data/lib/chemicalml/model/reaction.rb +0 -41
- data/lib/chemicalml/model/reaction_list.rb +0 -23
- data/lib/chemicalml/model/scalar.rb +0 -25
- data/lib/chemicalml/model/substance.rb +0 -25
- data/lib/chemicalml/model.rb +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed7130181d6d55cbadb29d2630668ab4f16746f10dc20db9c9d1d0ff066586c6
|
|
4
|
+
data.tar.gz: ac78d79e906862aa42639b2d237ec66661a8c3061e4b25c04535f8941520b3d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5909cc1b258048f0c5aefba5844fff9136f2db4713d5cd5b80a22c07045e60a5ee5ead34680a841a9044039824c76cd4913d48d8f3410f86bf99b043f5739ba4
|
|
7
|
+
data.tar.gz: ff4f54de5ce734ae649554f593cfc1affa766b7e541fef394704bcd1b4d192dbae3e788241ced6a4dc6306bacf62b409fad2fdafe6861617497d7ff2ced16dee
|
|
@@ -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:
|
|
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/.rubocop.yml
CHANGED
|
@@ -10,11 +10,34 @@ AllCops:
|
|
|
10
10
|
- "coverage/**/*"
|
|
11
11
|
- "reference-docs/**/*"
|
|
12
12
|
- "spec/fixtures/**/*"
|
|
13
|
+
- "data/**/*"
|
|
13
14
|
|
|
14
15
|
Metrics/BlockLength:
|
|
15
16
|
Exclude:
|
|
16
17
|
- "spec/**/*"
|
|
17
18
|
- "*.gemspec"
|
|
19
|
+
- "lib/chemicalml/cml/base/**/*.rb"
|
|
20
|
+
|
|
21
|
+
# Base::* modules are structurally long: each declares every attribute
|
|
22
|
+
# and both xml + key_value mapping blocks for one CML element in a
|
|
23
|
+
# single `self.included` hook. This is the correct structure — the
|
|
24
|
+
# alternative (splitting into smaller methods) would scatter one
|
|
25
|
+
# element's declarations across multiple files.
|
|
26
|
+
Metrics/MethodLength:
|
|
27
|
+
Exclude:
|
|
28
|
+
- "lib/chemicalml/cml/base/**/*.rb"
|
|
29
|
+
|
|
30
|
+
Metrics/AbcSize:
|
|
31
|
+
Exclude:
|
|
32
|
+
- "lib/chemicalml/cml/base/**/*.rb"
|
|
33
|
+
|
|
34
|
+
Metrics/ModuleLength:
|
|
35
|
+
Exclude:
|
|
36
|
+
- "lib/chemicalml/cml/base/**/*.rb"
|
|
37
|
+
|
|
38
|
+
Layout/LineLength:
|
|
39
|
+
Exclude:
|
|
40
|
+
- "lib/chemicalml/cml/base/**/*.rb"
|
|
18
41
|
|
|
19
42
|
Style/Documentation:
|
|
20
43
|
Enabled: false
|
data/CLAUDE.md
CHANGED
|
@@ -26,6 +26,9 @@ bundle exec rspec -e "round-trips" # by name match
|
|
|
26
26
|
bundle exec rake # alias for rspec
|
|
27
27
|
bundle exec rubocop # lint
|
|
28
28
|
bundle exec rubocop -A # autocorrect
|
|
29
|
+
bundle exec chemicalml validate <file.cml> # CLI validation
|
|
30
|
+
bundle exec chemicalml conventions # list registered conventions
|
|
31
|
+
bundle exec chemicalml dictionaries # list built-in dictionaries
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
`spec/examples.txt` and `Gemfile.lock` are gitignored — `spec/examples.txt`
|
|
@@ -33,23 +36,30 @@ is regenerated by RSpec on every run, and `Gemfile.lock` is development-only.
|
|
|
33
36
|
|
|
34
37
|
## Architecture (big picture)
|
|
35
38
|
|
|
36
|
-
There are **
|
|
39
|
+
There are **four namespaces** under `Chemicalml`, deliberately kept
|
|
37
40
|
independent:
|
|
38
41
|
|
|
39
42
|
```
|
|
40
43
|
Chemicalml
|
|
41
44
|
├── parse(xml, schema: :schema3) # top-level entry point
|
|
42
|
-
├──
|
|
43
|
-
├──
|
|
44
|
-
│ ├──
|
|
45
|
-
│ ├──
|
|
46
|
-
│ ├──
|
|
47
|
-
│
|
|
45
|
+
├── Cml # CML model (lutaml-model Serializables)
|
|
46
|
+
│ ├── Base::* # shared attribute + xml-mapping mixins
|
|
47
|
+
│ ├── Schema3::* # Schema 3 classes (121 elements)
|
|
48
|
+
│ ├── Schema24::* # Schema 2.4 classes (121 + 3 legacy)
|
|
49
|
+
│ ├── Role::* # type-marker modules (schema-version-agnostic)
|
|
50
|
+
│ ├── Visitable # constraint-walker interface
|
|
51
|
+
│ └── WireClassRegistry # (schema, role) → class lookup
|
|
48
52
|
├── Schema # version registry
|
|
49
53
|
├── Convention # 5 conventions + constraint framework
|
|
50
54
|
└── Dictionary # dictionary model + YAML store
|
|
51
55
|
```
|
|
52
56
|
|
|
57
|
+
The Cml classes ARE the model — every one is a
|
|
58
|
+
`Lutaml::Model::Serializable` subclass with `attribute` declarations
|
|
59
|
+
and an `xml do ... end` mapping block. lutaml-model handles XML
|
|
60
|
+
parsing and serialization directly. There is no separate "canonical"
|
|
61
|
+
layer and no translator.
|
|
62
|
+
|
|
53
63
|
### Schema-versioned wire classes (mirrors `mml` V3/V4 pattern)
|
|
54
64
|
|
|
55
65
|
Both Schema 3 and Schema 2.4 have **real, distinct** class hierarchies
|
|
@@ -83,43 +93,50 @@ Chemicalml::Cml::Schema3.parse(xml) # version-specific
|
|
|
83
93
|
Chemicalml::Cml::Schema24.parse(xml) # version-specific
|
|
84
94
|
```
|
|
85
95
|
|
|
86
|
-
### The
|
|
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.
|
|
96
|
+
### The CML model (`Chemicalml::Cml::*`)
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
Every CML element is a `Lutaml::Model::Serializable` subclass — these
|
|
99
|
+
ARE the model. lutaml-model is format-agnostic (XML/JSON/YAML/TOML
|
|
100
|
+
via adapters), so the same class supports whatever serialization
|
|
101
|
+
lutaml-model supports. Each class includes three mixins:
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
`
|
|
102
|
-
`wire_children`, `node_id`, `element_name`).
|
|
103
|
+
- a `Base::*` module (shared `attribute` declarations + `xml do ... end`
|
|
104
|
+
mapping block + `namespace Chemicalml::Cml::Namespace`)
|
|
105
|
+
- a `Role::*` marker module (type identity used by constraints —
|
|
106
|
+
independent of which schema version's class it is)
|
|
107
|
+
- `Cml::Visitable` (uniform interface for the constraint walker —
|
|
108
|
+
`wire_children`, `node_id`, `element_name`)
|
|
103
109
|
|
|
104
110
|
Wire classes are generated in-place by each schema module from the
|
|
105
|
-
shared `Chemicalml::Cml::Elements::ALL` table —
|
|
106
|
-
|
|
107
|
-
one `Base::*` mixin, and one `Role::*` module.
|
|
108
|
-
`Schema24::*` pick up the new element
|
|
109
|
-
listed in `Elements::SCHEMA3_ONLY`
|
|
111
|
+
shared `Chemicalml::Cml::Elements::ALL` table — 121 entries spanning
|
|
112
|
+
the entire Schema 3 XSD. Adding a new CML element = adding one entry
|
|
113
|
+
to `Elements::ALL`, one `Base::*` mixin, and one `Role::*` module.
|
|
114
|
+
Both `Schema3::*` and `Schema24::*` pick up the new element
|
|
115
|
+
automatically unless it's listed in `Elements::SCHEMA3_ONLY`
|
|
116
|
+
(currently `%i[AnyCml]` — the only element in Schema 3 that Schema 2.4
|
|
117
|
+
lacks; verified by direct XSD diff).
|
|
118
|
+
|
|
119
|
+
Schema 2.4 actually declares 137 elements (a superset of Schema 3 in
|
|
120
|
+
most respects); 17 legacy elements (`alternative`, `annotation`,
|
|
121
|
+
`appinfo`, `arg`, `complexObject`, `enumeration`, `expression`,
|
|
122
|
+
`float`, `floatArray`, `integer`, `integerArray`, `operator`,
|
|
123
|
+
`relatedEntry`, `string`, `stringArray`, `tcell`, `trow`) are
|
|
124
|
+
Schema-2.4-only. Three of them (`annotation`, `appinfo`,
|
|
125
|
+
`enumeration`) are explicitly modeled in `Elements::SCHEMA24_ONLY`
|
|
126
|
+
because they carry semantic meaning; the rest are redundant with
|
|
127
|
+
Schema 3's unified `scalar`/`array`/`table` machinery.
|
|
110
128
|
|
|
111
129
|
The framework handles (de)serialization; **never** add `def to_xml` /
|
|
112
|
-
`def from_xml` /
|
|
113
|
-
`def to_h` to these classes.
|
|
130
|
+
`def from_xml` / `def to_h` to these classes.
|
|
114
131
|
|
|
115
|
-
###
|
|
132
|
+
### JSON / YAML wire names
|
|
116
133
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
134
|
+
Every `Base::*` module declares a `key_value do ... end` block
|
|
135
|
+
alongside its `xml do ... end` block, mirroring the XML wire names
|
|
136
|
+
explicitly. JSON and YAML output carry CML wire names
|
|
137
|
+
(`elementType`, `atomArray`) rather than Ruby snake_case names.
|
|
138
|
+
The blocks are written out by hand per Base module — no runtime
|
|
139
|
+
introspection.
|
|
123
140
|
|
|
124
141
|
### Schema versions
|
|
125
142
|
|
|
@@ -127,11 +144,20 @@ means updating translator rules — the two namespaces stay decoupled.
|
|
|
127
144
|
(`schema24`, `schema3`). The schema XSDs are **archival source** —
|
|
128
145
|
they must never be deleted, edited, or regenerated from code.
|
|
129
146
|
|
|
147
|
+
**Type-name collision**: Schema24's legacy `<string>`, `<integer>`,
|
|
148
|
+
`<float>` elements share their XML names with lutaml-model primitives
|
|
149
|
+
(`:string`, `:integer`, `:float`). They are NOT registered as types
|
|
150
|
+
in the Schema24 context (would shadow the primitive, breaking every
|
|
151
|
+
`:string` attribute cast). They remain defined as wire classes and
|
|
152
|
+
parseable as document roots. See
|
|
153
|
+
`Cml::Elements::SCHEMA24_TYPE_COLLISIONS`.
|
|
154
|
+
|
|
130
155
|
### Conventions
|
|
131
156
|
|
|
132
157
|
`Chemicalml::Convention` is a registry of named constraint sets
|
|
133
158
|
(`molecular`, `compchem`, `dictionary`, `unit-dictionary`,
|
|
134
|
-
`unitType-dictionary`).
|
|
159
|
+
`unitType-dictionary`, `spectroscopy`, `cascade`, `simpleUnit`).
|
|
160
|
+
Each convention owns:
|
|
135
161
|
|
|
136
162
|
- a namespace URI (e.g. `http://www.xml-cml.org/convention/molecular`)
|
|
137
163
|
- a set of constraint classes registered against it
|
|
@@ -143,6 +169,33 @@ renderer code (Open/Closed Principle).
|
|
|
143
169
|
The constraint walker uses `Cml::Visitable#wire_children` to traverse
|
|
144
170
|
the tree — no `respond_to?` duck typing.
|
|
145
171
|
|
|
172
|
+
The shared `Cml::Base::CommonChildren` mixin provides `metadataList`,
|
|
173
|
+
`label`, `name`, and `description` children that the XSD grants to
|
|
174
|
+
most container elements. Including it in a `Base::*` module is the
|
|
175
|
+
DRY way to declare the universal child set.
|
|
176
|
+
|
|
177
|
+
`Cml::Enums` is the canonical Ruby source of truth for every XSD
|
|
178
|
+
enum simpleType. Three constraints validate against it
|
|
179
|
+
(`BondOrderShouldBeInEnum`, `BondStereoShouldBeInEnum`,
|
|
180
|
+
`MoleculeChiralityShouldBeInEnum`) at warning severity — extension
|
|
181
|
+
values are permitted but flagged.
|
|
182
|
+
|
|
183
|
+
`Cml::ReferenceResolver` walks a document and resolves
|
|
184
|
+
id-references (`atomRefs2`, `atomRefs4`, `bondRefs`, `ref`) to
|
|
185
|
+
target wire instances. `unresolved_refs` lists missing targets;
|
|
186
|
+
useful for callers that need to follow CML references.
|
|
187
|
+
|
|
188
|
+
### Parallel-array serialisation
|
|
189
|
+
|
|
190
|
+
`<atomArray>` and `<bondArray>` support two equivalent XML forms: the
|
|
191
|
+
child form (`<atomArray><atom.../><atom.../></atomArray>`) and the
|
|
192
|
+
parallel-array form (`<atomArray atomID="a1 a2" elementType="C O"/>`).
|
|
193
|
+
The wire attribute names in the parallel-array form match the
|
|
194
|
+
singular `<atom>` / `<bond>` attribute names (e.g. `elementType`,
|
|
195
|
+
`atomRef1`) — the XSD attribute *group* is named `elementTypeArray`
|
|
196
|
+
etc., but the wire attribute is `elementType`. Ruby attribute names
|
|
197
|
+
carry an `_array` suffix for clarity at the call site.
|
|
198
|
+
|
|
146
199
|
### Dictionaries
|
|
147
200
|
|
|
148
201
|
`Chemicalml::Dictionary` is the model; entries have `id`, `term`,
|
|
@@ -172,9 +225,11 @@ These are non-negotiable and apply in addition to the user's global rules:
|
|
|
172
225
|
or `respond_to?` for type checks.** Use `is_a?` or design the type
|
|
173
226
|
hierarchy so the check isn't needed.
|
|
174
227
|
|
|
175
|
-
5. **One concern, one place (MECE).** Adding a CML element = adding
|
|
176
|
-
|
|
177
|
-
|
|
228
|
+
5. **One concern, one place (MECE).** Adding a CML element = adding
|
|
229
|
+
one `Base::*` mixin + one `Role::*` module + one entry to
|
|
230
|
+
`Elements::ALL` + (if needed) one entry to `SCHEMA3_ONLY` or
|
|
231
|
+
`SCHEMA24_ONLY`. Both Schema3::* and Schema24::* pick it up
|
|
232
|
+
automatically.
|
|
178
233
|
|
|
179
234
|
## Reference docs (in-tree)
|
|
180
235
|
|
data/README.adoc
CHANGED
|
@@ -4,13 +4,19 @@ ChemML provides a https://www.xml-cml.org/[Chemical Markup Language (CML)]
|
|
|
4
4
|
object model for Ruby, built on
|
|
5
5
|
{lutaml-model}[https://github.com/lutaml/lutaml-model].
|
|
6
6
|
|
|
7
|
-
==
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
== Features
|
|
8
|
+
|
|
9
|
+
* Full Schema 3 and Schema 2.4 coverage — every CML element, attribute,
|
|
10
|
+
and XSD enum/pattern modelled as Ruby classes.
|
|
11
|
+
* Format-agnostic serialization — XML, JSON, YAML, and TOML round-trip
|
|
12
|
+
via lutaml-model adapters.
|
|
13
|
+
* Eight built-in conventions with 88+ registered constraints:
|
|
14
|
+
`molecular`, `compchem`, `dictionary`, `unit-dictionary`,
|
|
15
|
+
`unitType-dictionary`, `spectroscopy`, `cascade`, `simpleUnit`.
|
|
16
|
+
* Built-in dictionaries (cml, compchem, cif, unit_si, unit_non_si,
|
|
17
|
+
unit_type, cml_name, cml_formula) loaded from YAML.
|
|
18
|
+
* CLI for command-line validation and inspection.
|
|
19
|
+
* Ruby-native query API (`doc.find_atom(id)`, `doc.each_molecule`).
|
|
14
20
|
|
|
15
21
|
== Install
|
|
16
22
|
|
|
@@ -30,45 +36,167 @@ $ gem install chemicalml
|
|
|
30
36
|
|
|
31
37
|
== Usage
|
|
32
38
|
|
|
33
|
-
Parse a CML document
|
|
39
|
+
=== Parse a CML document
|
|
34
40
|
|
|
35
41
|
[source,ruby]
|
|
36
42
|
----
|
|
37
43
|
require "chemicalml"
|
|
38
44
|
|
|
39
|
-
doc = Chemicalml
|
|
40
|
-
doc.molecules.first.atoms.first.element_type # => "C"
|
|
45
|
+
doc = Chemicalml.parse_file("ethanol.cml")
|
|
46
|
+
doc.molecules.first.atom_array.atoms.first.element_type # => "C"
|
|
47
|
+
----
|
|
48
|
+
|
|
49
|
+
=== Validate against a convention
|
|
50
|
+
|
|
51
|
+
[source,ruby]
|
|
52
|
+
----
|
|
53
|
+
report = Chemicalml.validate(doc)
|
|
54
|
+
puts report.summary
|
|
55
|
+
puts report.errors.map(&:message)
|
|
41
56
|
----
|
|
42
57
|
|
|
43
|
-
Build a document programmatically
|
|
58
|
+
=== Build a document programmatically
|
|
44
59
|
|
|
45
60
|
[source,ruby]
|
|
46
61
|
----
|
|
47
62
|
atom = Chemicalml::Cml::Atom.new(id: "a1", element_type: "C")
|
|
48
|
-
mol = Chemicalml::Cml::Molecule.new(
|
|
63
|
+
mol = Chemicalml::Cml::Molecule.new(
|
|
64
|
+
id: "m1",
|
|
65
|
+
atom_array: Chemicalml::Cml::AtomArray.new(atoms: [atom])
|
|
66
|
+
)
|
|
49
67
|
doc = Chemicalml::Cml::Document.new(molecules: [mol])
|
|
50
68
|
|
|
51
69
|
doc.to_xml # => well-formed CML XML
|
|
52
70
|
----
|
|
53
71
|
|
|
54
|
-
|
|
72
|
+
=== Query the tree
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
74
|
+
[source,ruby]
|
|
75
|
+
----
|
|
76
|
+
doc.each_atom { |a| puts "#{a.id}: #{a.element_type}" }
|
|
77
|
+
doc.find_atom("a1") # => Atom instance
|
|
78
|
+
doc.atom_count # => recursive count
|
|
79
|
+
doc.find_molecule("m1") # => Molecule instance
|
|
80
|
+
----
|
|
81
|
+
|
|
82
|
+
=== Cross-format serialisation
|
|
83
|
+
|
|
84
|
+
[source,ruby]
|
|
85
|
+
----
|
|
86
|
+
doc.to_xml # CML XML
|
|
87
|
+
doc.to_json # JSON with CML wire names (elementType, atomArray, ...)
|
|
88
|
+
doc.to_yaml # YAML
|
|
89
|
+
----
|
|
90
|
+
|
|
91
|
+
=== Resolve references
|
|
92
|
+
|
|
93
|
+
[source,ruby]
|
|
94
|
+
----
|
|
95
|
+
resolver = Chemicalml::Cml::ReferenceResolver.new(doc)
|
|
96
|
+
resolver.unresolved_refs # => [{ node: <Bond>, attr: :atom_refs2, missing: ["a99"] }]
|
|
97
|
+
----
|
|
98
|
+
|
|
99
|
+
== CLI
|
|
100
|
+
|
|
101
|
+
[source,sh]
|
|
102
|
+
----
|
|
103
|
+
$ chemicalml validate file.cml # auto-detect convention, print violations
|
|
104
|
+
$ chemicalml inspect file.cml # tree-style summary
|
|
105
|
+
$ chemicalml conventions # list 8 registered conventions
|
|
106
|
+
$ chemicalml dictionaries # list built-in YAML dictionaries
|
|
107
|
+
$ chemicalml elements # list all CML wire classes
|
|
108
|
+
----
|
|
109
|
+
|
|
110
|
+
== Conventions
|
|
111
|
+
|
|
112
|
+
Eight conventions register 88+ constraints:
|
|
113
|
+
|
|
114
|
+
[cols="1,1,1"]
|
|
115
|
+
|===
|
|
116
|
+
| Convention | Constraints | Description
|
|
117
|
+
|
|
118
|
+
| molecular | 35 | Atom/bond/molecule well-formedness, id patterns,
|
|
119
|
+
element type validation, dictRef resolution, AtomParity parent
|
|
120
|
+
check, references-resolve check.
|
|
121
|
+
| compchem | 20 | JobList/Job/Initialization/Calculation/Finalization
|
|
122
|
+
module structure, scalar/array/matrix value rules.
|
|
123
|
+
| dictionary | 8 | Dictionary namespace, prefix, entry id/term/definition,
|
|
124
|
+
unitType/units co-constraints.
|
|
125
|
+
| unit-dictionary | 8 | UnitList namespace, unit id/title/symbol/parentSI/
|
|
126
|
+
multiplierToSI, definition child.
|
|
127
|
+
| unitType-dictionary | 5 | UnitTypeList namespace, unitType id/name/definition.
|
|
128
|
+
| spectroscopy | 5 | Spectrum convention/format/content, peakList, peak values.
|
|
129
|
+
| cascade | 4 | ReactionScheme content, reactionStepList, reactiveCentre atomRefs.
|
|
130
|
+
| simpleUnit | 3 | simpleUnit root, unit power, unit symbol.
|
|
131
|
+
|===
|
|
132
|
+
|
|
133
|
+
Add a custom convention at runtime:
|
|
134
|
+
|
|
135
|
+
[source,ruby]
|
|
136
|
+
----
|
|
137
|
+
module MyConvention
|
|
138
|
+
extend Chemicalml::Convention::Base
|
|
139
|
+
|
|
140
|
+
def self.qname; "convention:my"; end
|
|
141
|
+
def self.namespace_uri; "http://example.com/my"; end
|
|
142
|
+
|
|
143
|
+
register MyConstraintClass
|
|
144
|
+
end
|
|
59
145
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
146
|
+
Chemicalml::Convention::Registry.register_custom(MyConvention)
|
|
147
|
+
----
|
|
148
|
+
|
|
149
|
+
== Dictionaries
|
|
150
|
+
|
|
151
|
+
Eight built-in YAML dictionaries ship under `data/dictionaries/`:
|
|
152
|
+
|
|
153
|
+
[cols="1,1"]
|
|
154
|
+
|===
|
|
155
|
+
| Dictionary | Prefix
|
|
156
|
+
|
|
157
|
+
| cml | cml
|
|
158
|
+
| cml_name | cmlName
|
|
159
|
+
| cml_formula | cmlFormula
|
|
160
|
+
| cif | cif
|
|
161
|
+
| compchem | compchem
|
|
162
|
+
| unit_si | si
|
|
163
|
+
| unit_non_si | nonsi
|
|
164
|
+
| unit_type | unitType
|
|
165
|
+
|===
|
|
166
|
+
|
|
167
|
+
Load via:
|
|
63
168
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
169
|
+
[source,ruby]
|
|
170
|
+
----
|
|
171
|
+
dict = Chemicalml::Dictionary.load(:cml)
|
|
172
|
+
entry = Chemicalml::Dictionary::Registry.lookup("cml:bp")
|
|
173
|
+
entry.term # => "Boiling Point"
|
|
174
|
+
entry.definition # => "The temperature at which a substance boils..."
|
|
175
|
+
----
|
|
67
176
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`
|
|
177
|
+
== Design
|
|
178
|
+
|
|
179
|
+
Each CML element is a `Lutaml::Model::Serializable` subclass with
|
|
180
|
+
declared attributes and parallel `xml do ... end` and
|
|
181
|
+
`key_value do ... end` mapping blocks. Serialisation is fully
|
|
182
|
+
framework-backed — no hand-rolled XML.
|
|
183
|
+
|
|
184
|
+
* `Cml::Base::*` modules declare shared attributes (mixed into both
|
|
185
|
+
Schema3 and Schema24 wire classes).
|
|
186
|
+
* `Cml::Role::*` modules are type-markers used by the convention
|
|
187
|
+
constraint walker for `is_a?` dispatch.
|
|
188
|
+
* `Cml::Elements::ALL` is the single source of truth for the CML
|
|
189
|
+
element table.
|
|
190
|
+
* `Cml::Enums` and `Cml::Patterns` mirror XSD simpleTypes.
|
|
191
|
+
* `Cml::CommonChildren` provides the universal `metadataList`,
|
|
192
|
+
`label`, `name`, `description` child set as a DRY mixin.
|
|
193
|
+
|
|
194
|
+
== Reference docs
|
|
195
|
+
|
|
196
|
+
`reference-docs/` holds archival source material from xml-cml.org:
|
|
197
|
+
the XSDs (`schemas/schema3/schema.xsd`, `schemas/schema24/schema.xsd`),
|
|
198
|
+
the convention specifications, and the CMLLite paper. These are
|
|
199
|
+
**source material, not derived output** — never delete or edit them.
|
|
72
200
|
|
|
73
201
|
== Acknowledgements
|
|
74
202
|
|
|
@@ -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.
|