Skip to content

Commit 79d0b9f

Browse files
authored
Merge pull request #724 from mimiframework/docs
Documentation
2 parents 74631a6 + 6533c26 commit 79d0b9f

File tree

8 files changed

+345
-168
lines changed

8 files changed

+345
-168
lines changed

docs/src/howto/howto_1.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,11 @@ set_dimension!(m, :regions, ["USA", "EU", "LATAM"])
6767
The next step is to add components to the model. This is done by the following syntax:
6868

6969
```julia
70+
add_comp!(m, ComponentA)
7071
add_comp!(m, ComponentA, :GDP)
71-
add_comp!(m, ComponentB; first=2010)
72-
add_comp!(m, ComponentC; first=2010, last=2100)
7372
```
7473

75-
The first argument to `add_comp!` is the model, the second is the name of the ComponentId defined by `@defcomp`. If an optional third symbol is provided (as in the first line above), this will be used as the name of the component in this model. This allows you to add multiple versions of the same component to a model, with different names.
74+
The first argument to `add_comp!` is the model, the second is the name of the ComponentId defined by `@defcomp`. If an optional third symbol is provided (as in the second line above), this will be used as the name of the component in this model. This allows you to add multiple versions of the same component to a model, with different names.
7675

7776
The next step is to set the values for all the parameters in the components. Parameters can either have their values assigned from external data, or they can internally connect to the values from variables in other components of the model.
7877

docs/src/howto/howto_3.md

Lines changed: 140 additions & 120 deletions
Large diffs are not rendered by default.

docs/src/howto/howto_5.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
The release of Mimi v0.5.0 is a breaking release, necessitating the adaptation of existing models' syntax and structure in order for those models to run on this new version. This guide provides an overview of the steps required to get most models using the v0.4.0 API working with v0.5.0. It is **not** a comprehensive review of all changes and new functionalities, but a guide to the minimum steps required to port old models between versions. For complete information on the new version and its functionalities, see the full documentation.
44

5-
This guide is organized into six main sections, each descripting an independent set of changes that can be undertaken in any order desired. For clarity, these sections echo the organization of the `userguide`.
5+
This guide is organized into six main sections, each descripting an independent set of changes that can be undertaken in any order desired.
66

77
1) Defining components
88
2) Constructing a model

docs/src/howto/howto_6.md

Lines changed: 194 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,209 @@
1-
# How-to Guide 6: Port to Mimi v1.0.0
1+
# How-to Guide 6: Port from (>=) Mimi v0.5.0 to Mimi v1.0.0
22

3-
The release of Mimi v1.0.0 is a breaking release, necessitating the adaptation of existing models' syntax and structure in order for those models to run on this new version. This guide provides an overview of the steps required to get most models using the v0.9.5 API working with v1.0.0. It is **not** a comprehensive review of all changes and new functionalities, but a guide to the minimum steps required to port old models between versions. For complete information on the new version and its functionalities, see the full documentation.
3+
The release of Mimi v1.0.0 is a breaking release, necessitating the adaptation of existing models' syntax and structure in order for those models to run on this new version. We have worked hard to keep these changes clear and as minimal as possible.
44

5-
To port your model, we recommend you update to **Mimi v0.10.0**, which is identical to Mimi v1.0.0 **except** that it includes deprecation warnings for (most) breaking changes, instead of errors. This means that models written using Mimi v0.9.5 will, in most cases, run successfully under Mimi v0.10.0 although things that will cause errors in v1.0.0 will throw deprecation warnings. Thus a good workflow would be:
5+
This guide provides an overview of the steps required to get most models using the v0.9.5 API working with v1.0.0. It is **not** a comprehensive review of all changes and new functionalities, but a guide to the minimum steps required to port old models between versions. For complete information on the new version and its additional functionalities, see the full documentation.
66

