From f67289d3817937be1841977de8018f737c497e32 Mon Sep 17 00:00:00 2001 From: Florian Henkes Date: Tue, 10 Dec 2024 12:16:41 +0100 Subject: [PATCH] Parse units with unit_from_string to include other units --- Project.toml | 2 ++ src/LegendDataManagement.jl | 1 + src/lprops.jl | 29 ++++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 1cd56a69..1f4b0d6c 100644 --- a/Project.toml +++ b/Project.toml @@ -29,6 +29,7 @@ Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" TypedTables = "9d95f2ec-7b3d-5a63-8d20-e2491e220bb9" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" +UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a" [weakdeps] LegendDataTypes = "99e09c13-5545-5ee2-bfa2-77f358fb75d8" @@ -73,4 +74,5 @@ Tables = "1.1" TypedTables = "1.4" UUIDs = "<0.0.1, 1" Unitful = "1.11" +UnitfulAtomic = "1" julia = "1.10" diff --git a/src/LegendDataManagement.jl b/src/LegendDataManagement.jl index 062acac9..20c1f5ec 100644 --- a/src/LegendDataManagement.jl +++ b/src/LegendDataManagement.jl @@ -17,6 +17,7 @@ using PropDicts using PropertyDicts using StructArrays using Unitful +using UnitfulAtomic using Measurements using Measurements: ±, value, uncertainty diff --git a/src/lprops.jl b/src/lprops.jl index 9bc1ab17..666117e7 100644 --- a/src/lprops.jl +++ b/src/lprops.jl @@ -1,12 +1,35 @@ # This file is a part of LegendDataManagement.jl, licensed under the MIT License (MIT). +const _pseudo_unit_expr = r"(^|[^A-Za-z])(ADC|adc|sample)([^A-Za-z]|$)" + +function units_from_string(s::AbstractString) + if isempty(s) || s == "none" + NoUnits + elseif !isnothing(match(_pseudo_unit_expr, s)) + NoUnits + else + try + uparse(s, unit_context=[Unitful, UnitfulAtomic]) + catch e + s == "e" && return u"e_au" # parse "e" as u"e_au" from UnitfulAtomic + if e isa ErrorException + rethrow(ArgumentError("Unknown physical unit \"$s\"")) + else + rethrow(e) + end + end + end +end + +units_to_string(u::Unitful.Unitlike) = string(u) + function _props2lprops(pd::PropDict) if haskey(pd, :val) && length(keys(pd)) <= 3 && (haskey(pd, :unit) || haskey(pd, :err)) if haskey(pd, :unit) if haskey(pd, :err) - Unitful.Quantity.(measurement.(pd.val, ifelse(isnothing(pd.err), NaN, pd.err)), Unitful.uparse(pd.unit)) + Unitful.Quantity.(measurement.(pd.val, ifelse(isnothing(pd.err), NaN, pd.err)), units_from_string(pd.unit)) else - Unitful.Quantity.(pd.val, Unitful.uparse(pd.unit)) + Unitful.Quantity.(pd.val, units_from_string(pd.unit)) end elseif haskey(pd, :err) measurement.(pd.val, ifelse(isnothing(pd.err), NaN, pd.err)) @@ -14,7 +37,7 @@ function _props2lprops(pd::PropDict) throw(ArgumentError("_props2lprops can't handle PropDict $pd")) end elseif haskey(pd, :unit) && length(keys(pd)) == 1 - Unitful.Quantity(NaN, Unitful.uparse(pd.unit)) + Unitful.Quantity(NaN, units_from_string(pd.unit)) else PropDict(Dict([key => _props2lprops(val) for (key, val) in pd])) end