fmdtools 2.0.3__tar.gz → 2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fmdtools-2.0.3 → fmdtools-2.0.4}/LICENSE +1 -1
- {fmdtools-2.0.3/fmdtools.egg-info → fmdtools-2.0.4}/PKG-INFO +33 -18
- {fmdtools-2.0.3 → fmdtools-2.0.4}/README.md +30 -15
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/ex_pump.py +4 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/__init__.py +1 -1
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/graph/base.py +1 -1
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/graph/model.py +39 -5
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/graph/style.py +22 -4
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/base.py +31 -1
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/block/base.py +25 -24
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/parameter.py +3 -2
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/object/base.py +37 -10
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/sim/propagate.py +10 -8
- {fmdtools-2.0.3 → fmdtools-2.0.4/fmdtools.egg-info}/PKG-INFO +33 -18
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools.egg-info/requires.txt +1 -1
- {fmdtools-2.0.3 → fmdtools-2.0.4}/pyproject.toml +22 -2
- {fmdtools-2.0.3 → fmdtools-2.0.4}/tests/test_graph.py +1 -1
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/asg_demo/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/asg_demo/demo_model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/eps/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/eps/eps.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/eps/test_eps.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multiflow_demo/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multiflow_demo/multiflow_demo.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multiflow_demo/test_multiflow.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/drone_mdl_dynamic.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/drone_mdl_hierarchical.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/drone_mdl_rural.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/drone_mdl_static.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/drone_mdl_urban.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/opt_drone_rural.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/multirotor/test_multirotor.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/jointfaults_ex.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/parallelism_methods.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/pump_indiv.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/pump_stochastic.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/test_pump.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/test_pump_example.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/pump/test_pump_stochastic.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/opt_rover.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/optimization/ea_analysis.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/optimization/search_rover.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/optimization/untitled2.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/rover_degradation.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/rover_mode_space.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/rover_model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/rover_model_human.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/rover/test_rover.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/tank/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/tank/tank_model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/tank/tank_optimization_model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/tank/test_tank.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/ATC.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/asset.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/common.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/test_asset.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/examples/taxiway/test_model.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/common.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/history.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/phases.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/result.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/analyze/tabulate.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/action.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/base.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/component.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/function.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/architecture/geom.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/block/action.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/block/function.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/base.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/mode.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/rand.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/state.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/container/time.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/environment.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/flow/base.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/flow/commsflow.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/flow/multiflow.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/object/coords.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/object/geom.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/define/object/timer.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/sim/sample.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/sim/scenario.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools/sim/search.py +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools.egg-info/SOURCES.txt +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/fmdtools.egg-info/top_level.txt +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/setup.cfg +0 -0
- {fmdtools-2.0.3 → fmdtools-2.0.4}/tests/test_packages.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fmdtools
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: System resilience modelling, simulation, and assessment in Python
|
|
5
5
|
Author: fmdtools Developers
|
|
6
6
|
Maintainer-email: Daniel Hulse <daniel.e.hulse@nasa.gov>
|
|
7
|
-
License: fmdtools version 2.0.
|
|
7
|
+
License: fmdtools version 2.0.4
|
|
8
8
|
---------------------------
|
|
9
9
|
Apache License
|
|
10
10
|
Version 2.0, January 2004
|
|
@@ -251,22 +251,24 @@ Requires-Dist: matplotlib>=3.7.0
|
|
|
251
251
|
Requires-Dist: pandas
|
|
252
252
|
Requires-Dist: ordered-set
|
|
253
253
|
Requires-Dist: dill
|
|
254
|
-
Requires-Dist: recordclass==0.
|
|
254
|
+
Requires-Dist: recordclass==0.22.1
|
|
255
255
|
Requires-Dist: pytest
|
|
256
256
|
Requires-Dist: graphviz
|
|
257
257
|
Requires-Dist: shapely>=2.0
|
|
258
258
|
|
|
259
|
-
[](https://github.com/nasa/fmdtools)
|
|
259
|
+
[](https://github.com/nasa/fmdtools)
|
|
260
260
|
|
|
261
261
|
# Overview
|
|
262
262
|
|
|
263
263
|

|
|
264
264
|
[](https://pypi.org/project/fmdtools/)
|
|
265
|
+
[](https://pepy.tech/project/fmdtools)
|
|
266
|
+
[](https://pepy.tech/project/fmdtools)
|
|
265
267
|
[](https://github.com/nasa/fmdtools/releases)
|
|
266
268
|
[](https://github.com/nasa/fmdtools/tags)
|
|
267
269
|
[](https://www.codefactor.io/repository/github/nasa/fmdtools)
|
|
268
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/junit/report.html)
|
|
269
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/coverage/index.html)
|
|
270
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/full-py311/junit/report.html)
|
|
271
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/full-py311/coverage/index.html)
|
|
270
272
|
[](https://github.com/nasa/fmdtools/blob/main/LICENSE)
|
|
271
273
|
[](https://nodis3.gsfc.nasa.gov/displayDir.cfm?Internal_ID=N_PR_7150_002D_&page_name=AppendixD)
|
|
272
274
|
|
|
@@ -274,21 +276,22 @@ Requires-Dist: shapely>=2.0
|
|
|
274
276
|
|
|
275
277
|
[Click here to view the the full documentation website.](https://nasa.github.io/fmdtools)
|
|
276
278
|
|
|
279
|
+
|
|
277
280
|
## About
|
|
278
281
|
|
|
279
|
-
The fmdtools library provides the computational support needed to perform a simulation-based (rather than document-based) hazard analysis process that [**enables the consideration of systems resilience**](https://nasa.github.io/fmdtools/docs/Development%20Guide.html#why-fmdtools). This means that it can be used to extend the scope of hazard analysis from component faults to the dynamic interactions between the system, operators, and the environment. Some key features include:
|
|
282
|
+
The fmdtools library provides the computational support needed to perform a simulation-based (rather than document-based) hazard analysis process that [**enables the consideration of systems resilience**](https://nasa.github.io/fmdtools/docs-source/Development%20Guide.html#why-fmdtools). This means that it can be used to extend the scope of hazard analysis from component faults to the dynamic interactions between the system, operators, and the environment. Some key features include:
|
|
280
283
|
|
|
281
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/flexible.svg">
|
|
284
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/flexible.svg">
|
|
282
285
|
|
|
283
286
|
### Flexible Modelling Paradigm
|
|
284
287
|
Models in fmdtools use a consistent and composable representation of system structure and behavior. Whether you want to model a simple component, a complex system-of-systems, or both, fmdtools can help.
|
|
285
288
|
|
|
286
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/powerful.svg">
|
|
289
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/powerful.svg">
|
|
287
290
|
|
|
288
291
|
### Powerful Simulation Techniques
|
|
289
292
|
Simulation techniques in fmdtools represent the state-of-the-art in dynamical systems modelling for resilience quantification. With fmdtools, you can simulate the dynamic effects of hazardous scenarios over a wide range of variables to quantify and optimize risk, resilience, and safety metrics.
|
|
290
293
|
|
|
291
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/efficient.svg">
|
|
294
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/efficient.svg">
|
|
292
295
|
|
|
293
296
|
### Efficient Analysis Process
|
|
294
297
|
Readily-deployable analysis methods are built in to fmdtools to enable the rapid and iterative statistical analysis of simulation results. With fmdtools, you can write 2-3 lines of code to visualize model behavior instead of spending hours writing it yourself.
|
|
@@ -297,6 +300,18 @@ Readily-deployable analysis methods are built in to fmdtools to enable the rapid
|
|
|
297
300
|
|
|
298
301
|
## Getting Started
|
|
299
302
|
|
|
303
|
+
### Python version compatibility
|
|
304
|
+
|
|
305
|
+
The fmdtools library is developed in Python 3.11 but tested to maintain compatibility over three versions of Python. See current doctest reports below:
|
|
306
|
+
|
|
307
|
+
| Python Version | Doctests |
|
|
308
|
+
| -------- | ------- |
|
|
309
|
+
| 3.10 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py310/junit/report.html) |
|
|
310
|
+
| 3.11 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py311/junit/report.html) |
|
|
311
|
+
| 3.12 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py312/junit/report.html) |
|
|
312
|
+
|
|
313
|
+
Further (functional and integration) tests are performed in the Python 3.11 to ensure that examples run as desired. Thus, it is generally reccommended to use Python 3.11 to keep pace with development, especially when running examples.
|
|
314
|
+
|
|
300
315
|
### Set up python environment
|
|
301
316
|
|
|
302
317
|
The fmdtools library was developed to run in an anaconda python environment. If you do not have an existing python environment, first [download and install anaconda.](https://docs.anaconda.com/free/anaconda/install/index.html).
|
|
@@ -314,7 +329,7 @@ graphviz
|
|
|
314
329
|
# install from: https://anaconda.org/anaconda/graphviz
|
|
315
330
|
```
|
|
316
331
|
|
|
317
|
-
Note: some versions `fmdtools` dependencies may
|
|
332
|
+
Note: On Windows, some versions `fmdtools` dependencies may require a compiler such as that provided with [Microsoft Studio Build tools](https://visualstudio.microsoft.com/downloads/?q=build+tools) to build, so it (while not required) may be helpful to install it also.
|
|
318
333
|
|
|
319
334
|
|
|
320
335
|
### Install fmdtools
|
|
@@ -340,7 +355,7 @@ This may then be installed using:
|
|
|
340
355
|
Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` you can checkout the tag corresponding to the version you want, e.g.:
|
|
341
356
|
|
|
342
357
|
```
|
|
343
|
-
git checkout v2.0.
|
|
358
|
+
git checkout v2.0.4
|
|
344
359
|
```
|
|
345
360
|
|
|
346
361
|
|
|
@@ -365,7 +380,7 @@ ordered-set
|
|
|
365
380
|
# license: (MIT) https://github.com/rspeer/ordered-set/blob/master/MIT-LICENSE
|
|
366
381
|
dill
|
|
367
382
|
# license: (MIT) https://github.com/uqfoundation/dill/blob/master/LICENSE
|
|
368
|
-
recordclass == 0.
|
|
383
|
+
recordclass == 0.22.1
|
|
369
384
|
# license: (MIT) https://github.com/intellimath/recordclass/blob/main/LICENSE.txt
|
|
370
385
|
pytest
|
|
371
386
|
# license: (MIT) https://docs.pytest.org/en/7.3.x/license.html
|
|
@@ -433,13 +448,13 @@ If a development install has been performed, you can further check aspects of yo
|
|
|
433
448
|
|
|
434
449
|
Once fmdtools is installed, use the following to get acquainted with how to use the library:
|
|
435
450
|
|
|
436
|
-
- Go through the [Intro to fmdtools workshop](https://nasa.github.io/fmdtools/docs/Intro_to_fmdtools.html) to learn about some of the basics of the fmdtools library and work with an existing model.
|
|
451
|
+
- Go through the [Intro to fmdtools workshop](https://nasa.github.io/fmdtools/docs-source/Intro_to_fmdtools.html) to learn about some of the basics of the fmdtools library and work with an existing model.
|
|
437
452
|
|
|
438
453
|
- Explore more [examples](https://nasa.github.io/fmdtools/examples/Examples.html) of particular use-cases by going through the [examples folder](https://github.com/nasa/fmdtools/tree/main/examples)
|
|
439
454
|
|
|
440
|
-
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs/Development%20Guide.html#).
|
|
455
|
+
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/Development%20Guide.html#).
|
|
441
456
|
|
|
442
|
-
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs/fmdtools.html) for syntax and usage documentation.
|
|
457
|
+
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs-source/fmdtools.html) for syntax and usage documentation.
|
|
443
458
|
|
|
444
459
|
## Contributions
|
|
445
460
|
fmdtools is developed primarily by researchers at NASA Ames Research Center. External contributions are welcome under a Contributor License Agreement:
|
|
@@ -478,8 +493,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
478
493
|
author = {{NASA}},
|
|
479
494
|
title = {fmdtools},
|
|
480
495
|
url = {https://github.com/nasa/fmdtools},
|
|
481
|
-
version = {2.0.
|
|
482
|
-
date = {2024-
|
|
496
|
+
version = {2.0.4}, # <- replace with your version number
|
|
497
|
+
date = {2024-10-25},
|
|
483
498
|
}
|
|
484
499
|
```
|
|
485
500
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
[](https://github.com/nasa/fmdtools)
|
|
1
|
+
[](https://github.com/nasa/fmdtools)
|
|
2
2
|
|
|
3
3
|
# Overview
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
[](https://pypi.org/project/fmdtools/)
|
|
7
|
+
[](https://pepy.tech/project/fmdtools)
|
|
8
|
+
[](https://pepy.tech/project/fmdtools)
|
|
7
9
|
[](https://github.com/nasa/fmdtools/releases)
|
|
8
10
|
[](https://github.com/nasa/fmdtools/tags)
|
|
9
11
|
[](https://www.codefactor.io/repository/github/nasa/fmdtools)
|
|
10
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/junit/report.html)
|
|
11
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/coverage/index.html)
|
|
12
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/full-py311/junit/report.html)
|
|
13
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/full-py311/coverage/index.html)
|
|
12
14
|
[](https://github.com/nasa/fmdtools/blob/main/LICENSE)
|
|
13
15
|
[](https://nodis3.gsfc.nasa.gov/displayDir.cfm?Internal_ID=N_PR_7150_002D_&page_name=AppendixD)
|
|
14
16
|
|
|
@@ -16,21 +18,22 @@
|
|
|
16
18
|
|
|
17
19
|
[Click here to view the the full documentation website.](https://nasa.github.io/fmdtools)
|
|
18
20
|
|
|
21
|
+
|
|
19
22
|
## About
|
|
20
23
|
|
|
21
|
-
The fmdtools library provides the computational support needed to perform a simulation-based (rather than document-based) hazard analysis process that [**enables the consideration of systems resilience**](https://nasa.github.io/fmdtools/docs/Development%20Guide.html#why-fmdtools). This means that it can be used to extend the scope of hazard analysis from component faults to the dynamic interactions between the system, operators, and the environment. Some key features include:
|
|
24
|
+
The fmdtools library provides the computational support needed to perform a simulation-based (rather than document-based) hazard analysis process that [**enables the consideration of systems resilience**](https://nasa.github.io/fmdtools/docs-source/Development%20Guide.html#why-fmdtools). This means that it can be used to extend the scope of hazard analysis from component faults to the dynamic interactions between the system, operators, and the environment. Some key features include:
|
|
22
25
|
|
|
23
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/flexible.svg">
|
|
26
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/flexible.svg">
|
|
24
27
|
|
|
25
28
|
### Flexible Modelling Paradigm
|
|
26
29
|
Models in fmdtools use a consistent and composable representation of system structure and behavior. Whether you want to model a simple component, a complex system-of-systems, or both, fmdtools can help.
|
|
27
30
|
|
|
28
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/powerful.svg">
|
|
31
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/powerful.svg">
|
|
29
32
|
|
|
30
33
|
### Powerful Simulation Techniques
|
|
31
34
|
Simulation techniques in fmdtools represent the state-of-the-art in dynamical systems modelling for resilience quantification. With fmdtools, you can simulate the dynamic effects of hazardous scenarios over a wide range of variables to quantify and optimize risk, resilience, and safety metrics.
|
|
32
35
|
|
|
33
|
-
<img align="left" width="100" height="100" src="/docs/figures/powerpoint/efficient.svg">
|
|
36
|
+
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/efficient.svg">
|
|
34
37
|
|
|
35
38
|
### Efficient Analysis Process
|
|
36
39
|
Readily-deployable analysis methods are built in to fmdtools to enable the rapid and iterative statistical analysis of simulation results. With fmdtools, you can write 2-3 lines of code to visualize model behavior instead of spending hours writing it yourself.
|
|
@@ -39,6 +42,18 @@ Readily-deployable analysis methods are built in to fmdtools to enable the rapid
|
|
|
39
42
|
|
|
40
43
|
## Getting Started
|
|
41
44
|
|
|
45
|
+
### Python version compatibility
|
|
46
|
+
|
|
47
|
+
The fmdtools library is developed in Python 3.11 but tested to maintain compatibility over three versions of Python. See current doctest reports below:
|
|
48
|
+
|
|
49
|
+
| Python Version | Doctests |
|
|
50
|
+
| -------- | ------- |
|
|
51
|
+
| 3.10 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py310/junit/report.html) |
|
|
52
|
+
| 3.11 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py311/junit/report.html) |
|
|
53
|
+
| 3.12 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/reports/doctests-py312/junit/report.html) |
|
|
54
|
+
|
|
55
|
+
Further (functional and integration) tests are performed in the Python 3.11 to ensure that examples run as desired. Thus, it is generally reccommended to use Python 3.11 to keep pace with development, especially when running examples.
|
|
56
|
+
|
|
42
57
|
### Set up python environment
|
|
43
58
|
|
|
44
59
|
The fmdtools library was developed to run in an anaconda python environment. If you do not have an existing python environment, first [download and install anaconda.](https://docs.anaconda.com/free/anaconda/install/index.html).
|
|
@@ -56,7 +71,7 @@ graphviz
|
|
|
56
71
|
# install from: https://anaconda.org/anaconda/graphviz
|
|
57
72
|
```
|
|
58
73
|
|
|
59
|
-
Note: some versions `fmdtools` dependencies may
|
|
74
|
+
Note: On Windows, some versions `fmdtools` dependencies may require a compiler such as that provided with [Microsoft Studio Build tools](https://visualstudio.microsoft.com/downloads/?q=build+tools) to build, so it (while not required) may be helpful to install it also.
|
|
60
75
|
|
|
61
76
|
|
|
62
77
|
### Install fmdtools
|
|
@@ -82,7 +97,7 @@ This may then be installed using:
|
|
|
82
97
|
Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` you can checkout the tag corresponding to the version you want, e.g.:
|
|
83
98
|
|
|
84
99
|
```
|
|
85
|
-
git checkout v2.0.
|
|
100
|
+
git checkout v2.0.4
|
|
86
101
|
```
|
|
87
102
|
|
|
88
103
|
|
|
@@ -107,7 +122,7 @@ ordered-set
|
|
|
107
122
|
# license: (MIT) https://github.com/rspeer/ordered-set/blob/master/MIT-LICENSE
|
|
108
123
|
dill
|
|
109
124
|
# license: (MIT) https://github.com/uqfoundation/dill/blob/master/LICENSE
|
|
110
|
-
recordclass == 0.
|
|
125
|
+
recordclass == 0.22.1
|
|
111
126
|
# license: (MIT) https://github.com/intellimath/recordclass/blob/main/LICENSE.txt
|
|
112
127
|
pytest
|
|
113
128
|
# license: (MIT) https://docs.pytest.org/en/7.3.x/license.html
|
|
@@ -175,13 +190,13 @@ If a development install has been performed, you can further check aspects of yo
|
|
|
175
190
|
|
|
176
191
|
Once fmdtools is installed, use the following to get acquainted with how to use the library:
|
|
177
192
|
|
|
178
|
-
- Go through the [Intro to fmdtools workshop](https://nasa.github.io/fmdtools/docs/Intro_to_fmdtools.html) to learn about some of the basics of the fmdtools library and work with an existing model.
|
|
193
|
+
- Go through the [Intro to fmdtools workshop](https://nasa.github.io/fmdtools/docs-source/Intro_to_fmdtools.html) to learn about some of the basics of the fmdtools library and work with an existing model.
|
|
179
194
|
|
|
180
195
|
- Explore more [examples](https://nasa.github.io/fmdtools/examples/Examples.html) of particular use-cases by going through the [examples folder](https://github.com/nasa/fmdtools/tree/main/examples)
|
|
181
196
|
|
|
182
|
-
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs/Development%20Guide.html#).
|
|
197
|
+
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/Development%20Guide.html#).
|
|
183
198
|
|
|
184
|
-
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs/fmdtools.html) for syntax and usage documentation.
|
|
199
|
+
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs-source/fmdtools.html) for syntax and usage documentation.
|
|
185
200
|
|
|
186
201
|
## Contributions
|
|
187
202
|
fmdtools is developed primarily by researchers at NASA Ames Research Center. External contributions are welcome under a Contributor License Agreement:
|
|
@@ -220,8 +235,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
220
235
|
author = {{NASA}},
|
|
221
236
|
title = {fmdtools},
|
|
222
237
|
url = {https://github.com/nasa/fmdtools},
|
|
223
|
-
version = {2.0.
|
|
224
|
-
date = {2024-
|
|
238
|
+
version = {2.0.4}, # <- replace with your version number
|
|
239
|
+
date = {2024-10-25},
|
|
225
240
|
}
|
|
226
241
|
```
|
|
227
242
|
|
|
@@ -672,6 +672,7 @@ if __name__ == "__main__":
|
|
|
672
672
|
Pump().get_vars("flows.ee_1")
|
|
673
673
|
g = Pump().create_graph()
|
|
674
674
|
from fmdtools.analyze.graph.base import Graph
|
|
675
|
+
from fmdtools.define.object.base import ObjectGraph
|
|
675
676
|
# horizontal alignment test:
|
|
676
677
|
g2 = Graph(g)
|
|
677
678
|
g2.set_node_labels(subtext="nodetype", title_style={'horizontalalignment': 'left'},
|
|
@@ -685,3 +686,6 @@ if __name__ == "__main__":
|
|
|
685
686
|
check_model_pickleability(Pump(), try_pick=True)
|
|
686
687
|
import inspect
|
|
687
688
|
source = inspect.getsource(Pump)
|
|
689
|
+
og = ObjectGraph(Pump(), get_source=True)
|
|
690
|
+
og.set_node_labels(title='shortname', title2='classname', subtext='docs')
|
|
691
|
+
og.draw_graphviz()
|
|
@@ -86,7 +86,7 @@ class Graph(object):
|
|
|
86
86
|
>>> graph.set_pos(auto='kamada_kawai')
|
|
87
87
|
>>> fig, ax = graph.draw(saveas=loc+'nx_funcdecomp.svg')
|
|
88
88
|
>>> graph.set_edge_labels(title="name")
|
|
89
|
-
>>> dot = graph.draw_graphviz(saveas=loc+'gv_funcdecomp.svg')
|
|
89
|
+
>>> dot = graph.draw_graphviz(disp=False, saveas=loc+'gv_funcdecomp.svg')
|
|
90
90
|
"""
|
|
91
91
|
|
|
92
92
|
def __init__(self, g, check_info=True):
|
|
@@ -30,7 +30,7 @@ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
|
30
30
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
31
31
|
specific language governing permissions and limitations under the License.
|
|
32
32
|
"""
|
|
33
|
-
from fmdtools.define.base import get_code_attrs, get_obj_name
|
|
33
|
+
from fmdtools.define.base import get_code_attrs, get_obj_name, get_inheritance
|
|
34
34
|
from fmdtools.analyze.graph.base import Graph
|
|
35
35
|
from fmdtools.analyze.graph.label import shorten_name
|
|
36
36
|
from fmdtools.analyze.result import Result
|
|
@@ -58,12 +58,12 @@ def add_node(obj, g=None, name='', classname='', nodetype='', get_attrs=False,
|
|
|
58
58
|
"""
|
|
59
59
|
if not g:
|
|
60
60
|
g = nx.DiGraph()
|
|
61
|
-
if
|
|
62
|
-
name = obj
|
|
61
|
+
if not name:
|
|
62
|
+
name = get_obj_name(obj)
|
|
63
63
|
if not classname:
|
|
64
64
|
classname = obj.__class__.__name__
|
|
65
65
|
if not nodetype:
|
|
66
|
-
if hasattr(obj, 'get_typename'):
|
|
66
|
+
if hasattr(obj, 'get_typename') and not inspect.isclass(obj):
|
|
67
67
|
nodetype = obj.get_typename()
|
|
68
68
|
else:
|
|
69
69
|
nodetype = obj.__class__.__name__
|
|
@@ -103,6 +103,41 @@ def add_edge(g, basename, name, rolename, edgetype):
|
|
|
103
103
|
g.add_edge(basename, name, edgetype=edgetype, role=rolename)
|
|
104
104
|
|
|
105
105
|
|
|
106
|
+
def create_inheritance_subgraph(obj, g=None, name='', end_at_fmdtools=True):
|
|
107
|
+
"""
|
|
108
|
+
Create a graph of the inheritance of a given object from fmdtools classes.
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
obj : Object
|
|
113
|
+
Object.
|
|
114
|
+
g : graph, optional
|
|
115
|
+
Networkx graph to add to. The default is None.
|
|
116
|
+
end_at_fmdtools : bool
|
|
117
|
+
Option to end at first fmdtools node while building the subgraph
|
|
118
|
+
Default is False, which stops the subgraph at the first fmdtools class, rather
|
|
119
|
+
than includeing the fmdtools class inheritance.
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
g : graph
|
|
124
|
+
Networkx graph of inheritance from classes.
|
|
125
|
+
"""
|
|
126
|
+
if not name:
|
|
127
|
+
name = get_obj_name(obj)
|
|
128
|
+
if inspect.isclass(obj):
|
|
129
|
+
nodetype = "class"
|
|
130
|
+
g = add_node(obj, g, name=name, nodetype=nodetype)
|
|
131
|
+
else:
|
|
132
|
+
g = add_node(obj, g, name=name)
|
|
133
|
+
if not (end_at_fmdtools and 'fmdtools.' in name):
|
|
134
|
+
base_classes = get_inheritance(obj)
|
|
135
|
+
for bc in base_classes:
|
|
136
|
+
g = create_inheritance_subgraph(bc, g, end_at_fmdtools=end_at_fmdtools)
|
|
137
|
+
add_edge(g, name, get_obj_name(bc), "base", "inheritance")
|
|
138
|
+
return g
|
|
139
|
+
|
|
140
|
+
|
|
106
141
|
def set_node_states(g, obj, name, time=None):
|
|
107
142
|
"""
|
|
108
143
|
Attach stateful attributes to the given node.
|
|
@@ -155,7 +190,6 @@ def remove_base(g, basename):
|
|
|
155
190
|
g.remove_nodes_from([*nx.isolates(g)])
|
|
156
191
|
|
|
157
192
|
|
|
158
|
-
|
|
159
193
|
class ModelGraph(Graph):
|
|
160
194
|
"""
|
|
161
195
|
Superclass for Graphs meant to represent specific model constructs.
|
|
@@ -87,9 +87,9 @@ def mod_prefix():
|
|
|
87
87
|
import os
|
|
88
88
|
wd = os.getcwd()
|
|
89
89
|
if 'graph' in wd:
|
|
90
|
-
return '../../../docs/figures/frdl/'
|
|
90
|
+
return '../../../docs-source/figures/frdl/'
|
|
91
91
|
else:
|
|
92
|
-
return 'docs/figures/frdl/'
|
|
92
|
+
return 'docs-source/figures/frdl/'
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
class BaseStyle(dataobject, copy_default=True):
|
|
@@ -199,7 +199,7 @@ def save_dot(dot, saveas=''):
|
|
|
199
199
|
"""Save a graphviz diagram."""
|
|
200
200
|
if saveas:
|
|
201
201
|
filecomponents = saveas.split('.')
|
|
202
|
-
dot.render('.'.join(filecomponents[:-1]), format=filecomponents[-1])
|
|
202
|
+
dot.render('.'.join(filecomponents[:-1]), format=filecomponents[-1], view=False)
|
|
203
203
|
|
|
204
204
|
|
|
205
205
|
class FlowEdgeStyle(EdgeStyle):
|
|
@@ -267,6 +267,19 @@ class ConnectionEdgeStyle(EdgeStyle):
|
|
|
267
267
|
gv_style: str = 'dashed'
|
|
268
268
|
|
|
269
269
|
|
|
270
|
+
class InheritanceEdgeStyle(EdgeStyle):
|
|
271
|
+
"""EdgeStyle representing inheritance."""
|
|
272
|
+
|
|
273
|
+
nx_edge_color: str = 'grey'
|
|
274
|
+
nx_style: str = 'solid'
|
|
275
|
+
nx_arrows: bool = True
|
|
276
|
+
nx_arrowstyle: str = '-|>'
|
|
277
|
+
nx_arrowsize: int = 15
|
|
278
|
+
gv_arrowhead: str = 'empty'
|
|
279
|
+
gv_color: str = 'black'
|
|
280
|
+
gv_style: str = 'solid'
|
|
281
|
+
|
|
282
|
+
|
|
270
283
|
def edge_style_factory(style_tag, styles={}, **kwargs):
|
|
271
284
|
"""
|
|
272
285
|
Get the appropriate EdgeStyle for networkx plotting.
|
|
@@ -307,6 +320,8 @@ def edge_style_factory(style_tag, styles={}, **kwargs):
|
|
|
307
320
|
style_class = ContainmentEdgeStyle
|
|
308
321
|
elif style_tag == 'connection':
|
|
309
322
|
style_class = ConnectionEdgeStyle
|
|
323
|
+
elif style_tag == 'inheritance':
|
|
324
|
+
style_class = InheritanceEdgeStyle
|
|
310
325
|
else:
|
|
311
326
|
raise Exception("Invalid edge style: "+str(style_tag))
|
|
312
327
|
return style_class(styles=styles, **kwargs)
|
|
@@ -383,7 +398,8 @@ class NodeStyle(BaseStyle):
|
|
|
383
398
|
Digraph, Graph = gv_import_check()
|
|
384
399
|
dot = Digraph()
|
|
385
400
|
dot.node('0', label=self.__class__.__name__, **self.gv_kwargs())
|
|
386
|
-
|
|
401
|
+
if disp:
|
|
402
|
+
display(SVG(dot._repr_image_svg_xml()))
|
|
387
403
|
gv_plot_ending(dot, disp=disp, saveas=saveas)
|
|
388
404
|
return dot
|
|
389
405
|
|
|
@@ -556,6 +572,8 @@ def node_style_factory(style_tag, styles={}, **kwargs):
|
|
|
556
572
|
node_style = MethodNodeStyle
|
|
557
573
|
elif style_tag in ['dict', 'flexible']:
|
|
558
574
|
node_style = OtherNodeStyle
|
|
575
|
+
elif style_tag in ['class', 'Class']:
|
|
576
|
+
node_style = OtherNodeStyle
|
|
559
577
|
else:
|
|
560
578
|
raise Exception("Invalid node style: "+str(style_tag))
|
|
561
579
|
return node_style(styles=styles, **kwargs)
|
|
@@ -244,11 +244,17 @@ def get_code_attrs(obj):
|
|
|
244
244
|
code = "\n".join(code.split("\n "))
|
|
245
245
|
code = remove_para(code)
|
|
246
246
|
else:
|
|
247
|
-
|
|
247
|
+
if inspect.isclass(obj):
|
|
248
|
+
objcl = obj
|
|
249
|
+
else:
|
|
250
|
+
objcl = obj.__class__
|
|
251
|
+
source = inspect.getsource(objcl)
|
|
248
252
|
if hasattr(obj, 'get_code'):
|
|
249
253
|
code = obj.get_code(source)
|
|
250
254
|
else:
|
|
251
255
|
code = ""
|
|
256
|
+
if str(obj.__doc__) not in source or 'fmdtools.' in objcl.__module__:
|
|
257
|
+
docs = ""
|
|
252
258
|
return {'source': source, 'code': code, 'docs': docs}
|
|
253
259
|
|
|
254
260
|
|
|
@@ -259,6 +265,7 @@ def remove_para(source):
|
|
|
259
265
|
else:
|
|
260
266
|
return source
|
|
261
267
|
|
|
268
|
+
|
|
262
269
|
def get_methods(obj):
|
|
263
270
|
"""Get methods from the given object."""
|
|
264
271
|
methods = {at[0]: at[1] for at in inspect.getmembers(obj)
|
|
@@ -282,6 +289,8 @@ def get_obj_name(obj, role='', basename=''):
|
|
|
282
289
|
name : str
|
|
283
290
|
Name of the object.
|
|
284
291
|
"""
|
|
292
|
+
if inspect.isclass(obj):
|
|
293
|
+
return obj.__module__ + '.' + obj.__name__
|
|
285
294
|
if hasattr(obj, 'get_full_name'):
|
|
286
295
|
return obj.get_full_name()
|
|
287
296
|
elif inspect.ismethod(obj):
|
|
@@ -301,3 +310,24 @@ def get_memory(role):
|
|
|
301
310
|
else:
|
|
302
311
|
mem = sys.getsizeof(role)
|
|
303
312
|
return mem
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def get_inheritance(obj):
|
|
316
|
+
"""
|
|
317
|
+
Get the base class(es) that the object inherits from.
|
|
318
|
+
|
|
319
|
+
Parameters
|
|
320
|
+
----------
|
|
321
|
+
obj : object
|
|
322
|
+
Object to get base of.
|
|
323
|
+
|
|
324
|
+
Returns
|
|
325
|
+
-------
|
|
326
|
+
classes : tuple
|
|
327
|
+
Tuple of classes that are the base of the object.
|
|
328
|
+
"""
|
|
329
|
+
if inspect.isclass(obj):
|
|
330
|
+
return tuple([b for b in obj.__bases__
|
|
331
|
+
if b is not object and b is not dataobject])
|
|
332
|
+
else:
|
|
333
|
+
return (obj.__class__, )
|
|
@@ -37,30 +37,31 @@ class SimParam(Parameter, readonly=True):
|
|
|
37
37
|
"""
|
|
38
38
|
Class defining Simulation parameters.
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
phases : tuple
|
|
43
|
+
phases (('name', start, end)...) that the simulation progresses through
|
|
44
|
+
start_time : float
|
|
45
|
+
Start time of the simulation.
|
|
46
|
+
end_time : float
|
|
47
|
+
End time of the simulation.
|
|
48
|
+
track_times : tuple
|
|
49
|
+
Defines what times to include in the history.
|
|
50
|
+
Options are:
|
|
51
|
+
- ('all',)--all simulated times
|
|
52
|
+
- ('interval', n)--includes every nth time in the history
|
|
53
|
+
- ('times', [t1, ... tn])--only includes times defined in the
|
|
54
|
+
vector [t1 ... tn]
|
|
55
|
+
dt : float
|
|
56
|
+
time-step used in the simulation. default is 1.0
|
|
57
|
+
units : str
|
|
58
|
+
time-units. default is hours`
|
|
59
|
+
end_condition : str
|
|
60
|
+
Name of indicator method to use to end the simulation. If not provided (''),
|
|
61
|
+
the simulation ends at the final time. Default is ''
|
|
62
|
+
use_local : bool
|
|
63
|
+
Whether to use locally-defined time-steps in functions (if any).
|
|
64
|
+
Default is True.
|
|
64
65
|
"""
|
|
65
66
|
|
|
66
67
|
rolename = "sp"
|
|
@@ -27,8 +27,9 @@ import numpy as np
|
|
|
27
27
|
|
|
28
28
|
class Parameter(BaseContainer, readonly=True):
|
|
29
29
|
"""
|
|
30
|
-
The Parameter class defines model/function/flow values which are immutable
|
|
31
|
-
|
|
30
|
+
The Parameter class defines model/function/flow values which are immutable.
|
|
31
|
+
|
|
32
|
+
That is, the same from model instantiation through a simulation. Parameters
|
|
32
33
|
inherit from recordclass, giving them a low memory footprint, and use type
|
|
33
34
|
hints and ranges to ensure parameter values are valid. e.g.,:
|
|
34
35
|
|