dcc 0.2.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 +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.rubocop_todo.yml +10 -0
- data/CHANGELOG.adoc +54 -0
- data/CONTRIBUTING.adoc +64 -0
- data/Gemfile +25 -0
- data/LICENSE +21 -0
- data/README.adoc +69 -0
- data/Rakefile +13 -0
- data/dcc.gemspec +41 -0
- data/docs/cli-reference.adoc +67 -0
- data/docs/getting-started.adoc +117 -0
- data/docs/schema-versions.adoc +65 -0
- data/examples/build_minimal_dcc.rb +23 -0
- data/examples/convert_all_formats.rb +19 -0
- data/examples/parse_and_inspect.rb +19 -0
- data/examples/quantity_math_demo.rb +32 -0
- data/examples/validate_full.rb +27 -0
- data/exe/dcc +7 -0
- data/lib/dcc/base/administrative_data.rb +43 -0
- data/lib/dcc/base/byte_data.rb +36 -0
- data/lib/dcc/base/calibration_laboratory.rb +29 -0
- data/lib/dcc/base/comment.rb +23 -0
- data/lib/dcc/base/condition.rb +34 -0
- data/lib/dcc/base/contact.rb +38 -0
- data/lib/dcc/base/contact_not_strict.rb +38 -0
- data/lib/dcc/base/core_data.rb +44 -0
- data/lib/dcc/base/data.rb +42 -0
- data/lib/dcc/base/digital_calibration_certificate.rb +32 -0
- data/lib/dcc/base/equipment_class.rb +24 -0
- data/lib/dcc/base/formula.rb +33 -0
- data/lib/dcc/base/hash_type.rb +34 -0
- data/lib/dcc/base/identification.rb +27 -0
- data/lib/dcc/base/identifications.rb +27 -0
- data/lib/dcc/base/influence_condition.rb +16 -0
- data/lib/dcc/base/influence_condition_list.rb +40 -0
- data/lib/dcc/base/item.rb +38 -0
- data/lib/dcc/base/item_list.rb +38 -0
- data/lib/dcc/base/list.rb +44 -0
- data/lib/dcc/base/location.rb +36 -0
- data/lib/dcc/base/measurement_meta_data.rb +15 -0
- data/lib/dcc/base/measurement_meta_data_list.rb +27 -0
- data/lib/dcc/base/measurement_result.rb +41 -0
- data/lib/dcc/base/measurement_result_list.rb +28 -0
- data/lib/dcc/base/measuring_equipment.rb +41 -0
- data/lib/dcc/base/measuring_equipment_list.rb +38 -0
- data/lib/dcc/base/quantity.rb +61 -0
- data/lib/dcc/base/ref_type_definition.rb +36 -0
- data/lib/dcc/base/ref_type_definition_list.rb +21 -0
- data/lib/dcc/base/resp_person.rb +38 -0
- data/lib/dcc/base/resp_person_list.rb +27 -0
- data/lib/dcc/base/result.rb +31 -0
- data/lib/dcc/base/result_list.rb +27 -0
- data/lib/dcc/base/rich_content.rb +34 -0
- data/lib/dcc/base/software.rb +35 -0
- data/lib/dcc/base/software_list.rb +27 -0
- data/lib/dcc/base/statement.rb +50 -0
- data/lib/dcc/base/statement_list.rb +27 -0
- data/lib/dcc/base/string_with_lang.rb +24 -0
- data/lib/dcc/base/text.rb +33 -0
- data/lib/dcc/base/used_method.rb +31 -0
- data/lib/dcc/base/used_method_list.rb +27 -0
- data/lib/dcc/base/xml_blob.rb +20 -0
- data/lib/dcc/base.rb +58 -0
- data/lib/dcc/builder/dsl.rb +10 -0
- data/lib/dcc/builder/session.rb +170 -0
- data/lib/dcc/builder.rb +34 -0
- data/lib/dcc/cli/cli.rb +149 -0
- data/lib/dcc/cli/formatters.rb +77 -0
- data/lib/dcc/cli.rb +7 -0
- data/lib/dcc/common_elements.rb +20 -0
- data/lib/dcc/context_configuration.rb +167 -0
- data/lib/dcc/context_options.rb +47 -0
- data/lib/dcc/convert/csv.rb +129 -0
- data/lib/dcc/convert/html.rb +127 -0
- data/lib/dcc/convert/json.rb +62 -0
- data/lib/dcc/convert/result.rb +51 -0
- data/lib/dcc/convert/yaml.rb +21 -0
- data/lib/dcc/convert.rb +14 -0
- data/lib/dcc/diff/change.rb +21 -0
- data/lib/dcc/diff/result.rb +58 -0
- data/lib/dcc/diff.rb +83 -0
- data/lib/dcc/error.rb +54 -0
- data/lib/dcc/extract/file.rb +143 -0
- data/lib/dcc/extract/ring.rb +28 -0
- data/lib/dcc/extract.rb +9 -0
- data/lib/dcc/i18n/text_lookup.rb +67 -0
- data/lib/dcc/i18n.rb +12 -0
- data/lib/dcc/inspect/report.rb +139 -0
- data/lib/dcc/inspect.rb +9 -0
- data/lib/dcc/migrate.rb +41 -0
- data/lib/dcc/namespace/dcc.rb +30 -0
- data/lib/dcc/namespace/dsig.rb +15 -0
- data/lib/dcc/namespace/math_ml.rb +14 -0
- data/lib/dcc/namespace/qudt.rb +15 -0
- data/lib/dcc/namespace/si.rb +26 -0
- data/lib/dcc/namespace.rb +18 -0
- data/lib/dcc/plugin/registry.rb +45 -0
- data/lib/dcc/plugin.rb +42 -0
- data/lib/dcc/quantity_format/formatter.rb +90 -0
- data/lib/dcc/quantity_format.rb +10 -0
- data/lib/dcc/quantity_math/quantity.rb +46 -0
- data/lib/dcc/quantity_math/real.rb +116 -0
- data/lib/dcc/quantity_math.rb +14 -0
- data/lib/dcc/schema/resources/dcc/dsi/v1.0.1.xsd +415 -0
- data/lib/dcc/schema/resources/dcc/dsi/v1.3.0.xsd +814 -0
- data/lib/dcc/schema/resources/dcc/dsi/v1.3.1.xsd +814 -0
- data/lib/dcc/schema/resources/dcc/dsi/v2.0.0.xsd +869 -0
- data/lib/dcc/schema/resources/dcc/dsi/v2.1.0.xsd +1031 -0
- data/lib/dcc/schema/resources/dcc/dsi/v2.2.1.xsd +1574 -0
- data/lib/dcc/schema/resources/dcc/qudt/v2.2.1.xsd +44 -0
- data/lib/dcc/schema/resources/dcc/v2.1.0/dcc.xsd +650 -0
- data/lib/dcc/schema/resources/dcc/v2.1.1/dcc.xsd +669 -0
- data/lib/dcc/schema/resources/dcc/v2.2.0/dcc.xsd +730 -0
- data/lib/dcc/schema/resources/dcc/v2.3.0/dcc.xsd +708 -0
- data/lib/dcc/schema/resources/dcc/v2.4.0/dcc.xsd +725 -0
- data/lib/dcc/schema/resources/dcc/v3.0.0/dcc.xsd +749 -0
- data/lib/dcc/schema/resources/dcc/v3.1.0/dcc.xsd +843 -0
- data/lib/dcc/schema/resources/dcc/v3.1.1/dcc.xsd +843 -0
- data/lib/dcc/schema/resources/dcc/v3.1.2/dcc.xsd +844 -0
- data/lib/dcc/schema/resources/dcc/v3.2.0/dcc.xsd +940 -0
- data/lib/dcc/schema/resources/dcc/v3.2.1/dcc.xsd +963 -0
- data/lib/dcc/schema/resources/dcc/v3.3.0/dcc.xsd +1008 -0
- data/lib/dcc/schema/resources/dcc/xmldsig-core-schema.xsd +312 -0
- data/lib/dcc/schema/resources/dsi/qudt/v2.2.1.xsd +44 -0
- data/lib/dcc/schema/resources/dsi/v1.0.1/SI_Format.xsd +415 -0
- data/lib/dcc/schema/resources/dsi/v1.3.0/SI_Format.xsd +814 -0
- data/lib/dcc/schema/resources/dsi/v1.3.1/SI_Format.xsd +814 -0
- data/lib/dcc/schema/resources/dsi/v2.0.0/SI_Format.xsd +869 -0
- data/lib/dcc/schema/resources/dsi/v2.1.0/SI_Format.xsd +1031 -0
- data/lib/dcc/schema/resources/dsi/v2.2.1/SI_Format.xsd +1574 -0
- data/lib/dcc/schema/resources/qudt/qudt.xsd +44 -0
- data/lib/dcc/schema/resources/schematron/dcc.sch +523 -0
- data/lib/dcc/schema/resources/schematron/dcc.svrl +2302 -0
- data/lib/dcc/schema/resources/xmldsig/xmldsig-core-schema.xsd +312 -0
- data/lib/dcc/schema/version.rb +94 -0
- data/lib/dcc/schema.rb +35 -0
- data/lib/dcc/server/app.rb +133 -0
- data/lib/dcc/server/storage/entry.rb +15 -0
- data/lib/dcc/server/storage/memory.rb +57 -0
- data/lib/dcc/server/storage.rb +13 -0
- data/lib/dcc/server.rb +33 -0
- data/lib/dcc/si/base/complex.rb +43 -0
- data/lib/dcc/si/base/complex_list_xml_list.rb +39 -0
- data/lib/dcc/si/base/constant.rb +39 -0
- data/lib/dcc/si/base/coverage_interval_mu.rb +31 -0
- data/lib/dcc/si/base/expanded_mu.rb +29 -0
- data/lib/dcc/si/base/expanded_unc_xml_list.rb +30 -0
- data/lib/dcc/si/base/hybrid.rb +42 -0
- data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +28 -0
- data/lib/dcc/si/base/real.rb +48 -0
- data/lib/dcc/si/base/real_list_xml_list.rb +45 -0
- data/lib/dcc/si/base/si_list.rb +37 -0
- data/lib/dcc/si/base/standard_mu.rb +25 -0
- data/lib/dcc/si/base.rb +24 -0
- data/lib/dcc/si/common_elements.rb +13 -0
- data/lib/dcc/si/namespace.rb +7 -0
- data/lib/dcc/si/v1/common_elements.rb +13 -0
- data/lib/dcc/si/v1/complex.rb +8 -0
- data/lib/dcc/si/v1/complex_list_xml_list.rb +8 -0
- data/lib/dcc/si/v1/configuration.rb +13 -0
- data/lib/dcc/si/v1/constant.rb +8 -0
- data/lib/dcc/si/v1/coverage_interval_mu.rb +8 -0
- data/lib/dcc/si/v1/expanded_mu.rb +8 -0
- data/lib/dcc/si/v1/expanded_unc.rb +23 -0
- data/lib/dcc/si/v1/expanded_unc_xml_list.rb +8 -0
- data/lib/dcc/si/v1/hybrid.rb +8 -0
- data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +8 -0
- data/lib/dcc/si/v1/namespace.rb +9 -0
- data/lib/dcc/si/v1/real.rb +8 -0
- data/lib/dcc/si/v1/real_list_xml_list.rb +8 -0
- data/lib/dcc/si/v1/si_list.rb +8 -0
- data/lib/dcc/si/v1/standard_mu.rb +8 -0
- data/lib/dcc/si/v1.rb +46 -0
- data/lib/dcc/si/v2/common_elements.rb +13 -0
- data/lib/dcc/si/v2/complex.rb +8 -0
- data/lib/dcc/si/v2/complex_list_xml_list.rb +8 -0
- data/lib/dcc/si/v2/configuration.rb +13 -0
- data/lib/dcc/si/v2/constant.rb +8 -0
- data/lib/dcc/si/v2/coverage_interval_mu.rb +8 -0
- data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +24 -0
- data/lib/dcc/si/v2/expanded_mu.rb +8 -0
- data/lib/dcc/si/v2/expanded_mu_xml_list.rb +22 -0
- data/lib/dcc/si/v2/expanded_unc_xml_list.rb +8 -0
- data/lib/dcc/si/v2/hybrid.rb +8 -0
- data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +8 -0
- data/lib/dcc/si/v2/namespace.rb +9 -0
- data/lib/dcc/si/v2/real.rb +8 -0
- data/lib/dcc/si/v2/real_list_xml_list.rb +8 -0
- data/lib/dcc/si/v2/si_list.rb +8 -0
- data/lib/dcc/si/v2/standard_mu.rb +8 -0
- data/lib/dcc/si/v2/standard_mu_xml_list.rb +18 -0
- data/lib/dcc/si/v2.rb +49 -0
- data/lib/dcc/si.rb +34 -0
- data/lib/dcc/signature/result.rb +43 -0
- data/lib/dcc/signature/signer.rb +36 -0
- data/lib/dcc/signature/verifier.rb +41 -0
- data/lib/dcc/signature.rb +13 -0
- data/lib/dcc/transform/result.rb +24 -0
- data/lib/dcc/transform/xslt.rb +72 -0
- data/lib/dcc/transform.rb +12 -0
- data/lib/dcc/type/base64_binary.rb +55 -0
- data/lib/dcc/type/decimal_xml_list.rb +47 -0
- data/lib/dcc/type/iso_country_code.rb +23 -0
- data/lib/dcc/type/iso_language_code.rb +23 -0
- data/lib/dcc/type/schema_version.rb +37 -0
- data/lib/dcc/type/si_unit.rb +26 -0
- data/lib/dcc/type.rb +16 -0
- data/lib/dcc/type_guards.rb +140 -0
- data/lib/dcc/v2/administrative_data.rb +8 -0
- data/lib/dcc/v2/byte_data.rb +8 -0
- data/lib/dcc/v2/calibration_laboratory.rb +8 -0
- data/lib/dcc/v2/comment.rb +8 -0
- data/lib/dcc/v2/common_elements.rb +13 -0
- data/lib/dcc/v2/condition.rb +8 -0
- data/lib/dcc/v2/configuration.rb +17 -0
- data/lib/dcc/v2/contact.rb +8 -0
- data/lib/dcc/v2/contact_not_strict.rb +8 -0
- data/lib/dcc/v2/core_data.rb +8 -0
- data/lib/dcc/v2/data.rb +8 -0
- data/lib/dcc/v2/digital_calibration_certificate.rb +8 -0
- data/lib/dcc/v2/equipment_class.rb +8 -0
- data/lib/dcc/v2/formula.rb +8 -0
- data/lib/dcc/v2/hash_type.rb +8 -0
- data/lib/dcc/v2/identification.rb +8 -0
- data/lib/dcc/v2/identifications.rb +8 -0
- data/lib/dcc/v2/influence_condition.rb +7 -0
- data/lib/dcc/v2/influence_condition_list.rb +8 -0
- data/lib/dcc/v2/item.rb +8 -0
- data/lib/dcc/v2/item_list.rb +8 -0
- data/lib/dcc/v2/list.rb +8 -0
- data/lib/dcc/v2/location.rb +8 -0
- data/lib/dcc/v2/measurement_meta_data.rb +8 -0
- data/lib/dcc/v2/measurement_meta_data_list.rb +8 -0
- data/lib/dcc/v2/measurement_result.rb +8 -0
- data/lib/dcc/v2/measurement_result_list.rb +8 -0
- data/lib/dcc/v2/measuring_equipment.rb +8 -0
- data/lib/dcc/v2/measuring_equipment_list.rb +8 -0
- data/lib/dcc/v2/namespace.rb +8 -0
- data/lib/dcc/v2/quantity.rb +49 -0
- data/lib/dcc/v2/ref_type_definition.rb +11 -0
- data/lib/dcc/v2/ref_type_definition_list.rb +15 -0
- data/lib/dcc/v2/resp_person.rb +8 -0
- data/lib/dcc/v2/resp_person_list.rb +8 -0
- data/lib/dcc/v2/result.rb +8 -0
- data/lib/dcc/v2/result_list.rb +8 -0
- data/lib/dcc/v2/rich_content.rb +12 -0
- data/lib/dcc/v2/software.rb +8 -0
- data/lib/dcc/v2/software_list.rb +8 -0
- data/lib/dcc/v2/statement.rb +8 -0
- data/lib/dcc/v2/statement_list.rb +8 -0
- data/lib/dcc/v2/string_with_lang.rb +8 -0
- data/lib/dcc/v2/text.rb +8 -0
- data/lib/dcc/v2/used_method.rb +8 -0
- data/lib/dcc/v2/used_method_list.rb +8 -0
- data/lib/dcc/v2/xml_blob.rb +8 -0
- data/lib/dcc/v2.rb +84 -0
- data/lib/dcc/v3/administrative_data.rb +8 -0
- data/lib/dcc/v3/byte_data.rb +8 -0
- data/lib/dcc/v3/calibration_laboratory.rb +8 -0
- data/lib/dcc/v3/comment.rb +8 -0
- data/lib/dcc/v3/common_elements.rb +11 -0
- data/lib/dcc/v3/condition.rb +8 -0
- data/lib/dcc/v3/configuration.rb +17 -0
- data/lib/dcc/v3/contact.rb +8 -0
- data/lib/dcc/v3/contact_not_strict.rb +8 -0
- data/lib/dcc/v3/core_data.rb +8 -0
- data/lib/dcc/v3/data.rb +8 -0
- data/lib/dcc/v3/digital_calibration_certificate.rb +8 -0
- data/lib/dcc/v3/equipment_class.rb +8 -0
- data/lib/dcc/v3/formula.rb +8 -0
- data/lib/dcc/v3/hash_type.rb +8 -0
- data/lib/dcc/v3/identification.rb +8 -0
- data/lib/dcc/v3/identifications.rb +8 -0
- data/lib/dcc/v3/influence_condition.rb +7 -0
- data/lib/dcc/v3/influence_condition_list.rb +8 -0
- data/lib/dcc/v3/item.rb +8 -0
- data/lib/dcc/v3/item_list.rb +8 -0
- data/lib/dcc/v3/list.rb +8 -0
- data/lib/dcc/v3/location.rb +8 -0
- data/lib/dcc/v3/measurement_meta_data.rb +8 -0
- data/lib/dcc/v3/measurement_meta_data_list.rb +8 -0
- data/lib/dcc/v3/measurement_result.rb +8 -0
- data/lib/dcc/v3/measurement_result_list.rb +8 -0
- data/lib/dcc/v3/measuring_equipment.rb +8 -0
- data/lib/dcc/v3/measuring_equipment_list.rb +8 -0
- data/lib/dcc/v3/namespace.rb +7 -0
- data/lib/dcc/v3/quantity.rb +49 -0
- data/lib/dcc/v3/ref_type_definition.rb +8 -0
- data/lib/dcc/v3/ref_type_definition_list.rb +8 -0
- data/lib/dcc/v3/resp_person.rb +8 -0
- data/lib/dcc/v3/resp_person_list.rb +8 -0
- data/lib/dcc/v3/result.rb +8 -0
- data/lib/dcc/v3/result_list.rb +8 -0
- data/lib/dcc/v3/rich_content.rb +8 -0
- data/lib/dcc/v3/software.rb +8 -0
- data/lib/dcc/v3/software_list.rb +8 -0
- data/lib/dcc/v3/statement.rb +8 -0
- data/lib/dcc/v3/statement_list.rb +8 -0
- data/lib/dcc/v3/string_with_lang.rb +8 -0
- data/lib/dcc/v3/text.rb +8 -0
- data/lib/dcc/v3/used_method.rb +8 -0
- data/lib/dcc/v3/used_method_list.rb +8 -0
- data/lib/dcc/v3/xml_blob.rb +8 -0
- data/lib/dcc/v3.rb +111 -0
- data/lib/dcc/validate/business_rules.rb +121 -0
- data/lib/dcc/validate/issue.rb +56 -0
- data/lib/dcc/validate/result.rb +105 -0
- data/lib/dcc/validate/schematron/profile.rb +64 -0
- data/lib/dcc/validate/schematron/rule.rb +49 -0
- data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +42 -0
- data/lib/dcc/validate/schematron/rules/base.rb +15 -0
- data/lib/dcc/validate/schematron/rules/date_range_check.rb +41 -0
- data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +61 -0
- data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +58 -0
- data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +53 -0
- data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +39 -0
- data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +82 -0
- data/lib/dcc/validate/schematron/rules/release_format_check.rb +44 -0
- data/lib/dcc/validate/schematron/rules/schema_version_check.rb +31 -0
- data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +58 -0
- data/lib/dcc/validate/schematron/rules/unit_format_check.rb +74 -0
- data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +65 -0
- data/lib/dcc/validate/schematron/rules/used_software_placement.rb +43 -0
- data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +42 -0
- data/lib/dcc/validate/schematron/rules.rb +30 -0
- data/lib/dcc/validate/schematron.rb +22 -0
- data/lib/dcc/validate/severity.rb +39 -0
- data/lib/dcc/validate/xsd.rb +97 -0
- data/lib/dcc/validate.rb +15 -0
- data/lib/dcc/version.rb +5 -0
- data/lib/dcc/versioned_parser.rb +48 -0
- data/lib/dcc.rb +141 -0
- metadata +425 -0
data/lib/dcc/migrate.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `Dcc::Migrate` upgrades or downgrades a parsed DCC between schema versions,
|
|
4
|
+
# applying the necessary field renames and D-SI version transitions.
|
|
5
|
+
#
|
|
6
|
+
# Currently a thin shim: serializes the source DCC and re-parses under
|
|
7
|
+
# the target version's context. Future work will add per-field transformations.
|
|
8
|
+
module Dcc
|
|
9
|
+
module Migrate
|
|
10
|
+
class << self
|
|
11
|
+
# @param dcc [Lutaml::Model::Serializable]
|
|
12
|
+
# @param from [String] source version (e.g. "2.3.0").
|
|
13
|
+
# @param to [String] target version (e.g. "3.3.0").
|
|
14
|
+
# @return [Dcc::V2::DigitalCalibrationCertificate, Dcc::V3::DigitalCalibrationCertificate]
|
|
15
|
+
def call(dcc, from:, to:)
|
|
16
|
+
from_major = ::Dcc::Schema::Version.major(from)
|
|
17
|
+
to_major = ::Dcc::Schema::Version.major(to)
|
|
18
|
+
if from_major == to_major
|
|
19
|
+
# Same major: just rewrite the schemaVersion attribute.
|
|
20
|
+
return rewrite_schema_version(dcc, to)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Cross-major migration: serialize then re-parse under target.
|
|
24
|
+
xml = dcc.to_xml
|
|
25
|
+
target_parser = ::Dcc.parser_for(to_major)
|
|
26
|
+
target_parser.load_all!
|
|
27
|
+
migrated = target_parser.parse(xml)
|
|
28
|
+
rewrite_schema_version(migrated, to)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def rewrite_schema_version(dcc, version)
|
|
34
|
+
return dcc unless Dcc::TypeGuards.has_writer?(dcc, :schema_version)
|
|
35
|
+
|
|
36
|
+
dcc.schema_version = version
|
|
37
|
+
dcc
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/xml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Namespace
|
|
7
|
+
# The DCC XML namespace. PTB publishes the canonical URI as
|
|
8
|
+
# `https://ptb.de/dcc`; older documents occasionally use the
|
|
9
|
+
# `https://ptb.de/dcc.xsd` alias which we accept via `uri_aliases`.
|
|
10
|
+
#
|
|
11
|
+
# Schema location is versioned (e.g. `https://ptb.de/dcc/v3.3.0/dcc.xsd`).
|
|
12
|
+
# The default points to the latest published version; per-version overrides
|
|
13
|
+
# happen in `Dcc::V2::Namespace` and `Dcc::V3::Namespace`.
|
|
14
|
+
class Dcc < Lutaml::Xml::Namespace
|
|
15
|
+
uri "https://ptb.de/dcc"
|
|
16
|
+
uri_aliases "https://ptb.de/dcc.xsd"
|
|
17
|
+
schema_location "https://ptb.de/dcc/v3.3.0/dcc.xsd"
|
|
18
|
+
prefix_default "dcc"
|
|
19
|
+
element_form_default :qualified
|
|
20
|
+
attribute_form_default :unqualified
|
|
21
|
+
version "3.3.0"
|
|
22
|
+
|
|
23
|
+
# DCC imports D-SI for quantity expressions, MathML for formulae, and
|
|
24
|
+
# (from v3.4.0) W3C XMLDSig for digital signatures.
|
|
25
|
+
imports ::Dcc::Namespace::Si,
|
|
26
|
+
::Dcc::Namespace::MathMl,
|
|
27
|
+
::Dcc::Namespace::Dsig
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/xml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Namespace
|
|
7
|
+
# W3C XML Digital Signature namespace. Imported by DCC v3.4.0+ to support
|
|
8
|
+
# `ds:Signature` elements on the root `digitalCalibrationCertificate`.
|
|
9
|
+
class Dsig < Lutaml::Xml::Namespace
|
|
10
|
+
uri "http://www.w3.org/2000/09/xmldsig#"
|
|
11
|
+
prefix_default "ds"
|
|
12
|
+
element_form_default :qualified
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/xml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Namespace
|
|
7
|
+
# W3C MathML namespace used inside DCC `dcc:formula` elements.
|
|
8
|
+
class MathMl < Lutaml::Xml::Namespace
|
|
9
|
+
uri "http://www.w3.org/1998/Math/MathML"
|
|
10
|
+
prefix_default "ml"
|
|
11
|
+
element_form_default :qualified
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/xml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Namespace
|
|
7
|
+
# QUDT vocabulary namespace. Referenced by D-SI for quantity-kind
|
|
8
|
+
# identifiers (e.g. `https://qudt.org/vocab/quantitykind/Length`).
|
|
9
|
+
class Qudt < Lutaml::Xml::Namespace
|
|
10
|
+
uri "http://qudt.org/vocab/"
|
|
11
|
+
prefix_default "qudt"
|
|
12
|
+
element_form_default :qualified
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/xml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Namespace
|
|
7
|
+
# The D-SI XML namespace (https://ptb.de/si). Used to express measurement
|
|
8
|
+
# quantities (real, complex, constant, list) and their uncertainties inside
|
|
9
|
+
# DCC documents.
|
|
10
|
+
#
|
|
11
|
+
# Schema location is versioned. The default points to the latest D-SI
|
|
12
|
+
# release; per-version overrides live in `Dcc::Si::V1::Namespace` and
|
|
13
|
+
# `Dcc::Si::V2::Namespace`.
|
|
14
|
+
class Si < Lutaml::Xml::Namespace
|
|
15
|
+
uri "https://ptb.de/si"
|
|
16
|
+
uri_aliases "https://ptb.de/si.xsd"
|
|
17
|
+
schema_location "https://ptb.de/si/v2.2.1/SI_Format.xsd"
|
|
18
|
+
prefix_default "si"
|
|
19
|
+
element_form_default :qualified
|
|
20
|
+
attribute_form_default :unqualified
|
|
21
|
+
version "2.2.1"
|
|
22
|
+
|
|
23
|
+
imports ::Dcc::Namespace::Qudt
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `Dcc::Namespace` aggregates the five XML namespaces used by DCC documents:
|
|
4
|
+
#
|
|
5
|
+
# * `dcc:` — the Digital Calibration Certificate itself (https://ptb.de/dcc)
|
|
6
|
+
# * `si:` — D-SI quantity values (https://ptb.de/si)
|
|
7
|
+
# * `ml:` — MathML formulae (http://www.w3.org/1998/Math/MathML)
|
|
8
|
+
# * `ds:` — W3C XML Digital Signature (http://www.w3.org/2000/09/xmldsig#)
|
|
9
|
+
# * `qudt:` — QUDT quantity kinds (http://qudt.org/vocab/)
|
|
10
|
+
module Dcc
|
|
11
|
+
module Namespace
|
|
12
|
+
autoload :Dcc, "dcc/namespace/dcc"
|
|
13
|
+
autoload :Si, "dcc/namespace/si"
|
|
14
|
+
autoload :MathMl, "dcc/namespace/math_ml"
|
|
15
|
+
autoload :Dsig, "dcc/namespace/dsig"
|
|
16
|
+
autoload :Qudt, "dcc/namespace/qudt"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dcc
|
|
4
|
+
module Plugin
|
|
5
|
+
# Category-based registry. Each category (validators, converters,
|
|
6
|
+
# cli_commands) gets its own array. Thread-safe via a Mutex.
|
|
7
|
+
class Registry
|
|
8
|
+
@categories = ::Hash.new { |h, k| h[k] = [] }
|
|
9
|
+
@mutex = ::Mutex.new
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# @param category [Symbol]
|
|
13
|
+
# @param entry [Class, Object]
|
|
14
|
+
# @return [Class, Object]
|
|
15
|
+
def register(category, entry)
|
|
16
|
+
@mutex.synchronize do
|
|
17
|
+
@categories[category.to_sym] << entry
|
|
18
|
+
entry
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param category [Symbol]
|
|
23
|
+
# @return [Array<Object>]
|
|
24
|
+
def all(category)
|
|
25
|
+
@mutex.synchronize { @categories[category.to_sym].dup }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @param category [Symbol]
|
|
29
|
+
# @return [Boolean]
|
|
30
|
+
def any?(category)
|
|
31
|
+
@mutex.synchronize { !@categories[category.to_sym].empty? }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def reset!
|
|
35
|
+
@mutex.synchronize { @categories.clear }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Array<Symbol>] the registered category names.
|
|
39
|
+
def categories
|
|
40
|
+
@mutex.synchronize { @categories.keys.dup }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/dcc/plugin.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `Dcc::Plugin` is the registry-based extension point for the gem.
|
|
4
|
+
# Plugins can register custom validators, converters, or CLI commands
|
|
5
|
+
# without modifying the core codebase (Open/Closed Principle).
|
|
6
|
+
#
|
|
7
|
+
# @example Register a custom validator
|
|
8
|
+
# Dcc::Plugin.register(:validators, MyCustomRule)
|
|
9
|
+
#
|
|
10
|
+
# @example List all registered validators
|
|
11
|
+
# Dcc::Plugin.all(:validators)
|
|
12
|
+
module Dcc
|
|
13
|
+
module Plugin
|
|
14
|
+
autoload :Registry, "dcc/plugin/registry"
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
# @param category [Symbol] e.g. :validators, :converters, :cli_commands.
|
|
18
|
+
# @param entry [Class, Object] the plugin to register.
|
|
19
|
+
# @return [Class, Object] the entry.
|
|
20
|
+
def register(category, entry)
|
|
21
|
+
::Dcc::Plugin::Registry.register(category, entry)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param category [Symbol]
|
|
25
|
+
# @return [Array<Object>]
|
|
26
|
+
def all(category)
|
|
27
|
+
::Dcc::Plugin::Registry.all(category)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param category [Symbol]
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
def any?(category)
|
|
33
|
+
::Dcc::Plugin::Registry.any?(category)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Reset the registry (test-only helper).
|
|
37
|
+
def reset!
|
|
38
|
+
::Dcc::Plugin::Registry.reset!
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dcc
|
|
4
|
+
module QuantityFormat
|
|
5
|
+
# SmartCom-style quantity pretty-printing. Significant digits derived
|
|
6
|
+
# from uncertainty (PTB convention: 2 sig digits in uncertainty).
|
|
7
|
+
class Formatter
|
|
8
|
+
attr_reader :value, :uncertainty, :unit
|
|
9
|
+
|
|
10
|
+
# @param value [BigDecimal, Numeric]
|
|
11
|
+
# @param uncertainty [BigDecimal, Numeric, nil]
|
|
12
|
+
# @param unit [String, nil] siunitx expression
|
|
13
|
+
def initialize(value:, uncertainty: nil, unit: nil)
|
|
14
|
+
@value = BigDecimal(value.to_s)
|
|
15
|
+
@uncertainty = uncertainty.nil? ? nil : BigDecimal(uncertainty.to_s)
|
|
16
|
+
@unit = unit
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [String] compact notation: `42.00(5) K`
|
|
20
|
+
def to_short
|
|
21
|
+
return format_value.to_s + unit_suffix if uncertainty.nil?
|
|
22
|
+
|
|
23
|
+
v_str, u_str = align_value_and_uncertainty
|
|
24
|
+
"#{v_str}(#{u_str})#{unit_suffix}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [String] verbose: `42.00 ± 0.05 K`
|
|
28
|
+
def to_long
|
|
29
|
+
if uncertainty.nil?
|
|
30
|
+
"#{format_value}#{unit_suffix}"
|
|
31
|
+
else
|
|
32
|
+
"#{format_value} ± #{format_uncertainty}#{unit_suffix}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [String] LaTeX siunitx: `\qty{42.00 +- 0.05}{\kelvin}`
|
|
37
|
+
def to_latex
|
|
38
|
+
if uncertainty.nil?
|
|
39
|
+
"\\qty{#{format_value}}{#{unit || ''}}"
|
|
40
|
+
else
|
|
41
|
+
"\\qty{#{format_value} +- #{format_uncertainty}}{#{unit || ''}}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def format_value
|
|
48
|
+
# Two decimals by default; tightened to uncertainty precision when known.
|
|
49
|
+
return @value.round(2).to_s("F") if uncertainty.nil?
|
|
50
|
+
|
|
51
|
+
# Decimal places = 1 - floor(log10(uncertainty))
|
|
52
|
+
decimal_places = [0, 1 - Integer(Math.log10(uncertainty.to_f).floor)].max
|
|
53
|
+
@value.round(decimal_places).to_s("F")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def format_uncertainty
|
|
57
|
+
return "" if uncertainty.nil?
|
|
58
|
+
|
|
59
|
+
decimal_places = [0, 1 - Integer(Math.log10(uncertainty.to_f).floor)].max
|
|
60
|
+
uncertainty.round(decimal_places).to_s("F")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def align_value_and_uncertainty
|
|
64
|
+
return [@value.to_s("F"), uncertainty.to_s("F")] if uncertainty.nil?
|
|
65
|
+
|
|
66
|
+
decimal_places = [0, 1 - Integer(Math.log10(uncertainty.to_f).floor)].max
|
|
67
|
+
v_str = @value.round(decimal_places).to_s("F")
|
|
68
|
+
u_str = uncertainty.round(decimal_places).to_s("F")
|
|
69
|
+
# Short form: digits of uncertainty after the last common digit
|
|
70
|
+
last_digits = u_str.gsub(/[^0-9]/, "")[-2..]
|
|
71
|
+
[v_str, last_digits]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def unit_suffix
|
|
75
|
+
return "" if unit.nil? || unit.empty?
|
|
76
|
+
|
|
77
|
+
" #{human_unit}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def human_unit
|
|
81
|
+
unit
|
|
82
|
+
.to_s
|
|
83
|
+
.gsub(/\\([a-z]+)/, '\\1') # \kelvin → kelvin
|
|
84
|
+
.gsub(/\\per/, '/')
|
|
85
|
+
.gsub(/\\cubic/, '^3')
|
|
86
|
+
.gsub(/\\square/, '^2')
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `Dcc::QuantityFormat` renders quantities in human-readable form. Three
|
|
4
|
+
# formats: `:short` (compact, e.g. `42.00(5) K`), `:long` (verbose), and
|
|
5
|
+
# `:latex` (siunitx).
|
|
6
|
+
module Dcc
|
|
7
|
+
module QuantityFormat
|
|
8
|
+
autoload :Formatter, "dcc/quantity_format/formatter"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module QuantityMath
|
|
7
|
+
# A simple `(value, unit, uncertainty)` value object used by
|
|
8
|
+
# `Dcc::QuantityMath::Real` for arithmetic. Immutable.
|
|
9
|
+
class Quantity
|
|
10
|
+
attr_reader :value, :unit, :uncertainty
|
|
11
|
+
|
|
12
|
+
# @param value [BigDecimal, Numeric]
|
|
13
|
+
# @param unit [String, nil] siunitx expression
|
|
14
|
+
# @param uncertainty [BigDecimal, Numeric, nil] 1σ absolute uncertainty
|
|
15
|
+
def initialize(value:, unit: nil, uncertainty: nil)
|
|
16
|
+
@value = cast_decimal(value)
|
|
17
|
+
@unit = unit
|
|
18
|
+
@uncertainty = uncertainty.nil? ? nil : cast_decimal(uncertainty)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Boolean] whether the quantity carries uncertainty info.
|
|
22
|
+
def uncertain?
|
|
23
|
+
!uncertainty.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [Boolean] whether units match (or both are nil).
|
|
27
|
+
def same_unit?(other)
|
|
28
|
+
unit == other.unit
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
u = uncertain? ? " ± #{uncertainty}" : ""
|
|
33
|
+
n = unit ? " #{unit}" : ""
|
|
34
|
+
"#{value}#{u}#{n}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def cast_decimal(value)
|
|
40
|
+
return value if value.is_a?(::BigDecimal)
|
|
41
|
+
|
|
42
|
+
BigDecimal(value.to_s)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module QuantityMath
|
|
7
|
+
# BigDecimal arithmetic on real-valued quantities with RSS uncertainty
|
|
8
|
+
# propagation for add/sub and fractional propagation for mul/div.
|
|
9
|
+
class Real < Quantity
|
|
10
|
+
# @return [Real]
|
|
11
|
+
def +(other)
|
|
12
|
+
ensure_same_unit!(other)
|
|
13
|
+
Real.new(
|
|
14
|
+
value: value + other.value,
|
|
15
|
+
unit: unit,
|
|
16
|
+
uncertainty: rss_uncertainty(other),
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Real]
|
|
21
|
+
def -(other)
|
|
22
|
+
ensure_same_unit!(other)
|
|
23
|
+
Real.new(
|
|
24
|
+
value: value - other.value,
|
|
25
|
+
unit: unit,
|
|
26
|
+
uncertainty: rss_uncertainty(other),
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Real]
|
|
31
|
+
def *(other)
|
|
32
|
+
new_value = value * other.value
|
|
33
|
+
new_unit = compose_unit(unit, other.unit)
|
|
34
|
+
Real.new(
|
|
35
|
+
value: new_value,
|
|
36
|
+
unit: new_unit,
|
|
37
|
+
uncertainty: fractional_uncertainty_mul_div(other, new_value),
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Real]
|
|
42
|
+
def /(other)
|
|
43
|
+
new_value = value / other.value
|
|
44
|
+
new_unit = compose_unit(unit, inverse_unit(other.unit))
|
|
45
|
+
Real.new(
|
|
46
|
+
value: new_value,
|
|
47
|
+
unit: new_unit,
|
|
48
|
+
uncertainty: fractional_uncertainty_mul_div(other, new_value),
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param exponent [Integer]
|
|
53
|
+
# @return [Real]
|
|
54
|
+
def **(exponent)
|
|
55
|
+
new_value = value ** exponent
|
|
56
|
+
Real.new(
|
|
57
|
+
value: new_value,
|
|
58
|
+
unit: unit && "^#{exponent}",
|
|
59
|
+
uncertainty: power_uncertainty(exponent, new_value),
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def ensure_same_unit!(other)
|
|
66
|
+
return if same_unit?(other)
|
|
67
|
+
|
|
68
|
+
raise ::ArgumentError,
|
|
69
|
+
"unit mismatch: #{unit.inspect} vs #{other.unit.inspect}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Root-sum-square for add/sub: σ_result = sqrt(σ1² + σ2²)
|
|
73
|
+
def rss_uncertainty(other)
|
|
74
|
+
return nil unless uncertain? && other.uncertain?
|
|
75
|
+
return other.uncertainty if uncertainty.nil?
|
|
76
|
+
return uncertainty if other.uncertainty.nil?
|
|
77
|
+
|
|
78
|
+
sum_of_squares = (uncertainty ** 2) + (other.uncertainty ** 2)
|
|
79
|
+
BigDecimal(Math.sqrt(sum_of_squares.to_f).to_s)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Fractional for mul/div: σ_y / y = sqrt((σ_a/a)² + (σ_b/b)²)
|
|
83
|
+
def fractional_uncertainty_mul_div(other, new_value)
|
|
84
|
+
return nil unless uncertain? && other.uncertain?
|
|
85
|
+
return nil if value.zero? || other.value.zero?
|
|
86
|
+
|
|
87
|
+
a_rel = uncertainty / value
|
|
88
|
+
b_rel = other.uncertainty / other.value
|
|
89
|
+
sum_of_squares = (a_rel ** 2) + (b_rel ** 2)
|
|
90
|
+
BigDecimal(Math.sqrt(sum_of_squares.to_f).to_s) * new_value.abs
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Power rule: σ_y = |n * x^(n-1)| * σ_x
|
|
94
|
+
def power_uncertainty(exponent, new_value)
|
|
95
|
+
return nil unless uncertain?
|
|
96
|
+
|
|
97
|
+
derivative = exponent * (value ** (exponent - 1))
|
|
98
|
+
(derivative.abs * uncertainty)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def compose_unit(u1, u2)
|
|
102
|
+
return nil if u1.nil? && u2.nil?
|
|
103
|
+
return u1 if u2.nil?
|
|
104
|
+
return u2 if u1.nil?
|
|
105
|
+
|
|
106
|
+
"#{u1}\\cdot#{u2}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def inverse_unit(u)
|
|
110
|
+
return nil if u.nil?
|
|
111
|
+
|
|
112
|
+
"#{u}^-1"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
require "bigdecimal/math"
|
|
5
|
+
|
|
6
|
+
module Dcc
|
|
7
|
+
# `Dcc::QuantityMath` provides BigDecimal-based arithmetic on D-SI
|
|
8
|
+
# quantities with proper uncertainty propagation. RSS (root-sum-square)
|
|
9
|
+
# for addition/subtraction, fractional for multiplication/division.
|
|
10
|
+
module QuantityMath
|
|
11
|
+
autoload :Quantity, "dcc/quantity_math/quantity"
|
|
12
|
+
autoload :Real, "dcc/quantity_math/real"
|
|
13
|
+
end
|
|
14
|
+
end
|