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,49 @@
|
|
|
1
|
+
# 62 — Per-element attribute gaps
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
XSD vs Ruby Base comparison reveals 53 (schema3) / 58 (schema24)
|
|
6
|
+
attribute declarations that are not yet modelled. They cluster across
|
|
7
|
+
20 elements. Most are 1-3 missing attributes; the parallel-array
|
|
8
|
+
attributes for atomArray/bondArray are split out into TODO 61.
|
|
9
|
+
|
|
10
|
+
## Gaps (after TODO 61 closes)
|
|
11
|
+
|
|
12
|
+
| Element | Missing |
|
|
13
|
+
|---|---|
|
|
14
|
+
| alternative | type |
|
|
15
|
+
| band | kpoint (schema24 only) |
|
|
16
|
+
| bond | atomRefs (singular, not atomRefs2) |
|
|
17
|
+
| cellParameter | error, type |
|
|
18
|
+
| cml (module) | fileId, version |
|
|
19
|
+
| eigen | orientation |
|
|
20
|
+
| entry | convention, title, columns, rows, length, minLength, maxLength, pattern, minExclusive, minInclusive, maxExclusive, maxInclusive, fractionDigits, totalDigits, whiteSpace (XSD facets) |
|
|
21
|
+
| isotope | spin |
|
|
22
|
+
| module | role, serial |
|
|
23
|
+
| molecule | formula |
|
|
24
|
+
| peakStructure | type |
|
|
25
|
+
| potential | form |
|
|
26
|
+
| reaction | format, role |
|
|
27
|
+
| reactionScheme | format, role, type |
|
|
28
|
+
| reactionStepList | format |
|
|
29
|
+
| relatedEntry | type (schema24 only) |
|
|
30
|
+
| spectrum | type |
|
|
31
|
+
| substance | id |
|
|
32
|
+
| substanceList | type |
|
|
33
|
+
| unitList | type |
|
|
34
|
+
|
|
35
|
+
## Work
|
|
36
|
+
|
|
37
|
+
For each row above, add `attribute :foo, :string` + `map_attribute "foo", to: :foo`
|
|
38
|
+
to the relevant `lib/chemicalml/cml/base/*.rb` module.
|
|
39
|
+
|
|
40
|
+
The 15 XSD facets on `entry` (columns, fractionDigits, etc.) are
|
|
41
|
+
genuine CML — they describe the data type the entry represents, and
|
|
42
|
+
are emitted by the upstream dictionary files. They are not internal
|
|
43
|
+
XSD noise.
|
|
44
|
+
|
|
45
|
+
## Acceptance
|
|
46
|
+
|
|
47
|
+
- XSD vs Ruby comparison reports 0 attribute gaps.
|
|
48
|
+
- Round-trip of an example with `entry/@pattern` etc. is preserved.
|
|
49
|
+
- Spec coverage for at least one new attribute on each touched element.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# 63 — Universal children mixin
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
The CML Schema 2.4 XSD declares `metadataList`, `label`, `name`, and
|
|
6
|
+
`description` as children of nearly every element. Adding these four
|
|
7
|
+
declarations to every `Base::*` module individually is a DRY
|
|
8
|
+
violation: the same 16 lines of `attribute` + `map_element` would
|
|
9
|
+
appear in ~50 files.
|
|
10
|
+
|
|
11
|
+
## Solution
|
|
12
|
+
|
|
13
|
+
Introduce a shared mixin `Chemicalml::Cml::Base::CommonChildren`
|
|
14
|
+
that declares:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
attribute :metadata_lists, :metadataList, collection: true
|
|
18
|
+
attribute :labels, :label, collection: true
|
|
19
|
+
attribute :names, :name, collection: true
|
|
20
|
+
attribute :descriptions, :description, collection: true
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
with matching `map_element` declarations. The mixin is included by
|
|
24
|
+
the `Base::*` modules whose XSD declares these children.
|
|
25
|
+
|
|
26
|
+
The mixin is **opt-in** — elements that the XSD does not grant these
|
|
27
|
+
children to (e.g. `<atom>`, `<bond>` in schema24) do not include it.
|
|
28
|
+
This keeps MECE discipline: one place owns the universal child set.
|
|
29
|
+
|
|
30
|
+
## Work
|
|
31
|
+
|
|
32
|
+
1. Create `lib/chemicalml/cml/base/common_children.rb`.
|
|
33
|
+
2. For each Base module where the XSD declares metadataList/label/name/description as a child, add `include CommonChildren` and remove the now-redundant individual declarations.
|
|
34
|
+
3. Add a spec `spec/chemicalml/cml/common_children_spec.rb` asserting
|
|
35
|
+
the children appear after `include CommonChildren` and round-trip
|
|
36
|
+
through XML.
|
|
37
|
+
|
|
38
|
+
## Acceptance
|
|
39
|
+
|
|
40
|
+
- `CommonChildren` exists and is included by at least 10 Base modules.
|
|
41
|
+
- No Base module re-declares `metadata_lists` / `labels` / `names` / `descriptions` individually.
|
|
42
|
+
- Specs green.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# 64 — Per-element child element gaps (Schema 2.4)
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
XSD vs Ruby Base comparison reveals 235 missing child declarations
|
|
6
|
+
across ~60 Schema 2.4 elements. These are real CML elements that
|
|
7
|
+
real CML documents contain but our Ruby model drops silently.
|
|
8
|
+
|
|
9
|
+
The Schema 3 XSD declares `<anyCml>` (a wildcard) as a child of every
|
|
10
|
+
element — that is intentionally NOT modelled as a concrete child,
|
|
11
|
+
because doing so would defeat the type system. The Schema 2.4 gaps
|
|
12
|
+
below are *specific* named children, not wildcards.
|
|
13
|
+
|
|
14
|
+
## Largest clusters
|
|
15
|
+
|
|
16
|
+
| Element | Missing children |
|
|
17
|
+
|---|---|
|
|
18
|
+
| molecule | angle, arg, array, crystal, electron, join, length, list, matrix, metadataList, propertyList, scalar, symmetry, torsion, zMatrix |
|
|
19
|
+
| reaction | conditionList, identifier, label, map, mechanism, metadataList, name, object, propertyList, reactiveCentre, spectatorList, substanceList, transitionState |
|
|
20
|
+
| reactant, product | amount, electron, formula, identifier, label, metadataList, molecule, name, substanceList |
|
|
21
|
+
| atom | array, atomType, electron, label, matrix, name, particle, scalar, vector3 |
|
|
22
|
+
| atomType, bondType | array, atom/bond, label, matrix, molecule, property, scalar |
|
|
23
|
+
| join | angle, arg, label, length, metadataList, molecule, torsion |
|
|
24
|
+
| peak, peakGroup | atom, bond, metadataList, molecule, peakStructure/peakGroup |
|
|
25
|
+
| spectrum | metadataList, parameterList, sample, spectrumData, substanceList |
|
|
26
|
+
| reactiveCentre | atomSet, atomTypeList, bondSet, bondTypeList, description |
|
|
27
|
+
| parameter | expression, gradient, property |
|
|
28
|
+
| property | metadataList, name |
|
|
29
|
+
| parameterList, productList, reactantList, reactionStepList | metadataList, name, *(selfRef)* |
|
|
30
|
+
| moleculeList | list, metadataList, moleculeList |
|
|
31
|
+
| sample | metadataList, molecule, substance, substanceList |
|
|
32
|
+
| spectator | label, metadataList, molecule, object |
|
|
33
|
+
| substance | amount, metadataList, property |
|
|
34
|
+
| substanceList | amount, metadataList, propertyList |
|
|
35
|
+
| lattice | matrix, scalar, symmetry |
|
|
36
|
+
| gradient | array, matrix, property, scalar |
|
|
37
|
+
| table | arrayList, tableRowList |
|
|
38
|
+
| transitionState | molecule, propertyList |
|
|
39
|
+
| unit | annotation, metadata, metadataList, unit, unitType |
|
|
40
|
+
| unitType | annotation, dimension |
|
|
41
|
+
| zMatrix | angle, length, torsion |
|
|
42
|
+
| symmetry | matrix, transform3 |
|
|
43
|
+
| eigen | array, matrix |
|
|
44
|
+
| xaxis, yaxis | array |
|
|
45
|
+
| metadataList | metadataList |
|
|
46
|
+
| crystal | cellParameter |
|
|
47
|
+
| formula | formula |
|
|
48
|
+
| dictionary | annotation, unitList |
|
|
49
|
+
| dictionary entry | alternative, annotation, enumeration, metadataList, relatedEntry |
|
|
50
|
+
| map | link |
|
|
51
|
+
| mechanism | description, label, name |
|
|
52
|
+
| peakStructure | metadataList, peakStructure |
|
|
53
|
+
| reactionList | metadataList, reactionScheme |
|
|
54
|
+
| reactionScheme | identifier, label, metadataList, name, reactionScheme |
|
|
55
|
+
| reactionStep | label, metadataList, name, reactionScheme |
|
|
56
|
+
| potentialForm | arg, expression, parameter |
|
|
57
|
+
| trow | tcell |
|
|
58
|
+
| peakList | metadataList |
|
|
59
|
+
| atomTypeList, bondTypeList, basisSet | metadataList, name |
|
|
60
|
+
| conditionList | list, metadataList, name |
|
|
61
|
+
| propertyList | metadataList, name, observation, propertyList |
|
|
62
|
+
| spectrumList | list, metadataList, spectrumList |
|
|
63
|
+
|
|
64
|
+
## Strategy
|
|
65
|
+
|
|
66
|
+
After TODO 63 (CommonChildren mixin) closes, ~80% of the
|
|
67
|
+
`metadataList`/`label`/`name`/`description` gaps are absorbed by
|
|
68
|
+
adding one `include CommonChildren` line. The remaining ~150 gaps are
|
|
69
|
+
element-specific and require individual declarations.
|
|
70
|
+
|
|
71
|
+
## Work
|
|
72
|
+
|
|
73
|
+
1. Apply CommonChildren where the XSD permits.
|
|
74
|
+
2. For each remaining gap, add the specific `attribute` + `map_element` declarations.
|
|
75
|
+
3. Add at least one spec per touched element covering a round-trip
|
|
76
|
+
with the new child.
|
|
77
|
+
|
|
78
|
+
## Acceptance
|
|
79
|
+
|
|
80
|
+
- XSD vs Ruby child comparison reports only `<anyCml>` Schema3 wildcard gaps (intentionally unmodelled).
|
|
81
|
+
- Specs green.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# 65 — SimpleUnit convention
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`reference-docs/conventions/index.md` lists six CML conventions.
|
|
6
|
+
We implement five + two added later (spectroscopy, cascade). The
|
|
7
|
+
sixth "official" one is `simpleUnit`, used as the worked example in
|
|
8
|
+
the CMLLite paper. Without it, the convention set is incomplete
|
|
9
|
+
relative to the upstream CML spec.
|
|
10
|
+
|
|
11
|
+
## Source
|
|
12
|
+
|
|
13
|
+
`reference-docs/schemas/schema3/schema.xsd` — does not define
|
|
14
|
+
convention rules; the rules come from the CMLLite paper. The
|
|
15
|
+
namespace is `http://www.xml-cml.org/convention/simpleUnit`.
|
|
16
|
+
|
|
17
|
+
The paper's simpleUnit example constraints:
|
|
18
|
+
|
|
19
|
+
- A `<unit>` under simpleUnit MUST have a `power` attribute (integer).
|
|
20
|
+
- A `<unit>` under simpleUnit MUST have a `symbol` attribute (non-empty string).
|
|
21
|
+
- The root must be a `<unitList>` declaring `convention='convention:simpleUnit'`.
|
|
22
|
+
|
|
23
|
+
## Work
|
|
24
|
+
|
|
25
|
+
1. `lib/chemicalml/convention/simple_unit.rb` — main module (QNAME =
|
|
26
|
+
`convention:simpleUnit`, NAMESPACE_URI ends in `/simpleUnit`).
|
|
27
|
+
2. `lib/chemicalml/convention/simple_unit/constraints.rb` — autoload registry.
|
|
28
|
+
3. Three constraint files:
|
|
29
|
+
- `unit_must_have_power.rb` — applies_to Role::Unit
|
|
30
|
+
- `unit_must_have_symbol.rb` — applies_to Role::Unit
|
|
31
|
+
- `root_must_be_unit_list.rb` — DocumentConstraint
|
|
32
|
+
4. Register in `Convention::Registry.load_cache`.
|
|
33
|
+
5. Add `autoload :SimpleUnit` to `lib/chemicalml/convention.rb`.
|
|
34
|
+
6. Specs at `spec/chemicalml/convention/simple_unit_spec.rb`.
|
|
35
|
+
|
|
36
|
+
## Acceptance
|
|
37
|
+
|
|
38
|
+
- `Chemicalml::Convention.lookup("convention:simpleUnit")` returns the module.
|
|
39
|
+
- Specs cover all three constraints (positive + negative cases).
|
|
40
|
+
- Full suite green.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 66 — Schema24-only legacy element children
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
Schema 2.4 declares 17 elements absent from Schema 3 (TODO 52 modelled
|
|
6
|
+
them). Of those, several have non-trivial child models that were
|
|
7
|
+
skipped during initial modelling. XSD vs Ruby comparison shows:
|
|
8
|
+
|
|
9
|
+
| Element | Missing children |
|
|
10
|
+
|---|---|
|
|
11
|
+
| annotation | appinfo |
|
|
12
|
+
| arg | array, atom, atomType, expression, matrix, scalar |
|
|
13
|
+
| atomType | array, atom, label, matrix, molecule, property, scalar |
|
|
14
|
+
| bondType | array, bond, label, matrix, molecule, property, scalar |
|
|
15
|
+
| expression | operator, parameter |
|
|
16
|
+
| enumeration | annotation |
|
|
17
|
+
| potentialForm | arg, expression, parameter |
|
|
18
|
+
|
|
19
|
+
These are real Schema 2.4 features; the rest of the legacy set
|
|
20
|
+
(`float`, `integer`, `string`, `tcell`, `trow`, etc.) are scalar
|
|
21
|
+
leaves without children.
|
|
22
|
+
|
|
23
|
+
## Work
|
|
24
|
+
|
|
25
|
+
1. Update each Schema24-only `Base::*` module to declare the missing
|
|
26
|
+
children + matching `map_element`.
|
|
27
|
+
2. Add a spec per touched element.
|
|
28
|
+
|
|
29
|
+
## Acceptance
|
|
30
|
+
|
|
31
|
+
- XSD vs Ruby child comparison reports 0 Schema24-only-legacy gaps.
|
|
32
|
+
- Specs green.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 67 — Final spec / lint / docs verification
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
After TODOs 61-66 land, the public surface area grows by ~330 element
|
|
6
|
+
attribute/child declarations plus a new convention. CLAUDE.md and the
|
|
7
|
+
spec suite need to reflect the new state.
|
|
8
|
+
|
|
9
|
+
## Work
|
|
10
|
+
|
|
11
|
+
1. Update `CLAUDE.md`:
|
|
12
|
+
- List 8 conventions (molecular, compchem, dictionary, unit-dictionary,
|
|
13
|
+
unitType-dictionary, spectroscopy, cascade, simpleUnit).
|
|
14
|
+
- Note the parallel-array atomArray/bondArray serialisation forms.
|
|
15
|
+
- Note the `CommonChildren` mixin pattern.
|
|
16
|
+
2. Scan the codebase for forbidden patterns:
|
|
17
|
+
- `require_relative` inside `lib/`
|
|
18
|
+
- `def to_h`, `def from_h`, `def to_xml`, `def from_xml`, `def to_json`, `def from_json` on model classes
|
|
19
|
+
- `double(` in specs
|
|
20
|
+
- `\.send(`, `instance_variable_set`, `instance_variable_get`, `respond_to?`
|
|
21
|
+
- AI attribution trailers in commit history
|
|
22
|
+
3. Run full `bundle exec rspec` — must be green.
|
|
23
|
+
4. Run `bundle exec rubocop` on touched files — must be clean.
|
|
24
|
+
5. Add a top-level README under `TODO.align/` summarising rounds 1-17.
|
|
25
|
+
|
|
26
|
+
## Acceptance
|
|
27
|
+
|
|
28
|
+
- `bundle exec rspec` exits 0.
|
|
29
|
+
- `grep -rn 'require_relative' lib/` returns nothing.
|
|
30
|
+
- `grep -rn 'def to_h\|def from_h' lib/chemicalml/cml/` returns nothing.
|
|
31
|
+
- `grep -rn 'double(' spec/` returns nothing.
|
|
32
|
+
- CLAUDE.md convention list is current.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 68 — Detection coverage for all 8 conventions
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`Convention::Detection.convention_of` lists 6 root roles (Document,
|
|
6
|
+
Module, Molecule, Dictionary, UnitList, UnitTypeList). With 8
|
|
7
|
+
conventions now registered, several conventions have no auto-detection
|
|
8
|
+
path:
|
|
9
|
+
|
|
10
|
+
| Convention | Expected root role | Currently detected? |
|
|
11
|
+
|--------------|--------------------|---------------------|
|
|
12
|
+
| molecular | Document / Module / Molecule | yes |
|
|
13
|
+
| compchem | Module | yes |
|
|
14
|
+
| dictionary | Dictionary | yes |
|
|
15
|
+
| unit-dictionary | UnitList | yes |
|
|
16
|
+
| unitType-dictionary | UnitTypeList | yes |
|
|
17
|
+
| spectroscopy | Spectrum / SpectrumList | **no** |
|
|
18
|
+
| cascade | ReactionScheme / ReactionList | **no** |
|
|
19
|
+
| simpleUnit | UnitList | yes |
|
|
20
|
+
|
|
21
|
+
## Work
|
|
22
|
+
|
|
23
|
+
1. Extend `CONVENTION_ROOTS` to include:
|
|
24
|
+
- `Role::Spectrum`, `Role::SpectrumList`
|
|
25
|
+
- `Role::ReactionScheme`, `Role::ReactionList`
|
|
26
|
+
2. Add specs covering each convention's auto-detection from a root
|
|
27
|
+
element with the right `convention` attribute.
|
|
28
|
+
|
|
29
|
+
## Acceptance
|
|
30
|
+
|
|
31
|
+
- `Detection.convention_of(spectrum)` returns the convention string
|
|
32
|
+
when the spectrum declares one.
|
|
33
|
+
- All 8 conventions are auto-detectable from at least one root role.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 69 — JSON / YAML round-trip proof
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
CLAUDE.md claims "lutaml-model is format-agnostic (XML/JSON/YAML/TOML
|
|
6
|
+
via adapters), so the same class supports whatever serialization
|
|
7
|
+
lutaml-model supports". We have no specs proving this. If a downstream
|
|
8
|
+
caller wants to serialize CML to JSON (e.g. for a REST API), we should
|
|
9
|
+
verify it actually works.
|
|
10
|
+
|
|
11
|
+
## Work
|
|
12
|
+
|
|
13
|
+
Add `spec/chemicalml/cml/json_yaml_roundtrip_spec.rb` that:
|
|
14
|
+
|
|
15
|
+
1. Constructs a representative CML model (Document with a Molecule
|
|
16
|
+
containing an AtomArray).
|
|
17
|
+
2. Calls `to_json` / `from_json`.
|
|
18
|
+
3. Calls `to_yaml` / `from_yaml`.
|
|
19
|
+
4. Asserts the round-tripped model has the same data.
|
|
20
|
+
5. Asserts `from_json(to_json(model))` is structurally equivalent to
|
|
21
|
+
`from_xml(to_xml(model))` for the same source model.
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- JSON round-trip spec passes.
|
|
26
|
+
- YAML round-trip spec passes.
|
|
27
|
+
- The spec proves the format-agnostic claim is true.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# 70 — Iterative tree walker
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`Chemicalml::Convention::Constraint#walk_nodes` recurses through the
|
|
6
|
+
wire tree. CML documents can be deeply nested (cascading modules,
|
|
7
|
+
large reaction cascades, etc.) — recursion risks `SystemStackError`
|
|
8
|
+
on real-world files.
|
|
9
|
+
|
|
10
|
+
The constraint walker is also called from `Coordinator.validate`, so
|
|
11
|
+
a stack overflow there aborts validation entirely.
|
|
12
|
+
|
|
13
|
+
## Work
|
|
14
|
+
|
|
15
|
+
Replace the recursive walk in `lib/chemicalml/convention/constraint.rb`
|
|
16
|
+
with an iterative worklist:
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
def walk_nodes(node, path = [], &block)
|
|
20
|
+
return unless visitable?(node)
|
|
21
|
+
worklist = [[node, path]]
|
|
22
|
+
until worklist.empty?
|
|
23
|
+
current, current_path = worklist.shift
|
|
24
|
+
yield(current, current_path)
|
|
25
|
+
children = current.wire_children.map do |child|
|
|
26
|
+
[child, current_path + [describe(child)]]
|
|
27
|
+
end
|
|
28
|
+
worklist.unshift(*children)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This preserves the same traversal order (DFS pre-order) without
|
|
34
|
+
recursion.
|
|
35
|
+
|
|
36
|
+
## Acceptance
|
|
37
|
+
|
|
38
|
+
- A deeply-nested CML document (100+ levels of nested Module) walks
|
|
39
|
+
without stack overflow.
|
|
40
|
+
- All existing constraint specs pass unchanged.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 71 — Enrich Violation with offending value
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`Violation` carries `path`, `message`, `severity`, `constraint`.
|
|
6
|
+
Debugging is harder than necessary because the actual offending value
|
|
7
|
+
is not on the violation — only mentioned inside `message`. Callers
|
|
8
|
+
that want to render violations in a UI or aggregate them need to
|
|
9
|
+
parse the message string to extract the value.
|
|
10
|
+
|
|
11
|
+
## Work
|
|
12
|
+
|
|
13
|
+
1. Add an optional `value:` keyword to `Violation#initialize`. The
|
|
14
|
+
field is the literal offending value (e.g. the duplicated atom id
|
|
15
|
+
`"a1"`).
|
|
16
|
+
2. Update `Constraint#violation` to forward `value:` to `Violation.new`.
|
|
17
|
+
3. Constraint classes pass the offending value where natural
|
|
18
|
+
(e.g. duplicate id constraints pass the duplicate id).
|
|
19
|
+
4. Specs assert the value is carried.
|
|
20
|
+
|
|
21
|
+
## Acceptance
|
|
22
|
+
|
|
23
|
+
- `Violation.new(path: "x", message: "y", value: "a1").value == "a1"`.
|
|
24
|
+
- No existing spec breaks (value defaults to nil).
|
|
25
|
+
- At least 3 constraints populate `value` with the offending value.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 72 — Close remaining Schema24 child gaps
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
After TODO 64 closed the bulk of Schema24 child gaps via
|
|
6
|
+
`CommonChildren`, ~140 element-specific children remain unmodelled.
|
|
7
|
+
These are concrete child declarations the XSD permits and real CML
|
|
8
|
+
documents use.
|
|
9
|
+
|
|
10
|
+
## Work
|
|
11
|
+
|
|
12
|
+
Add element-specific children to each Base module below. For each,
|
|
13
|
+
add a round-trip spec covering at least one new child.
|
|
14
|
+
|
|
15
|
+
| Element | Children to add |
|
|
16
|
+
|---|---|
|
|
17
|
+
| reactiveCentre | atomSet, atomTypeList, bondSet, bondTypeList |
|
|
18
|
+
| sample | molecule, substance, substanceList |
|
|
19
|
+
| spectator | molecule, object |
|
|
20
|
+
| transitionState | molecule, propertyList |
|
|
21
|
+
| substance | amount, property |
|
|
22
|
+
| substanceList | amount, propertyList |
|
|
23
|
+
| lattice | matrix, scalar, symmetry |
|
|
24
|
+
| table | arrayList, tableRowList |
|
|
25
|
+
| trow | tcell |
|
|
26
|
+
| unit | metadata, unitType (annotation via CommonChildren) |
|
|
27
|
+
| unitType | dimension (annotation via CommonChildren) |
|
|
28
|
+
| dictionary | unitList (annotation via CommonChildren) |
|
|
29
|
+
| dictionaryEntry | alternative, enumeration, relatedEntry |
|
|
30
|
+
| gradient | array, matrix, property, scalar |
|
|
31
|
+
| eigen | array, matrix |
|
|
32
|
+
| xaxis, yaxis | array |
|
|
33
|
+
| zMatrix | angle, length, torsion |
|
|
34
|
+
| symmetry | matrix, transform3 |
|
|
35
|
+
| map | link |
|
|
36
|
+
| join | angle, length, torsion, molecule, arg |
|
|
37
|
+
| fragment | fragmentList, join |
|
|
38
|
+
| fragmentList | join |
|
|
39
|
+
| formula | formula (self-ref) |
|
|
40
|
+
| parameter | expression, gradient, property |
|
|
41
|
+
| potential | arg |
|
|
42
|
+
| atomicBasisFunction | gradient |
|
|
43
|
+
| isotope | abundance |
|
|
44
|
+
| atomType | atom, molecule, scalar, array, matrix, property |
|
|
45
|
+
| bondType | bond, molecule, scalar, array, matrix, property |
|
|
46
|
+
| arg | atom, atomType, expression, scalar, array, matrix |
|
|
47
|
+
| expression | operator, parameter |
|
|
48
|
+
| potentialForm | arg, expression, parameter |
|
|
49
|
+
| annotation | appinfo |
|
|
50
|
+
| enumeration | annotation |
|
|
51
|
+
| metadataList | metadataList (self-ref) |
|
|
52
|
+
| moleculeList | list, moleculeList (self-ref) |
|
|
53
|
+
| parameterList | parameterList (self-ref) |
|
|
54
|
+
| productList | productList (self-ref) |
|
|
55
|
+
| reactantList | reactantList (self-ref) |
|
|
56
|
+
| reactionList | reactionScheme |
|
|
57
|
+
| reactionScheme | identifier, reactionScheme (self-ref) |
|
|
58
|
+
| reactionStep | reactionScheme |
|
|
59
|
+
| peakGroup | atom, bond, molecule, peakGroup (self-ref) |
|
|
60
|
+
| peakStructure | peakStructure (self-ref) |
|
|
61
|
+
| spectrumList | list, spectrumList (self-ref) |
|
|
62
|
+
|
|
63
|
+
## Acceptance
|
|
64
|
+
|
|
65
|
+
- Static XSD child gap analysis (accounting for CommonChildren) reports < 20 remaining gaps.
|
|
66
|
+
- All new child declarations have at least one round-trip spec.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 73 — Document Schema24 nested-parse limitation
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`Chemicalml::Cml::Schema24::Document.from_xml` fails on any document
|
|
6
|
+
with non-trivial nested content:
|
|
7
|
+
|
|
8
|
+
```ruby
|
|
9
|
+
Chemicalml::Cml::Schema24::Document.from_xml(
|
|
10
|
+
%(<cml xmlns="http://www.xml-cml.org/schema"><molecule id="m1"/></cml>),
|
|
11
|
+
register: :chemicalml_schema24
|
|
12
|
+
)
|
|
13
|
+
# => Lutaml::Model::InvalidFormatError: Document has no root element.
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Empty `<cml/>` parses; any child element triggers the failure.
|
|
17
|
+
|
|
18
|
+
## Root cause
|
|
19
|
+
|
|
20
|
+
Tracing the failure, the XML parser is invoked twice for nested
|
|
21
|
+
content. The second call receives the *attribute value* (e.g. `"m1"`)
|
|
22
|
+
instead of an XML fragment — indicating lutaml-model's TypeResolver
|
|
23
|
+
is mis-resolving the child type. The error surfaces as
|
|
24
|
+
`Unknown type 'molecule' in context 'default'`.
|
|
25
|
+
|
|
26
|
+
Schema3 does not exhibit this. Both Schema3 and Schema24 register
|
|
27
|
+
`:molecule` in their own contexts; the `chemicalml_schema24` context
|
|
28
|
+
resolves `:molecule` to `Chemicalml::Cml::Schema24::Molecule`
|
|
29
|
+
correctly when inspected directly. The failure is in the
|
|
30
|
+
*attribute cast* path inside `Lutaml::Model::Attribute#cast`, which
|
|
31
|
+
uses a different lookup mechanism that appears to default to the
|
|
32
|
+
`:default` context.
|
|
33
|
+
|
|
34
|
+
This looks like a lutaml-model issue with how `Attribute#cast` resolves
|
|
35
|
+
child types when multiple schema-version contexts are registered
|
|
36
|
+
globally. Investigating further requires changes inside lutaml-model.
|
|
37
|
+
|
|
38
|
+
## Workaround
|
|
39
|
+
|
|
40
|
+
Schema24 wire classes themselves work correctly when constructed
|
|
41
|
+
directly:
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
Chemicalml::Cml::Schema24::Molecule.new(id: "m1", atom_array: ...) # works
|
|
45
|
+
Chemicalml::Cml::Schema24::Molecule#to_xml # works
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
So Schema24 round-trips through *construction → serialize*, just not
|
|
49
|
+
through *parse → re-serialize*. Existing Schema24 specs use direct
|
|
50
|
+
construction; they continue to pass.
|
|
51
|
+
|
|
52
|
+
## Work
|
|
53
|
+
|
|
54
|
+
1. Document this limitation in `CLAUDE.md` and in a comment on
|
|
55
|
+
`Schema24::Configuration`.
|
|
56
|
+
2. Add a `pending: true` spec that asserts the behaviour fails today
|
|
57
|
+
and will catch the regression automatically when lutaml-model is
|
|
58
|
+
fixed.
|
|
59
|
+
3. File an issue upstream in `lutaml/lutaml-model`.
|
|
60
|
+
|
|
61
|
+
## Acceptance
|
|
62
|
+
|
|
63
|
+
- CLAUDE.md notes the limitation.
|
|
64
|
+
- Pending spec exists and is marked `pending`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 74 — Final verification round 18
|
|
2
|
+
|
|
3
|
+
## Work
|
|
4
|
+
|
|
5
|
+
1. Full rspec suite — must be green.
|
|
6
|
+
2. rubocop on touched files — must be clean.
|
|
7
|
+
3. Forbidden-pattern scan: 0 hits for require_relative, def to_h/from_h/to_xml/from_xml on model classes, double( in specs, send(/instance_variable_*, respond_to? in lib/.
|
|
8
|
+
4. Update CLAUDE.md with: Detection covers 8 conventions; JSON/YAML round-trip proven; iterative walker; enriched Violation; documented Schema24 limitation.
|
|
9
|
+
5. Write `TODO.align/README.round18.md` summarising this round.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
- All four scans clean.
|
|
14
|
+
- CLAUDE.md current.
|
|
15
|
+
- README.round18.md exists.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 75 — key_value mappings for JSON / YAML wire names
|
|
2
|
+
|
|
3
|
+
## Why
|
|
4
|
+
|
|
5
|
+
`lutaml-model` supports a `key_value do ... end` block alongside
|
|
6
|
+
`xml do ... end` to declare JSON/YAML wire names. Previously Base
|
|
7
|
+
modules declared only XML mappings, so JSON output used Ruby
|
|
8
|
+
snake_case names (`element_type`, `atom_array`) instead of CML wire
|
|
9
|
+
names (`elementType`, `atomArray`).
|
|
10
|
+
|
|
11
|
+
## Solution
|
|
12
|
+
|
|
13
|
+
Each `Base::*` module now has an explicit `key_value do ... end`
|
|
14
|
+
block written by hand, mirroring its `xml do ... end` block. The
|
|
15
|
+
two blocks are kept in sync manually — no runtime introspection,
|
|
16
|
+
no DSL, no generation.
|
|
17
|
+
|
|
18
|
+
This is more verbose than the auto-generation approach
|
|
19
|
+
(`Base::WireMappings.auto_key_value_mapping!`) that was tried and
|
|
20
|
+
reverted. The user explicitly preferred manual blocks for clarity
|
|
21
|
+
and explicitness over DRY.
|
|
22
|
+
|
|
23
|
+
## Work done
|
|
24
|
+
|
|
25
|
+
1. Generated initial `key_value do ... end` blocks from each
|
|
26
|
+
`Schema3::*` and `Schema24::*` wire class's XML mappings via a
|
|
27
|
+
one-shot script that introspected the loaded classes.
|
|
28
|
+
2. Inserted each block into the corresponding `Base::*` file right
|
|
29
|
+
after the `xml do ... end` block.
|
|
30
|
+
3. Removed `Base::WireMappings` module and all
|
|
31
|
+
`auto_key_value_mapping!` calls from wire classes.
|
|
32
|
+
4. Verified JSON output carries CML wire names (`elementType`,
|
|
33
|
+
`atomArray`, `formalCharge`).
|
|
34
|
+
5. Verified YAML also carries wire names.
|
|
35
|
+
6. All 422 specs pass.
|
|
36
|
+
|
|
37
|
+
## Acceptance
|
|
38
|
+
|
|
39
|
+
- `Atom.new(element_type: "C").to_json` includes `"elementType":"C"`.
|
|
40
|
+
- `Molecule.from_json(json)` round-trips wire names correctly.
|
|
41
|
+
- All existing specs pass.
|
|
42
|
+
- No runtime introspection or auto-generation — every key_value
|
|
43
|
+
block is hand-written in its Base module.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 76 — Schema24 parse bug: ROOT CAUSE FOUND AND FIXED
|
|
2
|
+
|
|
3
|
+
## Status: FIXED
|
|
4
|
+
|
|
5
|
+
## Root cause
|
|
6
|
+
|
|
7
|
+
The Schema24 nested-XML parse bug had nothing to do with
|
|
8
|
+
lutaml-model internals. The root cause was a **type-name collision**
|
|
9
|
+
in the Schema24 context registry.
|
|
10
|
+
|
|
11
|
+
Schema 2.4 declares legacy elements `<string>`, `<integer>`,
|
|
12
|
+
`<float>` that share their XML names with lutaml-model primitive
|
|
13
|
+
type names (`:string`, `:integer`, `:float`). The Schema24
|
|
14
|
+
Configuration registered these CML element classes as types in the
|
|
15
|
+
Schema24 context — shadowing the primitives.
|
|
16
|
+
|
|
17
|
+
Every `attribute :foo, :string` cast in a Schema24 wire class then
|
|
18
|
+
resolved `:string` to `Chemicalml::Cml::Schema24::String` (the CML
|
|
19
|
+
element class, a `Lutaml::Model::Serializable`) instead of
|
|
20
|
+
`Lutaml::Model::Type::String` (the primitive, which just casts to
|
|
21
|
+
Ruby String). The Serializable.cast path on a String value tried to
|
|
22
|
+
deserialize it as a CML `<string>` element, which failed.
|
|
23
|
+
|
|
24
|
+
Schema3 was unaffected because Schema 3's XSD doesn't declare
|
|
25
|
+
`<string>`, `<integer>`, `<float>` elements.
|
|
26
|
+
|
|
27
|
+
## Fix
|
|
28
|
+
|
|
29
|
+
`lib/chemicalml/cml/elements.rb` adds a new constant:
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
SCHEMA24_TYPE_COLLISIONS = %i[Float Integer String].freeze
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`lib/chemicalml/cml/schema24/configuration.rb#register_models!` now
|
|
36
|
+
passes this list as `except:` when registering SCHEMA24_ONLY:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
register_elements!(
|
|
40
|
+
only: true,
|
|
41
|
+
except: Chemicalml::Cml::Elements::SCHEMA24_TYPE_COLLISIONS
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The CML `<string>`, `<integer>`, `<float>` wire classes remain
|
|
46
|
+
defined and parseable as document roots (via VersionedParser), but
|
|
47
|
+
they are no longer registered as types — so `:string` attribute
|
|
48
|
+
casts resolve correctly to the primitive.
|
|
49
|
+
|
|
50
|
+
## Verification
|
|
51
|
+
|
|
52
|
+
- `Chemicalml::Cml::Schema24::Document.from_xml` now parses nested
|
|
53
|
+
content correctly.
|
|
54
|
+
- `spec/chemicalml/cml/schema24_nested_parse_spec.rb` has 3 passing
|
|
55
|
+
tests including one with parallel-array atomArray.
|
|
56
|
+
- Full suite: 422 examples, 0 failures (previously 2 pending — both
|
|
57
|
+
now pass).
|