Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique Backup Parameter Names #908

Merged
merged 2 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/core/connections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,20 @@ function _connect_param!(obj::AbstractCompositeComponentDef,

end

# create a backup parameter name with the destination leaf component and
# parameter names, as well as a trailing integer to ensure uniqueness in
# edge cases. Check if the name is already used, and if so increment the
# trailing integer until it is a unique model parameter name to the model
i = 1
backup_param_name = Symbol("backup_", dst_comp_path.names[end], "_", dst_par_name, "_", i)
while haskey(obj.model_params, backup_param_name)
i += 1
backup_param_name = Symbol("backup_", dst_comp_path.names[end], "_", dst_par_name, "_", i)
end

# NB: potentially unsafe way to add parameter/might be duplicating work so
# advise shifting to create_model_param ... but leaving it as is for now
add_model_array_param!(obj, dst_par_name, values, dst_dims)
backup_param_name = dst_par_name
add_model_array_param!(obj, backup_param_name, values, dst_dims)

else
# cannot use backup_offset keyword argument if there is no backup
Expand Down Expand Up @@ -714,8 +724,8 @@ end
Add an model parameter with name `name` and Model Parameter `value` to ModelDef `md`.
"""
function add_model_param!(md::ModelDef, name::Symbol, value::ModelParameter)
# if haskey(obj.model_params, name)
# @warn "Redefining model param :$name in $(obj.comp_path) from $(obj.model_params[name]) to $value"
# if haskey(md.model_params, name)
# @warn "Redefining model param :$name in $(md.comp_path) from $(md.model_params[name]) to $value"
# end
md.model_params[name] = value
dirty!(md)
Expand All @@ -740,6 +750,9 @@ using it and only do so under the hood.
function add_model_param!(md::ModelDef, name::Symbol, value::Number;
param_dims::Union{Nothing,Array{Symbol}} = nothing,
is_shared::Bool = false)
# if haskey(md.model_params, name)
# @warn "Redefining model param :$name in $(md.comp_path) from $(md.model_params[name]) to $value"
# end
add_model_scalar_param!(md, name, value, is_shared = is_shared)
end

Expand All @@ -757,6 +770,9 @@ function add_model_param!(md::ModelDef, name::Symbol,
value::Union{AbstractArray, AbstractRange, Tuple};
param_dims::Union{Nothing,Array{Symbol}} = nothing,
is_shared::Bool = false)
# if haskey(md.model_params, name)
# @warn "Redefining model param :$name in $(md.comp_path) from $(md.model_params[name]) to $value"
# end

ti = get_time_index_position(param_dims)
if !isnothing(ti)
Expand Down
28 changes: 28 additions & 0 deletions test/test_connectorcomp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module TestConnectorComp

using Mimi
using Test
using Query
using DataFrames

import Mimi: compdef, compdefs, components, getspan

Expand Down Expand Up @@ -261,5 +263,31 @@ short_var = model6[:Short, :var]
@test all(ismissing, short_var[1:year_dim[late_start]-1])
@test short_var[year_dim[late_start]:end] == years[year_dim[late_start]:end]

#------------------------------------------------------------------------------
# 6. Test multiple, identical components with backup
#------------------------------------------------------------------------------

model1 = Model()
set_dimension!(model1, :time, years)

add_comp!(model1, Short, :Short_A, first=late_start)
add_comp!(model1, Long, :Long_A)
update_param!(model1, :Short_A, :a, 2.)
connect_param!(model1, :Long_A, :x, :Short_A, :b, zeros(length(years)));

add_comp!(model1, Short, :Short_B, first=late_start)
add_comp!(model1, Long, :Long_B)
update_param!(model1, :Short_B, :a, 2.)
connect_param!(model1, :Long_B, :x, :Short_B, :b, ones(length(years)))

run(model1)

# the backup data should differ
@test all(iszero, (getdataframe(model1, :Long_A, :x) |> @filter(_.time < late_start) |> DataFrame).x)
@test all(i -> i == 1., (getdataframe(model1, :Long_B, :x) |> @filter(_.time < late_start) |> DataFrame).x)

# should see two model parameters added to the model instance
@test haskey(model1.mi.md.model_params, :backup_Long_A_x_1) # created to connect to :Long_A
@test haskey(model1.mi.md.model_params, :backup_Long_B_x_1) #created to connect to :Long B

end #module