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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 77 — Convention coverage matrix spec
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The gem registers 8 conventions, each with multiple constraints.
|
|
6
|
+
Currently each convention has its own spec file, but there is no
|
|
7
|
+
single source of truth asserting that every convention:
|
|
8
|
+
|
|
9
|
+
- is in the Registry
|
|
10
|
+
- is detectable via at least one root role
|
|
11
|
+
- has at least one violation case for at least one of its constraints
|
|
12
|
+
- has at least one passing-case example
|
|
13
|
+
|
|
14
|
+
A matrix spec catches gaps when adding a new convention (the new
|
|
15
|
+
convention's matrix entry fails until it has specs).
|
|
16
|
+
|
|
17
|
+
## Work
|
|
18
|
+
|
|
19
|
+
Add `spec/chemicalml/convention/coverage_matrix_spec.rb` that:
|
|
20
|
+
|
|
21
|
+
1. Iterates `Convention::Registry.builtin_qnames`.
|
|
22
|
+
2. For each, asserts the convention is detectable from its declared
|
|
23
|
+
root role.
|
|
24
|
+
3. For each constraint class registered against the convention,
|
|
25
|
+
asserts a spec file exists that exercises it (grep for the class
|
|
26
|
+
name in `spec/`).
|
|
27
|
+
|
|
28
|
+
## Acceptance
|
|
29
|
+
|
|
30
|
+
- Matrix spec passes for all 8 conventions.
|
|
31
|
+
- Adding a 9th convention without specs makes the matrix spec fail.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 78 — Fixture coverage audit
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`spec/fixtures/` holds CML examples. Current round-trip specs cover a
|
|
6
|
+
subset. After recent additions (parallel-array attrs, CommonChildren,
|
|
7
|
+
8 conventions), some features may have no fixture exercising them.
|
|
8
|
+
|
|
9
|
+
## Work
|
|
10
|
+
|
|
11
|
+
Audit `spec/fixtures/`:
|
|
12
|
+
|
|
13
|
+
1. Identify fixtures that exercise parallel-array atomArray/bondArray.
|
|
14
|
+
2. Identify fixtures covering each convention.
|
|
15
|
+
3. Identify fixtures using new child elements (reaction.mechanism,
|
|
16
|
+
reactiveCentre.atomSet, etc.).
|
|
17
|
+
4. For features with no fixture, add one under `spec/fixtures/`.
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
- Every convention has at least one fixture.
|
|
22
|
+
- Parallel-array form has at least one fixture.
|
|
23
|
+
- Schema24-only legacy elements have at least one fixture.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 79 — Final verification round 19
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green (or pending for documented limitations).
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting key_value support and JSON wire names.
|
|
9
|
+
5. Write `TODO.align/README.round19.md`.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All four scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round19.md exists.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# 80 — XSD enum constants
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The XSD declares ~30 simpleTypes that restrict to enumeration sets
|
|
6
|
+
(orderType, stereoType, chiralityType, latticeType, matrixType,
|
|
7
|
+
stateType, peakMultiplicityType, etc.). We model every attribute as
|
|
8
|
+
`:string` and accept any value.
|
|
9
|
+
|
|
10
|
+
Without a single source of truth for the allowed values, downstream
|
|
11
|
+
callers that want to validate CML have to scrape the XSD themselves
|
|
12
|
+
or hard-code the enums (which drift from the schema).
|
|
13
|
+
|
|
14
|
+
## Solution
|
|
15
|
+
|
|
16
|
+
`Chemicalml::Cml::Enums` — frozen-set constants for each XSD enum
|
|
17
|
+
simpleType. The constants are the canonical Ruby source of truth
|
|
18
|
+
for "what values does this attribute accept".
|
|
19
|
+
|
|
20
|
+
## Work
|
|
21
|
+
|
|
22
|
+
1. Create `lib/chemicalml/cml/enums.rb` with one constant per XSD
|
|
23
|
+
enum simpleType. Names match the XSD type name with `Type`
|
|
24
|
+
suffix stripped (e.g. `ORDER_VALUES` for `orderType`).
|
|
25
|
+
2. Each constant is a frozen Set of allowed string values.
|
|
26
|
+
3. Add specs asserting the constants match the XSD exactly.
|
|
27
|
+
|
|
28
|
+
## Acceptance
|
|
29
|
+
|
|
30
|
+
- `Chemicalml::Cml::Enums::ORDER_VALUES` includes `"S"`, `"D"`, `"T"`,
|
|
31
|
+
`"A"`, etc.
|
|
32
|
+
- `Chemicalml::Cml::Enums::STEREO_VALUES` includes `"C"`, `"T"`, `"W"`,
|
|
33
|
+
`"H"`.
|
|
34
|
+
- Constants are frozen.
|
|
35
|
+
- Generated from the XSD (no hand-maintenance).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# 81 — Enum validation constraints
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
With enum constants defined (TODO 80), add warning-severity
|
|
6
|
+
constraints that flag attribute values outside the XSD-declared
|
|
7
|
+
enum set. Warning (not error) because CML allows extension values.
|
|
8
|
+
|
|
9
|
+
## Work
|
|
10
|
+
|
|
11
|
+
Add constraints under the molecular convention (where most enum
|
|
12
|
+
attributes live):
|
|
13
|
+
|
|
14
|
+
1. `BondOrderShouldBeInEnum` (applies_to Role::Bond) — warning if
|
|
15
|
+
`bond.order` not in `Cml::Enums::ORDER_VALUES`.
|
|
16
|
+
2. `BondStereoShouldBeInEnum` (applies_to Role::BondStereo) —
|
|
17
|
+
warning if `bondStereo.value` not in `Cml::Enums::STEREO_VALUES`.
|
|
18
|
+
3. `MoleculeChiralityShouldBeInEnum` (applies_to Role::Molecule) —
|
|
19
|
+
warning if `molecule.chirality` not in `Cml::Enums::CHIRALITY_VALUES`.
|
|
20
|
+
4. `LatticeTypeShouldBeInEnum` (applies_to Role::Lattice) —
|
|
21
|
+
warning if not in `LATTICE_VALUES`.
|
|
22
|
+
|
|
23
|
+
Each constraint is registered against the molecular convention.
|
|
24
|
+
|
|
25
|
+
## Acceptance
|
|
26
|
+
|
|
27
|
+
- A bond with `order="X"` triggers a warning.
|
|
28
|
+
- A bond with `order="S"` passes silently.
|
|
29
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 82 — Reference resolver
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
CML documents reference atoms/bonds/molecules by id via attributes
|
|
6
|
+
like `atomRefs2`, `atomRefs4`, `bondRefs`, `moleculeRefs`, `ref`.
|
|
7
|
+
Currently callers must walk the document themselves to resolve
|
|
8
|
+
these to actual instances.
|
|
9
|
+
|
|
10
|
+
## Solution
|
|
11
|
+
|
|
12
|
+
`Chemicalml::Cml::ReferenceResolver` — walks a document, builds an
|
|
13
|
+
id → node index, then exposes lookup methods.
|
|
14
|
+
|
|
15
|
+
## Work
|
|
16
|
+
|
|
17
|
+
1. Create `lib/chemicalml/cml/reference_resolver.rb`.
|
|
18
|
+
2. API:
|
|
19
|
+
```ruby
|
|
20
|
+
resolver = Chemicalml::Cml::ReferenceResolver.new(document)
|
|
21
|
+
resolver.find_atom(molecule, "a1") # → Atom or nil
|
|
22
|
+
resolver.resolve_atom_refs2(bond) # → [Atom, Atom] or nils
|
|
23
|
+
resolver.unresolved_refs(document) # → [{ source: Bond, attr: :atom_refs2, missing: ["a99"] }]
|
|
24
|
+
```
|
|
25
|
+
3. Add a constraint `ReferencesShouldResolve` (warning severity)
|
|
26
|
+
that lists unresolved refs in a document.
|
|
27
|
+
4. Specs covering resolve + unresolved detection.
|
|
28
|
+
|
|
29
|
+
## Acceptance
|
|
30
|
+
|
|
31
|
+
- Resolver resolves a valid atomRefs2 to actual atoms.
|
|
32
|
+
- `unresolved_refs` returns missing atom ids.
|
|
33
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 83 — TOML round-trip spec
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
lutaml-model supports TOML as a key-value format. CLAUDE.md claims
|
|
6
|
+
format-agnosticism — XML/JSON/YAML are tested. Add TOML to complete
|
|
7
|
+
the set.
|
|
8
|
+
|
|
9
|
+
## Work
|
|
10
|
+
|
|
11
|
+
Add `spec/chemicalml/cml/toml_roundtrip_spec.rb` that round-trips
|
|
12
|
+
a Molecule through `to_toml` / `from_toml`. TOML's flat key/value
|
|
13
|
+
structure means nested objects get flattened — verify the same
|
|
14
|
+
data survives.
|
|
15
|
+
|
|
16
|
+
## Acceptance
|
|
17
|
+
|
|
18
|
+
- `Molecule#to_toml` produces a TOML string.
|
|
19
|
+
- `Molecule.from_toml(toml)` returns a Molecule with the same id
|
|
20
|
+
and atom data.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 84 — Final verification round 21
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green.
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting enum validation, reference resolver,
|
|
9
|
+
TOML round-trip.
|
|
10
|
+
5. Write `TODO.align/README.round21.md`.
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
- All scans clean.
|
|
15
|
+
- CLAUDE.md current.
|
|
16
|
+
- README.round21.md exists.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 85 — Bond atomRefs2 distinct constraint
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The molecular spec at `reference-docs/conventions/molecular.md` says:
|
|
6
|
+
|
|
7
|
+
> `atomRefs2` — REQUIRED, two distinct atom ids in same molecule
|
|
8
|
+
|
|
9
|
+
No current constraint enforces distinctness. A `<bond atomRefs2="a1 a1"/>`
|
|
10
|
+
(zero-length self-bond) is silently accepted.
|
|
11
|
+
|
|
12
|
+
## Work
|
|
13
|
+
|
|
14
|
+
Add `Molecular::Constraints::BondAtomRefs2ShouldBeDistinct` (warning
|
|
15
|
+
severity — there are edge cases in non-classical chemistry). The
|
|
16
|
+
constraint parses `node.atom_refs2`, splits on whitespace, and warns
|
|
17
|
+
if the two ids are identical.
|
|
18
|
+
|
|
19
|
+
Register against molecular convention.
|
|
20
|
+
|
|
21
|
+
## Acceptance
|
|
22
|
+
|
|
23
|
+
- `<bond atomRefs2="a1 a1"/>` triggers a warning.
|
|
24
|
+
- `<bond atomRefs2="a1 a2"/>` passes silently.
|
|
25
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 86 — References-should-resolve constraint
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
With `Cml::ReferenceResolver` (TODO 82), we can now detect bonds
|
|
6
|
+
whose `atomRefs2` reference atoms that don't exist in the parent
|
|
7
|
+
molecule. Currently no constraint flags this — typos like
|
|
8
|
+
`atomRefs2="a1 a99"` (where `a99` doesn't exist) pass silently.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add `Molecular::Constraints::ReferencesShouldResolve` as a
|
|
13
|
+
`DocumentConstraint`. It instantiates a `ReferenceResolver` and
|
|
14
|
+
reports each unresolved reference as a warning violation.
|
|
15
|
+
|
|
16
|
+
## Acceptance
|
|
17
|
+
|
|
18
|
+
- A bond referencing a missing atom triggers a warning.
|
|
19
|
+
- A bond referencing existing atoms passes silently.
|
|
20
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 87 — CLI utility for validation
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
A user-facing CLI makes the gem immediately useful for command-line
|
|
6
|
+
validation of CML files. Without a CLI, users have to write Ruby
|
|
7
|
+
to use the gem.
|
|
8
|
+
|
|
9
|
+
## Work
|
|
10
|
+
|
|
11
|
+
Create `exe/chemicalml` (executable) with subcommands:
|
|
12
|
+
|
|
13
|
+
- `chemicalml validate <file>` — auto-detect convention, print
|
|
14
|
+
violations to stderr, exit non-zero if errors.
|
|
15
|
+
- `chemicalml conventions` — list registered conventions.
|
|
16
|
+
- `chemicalml dictionaries` — list builtin dictionaries.
|
|
17
|
+
|
|
18
|
+
Wire it through `Chemicalml::Cli` module under
|
|
19
|
+
`lib/chemicalml/cli.rb` so the logic is reusable.
|
|
20
|
+
|
|
21
|
+
## Acceptance
|
|
22
|
+
|
|
23
|
+
- `bundle exec chemicalml validate spec/fixtures/schema3/molecular/water.cml`
|
|
24
|
+
parses, detects convention:molecular, prints nothing, exits 0.
|
|
25
|
+
- `chemicalml conventions` lists all 8 conventions.
|
|
26
|
+
- `chemicalml dictionaries` lists all built-in dictionaries.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 88 — Diverse real-world fixtures
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
Current fixtures cover basic structures (water, methanol, ethanol,
|
|
6
|
+
compchem, dictionary). Real CML documents have richer features:
|
|
7
|
+
bond stereo (wedge/hash), propertyList nesting, reaction mechanisms,
|
|
8
|
+
formulas, crystallographic lattices. Adding fixtures that exercise
|
|
9
|
+
these ensures the gem handles real-world CML.
|
|
10
|
+
|
|
11
|
+
## Work
|
|
12
|
+
|
|
13
|
+
Add fixtures under `spec/fixtures/schema3/`:
|
|
14
|
+
- `molecular/chiral_center_with_bond_stereo.cml` — bondStereo W/H
|
|
15
|
+
- `molecular/ethanol_with_properties.cml` — propertyList with scalars
|
|
16
|
+
- `molecular/ethanol_with_formula.cml` — formula concise
|
|
17
|
+
- `crystal/nacl_with_lattice.cml` — crystal + lattice + symmetry
|
|
18
|
+
- `reactions/diels_alder.cml` — reactionScheme with reactantList/productList
|
|
19
|
+
|
|
20
|
+
Round-trip each in a spec.
|
|
21
|
+
|
|
22
|
+
## Acceptance
|
|
23
|
+
|
|
24
|
+
- Each fixture parses without raising.
|
|
25
|
+
- The features it exercises (bondStereo, property, formula, lattice,
|
|
26
|
+
reaction) round-trip.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 89 — Final verification round 22
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green.
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting CLI + new constraints.
|
|
9
|
+
5. Write `TODO.align/README.round22.md`.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round22.md exists.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 90 — BondStereo completeness constraints
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The molecular spec at `reference-docs/conventions/molecular.md` says:
|
|
6
|
+
|
|
7
|
+
> If value is `C` or `T` — MUST have `atomRefs4` (four distinct atom
|
|
8
|
+
> ids; two MUST be the parent bond's atoms). MUST NOT have `atomRefs2`.
|
|
9
|
+
> If value is `W` or `H` — MUST have `atomRefs2` (two distinct atom
|
|
10
|
+
> ids ... both MUST be in the parent bond).
|
|
11
|
+
|
|
12
|
+
We have `BondStereoCisTransMustHaveAtomRefs4` and
|
|
13
|
+
`BondStereoWedgeHashMustHaveAtomRefs2` but not the distinctness or
|
|
14
|
+
parent-bond-membership rules.
|
|
15
|
+
|
|
16
|
+
## Work
|
|
17
|
+
|
|
18
|
+
Add to molecular convention:
|
|
19
|
+
- `BondStereoAtomRefs4ShouldBeDistinct` (warning) — atomRefs4 has 4 distinct ids
|
|
20
|
+
- `BondStereoAtomsShouldBeInParentBond` (warning) — atomRefs2/4
|
|
21
|
+
references should be a subset of the parent bond's atoms (the
|
|
22
|
+
walker doesn't track parents, so this is approximate — checks
|
|
23
|
+
against the document's atoms).
|
|
24
|
+
|
|
25
|
+
Register both against molecular.
|
|
26
|
+
|
|
27
|
+
## Acceptance
|
|
28
|
+
|
|
29
|
+
- `<bondStereo atomRefs4="a1 a2 a3 a3">C</bondStereo>` triggers warning.
|
|
30
|
+
- `<bondStereo atomRefs4="a1 a2 a3 a4">C</bondStereo>` passes.
|
|
31
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 91 — AtomParity atomRefs4 distinct constraint
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`<atomParity atomRefs4="a b c d">1</atomParity>` references 4 atoms
|
|
6
|
+
around a chiral center. Per CML semantics, all 4 must be distinct
|
|
7
|
+
(duplicates make the parity meaningless). No constraint enforces
|
|
8
|
+
this today.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add `Molecular::Constraints::AtomParityAtomRefs4ShouldBeDistinct`
|
|
13
|
+
(applies_to Role::AtomParity). Warning severity. Parses
|
|
14
|
+
`node.atom_refs4` and warns if not 4 distinct ids.
|
|
15
|
+
|
|
16
|
+
Register against molecular.
|
|
17
|
+
|
|
18
|
+
## Acceptance
|
|
19
|
+
|
|
20
|
+
- AtomParity with `atomRefs4="a1 a2 a3 a3"` triggers warning.
|
|
21
|
+
- AtomParity with `atomRefs4="a1 a2 a3 a4"` passes.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 92 — Unit-dictionary completeness
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`reference-docs/conventions/unit-dictionary.md` says unit MUST have:
|
|
6
|
+
- `id` (already covered)
|
|
7
|
+
- `title` — typically the full name
|
|
8
|
+
- `symbol` (already covered alongside unitType)
|
|
9
|
+
- `parentSI` — QName referencing an SI unit
|
|
10
|
+
- at least one of `multiplierToSI` or `constantToSI`
|
|
11
|
+
- `unitType` (already covered)
|
|
12
|
+
- single `definition` child (already covered)
|
|
13
|
+
|
|
14
|
+
Missing constraints: title, parentSI, multiplierTo/constantToSI.
|
|
15
|
+
|
|
16
|
+
## Work
|
|
17
|
+
|
|
18
|
+
Add three constraints to unit-dictionary convention:
|
|
19
|
+
- `UnitMustHaveTitle`
|
|
20
|
+
- `UnitMustHaveParentSI`
|
|
21
|
+
- `UnitMustHaveMultiplierOrConstantToSI`
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- A `<unit>` without `title` triggers an error.
|
|
26
|
+
- A `<unit>` with `parentSI="si:m"` passes.
|
|
27
|
+
- A `<unit>` without both `multiplierToSI` and `constantToSI` triggers error.
|
|
28
|
+
- All existing specs pass.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 93 — YARD docs for public API
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The public API (`Chemicalml.parse`, `Chemicalml.serialize`,
|
|
6
|
+
`Chemicalml::Cli.run`, `Chemicalml::Convention.validate`,
|
|
7
|
+
`Chemicalml::Dictionary.load`) lacks YARD docstrings. Without
|
|
8
|
+
docs, `yard doc` produces empty output and users have to read source.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add concise YARD docstrings to:
|
|
13
|
+
- `Chemicalml.parse`, `Chemicalml.serialize`, `Chemicalml.parser_for`
|
|
14
|
+
- `Chemicalml::Cli.run` and subcommand methods
|
|
15
|
+
- `Chemicalml::Convention.validate`, `validate_report`, `detect_and_validate`
|
|
16
|
+
- `Chemicalml::Dictionary.load`
|
|
17
|
+
- `Chemicalml::Cml::ReferenceResolver` public methods
|
|
18
|
+
- `Chemicalml::Cml::Enums` module
|
|
19
|
+
|
|
20
|
+
## Acceptance
|
|
21
|
+
|
|
22
|
+
- `bundle exec yard doc` succeeds with no errors.
|
|
23
|
+
- `bundle exec yard server` serves documented API.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 94 — Final verification round 23
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec — must be green.
|
|
6
|
+
2. rubocop on touched files.
|
|
7
|
+
3. Forbidden-pattern scan.
|
|
8
|
+
4. Update CLAUDE.md noting new constraints + YARD.
|
|
9
|
+
5. Write `TODO.align/README.round23.md`.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round23.md exists.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Round 17 — XSD gap closure
|
|
2
|
+
|
|
3
|
+
This round closes the remaining XSD-declared feature gaps in the gem.
|
|
4
|
+
Started from a clean XSD-vs-Ruby comparison and worked through each
|
|
5
|
+
cluster.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [61 — Parallel-array attrs for atomArray/bondArray](61-parallel-array-attrs.md)
|
|
10
|
+
- [62 — Per-element attribute gaps](62-per-element-attribute-gaps.md)
|
|
11
|
+
- [63 — Universal children mixin](63-universal-children-mixin.md)
|
|
12
|
+
- [64 — Per-element child element gaps (Schema 2.4)](64-per-element-child-gaps.md)
|
|
13
|
+
- [65 — SimpleUnit convention](65-simple-unit-convention.md)
|
|
14
|
+
- [66 — Schema24-only legacy element children](66-schema24-legacy-children.md)
|
|
15
|
+
- [67 — Final spec/lint/docs verification](67-final-verification.md)
|
|
16
|
+
|
|
17
|
+
## Outcomes
|
|
18
|
+
|
|
19
|
+
- Schema3 XSD: **0 attribute gaps, 0 child gaps** (excluding `<anyCml>`
|
|
20
|
+
wildcard, which is intentionally not modelled as a concrete child).
|
|
21
|
+
- Schema24 XSD: **0 attribute gaps**; child gaps reduced from 235 to
|
|
22
|
+
~140 element-specific declarations, with ~80% of the universal
|
|
23
|
+
children (metadataList/label/name/description) absorbed by the new
|
|
24
|
+
`CommonChildren` mixin.
|
|
25
|
+
- 8 conventions now registered (was 5 at start of round): molecular,
|
|
26
|
+
compchem, dictionary, unit-dictionary, unitType-dictionary,
|
|
27
|
+
spectroscopy, cascade, simpleUnit.
|
|
28
|
+
- 300 specs total, 0 failures, 0 forbidden patterns.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Round 18 — Convention detection, format coverage, robustness
|
|
2
|
+
|
|
3
|
+
This round closes convention-detection gaps, proves format-agnosticism
|
|
4
|
+
beyond XML, hardens the constraint walker, and enriches the violation
|
|
5
|
+
value-object.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [68 — Detection coverage for all 8 conventions](68-detection-coverage.md)
|
|
10
|
+
- [69 — JSON / YAML round-trip proof](69-json-yaml-roundtrip.md)
|
|
11
|
+
- [70 — Iterative tree walker](70-iterative-walker.md)
|
|
12
|
+
- [71 — Enrich Violation with offending value](71-violation-value.md)
|
|
13
|
+
- [72 — Close remaining Schema24 child gaps](72-close-child-gaps.md)
|
|
14
|
+
- [73 — Document Schema24 nested-parse limitation](73-schema24-parse-limitation.md)
|
|
15
|
+
- [74 — Final verification round 18](74-final-verification-round18.md)
|
|
16
|
+
|
|
17
|
+
## Outcomes
|
|
18
|
+
|
|
19
|
+
- `Convention::Detection` recognises Spectrum, SpectrumList,
|
|
20
|
+
ReactionScheme, ReactionList as convention-bearing roots.
|
|
21
|
+
- JSON and YAML round-trip specs prove the format-agnostic claim
|
|
22
|
+
(lutaml-model applies XML mappings only to XML; JSON/YAML use Ruby
|
|
23
|
+
snake_case names).
|
|
24
|
+
- The recursive walker in `Constraint#walk_nodes` is now an iterative
|
|
25
|
+
worklist (DFS pre-order preserved) — a 200-deep Module chain walks
|
|
26
|
+
without stack overflow.
|
|
27
|
+
- `Violation` carries an optional `value` field with the offending
|
|
28
|
+
literal; three constraints populate it (AtomIdMustMatchPattern,
|
|
29
|
+
PeakShouldHaveValues, UnitMustHavePower).
|
|
30
|
+
- ~25 additional Base modules gained element-specific children
|
|
31
|
+
(reactiveCentre, sample, spectator, transitionState, substance,
|
|
32
|
+
lattice, table, trow, zMatrix, symmetry, map, eigen, xaxis, yaxis)
|
|
33
|
+
plus self-references on 10 recursive containers.
|
|
34
|
+
- Schema24 nested-XML parse limitation documented with a pending
|
|
35
|
+
spec that will auto-resolve when lutaml-model fixes its
|
|
36
|
+
TypeResolver context handling.
|
|
37
|
+
- 342 specs total, 0 failures, 2 pending. Zero forbidden patterns.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Round 19 — JSON wire names, Schema24 workaround attempts, matrix coverage
|
|
2
|
+
|
|
3
|
+
This round directly addresses the user's question about `key_value`
|
|
4
|
+
blocks for JSON/YAML, and continues closing coverage gaps.
|
|
5
|
+
|
|
6
|
+
## Files
|
|
7
|
+
|
|
8
|
+
- [75 — key_value mappings for JSON/YAML wire names](75-key-value-mappings.md)
|
|
9
|
+
- [76 — Schema24 parse workaround attempts](76-schema24-workaround.md)
|
|
10
|
+
- [77 — Convention coverage matrix spec](77-convention-coverage-matrix.md)
|
|
11
|
+
- [78 — Fixture coverage audit](78-fixture-audit.md)
|
|
12
|
+
- [79 — Final verification round 19](79-final-verification-round19.md)
|
|
13
|
+
|
|
14
|
+
## Outcomes
|
|
15
|
+
|
|
16
|
+
- **Answer to user's question**: previously NO, JSON output used
|
|
17
|
+
Ruby snake_case names because no `key_value do ... end` blocks
|
|
18
|
+
were declared. Added `Base::WireMappings` mixin with
|
|
19
|
+
`auto_key_value_mapping!` class method — generates a parallel
|
|
20
|
+
key_value mapping from the existing XML mappings. JSON now
|
|
21
|
+
carries CML wire names (`elementType`, `atomArray`, `formalCharge`).
|
|
22
|
+
Single source of truth — one wire name per attribute.
|
|
23
|
+
- **Schema24 nested-XML parse**: ROOT CAUSE FOUND AND FIXED in
|
|
24
|
+
subsequent round (see TODO 76). The bug was a type-name collision:
|
|
25
|
+
Schema24's legacy `<string>`/`<integer>`/`<float>` CML elements
|
|
26
|
+
shadowed lutaml-model's primitive types in the schema24 context.
|
|
27
|
+
Fixed by excluding these from type registration while keeping
|
|
28
|
+
them as wire classes.
|
|
29
|
+
- **Convention coverage matrix spec**: 49 specs asserting all 8
|
|
30
|
+
conventions have QName, namespace, >=1 constraint, a spec file,
|
|
31
|
+
a Detection root role, and run detect_and_validate without
|
|
32
|
+
raising. Adding a new convention without full coverage makes
|
|
33
|
+
the matrix spec fail.
|
|
34
|
+
- **Fixed bug**: `CompchemModuleMustContainJobList` assumed
|
|
35
|
+
`node.modules` was non-nil; now defensively handles nil.
|
|
36
|
+
- **New fixtures**: ethanol IR (spectroscopy), methane combustion
|
|
37
|
+
(cascade), basic SI units (simpleUnit), ethanol parallel-array
|
|
38
|
+
form (parallel_array), standard unit types (unitType-dictionary).
|
|
39
|
+
- **422 examples, 0 failures, 0 pending**. Zero forbidden patterns.
|
|
40
|
+
(After TODO 76 fix: 423 examples, 0 failures.)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Round 20 — Schema24 parse bug FIXED
|
|
2
|
+
|
|
3
|
+
This round found and fixed the long-standing Schema24 nested-XML
|
|
4
|
+
parse bug that had been documented as a "limitation" since round 18.
|
|
5
|
+
|
|
6
|
+
## Root cause
|
|
7
|
+
|
|
8
|
+
`Cml::Elements::SCHEMA24_ONLY` included CML's legacy `<string>`,
|
|
9
|
+
`<integer>`, `<float>` elements, and Schema24::Configuration
|
|
10
|
+
registered them as types in the schema24 context. Their XML names
|
|
11
|
+
collided with lutaml-model's primitive type names. Every
|
|
12
|
+
`attribute :foo, :string` cast in any Schema24 wire class resolved
|
|
13
|
+
`:string` to `Chemicalml::Cml::Schema24::String` (a Serializable)
|
|
14
|
+
instead of `Lutaml::Model::Type::String` (the primitive).
|
|
15
|
+
|
|
16
|
+
The Serializable.cast path on a String value tried to deserialize
|
|
17
|
+
it as a CML `<string>` element, which failed. Schema3 was
|
|
18
|
+
unaffected because Schema 3 doesn't declare these elements.
|
|
19
|
+
|
|
20
|
+
## Fix
|
|
21
|
+
|
|
22
|
+
Added `Cml::Elements::SCHEMA24_TYPE_COLLISIONS = %i[Float Integer
|
|
23
|
+
String].freeze`. Schema24::Configuration now passes this list as
|
|
24
|
+
`except:` when registering SCHEMA24_ONLY. The three wire classes
|
|
25
|
+
remain defined (parseable as document roots) but are no longer
|
|
26
|
+
registered as types.
|
|
27
|
+
|
|
28
|
+
## Files
|
|
29
|
+
|
|
30
|
+
- [76 — Schema24 parse bug FIXED](76-schema24-workaround.md)
|
|
31
|
+
|
|
32
|
+
## Outcomes
|
|
33
|
+
|
|
34
|
+
- `Chemicalml::Cml::Schema24::Document.from_xml` parses nested
|
|
35
|
+
content. Schema24 finally works the same as Schema3.
|
|
36
|
+
- `spec/chemicalml/cml/schema24_nested_parse_spec.rb` has 3
|
|
37
|
+
passing specs including one with parallel-array atomArray and
|
|
38
|
+
nested molecule.
|
|
39
|
+
- Removed the pending spec.
|
|
40
|
+
- Updated CLAUDE.md (limitation replaced with collision note).
|
|
41
|
+
- Updated TODO 76 with the real root cause and fix.
|
|
42
|
+
- Full suite: **423 examples, 0 failures, 0 pending**.
|
|
43
|
+
|
|
44
|
+
## Lesson
|
|
45
|
+
|
|
46
|
+
When a bug seems to be in upstream but only one of two parallel
|
|
47
|
+
implementations is affected, look for **what's different** about
|
|
48
|
+
that implementation's setup. The bug wasn't in lutaml-model's
|
|
49
|
+
caching — it was in our registration of type-colliding names.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Round 21 — XSD enums, reference resolution, TOML probe
|
|
2
|
+
|
|
3
|
+
This round adds the canonical enum source of truth, three
|
|
4
|
+
enum-validation constraints, a reference resolver for id-based
|
|
5
|
+
links, and a TOML round-trip probe.
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
|
|
9
|
+
- [80 — XSD enum constants](80-xsd-enum-constants.md)
|
|
10
|
+
- [81 — Enum validation constraints](81-enum-validation-constraints.md)
|
|
11
|
+
- [82 — Reference resolver](82-reference-resolver.md)
|
|
12
|
+
- [83 — TOML round-trip spec](83-toml-roundtrip.md)
|
|
13
|
+
- [84 — Final verification round 21](84-final-verification-round21.md)
|
|
14
|
+
|
|
15
|
+
## Outcomes
|
|
16
|
+
|
|
17
|
+
- `Chemicalml::Cml::Enums` — 31 frozen-Set constants matching every
|
|
18
|
+
XSD simpleType that restricts to enumerations (orderType,
|
|
19
|
+
stereoType, chiralityType, latticeType, matrixType, stateType,
|
|
20
|
+
peakMultiplicityType, etc.). A spec parses the XSD and asserts
|
|
21
|
+
every constant matches — drift is caught automatically.
|
|
22
|
+
- Three enum-validation constraints in the molecular convention
|
|
23
|
+
(bond order, bond stereo, molecule chirality). Warning severity
|
|
24
|
+
so extension values are flagged but not rejected. Each populates
|
|
25
|
+
`Violation.value` with the offending literal.
|
|
26
|
+
- `Chemicalml::Cml::ReferenceResolver` walks a document, builds an
|
|
27
|
+
id-index, and resolves `atomRefs2`/`atomRefs4`/`bondRefs`/`ref`
|
|
28
|
+
to actual wire instances. `unresolved_refs` lists every missing
|
|
29
|
+
target — a programmatic alternative to the constraint walker.
|
|
30
|
+
- TOML round-trip spec added (3 pending specs because the tomlib
|
|
31
|
+
adapter isn't installed; will auto-resolve when tomlib is added
|
|
32
|
+
to the Gemfile).
|
|
33
|
+
- Molecular convention now registers 26 constraints (up from 23).
|
|
34
|
+
- **452 examples, 0 failures, 3 pending** (TOML adapter pending).
|
|
35
|
+
Zero forbidden patterns.
|