Skip to content

Commit 0a4e54c

Browse files
committed
Still working on adapting to MTG v0.15.0
1 parent 37e9b11 commit 0a4e54c

1 file changed

Lines changed: 42 additions & 12 deletions

File tree

src/dependencies/hard_dependencies.jl

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
11
"""
22
hard_dependencies(models; verbose::Bool=true)
33
hard_dependencies(mapping::ModelMapping; verbose::Bool=true)
4-
hard_dependencies(mapping::AbstractDict{String,T}; verbose::Bool=true)
4+
hard_dependencies(mapping::AbstractDict{Symbol,T}; verbose::Bool=true)
55
66
Compute the hard dependencies between models.
77
"""
8-
function hard_dependencies(models; scale="", verbose::Bool=true)
8+
function _normalize_hard_dependency_scales(scales, process::Symbol, dependency_process::Symbol)
9+
if scales isa Symbol || scales isa AbstractString
10+
return [Symbol(scales)]
11+
elseif scales isa Tuple || scales isa AbstractVector
12+
normalized = Symbol[]
13+
for s in scales
14+
if s isa Symbol || s isa AbstractString
15+
push!(normalized, Symbol(s))
16+
else
17+
error(
18+
"Invalid hard dependency scale declaration for process `$(process)` dependency `$(dependency_process)`: ",
19+
"expected Symbol or String scales, got `$(typeof(s))`."
20+
)
21+
end
22+
end
23+
isempty(normalized) && error(
24+
"Invalid hard dependency scale declaration for process `$(process)` dependency `$(dependency_process)`: ",
25+
"at least one target scale must be provided."
26+
)
27+
return normalized
28+
end
29+
30+
error(
31+
"Invalid hard dependency scale declaration for process `$(process)` dependency `$(dependency_process)`: ",
32+
"expected Symbol/String or a tuple/vector of them, got `$(typeof(scales))`."
33+
)
34+
end
35+
36+
function hard_dependencies(models; scale=nothing, verbose::Bool=true)
937
dep_graph = initialise_all_as_hard_dependency_node(models, scale)
1038
dep_not_found = Dict{Symbol,Any}()
1139
for (process, i) in pairs(models) # for each model in the model list. process=:state; i=pairs(models)[process]
@@ -17,9 +45,10 @@ function hard_dependencies(models; scale="", verbose::Bool=true)
1745
# This means we should search this model in another scale. This is not done here, but after the call to this
1846
# function in the other method for `hard_dependencies` below.
1947
if isa(depend, Pair)
20-
if scale != ""
48+
if !isnothing(scale)
2149
# We skip this hard-dependency if it is multiscale, we compute this afterwards in this case
22-
push!(dep_not_found, p => (parent_process=process, type=first(depend), scales=last(depend)))
50+
target_scales = _normalize_hard_dependency_scales(last(depend), process, p)
51+
push!(dep_not_found, p => (parent_process=process, type=first(depend), scales=target_scales))
2352
continue
2453
else
2554
# If we are not in a multi-scale setup e.g. in a ModelList, we shouldn't use a multiscale model.
@@ -40,7 +69,7 @@ function hard_dependencies(models; scale="", verbose::Bool=true)
4069
if verbose
4170
@info string(
4271
"Model ", typeof(i).name.name, " from process ", process,
43-
scale == "" ? "" : " at scale $scale",
72+
isnothing(scale) ? "" : " at scale $scale",
4473
" needs a model that is a subtype of ", depend, " in process ",
4574
p
4675
)
@@ -58,7 +87,7 @@ function hard_dependencies(models; scale="", verbose::Bool=true)
5887
if verbose
5988
@info string(
6089
"Model ", typeof(i).name.name, " from process ", process,
61-
scale == "" ? "" : " at scale $scale",
90+
isnothing(scale) ? "" : " at scale $scale",
6291
" needs a model that is a subtype of ", depend, " in process ",
6392
p, ", but the process is not parameterized in the ModelList."
6493
)
@@ -94,13 +123,14 @@ Take a set of models and initialise them all as a hard dependency node, and
94123
return a dictionary of `:process => HardDependencyNode`.
95124
"""
96125
function initialise_all_as_hard_dependency_node(models, scale)
126+
node_scale = isnothing(scale) ? :Default : Symbol(scale)
97127
dep_graph = Dict(
98128
p => HardDependencyNode(
99129
i,
100130
p,
101131
NamedTuple(),
102132
Int[],
103-
scale,
133+
node_scale,
104134
inputs_(i),
105135
outputs_(i),
106136
nothing,
@@ -113,9 +143,9 @@ end
113143

114144

115145
# When we use a mapping (multiscale), we return the set of soft-dependencies (we put the hard-dependencies as their children):
116-
function hard_dependencies(mapping::AbstractDict{String,T}; verbose::Bool=true) where {T}
146+
function hard_dependencies(mapping::AbstractDict{Symbol,T}; verbose::Bool=true) where {T}
117147
full_vars_mapping = Dict(first(mod) => Dict(get_mapped_variables(last(mod))) for mod in mapping)
118-
soft_dep_graphs = Dict{String,Any}()
148+
soft_dep_graphs = Dict{Symbol,Any}()
119149
not_found = Dict{Symbol,DataType}()
120150

121151
mods = Dict(organ => parse_models(get_models(model)) for (organ, model) in mapping)
@@ -125,7 +155,7 @@ function hard_dependencies(mapping::AbstractDict{String,T}; verbose::Bool=true)
125155
# Since the hard dependencies are inserted into the soft dependency graph as children and aren't referenced elsewhere
126156
# it becomes harder to keep track of them as needed without traversing the graph
127157
# so keep tabs on them during initialisation until they're no longer needed
128-
hard_dependency_dict = Dict{Pair{Symbol, String}, HardDependencyNode}()
158+
hard_dependency_dict = Dict{Pair{Symbol,Symbol}, HardDependencyNode}()
129159

130160
hard_deps = Dict(organ => hard_dependencies(mods_scale, scale=organ, verbose=false) for (organ, mods_scale) in mods)
131161

@@ -135,8 +165,8 @@ function hard_dependencies(mapping::AbstractDict{String,T}; verbose::Bool=true)
135165
#* Note that we compute this before computing the multiscale hard dependencies because the inputs/outputs
136166
#* of hard-dependency models should remain in their own scale. Note that the variables from the hard
137167
#* dependency may not appear in its own scale, but this is treated in the soft-dependency computation
138-
inputs_process = Dict{String,Dict{Symbol,Vector}}()
139-
outputs_process = Dict{String,Dict{Symbol,Vector}}()
168+
inputs_process = Dict{Symbol,Dict{Symbol,Vector}}()
169+
outputs_process = Dict{Symbol,Dict{Symbol,Vector}}()
140170
for (organ, model) in mapping
141171
# Get the status given by the user, that is used to set the default values of the variables in the mapping:
142172
st_scale_user = get_status(model)

0 commit comments

Comments
 (0)