From 078686946aa2cdbb620d91bcbd2c83674740083e Mon Sep 17 00:00:00 2001 From: lrennels Date: Fri, 12 Jun 2020 18:19:48 -0700 Subject: [PATCH 01/13] Remove deprecations --- docs/src/reference.md | 2 - src/Mimi.jl | 2 - src/core/defcomp.jl | 5 +- src/core/defmodel.jl | 82 ------------------------------- src/core/time.jl | 20 -------- src/core/time_arrays.jl | 95 +----------------------------------- src/core/types/model.jl | 8 --- test/test_marginal_models.jl | 4 +- test/test_timesteps.jl | 2 +- 9 files changed, 5 insertions(+), 215 deletions(-) delete mode 100644 src/core/defmodel.jl diff --git a/docs/src/reference.md b/docs/src/reference.md index 59583a9c5..b28854042 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -19,8 +19,6 @@ get_var_value hasvalue is_first is_last -is_time -is_timestep modeldef parameter_names parameter_dimensions diff --git a/src/Mimi.jl b/src/Mimi.jl index 55645a0a7..abce17178 100644 --- a/src/Mimi.jl +++ b/src/Mimi.jl @@ -31,8 +31,6 @@ export hasvalue, is_first, is_last, - is_time, - is_timestep, modeldef, name, # parameters, diff --git a/src/core/defcomp.jl b/src/core/defcomp.jl index 3cd117ecd..1c7d682ba 100644 --- a/src/core/defcomp.jl +++ b/src/core/defcomp.jl @@ -195,10 +195,7 @@ macro defcomp(comp_name, ex) continue end - if @capture(elt, name_::datum_type_ = elt_type_(args__)) - msg = "The following syntax has been deprecated in @defcomp: \"$name::$datum_type = $elt_type(...)\". Use curly bracket syntax instead: \"$name = $elt_type{$datum_type}(...)\"" - Base.depwarn("$msg\n$(reduce((x,y) -> "$x\n$y", stacktrace()))", :defcomp) - elseif ! @capture(elt, name_ = (elt_type_{datum_type_}(args__) | elt_type_(args__))) + if ! @capture(elt, name_ = (elt_type_{datum_type_}(args__) | elt_type_(args__))) error("Element syntax error: $elt") end diff --git a/src/core/defmodel.jl b/src/core/defmodel.jl deleted file mode 100644 index 87eebcf54..000000000 --- a/src/core/defmodel.jl +++ /dev/null @@ -1,82 +0,0 @@ -# -# @defmodel and supporting functions -# -using MacroTools - -""" - defmodel(model_name::Symbol, ex::Expr) - -Define a Mimi model. The following types of expressions are supported: - -1. `component(name)` # add comp to model -2. `dst_component.name = ex::Expr` # provide a value for a parameter -3. `src_component.name => dst_component.name` # connect a variable to a parameter -4. `index[name] = iterable-of-values` # define values for an index -""" -macro defmodel(model_name, ex) - - @warn("@defmodel is deprecated.") - - # @capture(ex, elements__) - - # # @__MODULE__ is evaluated in calling module when macro is interpreted - # result = :( - # let calling_module = @__MODULE__, comp_mod_name = nothing, comp_mod_obj = nothing - # global $model_name = Model() - # end - # ) - - # # helper function used in loop below - # function addexpr(expr) - # let_block = result.args[end].args - # push!(let_block, expr) - # end - - # for elt in elements - # offset = 0 - - # if @capture(elt, component(comp_mod_name_.comp_name_) | component(comp_name_) | - # component(comp_mod_name_.comp_name_, alias_) | component(comp_name_, alias_)) - - # # set local copy of comp_mod_name to the stated or default component module - # expr = (comp_mod_name === nothing ? :(comp_mod_obj = calling_module) # nameof(calling_module)) - # # TBD: This may still not be right: - # : :(comp_mod_obj = getfield(calling_module, $(QuoteNode(comp_mod_name))))) - # addexpr(expr) - - # name = (alias === nothing ? comp_name : alias) - # expr = :(add_comp!($model_name, Mimi.ComponentId(comp_mod_obj, $(QuoteNode(comp_name))), $(QuoteNode(name)))) - - - # # TBD: extend comp.var syntax to allow module name, e.g., FUND.economy.ygross - # elseif (@capture(elt, src_comp_.src_name_[arg_] => dst_comp_.dst_name_) || - # @capture(elt, src_comp_.src_name_ => dst_comp_.dst_name_)) - # if (arg !== nothing && (! @capture(arg, t - offset_) || offset <= 0)) - # error("Subscripted connection source must have subscript [t - x] where x is an integer > 0") - # end - - # expr = :(Mimi.connect_param!($model_name, - # $(QuoteNode(dst_comp)), $(QuoteNode(dst_name)), - # $(QuoteNode(src_comp)), $(QuoteNode(src_name)), - # offset=$offset)) - - # elseif @capture(elt, index[idx_name_] = rhs_) - # expr = :(Mimi.set_dimension!($model_name, $(QuoteNode(idx_name)), $rhs)) - - # elseif @capture(elt, lhs_ = rhs_) && @capture(lhs, comp_.name_) - # (path, param_name) = parse_dotted_symbols(lhs) - # expr = :(Mimi.set_param!($model_name, $path, $(QuoteNode(param_name)), $rhs)) - - # else - # # Pass through anything else to allow the user to define intermediate vars, etc. - # @info "Passing through: $elt" - # expr = elt - # end - - # addexpr(expr) - # end - - # # addexpr(:($model_name)) # return this or nothing? - # addexpr(:(nothing)) - # return esc(result) -end diff --git a/src/core/time.jl b/src/core/time.jl index dba24f471..48300e58d 100644 --- a/src/core/time.jl +++ b/src/core/time.jl @@ -20,16 +20,6 @@ function gettime(ts::VariableTimestep) return ts.current end -""" - is_time(ts::AbstractTimestep, t::Int) - -Return true or false, true if the current time (year) for `ts` is `t` -""" -function is_time(ts::AbstractTimestep, t::Int) - Base.depwarn("`is_time(ts, t)` is deprecated. Use comparison operators with TimestepValue objects instead: `ts == TimestepValue(t)` \n$(stacktrace())", :is_time) - return gettime(ts) == t -end - """ is_first(ts::AbstractTimestep) @@ -39,16 +29,6 @@ function is_first(ts::AbstractTimestep) return ts.t == 1 end -""" - is_timestep(ts::AbstractTimestep, t::Int) - -Return true or false, true if `ts` timestep is step `t`. -""" -function is_timestep(ts::AbstractTimestep, t::Int) - Base.depwarn("`is_timestep(ts, t)` is deprecated. Use comparison operators with TimestepIndex objects instead: `ts == TimestepIndex(t)` \n$(stacktrace())", :is_timestep) - return ts.t == t -end - """ is_last(ts::FixedTimestep) diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index da6e1890d..c07b89403 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -69,22 +69,6 @@ function _get_stacktrace_string() return s end -# Helper functionfor getindex; throws an error if one indexes into a TimestepArray with an integer -function _throw_int_getindex_depwarning() - msg = "Indexing with getindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndex(2)]\n" - st = _get_stacktrace_string() - full_msg = string(msg, " \n", st) - Base.depwarn(full_msg, :getindex) -end - -# Helper function for setindex; throws an deprecation warning if one indexes into a TimestepArray with an integer -function _throw_int_setindex_depwarning() - msg = "Indexing with setindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndec(2)]" - st = _get_stacktrace_string() - full_msg = string(msg, " \n", st) - Base.depwarn(full_msg, :setindex!) -end - # Helper macro used by connector macro allow_missing(expr) let e = gensym("e") @@ -205,29 +189,6 @@ end function Base.setindex!(v::TimestepVector, val, ts::TimestepIndex) setindex!(v.data, val, ts.index) end - -# int indexing version supports old-style components and internal functions, not -# part of the public API - -function Base.getindex(v::TimestepVector{FixedTimestep{FIRST, STEP}, T}, i::AnyIndex_NonColon) where {T, FIRST, STEP} - _throw_int_getindex_depwarning() - return v.data[i] -end - -function Base.getindex(v::TimestepVector{VariableTimestep{TIMES}, T}, i::AnyIndex_NonColon) where {T, TIMES} - _throw_int_getindex_depwarning() - return v.data[i] -end - -function Base.setindex!(v::TimestepVector{FixedTimestep{Start, STEP}, T}, val, i::AnyIndex_NonColon) where {T, Start, STEP} - _throw_int_setindex_depwarning() - setindex!(v.data, val, i) -end - -function Base.setindex!(v::TimestepVector{VariableTimestep{TIMES}, T}, val, i::AnyIndex_NonColon) where {T, TIMES} - _throw_int_setindex_depwarning() - setindex!(v.data, val, i) -end function Base.length(v::TimestepVector) return length(v.data) @@ -390,39 +351,6 @@ function Base.setindex!(mat::TimestepMatrix, val, ts::TimestepIndex, idx::AnyInd setindex!(mat.data, val, ts.index, idx) end -# int indexing version supports old-style components and internal functions, not -# part of the public API - -function Base.getindex(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, FIRST, STEP, ti} - _throw_int_getindex_depwarning() - return mat.data[idx1, idx2] -end - -function Base.getindex(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, TIMES, ti} - _throw_int_getindex_depwarning() - return mat.data[idx1, idx2] -end - -function Base.setindex!(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, val, idx1::Int, idx2::Int) where {T, FIRST, STEP, ti} - _throw_int_setindex_depwarning() - setindex!(mat.data, val, idx1, idx2) -end - -function Base.setindex!(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, val, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, FIRST, STEP, ti} - _throw_int_setindex_depwarning() - mat.data[idx1, idx2] .= val -end - -function Base.setindex!(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, val, idx1::Int, idx2::Int) where {T, TIMES, ti} - _throw_int_setindex_depwarning() - setindex!(mat.data, val, idx1, idx2) -end - -function Base.setindex!(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, val, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, TIMES, ti} - _throw_int_setindex_depwarning() - mat.data[idx1, idx2] .= val -end - # # TimestepArray methods # @@ -555,28 +483,7 @@ function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, v setindex!(arr.data, val, idxs1..., t, idxs2...) end -# Colon support - this allows the time dimension to be indexed with a colon, and -# the deprecation warning will become an error when integer indexing is fully deprecated - -function Base.getindex(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} - isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_depwarning() : nothing - return arr.data[idxs...] -end - -function Base.getindex(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, idxs::AnyIndex...) where {TIMES, T, N, ti} - isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_depwarning() : nothing - return arr.data[idxs...] -end - -function Base.setindex!(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, val, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} - isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_depwarning() : nothing - setindex!(arr.data, val, idxs...) -end - -function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, val, idxs::AnyIndex...) where {TIMES, T, N, ti} - isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_depwarning() : nothing - setindex!(arr.data, val, idxs...) -end +# Colon support - this allows the time dimension to be indexed with a colon # Indexing with arrays of TimestepIndexes or TimestepValues function Base.getindex(arr::TimestepArray{TS, T, N, ti}, idxs::Union{Array{TimestepIndex,1}, AnyIndex}...) where {TS, T, N, ti} diff --git a/src/core/types/model.jl b/src/core/types/model.jl index 5d81b9e34..a157417d4 100644 --- a/src/core/types/model.jl +++ b/src/core/types/model.jl @@ -45,11 +45,3 @@ end function Base.getindex(mm::MarginalModel, comp_name::Symbol, name::Symbol) return (mm.modified[comp_name, name] .- mm.base[comp_name, name]) ./ mm.delta end - -function Base.getproperty(base::MarginalModel, s::Symbol) - if (s == :marginal) - @warn("Use of 'MarginalModel.marginal' will be deprecated, in favor of 'MarginalModel.modified'"); - return getfield(base, :modified); - end - return getfield(base, s); -end diff --git a/test/test_marginal_models.jl b/test/test_marginal_models.jl index 08dacb942..d3c6b2655 100644 --- a/test/test_marginal_models.jl +++ b/test/test_marginal_models.jl @@ -32,9 +32,9 @@ for i in collect(1:10) end mm2 = create_marginal_model(model1, 0.5) +mm2_modified = mm2.modified -mm2_marginal = @test_logs (:warn, "Use of 'MarginalModel.marginal' will be deprecated, in favor of 'MarginalModel.modified'") mm2.marginal -update_param!(mm2_marginal, :parA, x2) +update_param!(mm2_modified, :parA, x2) run(mm2) diff --git a/test/test_timesteps.jl b/test/test_timesteps.jl index 19ad2f994..0fe9437e7 100644 --- a/test/test_timesteps.jl +++ b/test/test_timesteps.jl @@ -13,7 +13,7 @@ import Mimi: #------------------------------------------------------------------------------ t1 = FixedTimestep{1850, 10, 3000}(1) -@test is_first(t1) # is_first and is_timestep still run but are deprecated; will error in v1.0 and should remove these two tests then +@test is_first(t1) @test t1 == TimestepIndex(1) @test t1 == TimestepValue(1850) @test TimestepIndex(1) == t1 # test both ways because to test both method definitions From 9ce89e3b50b270834f211eed49e2a6556cdb5a12 Mon Sep 17 00:00:00 2001 From: lrennels Date: Fri, 12 Jun 2020 18:28:59 -0700 Subject: [PATCH 02/13] Remove defmodel --- docs/src/internals/structure.md | 49 +-------------------------------- src/Mimi.jl | 1 - 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/docs/src/internals/structure.md b/docs/src/internals/structure.md index 992ac790a..7d4ad3c8c 100644 --- a/docs/src/internals/structure.md +++ b/docs/src/internals/structure.md @@ -78,53 +78,6 @@ In the new version, all component definitions are represented by one type, `Comp ![Object structure](figs/MimiModelArchitecture-v1.png) -## 3. New macro `@defmodel` - -The `@defmodel` macro provides simplified syntax for model creation, eliminating many redundant parameters. For example, you can write: - -``` -@defmodel mymodel begin - - index[time] = 2015:5:2110 - - component(grosseconomy) - component(emissions) - - # Set parameters for the grosseconomy component - grosseconomy.l = [(1. + 0.015)^t *6404 for t in 1:20] - grosseconomy.tfp = [(1 + 0.065)^t * 3.57 for t in 1:20] - grosseconomy.s = ones(20).* 0.22 - grosseconomy.depk = 0.1 - grosseconomy.k0 = 130.0 - grosseconomy.share = 0.3 - - # Set parameters for the emissions component - emissions.sigma = [(1. - 0.05)^t *0.58 for t in 1:20] - - # Connect pararameters (source_variable => destination_parameter) - grosseconomy.YGROSS => emissions.YGROSS -end -``` - -which produces these function calls: - -``` -quote - mymodel = Model() - set_dimension!(mymodel, :time, 2015:5:2110) - add_comp!(mymodel, Main.grosseconomy, :grosseconomy) - add_comp!(mymodel, Main.emissions, :emissions) - set_param!(mymodel, :grosseconomy, :l, [(1.0 + 0.015) ^ t * 6404 for t = 1:20]) - set_param!(mymodel, :grosseconomy, :tfp, [(1 + 0.065) ^ t * 3.57 for t = 1:20]) - set_param!(mymodel, :grosseconomy, :s, ones(20) * 0.22) - set_param!(mymodel, :grosseconomy, :depk, 0.1) - set_param!(mymodel, :grosseconomy, :k0, 130.0) - set_param!(mymodel, :grosseconomy, :share, 0.3) - set_param!(mymodel, :emissions, :sigma, [(1.0 - 0.05) ^ t * 0.58 for t = 1:20]) - connect_param!(mymodel, :emissions, :YGROSS, :grosseconomy, :YGROSS) -end -``` - -## 4. Pre-compilation and built-in components +## 3. Pre-compilation and built-in components To get `__precompile__()` to work required moving the creation of "helper" components to an `__init__()` method in Mimi.jl, which is run automatically after Mimi loads. It defines the two "built-in" components, from `adder.jl` and `connector.jl` in the `components` subdirectory. diff --git a/src/Mimi.jl b/src/Mimi.jl index abce17178..954780aba 100644 --- a/src/Mimi.jl +++ b/src/Mimi.jl @@ -58,7 +58,6 @@ include("core/build.jl") include("core/connections.jl") include("core/defs.jl") include("core/defcomp.jl") -include("core/defmodel.jl") include("core/defcomposite.jl") include("core/dimensions.jl") include("core/instances.jl") From 354f1281df2d98fc61ab7a5fd3be384313c2dcbe Mon Sep 17 00:00:00 2001 From: lrennels Date: Sat, 13 Jun 2020 14:20:30 -0700 Subject: [PATCH 03/13] More deprecation cleanup --- docs/src/userguide.md | 2 +- src/core/time_arrays.jl | 13 ------------- test/test_parametertypes.jl | 3 +-- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/docs/src/userguide.md b/docs/src/userguide.md index 948b26d02..a31f72977 100644 --- a/docs/src/userguide.md +++ b/docs/src/userguide.md @@ -211,7 +211,7 @@ The API details for AbstractTimestep object `t` are as follows: - useful functions for commonly used conditionals are `is_first(t)` and `is_last(t)` - to access the index value of `t` as a `Number` representing the position in the time array, use `t.t`. Users are encouraged to avoid this access, and instead use comparisons with `TimestepIndex` objects to check if an AbstractTimestep `t` corresponds with a specific index number, as described above. -Indexing into a variable or parameter's `time` dimension with an `Integer` is deprecated and will soon error. Instead, users should take advantage of the `TimestepIndex` and `TimestepValue` types. For examples we will refer back to our component definition above, and repeated below. +Indexing into a variable or parameter's `time` dimension with an `Integer` is no longer supported. Instead, users should take advantage of the `TimestepIndex` and `TimestepValue` types. For examples we will refer back to our component definition above, and repeated below. ```julia @defcomp MyComponentName begin regions = Index() diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index c07b89403..cdec49425 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -56,19 +56,6 @@ function _single_index_check(data, idxs) end end -# Helper to print stacktrace for the integer indexing deprecatino warning -function _get_stacktrace_string() - s = "" - for line in stacktrace() - if startswith(string(line), "run_timestep") - return s - else - s = string(s, line, "\n") - end - end - return s -end - # Helper macro used by connector macro allow_missing(expr) let e = gensym("e") diff --git a/test/test_parametertypes.jl b/test/test_parametertypes.jl index c66beb46e..46284c8ce 100644 --- a/test/test_parametertypes.jl +++ b/test/test_parametertypes.jl @@ -38,8 +38,7 @@ expr = :( end end ) -eval(expr) # Just a deprecation warning for v0.10, then will change to error in v1.0 -# @test_throws LoadError eval(expr) +@test_throws LoadError eval(expr) @defcomp MyComp begin From ab3721ac8da62edf1fa41bf41aed6ddd55b48aa8 Mon Sep 17 00:00:00 2001 From: lrennels Date: Sun, 14 Jun 2020 17:38:52 -0700 Subject: [PATCH 04/13] Re-add colon timesteparray indexing support --- docs/src/tutorials/tutorial_4.md | 2 +- src/core/time_arrays.jl | 17 ++++++++++++++++- test/test_parametertypes.jl | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/src/tutorials/tutorial_4.md b/docs/src/tutorials/tutorial_4.md index 479ce1846..a5d2736f6 100644 --- a/docs/src/tutorials/tutorial_4.md +++ b/docs/src/tutorials/tutorial_4.md @@ -278,7 +278,7 @@ save("MyFigure.png", p) This example will discuss the more advanced SA capabilities of post-trial functions and payload objects. -Case: We want to do an SCC calculation with `MimiDICE2010`, which consists of running both a `base` and `marginal` model (the latter being a model including an additional emissions pulse, see the [`create_marginal_model`](@ref) function or create your own two models). We then take the difference between the consumption level in these two models and obtain the discounted net present value to get the SCC. +Case: We want to do an SCC calculation with `MimiDICE2010`, which consists of running both a `base` and `modified` model (the latter being a model including an additional emissions pulse, see the [`create_marginal_model`](@ref) function or create your own two models). We then take the difference between the consumption level in these two models and obtain the discounted net present value to get the SCC. The beginning steps for this case are identical to those above. We first define the typical variables for a simulation, including the number of trials `N` and the simulation definition `sd`. In this case we only define one random variable, `t2xco2`, but note there could be any number of random variables defined here. diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index cdec49425..6216a4fe6 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -27,7 +27,6 @@ function get_time_index_position(obj::AbstractCompositeComponentDef, comp_name:: end const AnyIndex = Union{Int, Vector{Int}, Tuple, Colon, OrdinalRange} -const AnyIndex_NonColon = Union{Int, Vector{Int}, Tuple, OrdinalRange} # Helper function for getindex; throws a MissingException if data is missing, otherwise returns data function _missing_data_check(data, t) @@ -472,6 +471,22 @@ end # Colon support - this allows the time dimension to be indexed with a colon + function Base.getindex(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} + return arr.data[idxs...] +end + +function Base.getindex(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, idxs::AnyIndex...) where {TIMES, T, N, ti} + return arr.data[idxs...] +end + +function Base.setindex!(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, val, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} + setindex!(arr.data, val, idxs...) +end + +function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, val, idxs::AnyIndex...) where {TIMES, T, N, ti} + setindex!(arr.data, val, idxs...) +end + # Indexing with arrays of TimestepIndexes or TimestepValues function Base.getindex(arr::TimestepArray{TS, T, N, ti}, idxs::Union{Array{TimestepIndex,1}, AnyIndex}...) where {TS, T, N, ti} idxs1, ts_array, idxs2 = split_indices(idxs, ti) diff --git a/test/test_parametertypes.jl b/test/test_parametertypes.jl index 46284c8ce..a5f39276f 100644 --- a/test/test_parametertypes.jl +++ b/test/test_parametertypes.jl @@ -38,7 +38,7 @@ expr = :( end end ) -@test_throws LoadError eval(expr) +@test_throws MethodError eval(expr) @defcomp MyComp begin From 038d99ac87887de814347dffb12876fbc5e0b9f6 Mon Sep 17 00:00:00 2001 From: lrennels Date: Sun, 14 Jun 2020 18:22:53 -0700 Subject: [PATCH 05/13] Remove doctest from tutorial 4 --- docs/src/tutorials/tutorial_4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/tutorials/tutorial_4.md b/docs/src/tutorials/tutorial_4.md index a5d2736f6..efc1cbbb1 100644 --- a/docs/src/tutorials/tutorial_4.md +++ b/docs/src/tutorials/tutorial_4.md @@ -350,7 +350,7 @@ my_scc_calculation (generic function with 1 method) Now that we have our post-trial function, we can proceed to obtain our two models and run the simulation. Note that we are using a Mimi MarginalModel `mm` from MimiDICE2010, which is a Mimi object that holds both the base model and the model with the additional pulse of emissions. -```jldoctest tutorial4; output = false, filter = r".*"s +```julia # Build the marginal model mm = MimiDICE2010.get_marginal_model(year = scc_year) # The additional emissions pulse will be added in the specified year From 54cc37829441dfd2eb58b652049aac35fae222a7 Mon Sep 17 00:00:00 2001 From: lrennels Date: Mon, 15 Jun 2020 12:06:53 -0700 Subject: [PATCH 06/13] Add errors instead of just removing deprecated code --- src/core/defcomp.jl | 9 ++-- src/core/model.jl | 8 ++++ src/core/time.jl | 20 +++++++++ src/core/time_arrays.jl | 88 ++++++++++++++++++++++++++++++++++++- test/test_parametertypes.jl | 2 +- test/test_timesteparrays.jl | 6 --- 6 files changed, 122 insertions(+), 11 deletions(-) diff --git a/src/core/defcomp.jl b/src/core/defcomp.jl index 1c7d682ba..f3309b137 100644 --- a/src/core/defcomp.jl +++ b/src/core/defcomp.jl @@ -195,10 +195,13 @@ macro defcomp(comp_name, ex) continue end - if ! @capture(elt, name_ = (elt_type_{datum_type_}(args__) | elt_type_(args__))) - error("Element syntax error: $elt") + # DEPRECATION TBD - ERROR OR REMOVE + if @capture(elt, name_::datum_type_ = elt_type_(args__)) + msg = "The following syntax has been deprecated in @defcomp: \"$name::$datum_type = $elt_type(...)\". Use curly bracket syntax instead: \"$name = $elt_type{$datum_type}(...)\"" + error("$msg\n$(reduce((x,y) -> "$x\n$y", stacktrace()))") + elseif ! @capture(elt, name_ = (elt_type_{datum_type_}(args__) | elt_type_(args__))) end - + # elt_type is one of {:Variable, :Parameter, :Index} if elt_type == :Index expr = _generate_dims_expr(name, args, datum_type) diff --git a/src/core/model.jl b/src/core/model.jl index 56d82d01c..1f11d80aa 100644 --- a/src/core/model.jl +++ b/src/core/model.jl @@ -232,6 +232,14 @@ dim_names(mm::MarginalModel, comp_name::Symbol, datum_name::Symbol) = dim_names( # Allow access of the form my_model[:grosseconomy, :tfp] @delegate Base.getindex(m::Model, comp_name::Symbol, datum_name::Symbol) => mi +# DEPRECATION TBD - ERROR OR REMOVE +function Base.getproperty(base::MarginalModel, s::Symbol) + if (s == :marginal) + error("Use of 'MarginalModel.marginal' is deprecated in favor of 'MarginalModel.modified'"); + end + return getfield(base, s); +end + """ dim_count(m::Model, dim_name::Symbol) diff --git a/src/core/time.jl b/src/core/time.jl index 48300e58d..9df9df500 100644 --- a/src/core/time.jl +++ b/src/core/time.jl @@ -20,6 +20,16 @@ function gettime(ts::VariableTimestep) return ts.current end +# DEPRECATION TBD - ERROR OR REMOVE +""" + is_time(ts::AbstractTimestep, t::Int) + + [DEPRECATED FUNCTION] Return true or false, true if the current time (year) for `ts` is `t` + """ + function is_time(ts::AbstractTimestep, t::Int) + error("`is_time(ts, t)` is deprecated. Use comparison operators with TimestepValue objects instead: `ts == TimestepValue(t)` \n$(stacktrace())", :is_time) + end + """ is_first(ts::AbstractTimestep) @@ -29,6 +39,16 @@ function is_first(ts::AbstractTimestep) return ts.t == 1 end +# DEPRECATION TBD - ERROR OR REMOVE +""" + is_timestep(ts::AbstractTimestep, t::Int) + +[DEPRECATED FUNCTION] Return true or false, true if `ts` timestep is step `t`. + """ + function is_timestep(ts::AbstractTimestep, t::Int) + error("`is_timestep(ts, t)` is deprecated. Use comparison operators with TimestepIndex objects instead: `ts == TimestepIndex(t)` \n$(stacktrace())", :is_timestep) + end + """ is_last(ts::FixedTimestep) diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index 1ba81b1a9..5d63eb13a 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -27,6 +27,8 @@ function get_time_index_position(obj::AbstractCompositeComponentDef, comp_name:: end const AnyIndex = Union{Int, Vector{Int}, Tuple, Colon, OrdinalRange} +# DEPRECATION TBD - ERROR OR REMOVE +const AnyIndex_NonColon = Union{Int, Vector{Int}, Tuple, OrdinalRange} # Helper function for getindex; throws a MissingException if data is missing, otherwise returns data function _missing_data_check(data, t) @@ -55,6 +57,38 @@ function _single_index_check(data, idxs) end end +# DEPRECATION TBD - ERROR OR REMOVE +# Helper to print stacktrace for the integer indexing errors +function _get_stacktrace_string() + s = "" + for line in stacktrace() + if startswith(string(line), "run_timestep") + return s + else + s = string(s, line, "\n") + end + end + return s +end + +# DEPRECATION TBD - ERROR OR REMOVE +# Helper function for getindex; throws an error if one indexes into a TimestepArray with an integer +function _throw_int_getindex_error() + msg = "Indexing with getindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndex(2)]\n" + st = _get_stacktrace_string() + full_msg = string(msg, " \n", st) + error(full_msg) +end + +# DEPRECATION TBD - ERROR OR REMOVE +# Helper function for setindex; throws an error if one indexes into a TimestepArray with an integer +function _throw_int_setindex_error() + msg = "Indexing with setindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndec(2)]" + st = _get_stacktrace_string() + full_msg = string(msg, " \n", st) + error(full_msg) +end + # Helper macro used by connector macro allow_missing(expr) let e = gensym("e") @@ -229,6 +263,26 @@ function Base.setindex!(v::TimestepVector, val, ts::TimestepIndex) setindex!(v.data, val, ts.index) end +# DEPRECATION TBD - ERROR OR REMOVE +# int indexing version supports old-style components and internal functions, not +# part of the public API + + function Base.getindex(v::TimestepVector{FixedTimestep{FIRST, STEP}, T}, i::AnyIndex_NonColon) where {T, FIRST, STEP} + _throw_int_getindex_error() +end + +function Base.getindex(v::TimestepVector{VariableTimestep{TIMES}, T}, i::AnyIndex_NonColon) where {T, TIMES} + _throw_int_getindex_error() +end + +function Base.setindex!(v::TimestepVector{FixedTimestep{Start, STEP}, T}, val, i::AnyIndex_NonColon) where {T, Start, STEP} + _throw_int_setindex_error() +end + +function Base.setindex!(v::TimestepVector{VariableTimestep{TIMES}, T}, val, i::AnyIndex_NonColon) where {T, TIMES} + _throw_int_setindex_error() +end + function Base.length(v::TimestepVector) return length(v.data) end @@ -387,6 +441,34 @@ function Base.setindex!(mat::TimestepMatrix, val, ts::TimestepIndex, idx::AnyInd setindex!(mat.data, val, ts.index, idx) end +# DEPRECATION TBD - ERROR OR REMOVE +# int indexing version supports old-style components and internal functions, not +# part of the public API + +function Base.getindex(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, FIRST, STEP, ti} + _throw_int_getindex_error() +end + +function Base.getindex(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, TIMES, ti} + _throw_int_getindex_error() +end + +function Base.setindex!(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, val, idx1::Int, idx2::Int) where {T, FIRST, STEP, ti} + _throw_int_setindex_error() +end + +function Base.setindex!(mat::TimestepMatrix{FixedTimestep{FIRST, STEP}, T, ti}, val, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, FIRST, STEP, ti} + _throw_int_setindex_error() +end + +function Base.setindex!(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, val, idx1::Int, idx2::Int) where {T, TIMES, ti} + _throw_int_setindex_error() +end + +function Base.setindex!(mat::TimestepMatrix{VariableTimestep{TIMES}, T, ti}, val, idx1::AnyIndex_NonColon, idx2::AnyIndex_NonColon) where {T, TIMES, ti} + _throw_int_setindex_error() +end + # # TimestepArray methods # @@ -519,21 +601,25 @@ function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, v setindex!(arr.data, val, idxs1..., t, idxs2...) end +# DEPRECATION TBD - ERROR OR REMOVE # Colon support - this allows the time dimension to be indexed with a colon - function Base.getindex(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} + isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_error() : nothing return arr.data[idxs...] end function Base.getindex(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, idxs::AnyIndex...) where {TIMES, T, N, ti} + isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_error() : nothing return arr.data[idxs...] end function Base.setindex!(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, val, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} + isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_setindex_error() : nothing setindex!(arr.data, val, idxs...) end function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, val, idxs::AnyIndex...) where {TIMES, T, N, ti} + isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_setindex_error() : nothing setindex!(arr.data, val, idxs...) end diff --git a/test/test_parametertypes.jl b/test/test_parametertypes.jl index a5f39276f..46284c8ce 100644 --- a/test/test_parametertypes.jl +++ b/test/test_parametertypes.jl @@ -38,7 +38,7 @@ expr = :( end end ) -@test_throws MethodError eval(expr) +@test_throws LoadError eval(expr) @defcomp MyComp begin diff --git a/test/test_timesteparrays.jl b/test/test_timesteparrays.jl index 5a93a1aac..0bcb9bf59 100644 --- a/test/test_timesteparrays.jl +++ b/test/test_timesteparrays.jl @@ -97,12 +97,6 @@ x[t3] = temp_dim_val[1] @test x[t3] == temp_dim_val[1] reset_time_val(x, time_dim_val) -# Deprecated int indexing should still run -@test x[3] == time_dim_val[3] -x[TimestepIndex(3)] = temp_dim_val[3] -@test x[TimestepIndex(3)] == temp_dim_val[3] -reset_time_val(x, time_dim_val) - #------------------------------------------------------------------------------ # 2. Test TimestepVector - Variable Timestep #------------------------------------------------------------------------------ From e36403091908d69734b95e053548752776b45eaf Mon Sep 17 00:00:00 2001 From: lrennels Date: Tue, 23 Jun 2020 14:54:55 -0700 Subject: [PATCH 07/13] Export deprecated fcns; edit deprecation comment --- docs/src/howto/howto_6.md | 2 +- docs/src/tutorials/tutorial_5.md | 2 +- src/Mimi.jl | 2 ++ src/core/defcomp.jl | 2 +- src/core/model.jl | 2 +- src/core/time.jl | 4 ++-- src/core/time_arrays.jl | 14 +++++++------- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/src/howto/howto_6.md b/docs/src/howto/howto_6.md index 3044b6ba3..4ccf7e447 100644 --- a/docs/src/howto/howto_6.md +++ b/docs/src/howto/howto_6.md @@ -39,7 +39,7 @@ This guide is organized into five main sections, each descripting an independent ## Integer indexing - cannot index with integers -- removed `is_time` and `is_timestep` +- `is_time` and `is_timestep` error now ## Composite components diff --git a/docs/src/tutorials/tutorial_5.md b/docs/src/tutorials/tutorial_5.md index e3d946d2a..af90e8bc4 100644 --- a/docs/src/tutorials/tutorial_5.md +++ b/docs/src/tutorials/tutorial_5.md @@ -279,7 +279,7 @@ save("MyFigure.png", p) This example will discuss the more advanced SA capabilities of post-trial functions and payload objects. -Case: We want to do an SCC calculation with `MimiDICE2010`, which consists of running both a `base` and `marginal` model (the latter being a model including an additional emissions pulse, see the [`create_marginal_model`](@ref) function or create your own two models). We then take the difference between the consumption level in these two models and obtain the discounted net present value to get the SCC. +Case: We want to do an SCC calculation with `MimiDICE2010`, which consists of running both a `base` and `modified` model (the latter being a model including an additional emissions pulse, see the [`create_marginal_model`](@ref) function or create your own two models). We then take the difference between the consumption level in these two models and obtain the discounted net present value to get the SCC. The beginning steps for this case are identical to those above. We first define the typical variables for a simulation, including the number of trials `N` and the simulation definition `sd`. In this case we only define one random variable, `t2xco2`, but note there could be any number of random variables defined here. diff --git a/src/Mimi.jl b/src/Mimi.jl index 954780aba..eab87c535 100644 --- a/src/Mimi.jl +++ b/src/Mimi.jl @@ -31,6 +31,8 @@ export hasvalue, is_first, is_last, + is_time, + is_timestep, modeldef, name, # parameters, diff --git a/src/core/defcomp.jl b/src/core/defcomp.jl index f3309b137..2c6edbad3 100644 --- a/src/core/defcomp.jl +++ b/src/core/defcomp.jl @@ -195,7 +195,7 @@ macro defcomp(comp_name, ex) continue end - # DEPRECATION TBD - ERROR OR REMOVE + # DEPRECATION - EVENTUALLY REMOVE if @capture(elt, name_::datum_type_ = elt_type_(args__)) msg = "The following syntax has been deprecated in @defcomp: \"$name::$datum_type = $elt_type(...)\". Use curly bracket syntax instead: \"$name = $elt_type{$datum_type}(...)\"" error("$msg\n$(reduce((x,y) -> "$x\n$y", stacktrace()))") diff --git a/src/core/model.jl b/src/core/model.jl index 160fa2ac4..ccc6a0b71 100644 --- a/src/core/model.jl +++ b/src/core/model.jl @@ -275,7 +275,7 @@ dim_names(mm::MarginalModel, comp_name::Symbol, datum_name::Symbol) = dim_names( # Allow access of the form my_model[:grosseconomy, :tfp] @delegate Base.getindex(m::Model, comp_name::Symbol, datum_name::Symbol) => mi -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE function Base.getproperty(base::MarginalModel, s::Symbol) if (s == :marginal) error("Use of 'MarginalModel.marginal' is deprecated in favor of 'MarginalModel.modified'"); diff --git a/src/core/time.jl b/src/core/time.jl index 9df9df500..9312775d8 100644 --- a/src/core/time.jl +++ b/src/core/time.jl @@ -20,7 +20,7 @@ function gettime(ts::VariableTimestep) return ts.current end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE """ is_time(ts::AbstractTimestep, t::Int) @@ -39,7 +39,7 @@ function is_first(ts::AbstractTimestep) return ts.t == 1 end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE """ is_timestep(ts::AbstractTimestep, t::Int) diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index 5d63eb13a..92dfa50a0 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -27,7 +27,7 @@ function get_time_index_position(obj::AbstractCompositeComponentDef, comp_name:: end const AnyIndex = Union{Int, Vector{Int}, Tuple, Colon, OrdinalRange} -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE const AnyIndex_NonColon = Union{Int, Vector{Int}, Tuple, OrdinalRange} # Helper function for getindex; throws a MissingException if data is missing, otherwise returns data @@ -57,7 +57,7 @@ function _single_index_check(data, idxs) end end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # Helper to print stacktrace for the integer indexing errors function _get_stacktrace_string() s = "" @@ -71,7 +71,7 @@ function _get_stacktrace_string() return s end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # Helper function for getindex; throws an error if one indexes into a TimestepArray with an integer function _throw_int_getindex_error() msg = "Indexing with getindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndex(2)]\n" @@ -80,7 +80,7 @@ function _throw_int_getindex_error() error(full_msg) end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # Helper function for setindex; throws an error if one indexes into a TimestepArray with an integer function _throw_int_setindex_error() msg = "Indexing with setindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndec(2)]" @@ -263,7 +263,7 @@ function Base.setindex!(v::TimestepVector, val, ts::TimestepIndex) setindex!(v.data, val, ts.index) end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # int indexing version supports old-style components and internal functions, not # part of the public API @@ -441,7 +441,7 @@ function Base.setindex!(mat::TimestepMatrix, val, ts::TimestepIndex, idx::AnyInd setindex!(mat.data, val, ts.index, idx) end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # int indexing version supports old-style components and internal functions, not # part of the public API @@ -601,7 +601,7 @@ function Base.setindex!(arr::TimestepArray{VariableTimestep{TIMES}, T, N, ti}, v setindex!(arr.data, val, idxs1..., t, idxs2...) end -# DEPRECATION TBD - ERROR OR REMOVE +# DEPRECATION - EVENTUALLY REMOVE # Colon support - this allows the time dimension to be indexed with a colon function Base.getindex(arr::TimestepArray{FixedTimestep{FIRST, STEP}, T, N, ti}, idxs::AnyIndex...) where {FIRST, STEP, T, N, ti} isa(idxs[ti], AnyIndex_NonColon) ? _throw_int_getindex_error() : nothing From 00c7a20ecf3f062c33b74ccc57e7d61e3908aca8 Mon Sep 17 00:00:00 2001 From: lrennels Date: Tue, 23 Jun 2020 15:39:42 -0700 Subject: [PATCH 08/13] Edit tutorials --- docs/src/tutorials/tutorial_2.md | 12 ++++++------ docs/src/tutorials/tutorial_4.md | 18 +++++++++--------- docs/src/tutorials/tutorial_5.md | 20 +++++++++----------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/docs/src/tutorials/tutorial_2.md b/docs/src/tutorials/tutorial_2.md index dee560d32..ecc4212d3 100644 --- a/docs/src/tutorials/tutorial_2.md +++ b/docs/src/tutorials/tutorial_2.md @@ -32,7 +32,7 @@ The next step is to run FUND. If you wish to first get more acquainted with the Now open a julia REPL and type the following command to load the MimiFUND package into the current environment: -```jldoctest tutorial1; output = false, filter = r".*"s +```jldoctest tutorial2; output = false, filter = r".*"s using MimiFUND # output @@ -40,7 +40,7 @@ using MimiFUND ``` Now we can access the public API of FUND, including the function `MimiFUND.get_model`. This function returns a copy of the default FUND model. Here we will first get the model, and then use the `run` function to run it. -```jldoctest tutorial1; output = false, filter = r".*"s +```jldoctest tutorial2; output = false, filter = r".*"s m = MimiFUND.get_model() run(m) @@ -58,7 +58,7 @@ get_model(; nsteps = default_nsteps, datadir = default_datadir, params = default Thus there are no required arguments, although the user can input `nsteps` to define the number of timesteps (years in this case) the model runs for, `datadir` to define the location of the input data, and `params`, a dictionary definining the parameters of the model. For example, if you wish to run only the first 200 timesteps, you may use: -```jldoctest tutorial1; output = false, filter = r".*"s +```jldoctest tutorial2; output = false, filter = r".*"s using MimiFUND m = MimiFUND.get_model(nsteps = 200) run(m) @@ -72,7 +72,7 @@ After the model has been run, you may access the results (the calculated variabl Start off by importing the Mimi package to your space with -```jldoctest tutorial1; output = false +```jldoctest tutorial2; output = false using Mimi # output @@ -89,7 +89,7 @@ m[:ComponentName, :VariableName][100] # returns just the 100th value Indexing into a model with the name of the component and variable will return an array with values from each timestep. You may index into this array to get one value (as in the second line, which returns just the 100th value). Note that if the requested variable is two-dimensional, then a 2-D array will be returned. For example, try taking a look at the `income` variable of the `socioeconomic` component of FUND using the code below: -```jldoctest tutorial1; output = false +```jldoctest tutorial2; output = false m[:socioeconomic, :income] m[:socioeconomic, :income][100] @@ -108,7 +108,7 @@ getdataframe(m, :Component1=>:Var1, :Component2=>:Var2) # request variables from Try doing this for the `income` variable of the `socioeconomic` component using: -```jldoctest tutorial1; output = false, filter = r".*"s +```jldoctest tutorial2; output = false, filter = r".*"s getdataframe(m, :socioeconomic=>:income) # request one variable from one component getdataframe(m, :socioeconomic=>:income)[1:16,:] # results for all regions in first year (1950) diff --git a/docs/src/tutorials/tutorial_4.md b/docs/src/tutorials/tutorial_4.md index d0573f327..4a5173f15 100644 --- a/docs/src/tutorials/tutorial_4.md +++ b/docs/src/tutorials/tutorial_4.md @@ -28,7 +28,7 @@ Next, the `run_timestep` function must be defined along with the various equatio It is important to note that `t` below is an `AbstractTimestep`, and the specific API for using this argument are described in detail in the how to guide How-to Guide 4: Work with Timesteps, Parameters, and Variables -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false using Mimi # start by importing the Mimi package to your space @defcomp grosseconomy begin @@ -61,7 +61,7 @@ end Next, the component for greenhouse gas emissions must be created. Although the steps are the same as for the `grosseconomy` component, there is one minor difference. While `YGROSS` was a variable in the `grosseconomy` component, it now enters the `emissions` component as a parameter. This will be true for any variable that becomes a parameter for another component in the model. -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false @defcomp emissions begin E = Variable(index=[time]) # Total greenhouse gas emissions sigma = Parameter(index=[time]) # Emissions output ratio @@ -88,7 +88,7 @@ We can now use Mimi to construct a model that binds the `grosseconomy` and `emis * To access model results, use `model_name[:component, :variable_name]`. * To observe model results in a graphical form , [`explore`](@ref) as either `explore(model_name)` to open the UI window, or use `Mimi.plot(model_name, :component_name, :variable_name)` or `Mimi.plot(model_name, :component_name, :parameter_name)` to plot a specific parameter or variable. -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false using Mimi @@ -128,7 +128,7 @@ Note that as an alternative to using many of the `set_param!` calls above, one m Now we can run the model and examine the results: -```jldoctest tutorial3; output = false, filter = r".*"s +```jldoctest tutorial4; output = false, filter = r".*"s # Run model m = construct_model() run(m) @@ -162,7 +162,7 @@ To create a three-regional model, we will again start by constructing the grosse As this model is also more complex and spread across several files, we will also take this as a chance to introduce the custom of using [Modules](https://docs.julialang.org/en/v1/manual/modules/index.html) to package Mimi models, as shown below. -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false using Mimi @defcomp grosseconomy begin @@ -202,7 +202,7 @@ end Save this component as **`gross_economy.jl`** -```jldoctest tutorial3; output = false, filter = r".*"s +```jldoctest tutorial4; output = false, filter = r".*"s using Mimi #Make sure to call Mimi again @defcomp emissions begin @@ -238,7 +238,7 @@ Save this component as **`emissions.jl`** Let's create a file with all of our parameters that we can call into our model. This will help keep things organized as the number of components and regions increases. Each column refers to parameter values for a region, reflecting differences in initial parameter values and growth rates between the three regions. -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false l = Array{Float64}(undef, 20, 3) for t in 1:20 l[t,1] = (1. + 0.015)^t *2000 @@ -288,7 +288,7 @@ include("emissions.jl") export construct_MyModel ``` -```jldoctest tutorial3; output = false +```jldoctest tutorial4; output = false function construct_MyModel() m = Model() @@ -332,7 +332,7 @@ using Mimi include("MyModel.jl") using .MyModel ``` -```jldoctest tutorial3; output = false, filter = r".*"s +```jldoctest tutorial4; output = false, filter = r".*"s m = construct_MyModel() run(m) diff --git a/docs/src/tutorials/tutorial_5.md b/docs/src/tutorials/tutorial_5.md index af90e8bc4..835cb6368 100644 --- a/docs/src/tutorials/tutorial_5.md +++ b/docs/src/tutorials/tutorial_5.md @@ -28,7 +28,7 @@ You should have `Mimi` installed by now, and if you do not have the `Distributio As a reminder, the following code is the multi-region model that was constructed in the second half of tutorial 3. You can either load the `MyModel` module from tutorial 3, or run the following code which defines the same `construct_Mymodel` function that we will use. -```jldoctest tutorial4; output = false +```jldoctest tutorial5; output = false using Mimi # Define the grosseconomy component @@ -155,7 +155,7 @@ construct_MyModel (generic function with 1 method) Then, we obtain a copy of the model: -```jldoctest tutorial4; output = false +```jldoctest tutorial5; output = false m = construct_MyModel() # output @@ -172,7 +172,7 @@ Mimi.Model The `@defsim` macro is the first step in the process, and returns a `SimulationDef`. The following syntax allows users to define random variables (RVs) as distributions, and associate model parameters with the defined random variables. There are two ways of assigning random variables to model parameters in the `@defsim` macro. Notice that both of the following syntaxes are used in the following example. - + The first is the following: ```julia rv(rv1) = Normal(0, 0.8) # create a random variable called "rv1" with the specified distribution @@ -187,7 +187,7 @@ param1 = Normal(0, 0.8) The `@defsim` macro also selects the sampling method. Simple random sampling (also called Monte Carlo sampling) is the default. Other options include Latin Hypercube sampling and Sobol sampling. -```jldoctest tutorial4; output = false, filter = r".*"s +```jldoctest tutorial5; output = false, filter = r".*"s using Mimi using Distributions @@ -235,7 +235,7 @@ Next, use the `run` function to run the simulation for the specified simulation In its simplest use, the `run` function generates and iterates over a sample of trial data from the distributions of the random variables defined in the `SimulationDef`, perturbing the subset of Mimi's "external parameters" that have been assigned random variables, and then runs the given Mimi model(s) for each set of trial data. The function returns a `SimulationInstance`, which holds a copy of the original `SimulationDef` in addition to trials information (`trials`, `current_trial`, and `current_data`), the model list `models`, and results information in `results`. Optionally, trial values and/or model results are saved to CSV files. Note that if there is concern about in-memory storage space for the results, use the `results_in_memory` flag set to `false` to incrementally clear the results from memory. -```jldoctest tutorial4; output = false, filter = r".*"s +```jldoctest tutorial5; output = false, filter = r".*"s # Run 100 trials, and optionally save results to the indicated directories si = run(sd, m, 100; trials_output_filename = "/tmp/trialdata.csv", results_output_dir="/tmp/tutorial4") @@ -283,7 +283,7 @@ Case: We want to do an SCC calculation with `MimiDICE2010`, which consists of ru The beginning steps for this case are identical to those above. We first define the typical variables for a simulation, including the number of trials `N` and the simulation definition `sd`. In this case we only define one random variable, `t2xco2`, but note there could be any number of random variables defined here. -```jldoctest tutorial4; output = false +```jldoctest tutorial5; output = false using Mimi using MimiDICE2010 using Distributions @@ -304,7 +304,7 @@ MCSData() #### Payload object Simulation definitions can hold a user-defined payload object which is not used or modified by Mimi. In this example, we will use the payload to hold an array of pre-computed discount factors that we will use in the SCC calculation, as well as a storage array for saving the SCC values. -```jldoctest tutorial4; output = false, filter = r".*"s +```jldoctest tutorial5; output = false, filter = r".*"s # Choose what year to calculate the SCC for scc_year = 2015 year_idx = findfirst(isequal(scc_year), MimiDICE2010.model_years) @@ -331,7 +331,7 @@ In the simple multi-region simulation example, the only values that were saved d Here we define a `post_trial_function` called `my_scc_calculation` which will calculate the SCC for each trial of the simulation. Notice that this function retrieves and uses the payload object that was previously stored in the `SimulationDef`. -```jldoctest tutorial4; output = false +```jldoctest tutorial5; output = false function my_scc_calculation(sim_inst::SimulationInstance, trialnum::Int, ntimesteps::Int, tup::Nothing) mm = sim_inst.models[1] discount_factors, scc_results = Mimi.payload(sim_inst) # Unpack the payload object @@ -351,7 +351,7 @@ my_scc_calculation (generic function with 1 method) Now that we have our post-trial function, we can proceed to obtain our two models and run the simulation. Note that we are using a Mimi MarginalModel `mm` from MimiDICE2010, which is a Mimi object that holds both the base model and the model with the additional pulse of emissions. -```jldoctest tutorial4; output = false, filter = r".*"s +```julia # Build the marginal model mm = MimiDICE2010.get_marginal_model(year = scc_year) # The additional emissions pulse will be added in the specified year @@ -361,8 +361,6 @@ si = run(sd, mm, N; trials_output_filename = "ecs_sample.csv", post_trial_func = # View the scc_results by retrieving them from the payload object scc_results = Mimi.payload(si)[2] # Recall that the SCC array was the second of two arrays we stored in the payload tuple -# output - ``` #### Simulation Modification Functions From 81ff2bf97527889cbf6347a847ba2fb72fbae38c Mon Sep 17 00:00:00 2001 From: lrennels Date: Fri, 26 Jun 2020 12:29:49 -0700 Subject: [PATCH 09/13] Handle repalce comp changes --- docs/src/ref/ref_API.md | 2 +- docs/src/tutorials/tutorial_3.md | 2 +- src/core/model.jl | 4 +-- src/core/time.jl | 4 +-- test/test_replace_comp.jl | 6 ++--- test/test_tmp.jl | 44 -------------------------------- 6 files changed, 8 insertions(+), 54 deletions(-) delete mode 100644 test/test_tmp.jl diff --git a/docs/src/ref/ref_API.md b/docs/src/ref/ref_API.md index fc7e165f2..0098a7246 100644 --- a/docs/src/ref/ref_API.md +++ b/docs/src/ref/ref_API.md @@ -23,7 +23,7 @@ modeldef parameter_names parameter_dimensions plot_comp_graph -replace_comp! +replace! set_dimension! set_leftover_params! set_param! diff --git a/docs/src/tutorials/tutorial_3.md b/docs/src/tutorials/tutorial_3.md index 95e706b3d..a3591337b 100644 --- a/docs/src/tutorials/tutorial_3.md +++ b/docs/src/tutorials/tutorial_3.md @@ -130,7 +130,7 @@ Note that here we use the `update_timesteps` flag and set it to `true`, because ## Component and Structural Modifications: The API -Most model modifications will include not only parametric updates, but also strutural changes and component modification, addition, replacement, and deletion along with the required re-wiring of parameters etc. The most useful functions of the common API, in these cases are likely **[`replace_comp!`](@ref), [`add_comp!`](@ref)** along with **`Mimi.delete!`** and the requisite functions for parameter setting and connecting. For detail on the public API functions look at the API reference. +Most model modifications will include not only parametric updates, but also strutural changes and component modification, addition, replacement, and deletion along with the required re-wiring of parameters etc. The most useful functions of the common API, in these cases are likely **[`replace!!`](@ref), [`add_comp!`](@ref)** along with **`Mimi.delete!`** and the requisite functions for parameter setting and connecting. For detail on the public API functions look at the API reference. If you wish to modify the component structure we recommend you also look into the **built-in helper components `adder`, `ConnectorCompVector`, and `ConnectorCompMatrix`** in the `src/components` folder, as these can prove quite useful. diff --git a/src/core/model.jl b/src/core/model.jl index ccc6a0b71..584d93468 100644 --- a/src/core/model.jl +++ b/src/core/model.jl @@ -172,7 +172,7 @@ function replace_comp!(m::Model, comp_id::ComponentId, comp_name::Symbol=comp_id msg = "Function `replace_comp!(m, comp_id, comp_name; kwargs...)` has been deprecated. Use `replace!(m, comp_name => Mimi.compdef(comp_id); kwargs...)` instead." st = _get_stacktrace_string() full_msg = string(msg, " \n", st) - Base.depwarn(full_msg, :replace_comp!) + error(full_msg) return replace!(m, comp_name => compdef(comp_id); kwargs...) end @@ -195,7 +195,7 @@ function replace_comp!(m::Model, comp_def::ComponentDef, comp_name::Symbol=comp_ msg = "Function `replace_comp!(m, comp_def, comp_name; kwargs...)` has been deprecated. Use `replace!(m, comp_name => comp_def; kwargs...)` instead." st = _get_stacktrace_string() full_msg = string(msg, " \n", st) - Base.depwarn(full_msg, :replace_comp!) + error(full_msg) return replace!(m, comp_name => comp_def; kwargs...) end diff --git a/src/core/time.jl b/src/core/time.jl index 9312775d8..6689a441c 100644 --- a/src/core/time.jl +++ b/src/core/time.jl @@ -24,7 +24,7 @@ end """ is_time(ts::AbstractTimestep, t::Int) - [DEPRECATED FUNCTION] Return true or false, true if the current time (year) for `ts` is `t` +Deprecated fucntion to return true or false, true if the current time (year) for `ts` is `t` """ function is_time(ts::AbstractTimestep, t::Int) error("`is_time(ts, t)` is deprecated. Use comparison operators with TimestepValue objects instead: `ts == TimestepValue(t)` \n$(stacktrace())", :is_time) @@ -43,7 +43,7 @@ end """ is_timestep(ts::AbstractTimestep, t::Int) -[DEPRECATED FUNCTION] Return true or false, true if `ts` timestep is step `t`. +Deprecated function to return true or false, true if `ts` timestep is step `t`. """ function is_timestep(ts::AbstractTimestep, t::Int) error("`is_timestep(ts, t)` is deprecated. Use comparison operators with TimestepIndex objects instead: `ts == TimestepIndex(t)` \n$(stacktrace())", :is_timestep) diff --git a/test/test_replace_comp.jl b/test/test_replace_comp.jl index 6b3e49658..978098e8e 100644 --- a/test/test_replace_comp.jl +++ b/test/test_replace_comp.jl @@ -47,9 +47,7 @@ m = Model() set_dimension!(m, :time, 2000:2005) add_comp!(m, X) # Original component X set_param!(m, :X, :x, zeros(6)) -# The following `replace_comp!` function name will be deprecated in v1.0.0. -# This one remains to test the preserved version with warning for v0.10.0. -replace_comp!(m, X_repl, :X) # Replace X with X_repl +replace!(m, :X => X_repl) # Replace X with X_repl run(m) @test length(components(m)) == 1 # Only one component exists in the model @test m[:X, :y] == 2 * ones(6) # Successfully ran the run_timestep function from X_repl @@ -66,7 +64,7 @@ connect_param!(m, :second => :x, :first => :y) # Make an internal c # The following `replace_comp!` function name will be deprecated in v1.0.0. # This one remains to test the preserved version with warning for v0.10.0. # Every other use in this test file has been switched to `replace!` instead. -replace_comp!(m, bad1.comp_id, :second, reconnect = false) # Can replace without reconnecting +replace!(m, :second => bad1, reconnect = false) # Can replace without reconnecting second = compdef(m, :second) @test second.comp_id.comp_name == :bad1 # Successfully replaced diff --git a/test/test_tmp.jl b/test/test_tmp.jl deleted file mode 100644 index 7bc25a9d6..000000000 --- a/test/test_tmp.jl +++ /dev/null @@ -1,44 +0,0 @@ -module Tmp - -using Test -using Mimi -import Mimi: - compdefs, compdef, external_param_conns - -@defcomp X begin - x = Parameter(index = [time]) - y = Variable(index = [time]) - function run_timestep(p, v, d, t) - v.y[t] = 1 - end -end - -@defcomp X_repl begin - x = Parameter(index = [time]) - y = Variable(index = [time]) - function run_timestep(p, v, d, t) - v.y[t] = 2 - end -end - -m = Model() -set_dimension!(m, :time, 2000:2005) -add_comp!(m, X, exports=[:x => :z]) # Original component X -add_comp!(m, X_repl) -set_param!(m, :X, :x, zeros(6)) - -if false - run(m) - @test m[:X, :y] == ones(6) - - replace_comp!(m, X_repl, :X) - run(m) - - @test length(components(m)) == 1 # Only one component exists in the model - @test m[:X, :y] == 2 * ones(6) # Successfully ran the run_timestep function from X_repl -end - -end # module - -using Mimi -m = Tmp.m From ac78518e97e21dc6034a4faaf4ac221338b6d85e Mon Sep 17 00:00:00 2001 From: Cora Kingdon Date: Mon, 6 Jul 2020 11:29:27 -0400 Subject: [PATCH 10/13] fix some typos; remove some old lines --- docs/src/tutorials/tutorial_3.md | 2 +- src/core/model.jl | 7 +++---- src/core/time_arrays.jl | 2 +- test/test_replace_comp.jl | 3 --- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/src/tutorials/tutorial_3.md b/docs/src/tutorials/tutorial_3.md index 97086dd2a..18d832de0 100644 --- a/docs/src/tutorials/tutorial_3.md +++ b/docs/src/tutorials/tutorial_3.md @@ -130,7 +130,7 @@ Note that here we use the `update_timesteps` flag and set it to `true`, because ## Component and Structural Modifications: The API -Most model modifications will include not only parametric updates, but also strutural changes and component modification, addition, replacement, and deletion along with the required re-wiring of parameters etc. The most useful functions of the common API, in these cases are likely **[`replace!!`](@ref), [`add_comp!`](@ref)** along with **`Mimi.delete!`** and the requisite functions for parameter setting and connecting. For detail on the public API functions look at the API reference. +Most model modifications will include not only parametric updates, but also structural changes and component modification, addition, replacement, and deletion along with the required re-wiring of parameters etc. The most useful functions of the common API, in these cases are likely **[`replace!`](@ref), [`add_comp!`](@ref)** along with **`delete!`** and the requisite functions for parameter setting and connecting. For detail on the public API functions look at the API reference. If you wish to modify the component structure we recommend you also look into the **built-in helper components `adder`, `ConnectorCompVector`, and `ConnectorCompMatrix`** in the `src/components` folder, as these can prove quite useful. diff --git a/src/core/model.jl b/src/core/model.jl index 520546735..c15af4f2a 100644 --- a/src/core/model.jl +++ b/src/core/model.jl @@ -154,6 +154,7 @@ function add_comp!(m::Model, comp_def::AbstractComponentDef, comp_name::Symbol=c return add_comp!(m, comp_def.comp_id, comp_name; kwargs...) end +# DEPRECATION - EVENTUALLY REMOVE """ replace_comp!( m::Model, comp_id::ComponentId, comp_name::Symbol=comp_id.comp_name; @@ -174,9 +175,9 @@ function replace_comp!(m::Model, comp_id::ComponentId, comp_name::Symbol=comp_id st = _get_stacktrace_string() full_msg = string(msg, " \n", st) error(full_msg) - return replace!(m, comp_name => compdef(comp_id); kwargs...) end +# DEPRECATION - EVENTUALLY REMOVE """ replace_comp!( m::Model, comp_def::ComponentDef, comp_name::Symbol=comp_id.comp_name; @@ -197,7 +198,6 @@ function replace_comp!(m::Model, comp_def::ComponentDef, comp_name::Symbol=comp_ st = _get_stacktrace_string() full_msg = string(msg, " \n", st) error(full_msg) - return replace!(m, comp_name => comp_def; kwargs...) end """ @@ -279,9 +279,8 @@ dim_names(mm::MarginalModel, comp_name::Symbol, datum_name::Symbol) = dim_names( # DEPRECATION - EVENTUALLY REMOVE function Base.getproperty(base::MarginalModel, s::Symbol) if (s == :marginal) - error("Use of 'MarginalModel.marginal' is deprecated in favor of 'MarginalModel.modified'"); + error("Use of `MarginalModel.marginal` is deprecated in favor of `MarginalModel.modified`.") end - return getfield(base, s); end """ diff --git a/src/core/time_arrays.jl b/src/core/time_arrays.jl index 92dfa50a0..9e611924e 100644 --- a/src/core/time_arrays.jl +++ b/src/core/time_arrays.jl @@ -83,7 +83,7 @@ end # DEPRECATION - EVENTUALLY REMOVE # Helper function for setindex; throws an error if one indexes into a TimestepArray with an integer function _throw_int_setindex_error() - msg = "Indexing with setindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndec(2)]" + msg = "Indexing with setindex into a TimestepArray with Integer(s) is deprecated, please index with a TimestepIndex(index::Int) instead ie. instead of t[2] use t[TimestepIndex(2)]" st = _get_stacktrace_string() full_msg = string(msg, " \n", st) error(full_msg) diff --git a/test/test_replace_comp.jl b/test/test_replace_comp.jl index 978098e8e..4badbede9 100644 --- a/test/test_replace_comp.jl +++ b/test/test_replace_comp.jl @@ -61,9 +61,6 @@ add_comp!(m, X, :first) # Add two components add_comp!(m, X, :second) connect_param!(m, :second => :x, :first => :y) # Make an internal connection with a parameter with a time dimension @test_throws ErrorException replace!(m, :second => bad1) # Cannot make reconnections because :x in bad1 has different dimensions -# The following `replace_comp!` function name will be deprecated in v1.0.0. -# This one remains to test the preserved version with warning for v0.10.0. -# Every other use in this test file has been switched to `replace!` instead. replace!(m, :second => bad1, reconnect = false) # Can replace without reconnecting second = compdef(m, :second) @test second.comp_id.comp_name == :bad1 # Successfully replaced From 62675b810936788912274e04d80c24d773f0655b Mon Sep 17 00:00:00 2001 From: lrennels Date: Mon, 6 Jul 2020 09:59:51 -0700 Subject: [PATCH 11/13] Move getproperty fcn to proper file --- src/core/model.jl | 7 ------- src/core/types/model.jl | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/model.jl b/src/core/model.jl index c15af4f2a..1b9359fb8 100644 --- a/src/core/model.jl +++ b/src/core/model.jl @@ -276,13 +276,6 @@ dim_names(mm::MarginalModel, comp_name::Symbol, datum_name::Symbol) = dim_names( # Allow access of the form my_model[:grosseconomy, :tfp] @delegate Base.getindex(m::Model, comp_name::Symbol, datum_name::Symbol) => mi -# DEPRECATION - EVENTUALLY REMOVE -function Base.getproperty(base::MarginalModel, s::Symbol) - if (s == :marginal) - error("Use of `MarginalModel.marginal` is deprecated in favor of `MarginalModel.modified`.") - end -end - """ dim_count(m::Model, dim_name::Symbol) diff --git a/src/core/types/model.jl b/src/core/types/model.jl index b2d79101f..c8c76fbda 100644 --- a/src/core/types/model.jl +++ b/src/core/types/model.jl @@ -45,3 +45,10 @@ end function Base.getindex(mm::MarginalModel, comp_name::Symbol, name::Symbol) return (mm.modified[comp_name, name] .- mm.base[comp_name, name]) ./ mm.delta end + +# DEPRECATION - EVENTUALLY REMOVE +function Base.getproperty(base::MarginalModel, s::Symbol) + if (s == :marginal) + error("Use of `MarginalModel.marginal` is deprecated in favor of `MarginalModel.modified`.") + end +end From 5f9d9498663cc45f003f3d357eefd38231b200b7 Mon Sep 17 00:00:00 2001 From: lrennels Date: Mon, 6 Jul 2020 10:33:25 -0700 Subject: [PATCH 12/13] FIx marginal model bug --- src/core/types/model.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/types/model.jl b/src/core/types/model.jl index c8c76fbda..953513308 100644 --- a/src/core/types/model.jl +++ b/src/core/types/model.jl @@ -46,9 +46,10 @@ function Base.getindex(mm::MarginalModel, comp_name::Symbol, name::Symbol) return (mm.modified[comp_name, name] .- mm.base[comp_name, name]) ./ mm.delta end -# DEPRECATION - EVENTUALLY REMOVE +# DEPRECATION - EVENTUALLY REMOVE (and go back to default getproperty behavior) function Base.getproperty(base::MarginalModel, s::Symbol) if (s == :marginal) error("Use of `MarginalModel.marginal` is deprecated in favor of `MarginalModel.modified`.") end + return getfield(base, s); end From 798f3b1946c82f1e18d055e38a0d0b1e83828246 Mon Sep 17 00:00:00 2001 From: Cora Kingdon Date: Tue, 7 Jul 2020 19:28:18 -0400 Subject: [PATCH 13/13] add tests with `@test_throws` for deprecated functions --- test/test_marginal_models.jl | 1 + test/test_replace_comp.jl | 4 +++- test/test_timesteparrays.jl | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test/test_marginal_models.jl b/test/test_marginal_models.jl index d3c6b2655..0d9d423e7 100644 --- a/test/test_marginal_models.jl +++ b/test/test_marginal_models.jl @@ -32,6 +32,7 @@ for i in collect(1:10) end mm2 = create_marginal_model(model1, 0.5) +@test_throws ErrorException mm2_modified = mm2.marginal # test that trying to access by the old field name, "marginal", now errors mm2_modified = mm2.modified update_param!(mm2_modified, :parA, x2) diff --git a/test/test_replace_comp.jl b/test/test_replace_comp.jl index 4badbede9..7e967ea8e 100644 --- a/test/test_replace_comp.jl +++ b/test/test_replace_comp.jl @@ -47,7 +47,8 @@ m = Model() set_dimension!(m, :time, 2000:2005) add_comp!(m, X) # Original component X set_param!(m, :X, :x, zeros(6)) -replace!(m, :X => X_repl) # Replace X with X_repl +@test_throws ErrorException replace_comp!(m, X_repl, :X) # test that the old function name now errors +replace!(m, :X => X_repl) # Replace X with X_repl run(m) @test length(components(m)) == 1 # Only one component exists in the model @test m[:X, :y] == 2 * ones(6) # Successfully ran the run_timestep function from X_repl @@ -61,6 +62,7 @@ add_comp!(m, X, :first) # Add two components add_comp!(m, X, :second) connect_param!(m, :second => :x, :first => :y) # Make an internal connection with a parameter with a time dimension @test_throws ErrorException replace!(m, :second => bad1) # Cannot make reconnections because :x in bad1 has different dimensions +@test_throws ErrorException replace_comp!(m, bad1.comp_id, :second, reconnect = false) # Test that the old function name now errors replace!(m, :second => bad1, reconnect = false) # Can replace without reconnecting second = compdef(m, :second) @test second.comp_id.comp_name == :bad1 # Successfully replaced diff --git a/test/test_timesteparrays.jl b/test/test_timesteparrays.jl index 80cebc70b..c620f9da7 100644 --- a/test/test_timesteparrays.jl +++ b/test/test_timesteparrays.jl @@ -97,6 +97,10 @@ x[t3] = temp_dim_val[1] @test x[t3] == temp_dim_val[1] reset_time_val(x, time_dim_val) +# Deprecated int indexing now errors +@test_throws ErrorException x[3] == time_dim_val[3] +@test_throws ErrorException x[3] = temp_dim_val[3] + #------------------------------------------------------------------------------ # 2. Test TimestepVector - Variable Timestep #------------------------------------------------------------------------------