7-
1) update to Mimi v0.10.0
8-
2) read through this guide to get a sense for what has changed
9-
3) run your code and incrementally update it, using the deprecation warnings as guides and the instructions in this guide as explanations, until no warnings are thrown
10-
4) double check for any of the cases in this guide
11-
5) update to Mimi v1.0.0 and run your model!
7+
To port your model, we recommend you update to **Mimi v0.10.0**, which is identical to Mimi v1.0.0 **except** that it includes deprecation warnings for most breaking changes, instead of errors. This means that models written using Mimi v0.9.5 will, in most cases, run successfully under Mimi v0.10.0 and things that will cause errors in v1.0.0 will throw deprecation warnings. your changes. These can guide Thus a good workflow would be:
128

13-
This guide is organized into five main sections, each descripting an independent set of changes that can be undertaken in any order desired.
9+
1) Update your environment to use Mimi v0.10.0 with
10+
```julia
11+
pkg> add Mimi#v0.10.0
12+
```
13+
2) Read through this guide to get a sense for what has changed
14+
3) Run your code and incrementally update it, using the deprecation warnings as guides for what to change and the instructions in this guide as explanations, until no warnings are thrown and you have changed anything relevant to your code that is explained in this gude.
15+
5) Update to Mimi v1.0.0 with the following code, which will update Mimi to it's latest version, v1.0.0
16+
```julia
17+
pkg> free Mimi
18+
```
19+
6) Run your model! Things should run smoothly now. If not double check the guide, and feel free to reach out on the forum with any questions. Also, if you are curious about the reasons behind a change, just ask!
1420

