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,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unitList>` element MUST have a `namespace` attribute
|
|
8
|
+
# whose value is a valid URI defining the scope within which
|
|
9
|
+
# the unit ids are unique. SHOULD end with `/` or `#`.
|
|
10
|
+
class UnitListMustHaveNamespace < Chemicalml::Convention::Constraint::NodeConstraint
|
|
11
|
+
self.description = 'A `<unitList>` element MUST have a `namespace` attribute whose value is a valid URI defining the scope within which the unit ids are unique. SHOULD end with `/` or `#`.'
|
|
12
|
+
applies_to Chemicalml::Cml::Role::UnitList
|
|
13
|
+
def check_node(node, path)
|
|
14
|
+
violations = []
|
|
15
|
+
ns = node.namespace.to_s
|
|
16
|
+
if ns.empty?
|
|
17
|
+
violations << violation(path: path.join('/'),
|
|
18
|
+
message: 'unitList must have a namespace attribute')
|
|
19
|
+
elsif !ns.end_with?('/', '#')
|
|
20
|
+
violations << violation(path: path.join('/'),
|
|
21
|
+
message: "unitList namespace #{ns.inspect} should end with / or #",
|
|
22
|
+
severity: :warning)
|
|
23
|
+
end
|
|
24
|
+
violations
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def unit_list?(node)
|
|
30
|
+
node.is_a?(Chemicalml::Cml::Role::UnitList)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>` element MUST contain a single `<definition>`
|
|
8
|
+
# child element with XHTML content.
|
|
9
|
+
class UnitMustContainDefinition < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'A `<unit>` element MUST contain a single `<definition>` child element with XHTML content.'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
12
|
+
def check_node(node, path)
|
|
13
|
+
return [] unless node.definition.to_s.strip.empty?
|
|
14
|
+
|
|
15
|
+
[violation(path: path.join('/'),
|
|
16
|
+
message: "unit #{node.id.inspect} must contain a single definition child")]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def unit?(node)
|
|
22
|
+
node.is_a?(Chemicalml::Cml::Role::Unit)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>` element MUST have an `id` attribute, unique
|
|
8
|
+
# within the unitList.
|
|
9
|
+
class UnitMustHaveId < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'A `<unit>` element MUST have an `id` attribute, unique within the unitList.'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
12
|
+
def check_node(node, path)
|
|
13
|
+
return [] unless node.id.to_s.empty?
|
|
14
|
+
|
|
15
|
+
[violation(path: path.join('/'),
|
|
16
|
+
message: 'unit must have an id attribute unique within the unitList')]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def unit?(node)
|
|
22
|
+
node.is_a?(Chemicalml::Cml::Role::Unit)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>` element MUST have at least one of `multiplierToSI`
|
|
8
|
+
# or `constantToSI` — to define the conversion to the parent
|
|
9
|
+
# SI unit. Per the unit-dictionary convention spec.
|
|
10
|
+
class UnitMustHaveMultiplierOrConstantToSi < Chemicalml::Convention::Constraint::NodeConstraint
|
|
11
|
+
self.description = 'A `<unit>` element MUST have at least one of `multiplierToSI` or `constantToSI` — to define the conversion to the parent SI unit. Per the unit-dictionary convention spec.'
|
|
12
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
13
|
+
|
|
14
|
+
def check_node(node, _path)
|
|
15
|
+
has_multiplier = !node.multiplier_to_si.to_s.strip.empty?
|
|
16
|
+
has_constant = !node.constant_to_si.to_s.strip.empty?
|
|
17
|
+
return [] if has_multiplier || has_constant
|
|
18
|
+
|
|
19
|
+
[violation(path: yield_path(node),
|
|
20
|
+
message: "unit #{node.id.inspect} must have at least one of " \
|
|
21
|
+
'multiplierToSI or constantToSI to convert to parent SI')]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def yield_path(node)
|
|
27
|
+
id = node.node_id
|
|
28
|
+
id ? "unit[#{id}]" : 'unit'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>` element MUST have a `parentSI` attribute — a
|
|
8
|
+
# QName referencing the SI unit it derives from. Per the
|
|
9
|
+
# unit-dictionary convention spec.
|
|
10
|
+
class UnitMustHaveParentSi < Chemicalml::Convention::Constraint::NodeConstraint
|
|
11
|
+
self.description = 'A `<unit>` element MUST have a `parentSI` attribute — a QName referencing the SI unit it derives from. Per the unit-dictionary convention spec.'
|
|
12
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
13
|
+
|
|
14
|
+
def check_node(node, _path)
|
|
15
|
+
return [] unless node.parent_si.to_s.strip.empty?
|
|
16
|
+
|
|
17
|
+
[violation(path: yield_path(node),
|
|
18
|
+
message: "unit #{node.id.inspect} must have a parentSI attribute " \
|
|
19
|
+
'(QName referencing the parent SI unit)')]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def yield_path(node)
|
|
25
|
+
id = node.node_id
|
|
26
|
+
id ? "unit[#{id}]" : 'unit'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type.rb
CHANGED
|
@@ -8,22 +8,22 @@ module Chemicalml
|
|
|
8
8
|
# at least one of `multiplierToSI`/`constantToSI`, and
|
|
9
9
|
# `unitType` per the unit-dictionary convention.
|
|
10
10
|
class UnitMustHaveSymbolAndUnitType < Chemicalml::Convention::Constraint::NodeConstraint
|
|
11
|
+
self.description = 'Every unit MUST have `id`, `title`, `symbol`, `parentSI`, at least one of `multiplierToSI`/`constantToSI`, and `unitType` per the unit-dictionary convention.'
|
|
12
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
11
13
|
REQUIRED = %i[title symbol parent_si unit_type].freeze
|
|
12
14
|
|
|
13
15
|
def check_node(node, path)
|
|
14
|
-
return [] unless unit?(node)
|
|
15
|
-
|
|
16
16
|
violations = []
|
|
17
17
|
REQUIRED.each do |attr|
|
|
18
18
|
val = node.public_send(attr)
|
|
19
19
|
next unless val.to_s.empty?
|
|
20
20
|
|
|
21
|
-
violations << violation(path: path.join(
|
|
21
|
+
violations << violation(path: path.join('/'),
|
|
22
22
|
message: "unit must have #{attr} (id=#{node.id.inspect})")
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
unless has_si_conversion?(node)
|
|
26
|
-
violations << violation(path: path.join(
|
|
26
|
+
violations << violation(path: path.join('/'),
|
|
27
27
|
message: "unit must have multiplierToSI or constantToSI (id=#{node.id.inspect})")
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>` element MUST have a `title` attribute (the full
|
|
8
|
+
# human-readable name of the unit). Per the unit-dictionary
|
|
9
|
+
# convention spec.
|
|
10
|
+
class UnitMustHaveTitle < Chemicalml::Convention::Constraint::NodeConstraint
|
|
11
|
+
self.description = 'A `<unit>` element MUST have a `title` attribute (the full human-readable name of the unit). Per the unit-dictionary convention spec.'
|
|
12
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
13
|
+
|
|
14
|
+
def check_node(node, _path)
|
|
15
|
+
return [] unless node.title.to_s.strip.empty?
|
|
16
|
+
|
|
17
|
+
[violation(path: yield_path(node),
|
|
18
|
+
message: "unit #{node.id.inspect} must have a title attribute " \
|
|
19
|
+
'(the full human-readable name of the unit)')]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def yield_path(node)
|
|
25
|
+
id = node.node_id
|
|
26
|
+
id ? "unit[#{id}]" : 'unit'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>`'s `parentSI` attribute SHOULD reference a unit
|
|
8
|
+
# that exists in a built-in dictionary (typically the SI
|
|
9
|
+
# dictionary). Catches typos like `parentSI="si:metr"`.
|
|
10
|
+
#
|
|
11
|
+
# Cross-component check parallel to UnitUnitTypeShouldResolve
|
|
12
|
+
# and the molecular convention's DictRefShouldResolve.
|
|
13
|
+
class UnitParentSiShouldResolve < Chemicalml::Convention::Constraint::NodeConstraint
|
|
14
|
+
self.description = "A `<unit>`'s `parentSI` attribute SHOULD reference a unit that exists in a built-in dictionary (typically the SI dictionary). Catches typos like `parentSI=\"si:metr\"`."
|
|
15
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
16
|
+
|
|
17
|
+
def check_node(node, _path)
|
|
18
|
+
parent_si = node.parent_si.to_s.strip
|
|
19
|
+
return [] if parent_si.empty?
|
|
20
|
+
return [] if resolves?(parent_si)
|
|
21
|
+
|
|
22
|
+
[violation(path: yield_path(node),
|
|
23
|
+
message: "unit #{node.id.inspect} parentSI #{parent_si.inspect} does not " \
|
|
24
|
+
'resolve against any built-in unit dictionary',
|
|
25
|
+
severity: :warning,
|
|
26
|
+
value: parent_si)]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def resolves?(parent_si)
|
|
32
|
+
!Chemicalml::Dictionary::Registry.lookup(parent_si).nil?
|
|
33
|
+
rescue StandardError
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def yield_path(node)
|
|
38
|
+
id = node.node_id
|
|
39
|
+
id ? "unit[#{id}]" : 'unit'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unit>`'s `unitType` attribute SHOULD reference a unitType
|
|
8
|
+
# that exists in a built-in unitType-dictionary. Catches typos
|
|
9
|
+
# like `unitType="unitType:lenght"` (misspelled).
|
|
10
|
+
#
|
|
11
|
+
# The lookup uses the dictionary registry, which inspects every
|
|
12
|
+
# built-in dictionary. Cross-component check parallel to
|
|
13
|
+
# DictRefShouldResolve in the molecular convention.
|
|
14
|
+
class UnitUnitTypeShouldResolve < Chemicalml::Convention::Constraint::NodeConstraint
|
|
15
|
+
self.description = "A `<unit>`'s `unitType` attribute SHOULD reference a unitType that exists in a built-in unitType-dictionary. Catches typos like `unitType=\"unitType:lenght\"` (misspelled)."
|
|
16
|
+
applies_to Chemicalml::Cml::Role::Unit
|
|
17
|
+
|
|
18
|
+
def check_node(node, _path)
|
|
19
|
+
unit_type = node.unit_type.to_s.strip
|
|
20
|
+
return [] if unit_type.empty?
|
|
21
|
+
return [] if resolves?(unit_type)
|
|
22
|
+
|
|
23
|
+
[violation(path: yield_path(node),
|
|
24
|
+
message: "unit #{node.id.inspect} unitType #{unit_type.inspect} does not " \
|
|
25
|
+
'resolve against any built-in unitType-dictionary',
|
|
26
|
+
severity: :warning,
|
|
27
|
+
value: unit_type)]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def resolves?(unit_type)
|
|
33
|
+
!Chemicalml::Dictionary::Registry.lookup(unit_type).nil?
|
|
34
|
+
rescue StandardError
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def yield_path(node)
|
|
39
|
+
id = node.node_id
|
|
40
|
+
id ? "unit[#{id}]" : 'unit'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -5,7 +5,25 @@ module Chemicalml
|
|
|
5
5
|
module UnitDictionary
|
|
6
6
|
module Constraints
|
|
7
7
|
autoload :UnitMustHaveSymbolAndUnitType,
|
|
8
|
-
|
|
8
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_have_symbol_and_unit_type'
|
|
9
|
+
autoload :UnitMustHaveId,
|
|
10
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_have_id'
|
|
11
|
+
autoload :UnitMustContainDefinition,
|
|
12
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_contain_definition'
|
|
13
|
+
autoload :UnitListMustHaveNamespace,
|
|
14
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_list_must_have_namespace'
|
|
15
|
+
autoload :UnitListMustContainAtLeastOneUnit,
|
|
16
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_list_must_contain_at_least_one_unit'
|
|
17
|
+
autoload :UnitMustHaveTitle,
|
|
18
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_have_title'
|
|
19
|
+
autoload :UnitMustHaveParentSi,
|
|
20
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_have_parent_si'
|
|
21
|
+
autoload :UnitMustHaveMultiplierOrConstantToSi,
|
|
22
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_must_have_multiplier_or_constant_to_si'
|
|
23
|
+
autoload :UnitUnitTypeShouldResolve,
|
|
24
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_unit_type_should_resolve'
|
|
25
|
+
autoload :UnitParentSiShouldResolve,
|
|
26
|
+
'chemicalml/convention/unit_dictionary/constraints/unit_parent_si_should_resolve'
|
|
9
27
|
end
|
|
10
28
|
end
|
|
11
29
|
end
|
|
@@ -8,9 +8,9 @@ module Chemicalml
|
|
|
8
8
|
module UnitDictionary
|
|
9
9
|
extend Base
|
|
10
10
|
|
|
11
|
-
autoload :Constraints,
|
|
11
|
+
autoload :Constraints, 'chemicalml/convention/unit_dictionary/constraints'
|
|
12
12
|
|
|
13
|
-
QNAME =
|
|
13
|
+
QNAME = 'convention:unit-dictionary'
|
|
14
14
|
NAMESPACE_URI = "#{Chemicalml::Convention::CONVENTION_NAMESPACE}unit-dictionary".freeze
|
|
15
15
|
|
|
16
16
|
def self.qname
|
|
@@ -22,6 +22,15 @@ module Chemicalml
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
register Constraints::UnitMustHaveSymbolAndUnitType
|
|
25
|
+
register Constraints::UnitMustHaveId
|
|
26
|
+
register Constraints::UnitMustContainDefinition
|
|
27
|
+
register Constraints::UnitListMustHaveNamespace
|
|
28
|
+
register Constraints::UnitListMustContainAtLeastOneUnit
|
|
29
|
+
register Constraints::UnitMustHaveTitle
|
|
30
|
+
register Constraints::UnitMustHaveParentSi
|
|
31
|
+
register Constraints::UnitMustHaveMultiplierOrConstantToSi
|
|
32
|
+
register Constraints::UnitUnitTypeShouldResolve
|
|
33
|
+
register Constraints::UnitParentSiShouldResolve
|
|
25
34
|
end
|
|
26
35
|
end
|
|
27
36
|
end
|
data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitTypeDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unitType>` `id` MUST match `[A-Za-z][A-Za-z0-9._-]*`.
|
|
8
|
+
class UnitTypeIdMustMatchPattern < Chemicalml::Convention::Constraint::NodeConstraint
|
|
9
|
+
self.description = 'A `<unitType>` `id` MUST match `[A-Za-z][A-Za-z0-9._-]*`.'
|
|
10
|
+
applies_to Chemicalml::Cml::Role::UnitType
|
|
11
|
+
PATTERN = /\A[A-Za-z][A-Za-z0-9._-]*\z/
|
|
12
|
+
|
|
13
|
+
def check_node(node, path)
|
|
14
|
+
id = node.id.to_s
|
|
15
|
+
return [] if id.empty?
|
|
16
|
+
return [] if id.match?(PATTERN)
|
|
17
|
+
|
|
18
|
+
[violation(path: path.join('/'),
|
|
19
|
+
message: "unitType id #{id.inspect} must match [A-Za-z][A-Za-z0-9._-]*")]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def unit_type?(node)
|
|
25
|
+
node.is_a?(Chemicalml::Cml::Role::UnitType)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitTypeDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unitTypeList>` MUST contain one or more `<unitType>`
|
|
8
|
+
# children.
|
|
9
|
+
class UnitTypeListMustContainAtLeastOneUnitType < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'A `<unitTypeList>` MUST contain one or more `<unitType>` children.'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::UnitTypeList
|
|
12
|
+
def check_node(node, path)
|
|
13
|
+
return [] if (node.unit_types || []).length.positive?
|
|
14
|
+
|
|
15
|
+
[violation(path: path.join('/'),
|
|
16
|
+
message: 'unitTypeList must contain at least one unitType child')]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def unit_type_list?(node)
|
|
22
|
+
node.is_a?(Chemicalml::Cml::Role::UnitTypeList)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitTypeDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unitTypeList>` MUST have a `namespace` attribute (valid
|
|
8
|
+
# URI, SHOULD end with `/` or `#`).
|
|
9
|
+
class UnitTypeListMustHaveNamespace < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'A `<unitTypeList>` MUST have a `namespace` attribute (valid URI, SHOULD end with `/` or `#`).'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::UnitTypeList
|
|
12
|
+
def check_node(node, path)
|
|
13
|
+
violations = []
|
|
14
|
+
ns = node.namespace.to_s
|
|
15
|
+
if ns.empty?
|
|
16
|
+
violations << violation(path: path.join('/'),
|
|
17
|
+
message: 'unitTypeList must have a namespace attribute')
|
|
18
|
+
elsif !ns.end_with?('/', '#')
|
|
19
|
+
violations << violation(path: path.join('/'),
|
|
20
|
+
message: "unitTypeList namespace #{ns.inspect} should end with / or #",
|
|
21
|
+
severity: :warning)
|
|
22
|
+
end
|
|
23
|
+
violations
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def unit_type_list?(node)
|
|
29
|
+
node.is_a?(Chemicalml::Cml::Role::UnitTypeList)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
module UnitTypeDictionary
|
|
6
|
+
module Constraints
|
|
7
|
+
# A `<unitType>` MUST contain a single `<definition>` child
|
|
8
|
+
# with XHTML content.
|
|
9
|
+
class UnitTypeMustContainDefinition < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'A `<unitType>` MUST contain a single `<definition>` child with XHTML content.'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::UnitType
|
|
12
|
+
def check_node(node, path)
|
|
13
|
+
return [] unless node.definition.to_s.strip.empty?
|
|
14
|
+
|
|
15
|
+
[violation(path: path.join('/'),
|
|
16
|
+
message: "unitType #{node.id.inspect} must contain a single definition child")]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def unit_type?(node)
|
|
22
|
+
node.is_a?(Chemicalml::Cml::Role::UnitType)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name.rb
CHANGED
|
@@ -7,17 +7,17 @@ module Chemicalml
|
|
|
7
7
|
# Every unitType MUST have an `id` and a `name` attribute per
|
|
8
8
|
# the unitType-dictionary convention.
|
|
9
9
|
class UnitTypeMustHaveIdAndName < Chemicalml::Convention::Constraint::NodeConstraint
|
|
10
|
+
self.description = 'Every unitType MUST have an `id` and a `name` attribute per the unitType-dictionary convention.'
|
|
11
|
+
applies_to Chemicalml::Cml::Role::UnitType
|
|
10
12
|
def check_node(node, path)
|
|
11
|
-
return [] unless unit_type?(node)
|
|
12
|
-
|
|
13
13
|
violations = []
|
|
14
14
|
if node.id.to_s.empty?
|
|
15
|
-
violations << violation(path: path.join(
|
|
16
|
-
message:
|
|
15
|
+
violations << violation(path: path.join('/'),
|
|
16
|
+
message: 'unitType must have an id')
|
|
17
17
|
end
|
|
18
18
|
if node.name.to_s.empty?
|
|
19
|
-
violations << violation(path: path.join(
|
|
20
|
-
message:
|
|
19
|
+
violations << violation(path: path.join('/'),
|
|
20
|
+
message: 'unitType must have a name')
|
|
21
21
|
end
|
|
22
22
|
violations
|
|
23
23
|
end
|
|
@@ -5,7 +5,15 @@ module Chemicalml
|
|
|
5
5
|
module UnitTypeDictionary
|
|
6
6
|
module Constraints
|
|
7
7
|
autoload :UnitTypeMustHaveIdAndName,
|
|
8
|
-
|
|
8
|
+
'chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_have_id_and_name'
|
|
9
|
+
autoload :UnitTypeIdMustMatchPattern,
|
|
10
|
+
'chemicalml/convention/unit_type_dictionary/constraints/unit_type_id_must_match_pattern'
|
|
11
|
+
autoload :UnitTypeMustContainDefinition,
|
|
12
|
+
'chemicalml/convention/unit_type_dictionary/constraints/unit_type_must_contain_definition'
|
|
13
|
+
autoload :UnitTypeListMustHaveNamespace,
|
|
14
|
+
'chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_have_namespace'
|
|
15
|
+
autoload :UnitTypeListMustContainAtLeastOneUnitType,
|
|
16
|
+
'chemicalml/convention/unit_type_dictionary/constraints/unit_type_list_must_contain_at_least_one_unit_type'
|
|
9
17
|
end
|
|
10
18
|
end
|
|
11
19
|
end
|
|
@@ -8,9 +8,9 @@ module Chemicalml
|
|
|
8
8
|
module UnitTypeDictionary
|
|
9
9
|
extend Base
|
|
10
10
|
|
|
11
|
-
autoload :Constraints,
|
|
11
|
+
autoload :Constraints, 'chemicalml/convention/unit_type_dictionary/constraints'
|
|
12
12
|
|
|
13
|
-
QNAME =
|
|
13
|
+
QNAME = 'convention:unitType-dictionary'
|
|
14
14
|
NAMESPACE_URI = "#{Chemicalml::Convention::CONVENTION_NAMESPACE}unitType-dictionary".freeze
|
|
15
15
|
|
|
16
16
|
def self.qname
|
|
@@ -22,6 +22,10 @@ module Chemicalml
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
register Constraints::UnitTypeMustHaveIdAndName
|
|
25
|
+
register Constraints::UnitTypeIdMustMatchPattern
|
|
26
|
+
register Constraints::UnitTypeMustContainDefinition
|
|
27
|
+
register Constraints::UnitTypeListMustHaveNamespace
|
|
28
|
+
register Constraints::UnitTypeListMustContainAtLeastOneUnitType
|
|
25
29
|
end
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Chemicalml
|
|
4
|
+
module Convention
|
|
5
|
+
# Value object wrapping the violations returned by `validate`.
|
|
6
|
+
# Gives callers severity-based views without losing the raw array
|
|
7
|
+
# (still exposed as `#violations`).
|
|
8
|
+
#
|
|
9
|
+
# Constructed by `Convention.validate_report` (new API) —
|
|
10
|
+
# `Convention.validate` keeps its array return shape so existing
|
|
11
|
+
# callers don't break.
|
|
12
|
+
class ValidationReport
|
|
13
|
+
attr_reader :violations
|
|
14
|
+
|
|
15
|
+
def initialize(violations)
|
|
16
|
+
@violations = violations.to_a.freeze
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def errors
|
|
20
|
+
@errors ||= violations.select(&:error?).freeze
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def warnings
|
|
24
|
+
@warnings ||= violations.select(&:warning?).freeze
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ok?
|
|
28
|
+
errors.empty?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def has_warnings?
|
|
32
|
+
warnings.any?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def size
|
|
36
|
+
violations.length
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def +(other)
|
|
40
|
+
return other if other.nil?
|
|
41
|
+
|
|
42
|
+
raise ArgumentError, "cannot combine ValidationReport with #{other.class}" unless other.is_a?(ValidationReport)
|
|
43
|
+
|
|
44
|
+
ValidationReport.new(violations + other.violations)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ==(other)
|
|
48
|
+
other.is_a?(ValidationReport) && violations == other.violations
|
|
49
|
+
end
|
|
50
|
+
alias eql? ==
|
|
51
|
+
|
|
52
|
+
def hash
|
|
53
|
+
violations.hash
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def to_s
|
|
57
|
+
"#{size} violation(s): #{errors.length} error(s), #{warnings.length} warning(s)"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Human-readable multi-line summary. Suitable for CLI output
|
|
61
|
+
# and logging. Each violation is rendered with severity, path,
|
|
62
|
+
# and message (and value when present).
|
|
63
|
+
#
|
|
64
|
+
# @return [String]
|
|
65
|
+
def summary
|
|
66
|
+
return 'OK — no violations' if ok? && !has_warnings?
|
|
67
|
+
|
|
68
|
+
lines = []
|
|
69
|
+
lines << "Errors: #{errors.size}, Warnings: #{warnings.size}"
|
|
70
|
+
unless errors.empty?
|
|
71
|
+
lines << ''
|
|
72
|
+
lines << 'Errors:'
|
|
73
|
+
errors.each { |v| lines << " ERROR #{v.path}: #{v.message}#{value_suffix(v)}" }
|
|
74
|
+
end
|
|
75
|
+
unless warnings.empty?
|
|
76
|
+
lines << ''
|
|
77
|
+
lines << 'Warnings:'
|
|
78
|
+
warnings.each { |v| lines << " WARN #{v.path}: #{v.message}#{value_suffix(v)}" }
|
|
79
|
+
end
|
|
80
|
+
lines.join("\n")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def value_suffix(violation)
|
|
86
|
+
violation.value.nil? ? '' : " (value=#{violation.value.inspect})"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|