Skip to content

Commit 8c70686

Browse files
committed
Support both DynamicQuantites and Unitful for scalar valiables
1 parent 1c45ee2 commit 8c70686

File tree

1 file changed

+30
-32
lines changed

1 file changed

+30
-32
lines changed

Diff for: src/systems/model_parsing.jl

+30-32
Original file line numberDiff line numberDiff line change
@@ -142,34 +142,16 @@ end
142142

143143
pop_structure_dict!(dict, key) = length(dict[key]) == 0 && pop!(dict, key)
144144

145-
create_kwarg_type(meta, where_types, type) = haskey(meta, VariableUnit) ? create_kwarg_type_(meta[VariableUnit], where_types, type) : Expr(:curly, Union, Nothing, type)
146-
function create_kwarg_type_(unitmacro, where_types, type)
147-
fn = gensym()
148-
quote
149-
#Expr(:curly, Union, :Nothing, Expr(:curly, Unitful.Quantity, Expr(:(<:), type), D, units))
150-
function $fn()
151-
let u = eval($unitmacro)
152-
if typeof(u) <: Unitful.FreeUnits
153-
Union{Nothing, Unitful.Quantity{<:$type, dimension(u), u}}
154-
elseif typeof(u) <: DynamicQuantities.Quantity
155-
Union{Nothing, DynamicQuantities.Quantity{<:$type, $units}}
156-
else
157-
throw("Unsupported units library")
158-
end
159-
end
160-
end
161-
$fn()
162-
end
163-
end
164-
# function create_kwarg_type_(::DynamicQuantities.Quantity{T, D}, where_types, type) where {T, D}
165-
# Expr(:curly, Union, :Nothing, Expr(:curly, DynamicQuantities.Quantity, Expr(:(<:), type), D))
166-
# end
167-
168145
function update_kwargs_and_metadata!(dict, kwargs, a, def, indices, type, var,
169146
varclass, where_types, meta)
170147
if indices isa Nothing
171-
kwtype = create_kwarg_type(meta, where_types, type)
172-
push!(kwargs, Expr(:kw, Expr(:(::), a, kwtype), nothing))
148+
if !isnothing(meta) && haskey(meta, VariableUnit)
149+
uvar = gensym()
150+
push!(where_types, uvar)
151+
push!(kwargs, Expr(:kw, :($a::Union{Nothing, $uvar}), nothing))
152+
else
153+
push!(kwargs, Expr(:kw, :($a::Union{Nothing, $type}), nothing))
154+
end
173155
dict[:kwargs][getname(var)] = Dict(:value => def, :type => type)
174156
else
175157
vartype = gensym(:T)
@@ -190,7 +172,7 @@ end
190172

191173
function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
192174
def = nothing, indices::Union{Vector{UnitRange{Int}}, Nothing} = nothing,
193-
meta = nothing, type::Type = Real)
175+
type::Type = Real, meta = Dict{DataType, Expr}())
194176
metatypes = [(:connection_type, VariableConnectType),
195177
(:description, VariableDescription),
196178
(:unit, VariableUnit),
@@ -215,12 +197,12 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
215197
end
216198
Expr(:(::), a, type) => begin
217199
type = getfield(mod, type)
218-
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types; def, type)
200+
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types; def, type, meta)
219201
end
220202
Expr(:(::), Expr(:call, a, b), type) => begin
221203
type = getfield(mod, type)
222204
def = _type_check!(def, a, type, varclass)
223-
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types; def, type)
205+
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types; def, type, meta)
224206
end
225207
Expr(:call, a, b) => begin
226208
var = generate_var!(dict, a, b, varclass, mod; indices, type)
@@ -232,7 +214,7 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
232214
Base.remove_linenums!(b)
233215
def, meta = parse_default(mod, b)
234216
var, def, _ = parse_variable_def!(
235-
dict, mod, a, varclass, kwargs, where_types; def, meta, type)
217+
dict, mod, a, varclass, kwargs, where_types; def, type, meta)
236218
if dict[varclass] isa Vector
237219
dict[varclass][1][getname(var)][:default] = def
238220
else
@@ -257,7 +239,7 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
257239
Expr(:tuple, a, b) => begin
258240
meta = parse_metadata(mod, b)
259241
var, def, _ = parse_variable_def!(
260-
dict, mod, a, varclass, kwargs, where_types; meta, type)
242+
dict, mod, a, varclass, kwargs, where_types, meta; type, meta)
261243
if meta !== nothing
262244
for (type, key) in metatypes
263245
if (mt = get(meta, key, nothing)) !== nothing
@@ -277,7 +259,7 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
277259
Expr(:ref, a, b...) => begin
278260
indices = map(i -> UnitRange(i.args[2], i.args[end]), b)
279261
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types;
280-
def, indices, type)
262+
def, indices, type, meta)
281263
end
282264
_ => error("$arg cannot be parsed")
283265
end
@@ -635,6 +617,14 @@ function parse_variable_arg!(exprs, vs, dict, mod, arg, varclass, kwargs, where_
635617
push!(exprs, ex)
636618
end
637619

620+
function convert_units(varunits::DynamicQuantities.Quantity, value)
621+
DynamicQuantities.ustrip(DynamicQuantities.uconvert(DynamicQuantities.SymbolicUnits.as_quantity(varunits), value))
622+
end
623+
624+
function convert_units(varunits::Unitful.FreeUnits, value)
625+
Unitful.ustrip(varunits, value)
626+
end
627+
638628
function parse_variable_arg(dict, mod, arg, varclass, kwargs, where_types)
639629
vv, def, metadata_with_exprs = parse_variable_def!(
640630
dict, mod, arg, varclass, kwargs, where_types)
@@ -646,7 +636,15 @@ function parse_variable_arg(dict, mod, arg, varclass, kwargs, where_types)
646636
$name = if $name === nothing
647637
$setdefault($vv, $def)
648638
else
649-
$setdefault($vv, $ustrip($unit, $name))
639+
try
640+
$setdefault($vv, $convert_units($unit, $name))
641+
catch e
642+
if isa(e, DynamicQuantities.DimensionError) || isa(e, Unitful.DimensionError)
643+
error("Unable to convert units for \'"*string(:($$vv))*"\'")
644+
else
645+
rethrow(e)
646+
end
647+
end
650648
end
651649
end
652650
else

0 commit comments

Comments
 (0)