15-
1) Syntax within @defcomp
16-
2) The set_param! function
17-
3) Different-length components
18-
4) Simulation syntax
19-
5) Composite components (this should probably have it's own guide, but should get a brief mention here)
21+
This guide is organized into a few main sections, each descripting an independent set of changes that can be undertaken in any order desired.
2022

21-
## Syntax within @defcomp
23+
- Syntax Within the @defcomp Macro
24+
- The set_param! Function
25+
- The replace_comp! Function
26+
- Different-length Components
27+
- Marginal Models
28+
- Simulation Syntax
29+
- Composite Components (optional)
2230

23-
- Parameter data type specification
24-
- no more integer indexing (use TimetsepIndex(2) or TimestepValue(1990) instead, available comparison functions, d.time returns AbstractTimesteps)
31+
## Syntax Within the @defcomp Macro
2532

26-
## The set_param! function
33+
#### Type-parameterization for Parameters
2734

28-
- explain new function (now has five arguments)
29-
- explain the shortcuts
30-
- explain when it errors
35+
*The Mimi Change:*
36+
To be consistent with julia syntax, Mimi now uses bracketing syntax to type-parameterize `Parameter`s inside the `@defcomp` macro instead of double-colon syntax. h
3137

32-
## Different-length components
33-
(either the functionality will be gone, or implemented differently)
38+
*The User Change:*
39+
Where you previously indicated that the parameter `a` should be an `Int` with
40+
```julia
41+
@defcomp my_comp begin
42+
a::Int = Parameter()
43+
function run_timestep(p, v, d, t)
44+
end
45+
end
46+
```
47+
you should now use
48+
```julia
49+
@defcomp my_comp begin
50+
a = Parameter{Int}()
51+
function run_timestep(p, v, d, t)
52+
end
53+
end
54+
```
3455

35-
## Changes to simulation syntax
56+
#### Integer Indexing
3657

37-
- Delete getindex (with square bracket shortcut) for getting values from a simulation instance; use getdataframe instead
38-
- rename some functions without camelCase
58+
*The Mimi Change:*
59+
For safety, Mimi no longer allows indexing into `Parameter`s or `Varaible`s with the `run_timestep` function of the `@defcomp` macro with integers. Instead, this functionality is supported with two new types: `TimestepIndex` and `TimestepValue`. Complete details on indexing options can be found in How-to Guide 4: Work with Timesteps, Parameters, and Variables, but below we will describe the minimum steps to get your models working.
3960

40-
## Integer indexing
41-
- cannot index with integers
42-
- removed `is_time` and `is_timestep`
61+
*The User Change:*
62+
Where you previously used integers to index into a `Parameter` or `Variable`, you should now use the `TimestepIndex` type. For example, the code
63+
```julia
64+
function run_timestep(p, v, d, t)
65+
v.my_var[t] = p.my_param[10]
66+
end
67+
```
68+
should now read
69+
```julia
70+
function run_timestep(p, v, d, t)
71+
v.my_var[t] = p.my_param[TimestepIndex(10)]
72+
end
73+
```
74+
Also, if you previously used logic to determine which integer index pertained to a specific year, and then used that integer for indexing, you should now use the `TimestepValue` type. For example, if you previously knew that the index 2 referred to the year 2012, and added that value to a parameter with
75+
```julia
76+
function run_timestep(p, v, d, t)
77+
v.my_var[t] = p.my_param[t] + p.my_other_param[2]
78+
end
79+
```
80+
you should now use
81+
```julia
82+
function run_timestep(p, v, d, t)
83+
v.my_var[t] = p.my_param[t] + p.my_other_param[TimestepValue(2012)]
84+
end
85+
```
4386

44-
## Composite components
87+
#### is_timestep and is_time
4588

46-
This should also have it's own comprehensive guide, but should get a brief description here.
89+
*The Mimi Change:*
90+
For simplicity and consistency with the change above, Mimi no longer supports the `is_timestep` or `is_time` functions and has replaced this functionality with comparison operators combined with the afformentioned `TimestepValue` and `TimestepIndex` types.
91+
92+
*The User Change:*
93+
Any instance of the `is_timestep` function should be replaced with simple comparison with a `TimestepIndex` object ie. replace the logic `if is_timestep(t, 10) ...` with `if t == TimestepIndex(10) ...`.
94+
95+
Any instance of the `is_time` function should be repalced with simple comparison with a `TimestepValue` object ie. replace the logic `if is_time(t, 2010) ...` with `if t == TimestepValue(2010) ...`.
96+
97+
## The set_param! Function
98+
99+
*The Mimi Change:*
100+
The `set_param!` method for setting a parameter value in a component now has the following signature:
101+
```
102+
set_param!(m::Model, comp_name::Symbol, param_name::Symbol, ext_param_name::Symbol, val::Any)
103+
```
104+
This function creates an external parameter called `ext_param_name` with value `val` in the model `m`'s list of external parameters, and connects the parameter `param_name` in component `comp_name` to this newly created external parameter. If there is already a parameter called `ext_param_name` in the model's list of external parameters, it errors.
105+
106+
There are two available shortcuts:
107+
```
108+
# Shortcut 1
109+
set_param!(m::Model, param_name::Symbol, val::Any)
110+
```
111+
This method creates an external parameter in the model called `param_name`, sets its value to `val`, looks at all the components in the model `m`, finds all the unbound parameters named `param_name`, and creates connections from all the unbound parameters that are named `param_name` to the newly created external parameter. If there is already a parameter called `param_name` in the external parameter list, it errors.
112+
113+
```
114+
# Shortcut 2
115+
set_param!(m::Model, comp_name::Symbol, param_name::Symbol, val::Any)
116+
```
117+
This method creates a new external parameter called `param_name` in the model `m` (if that already exists, it errors), sets its value to `val`, and then connects the parameter `param_name` in component `comp_name` to this newly created external parameter.
118+
119+
*The User Change:*
120+
Any old code that uses the `set_param!` method with only 4 arguments (shortcut #2 shown above) will still work for setting parameters **if they are found in only one component** ... but if you have multiple components that have parameters with the same name, using the old 4-argument version of `set_param!` multiple times will cause an error. Instead, you need to determine what behavior you want across multiple components with parameters of the same name:
121+
- If you want parameters with the same name that are found in multiple components to have the _same_ value, use the 3-argument method: `set_param!(m, :param_name, val)`. You only have to call this once and it will set the same value for all components with an unconnected parameter called `param_name`.
122+
- If you want different components that have parameters with the same name to have _different_ values, then you need to call the 5-argument version of `set_param!` individually for each parameter value, such as:
123+
```
124+
set_param!(m, :comp1, :foo, :foo1, 25) # creates an external parameter called :foo1 with value 25, and connects just comp1/foo to that value
125+
set_param!(m, :comp2, :foo, :foo2, 30) # creates an external parameter called :foo2 with value 30, and connects just comp2/foo to that value
126+
```
127+
128+
Also, you can no longer call `set_param!` to change the value of a parameter that has already been set in the model. If the parameter has already been set, you must use the following to change it:
129+
```
130+
update_param!(m, ext_param_name, new_val)
131+
```
132+
This updates the value of the external parameter called `ext_param_name` in the model `m`'s list of external parameters. Any component that have parameters connected to this external parameter will now be connected to this new value.
133+
134+
## The replace_comp! Function
135+
136+
*The Mimi Change:*
137+
For simplicity, the `replace_comp!` function has been replaced with a method augmenting the julia Base `replace!` function.
138+
139+
*The User Change:*
140+
Where you previously used
141+
```julia
142+
replace_comp!(m, new, old)
143+
```
144+
to replace the `old` component with `new`, they should now use
145+
```julia
146+
replace!(m, old => new)
147+
```
148+
149+
## Different-length Components
150+
151+
*The Mimi Change:*
152+
Through Mimi v0.9.4, the optional keyword arguments `first` and `last` could be used to specify times for components that do not run for the full length of the model, like this: `add_comp!(mymodel, ComponentC; first=2010, last=2100)`. This functionality is still disabled, as it was starting in v0.9.5, and all components must run for the full length of the model's time dimension. This functionality may be re-implemented in a later version of Mimi.
153+
154+
*The User Change:*
155+
Refactor your model so that all components are the same length. You may use the `run_timestep` function within each component to dictate it's behavior in different timesteps, including doing no calculations for a portion of the full model runtime.
156+
157+
## Marginal Models
158+
159+
*The Mimi Change:*
160+
For clarity, the previously named `marginal` attribute of a Mimi `MarginalModel` has been renamed to `modified`. Hence a `MarginalModel` is now described as a Mimi `Model` whose results are obtained by subtracting results of one `base` Model from those of another `marginal` Model that has a difference of `delta` with the signature:
161+
162+
*The User Change:*
163+
Any previous access to the `marginal` attribute of a `MarginalModel`, `mm` below, should be changed from
164+
```julia
165+
model = mm.marginal
166+
```
167+
to
168+
```julia
169+
model = mm.modified
170+
```
171+
## Simulation Syntax
172+
173+
#### Results Access
174+
175+
*The Mimi Change:*
176+
For clarity of return types, Mimi no longer supports use of square brackets (a shortcut for julia Base `getindex`) to access the results of a Monte Carlo analysis, which are stored in the `SimulationInstance`. Instead, access to resulst is supported with the `getdataframe` function, which will return the results in the same type and format as the square bracket method used to return.
177+
178+
*The User Change:*
179+
Results previously obtained with
180+
```julia
181+
results = si[:grosseconomy, :K]
182+
```
183+
should now be obtained with
184+
```julia
185+
results = getdataframe(si, :grosseconomy, :K)
186+
```
187+
#### Simulation Definition Modification Functions
188+
189+
*The Mimi Change:*
190+
For consistency with julia syntax rules, the small set of unexported functions available to modify an existing `SimulationDefinition` have been renamed, moving from a camel case format to an underscore-based format as follows.
191+
192+
*The User Change:*
193+
Replace your functions as follows.
194+
195+
- `deleteRV!` --> `delete_RV!`
196+
- `addRV!` --> `add_RV!`
197+
- `replaceRV!` --> `replace_RV!`
198+
- `deleteTransform!` --> `delete_transform!`
199+
- `addTransform!` --> `add_transform!`
200+
- `deleteSave!` --> `delete_save!`
201+
- `addSave!` --> `add_save!`
202+
203+
## Composite Components (optional)
204+
205+
*The Mimi Change:*
206+
The biggest functionality **addition** of Mimi v1.0.0 is the inclusion of composite components. Prior versions of Mimi supported only "flat" models, i.e., with one level of components. This new version supports mulitple layers of components, with some components being "final" or leaf components, and others being "composite" components which themselves contain other leaf or composite components. This approach allows for a cleaner organization of complex models, and allows the construction of building blocks that can be re-used in multiple models.
207+
208+
*The User Change:*
209+
All previous models are considered "flat" models, i.e. they have only one level of components, and do **not** need to be converted into multiple layer models to run. Thus this addition does not mean users need to alter their models, but we encourage you to check out the other documentation on composite components to learn how you can enhance your current models and built better onces in the future!

docs/src/howto/howto_main.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ If you find a bug in these guides, or have a clarifying question or suggestion,
3333

3434
6. **Port to Mimi v1.0.0**
3535

36-
[How-to Guide 6: Port to Mimi v1.0.0](@ref)
37-
36+
[How-to Guide 6: Port from (>=) Mimi v0.5.0 to Mimi v1.0.0](@ref)

docs/src/ref/ref_structures_1_overview.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@ For example, in Mimi, `ModelDef` is a subclass of `CompositeComponentDef`, which
2323

2424
## Core types
2525

26-
These are defined in `types/core.jl`.
26+
Several core types are defined in `types/core.jl`, including the two primary abstract types, `MimiStruct` and `MimiClass`.
2727

28-
1. `MimiStruct` and `MimiClass`
29-
30-
All structs and classes in Mimi are derived from these abstract types, which allows us to identify Mimi-defined items when writing `show()` methods.
28+
All structs and classes in Mimi are derived from these abstract types, which allows us to identify Mimi-defined items when writing `show()` methods. Important structs and classes include:
3129

3230
1. `ComponentId`
3331

@@ -41,7 +39,7 @@ All structs and classes in Mimi are derived from these abstract types, which all
4139
end
4240
```
4341

44-
1. `ComponentPath`
42+
2. `ComponentPath`
4543

4644
A `ComponentPath` identifies the path from one or more composites to any component, using an `NTuple` of symbols. Since component names are unique at the composite level, the sequence of names through a component hierarchy uniquely identifies a component in that hierarchy.
4745

docs/src/ref/ref_structures_3_instances.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,8 @@ Note: in the `ComponentInstanceParameters`, the values stored in the named tuple
4040

4141
## User-facing Classes
4242

43-
1. `Model`
43+
1. `Model`: The `Model` class contains the `ModelDef`, and after the `build()` function is called, a `ModelInstance` that can be run. The API for `Model` delegates many calls to either its top-level `ModeDef` or `ModelInstance`, while providing additional functionality including running a Monte Carlo simulation.
4444

45-
The `Model` class contains the `ModelDef`, and after the `build()` function is called, a `ModelInstance` that can be run. The API for `Model` delegates many calls to either its top-level `ModeDef` or `ModelInstance`, while providing additional functionality including running a Monte Carlo simulation.
45+
2. `ComponentReference`
4646

47-
1. `ComponentReference`
48-
49-
1. `VariableReference`
47+
3. `VariableReference`

src/core/types/model.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ end
3030
MarginalModel
3131
3232
A Mimi `Model` whose results are obtained by subtracting results of one `base` Model
33-
from those of another `marginal` Model` that has a difference of `delta`.
33+
from those of another `marginal` Model that has a difference of `delta`.
3434
"""
3535
struct MarginalModel <: AbstractModel
3636
base::Model

0 commit comments

Comments
 (0)