ltbams 0.9.10__tar.gz → 0.9.12__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.
- {ltbams-0.9.10 → ltbams-0.9.12}/LICENSE +1 -1
- {ltbams-0.9.10/ltbams.egg-info → ltbams-0.9.12}/PKG-INFO +37 -17
- {ltbams-0.9.10 → ltbams-0.9.12}/README.md +21 -3
- ltbams-0.9.12/ams/__init__.py +14 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/_version.py +3 -3
- ltbams-0.9.12/ams/benchmarks.py +302 -0
- ltbams-0.9.12/ams/cases/5bus/pjm5bus_jumper.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/5bus/pjm5bus_uced_esd1.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cli.py +6 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/documenter.py +74 -6
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/matprocessor.py +23 -7
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/param.py +7 -3
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/service.py +47 -26
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/symprocessor.py +22 -6
- ltbams-0.9.10/ams/interop/andes.py → ltbams-0.9.12/ams/interface.py +101 -64
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/__init__.py +0 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/json.py +2 -9
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/matpower.py +14 -14
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/xlsx.py +3 -10
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/main.py +83 -4
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/__init__.py +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/group.py +10 -3
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/line.py +28 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/reserve.py +4 -4
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/static/gen.py +9 -3
- ltbams-0.9.12/ams/opt/__init__.py +12 -0
- ltbams-0.9.12/ams/opt/constraint.py +172 -0
- ltbams-0.9.12/ams/opt/exprcalc.py +139 -0
- ltbams-0.9.12/ams/opt/expression.py +200 -0
- ltbams-0.9.12/ams/opt/objective.py +174 -0
- ltbams-0.9.12/ams/opt/omodel.py +432 -0
- ltbams-0.9.12/ams/opt/optbase.py +155 -0
- ltbams-0.9.12/ams/opt/param.py +156 -0
- ltbams-0.9.12/ams/opt/var.py +245 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/opf.py +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/report.py +21 -4
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/__init__.py +2 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/acopf.py +7 -9
- ltbams-0.9.12/ams/routines/dcopf.py +194 -0
- ltbams-0.9.12/ams/routines/dcpf.py +205 -0
- ltbams-0.9.10/ams/routines/dcpf.py → ltbams-0.9.12/ams/routines/dcpf0.py +12 -13
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/dopf.py +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/ed.py +22 -31
- ltbams-0.9.12/ams/routines/pflow.py +255 -0
- ltbams-0.9.10/ams/routines/pflow.py → ltbams-0.9.12/ams/routines/pflow0.py +11 -11
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/routine.py +135 -56
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/rted.py +15 -14
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/uc.py +15 -12
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/shared.py +34 -9
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/system.py +19 -10
- ltbams-0.9.12/ams/utils/__init__.py +59 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/api.rst +4 -2
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/conf.py +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/examples/index.rst +2 -1
- ltbams-0.9.12/docs/source/genmodelref.py +61 -0
- ltbams-0.9.12/docs/source/genroutineref.py +47 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/install.rst +2 -2
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/modeling/example.rst +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/modeling/routine.rst +5 -12
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/release-notes.rst +67 -25
- {ltbams-0.9.10 → ltbams-0.9.12/ltbams.egg-info}/PKG-INFO +37 -17
- {ltbams-0.9.10 → ltbams-0.9.12}/ltbams.egg-info/SOURCES.txt +27 -5
- {ltbams-0.9.10 → ltbams-0.9.12}/ltbams.egg-info/requires.txt +28 -23
- ltbams-0.9.12/pyproject.toml +73 -0
- ltbams-0.9.12/requirements-extra.txt +19 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/requirements.txt +3 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_1st_system.py +1 -1
- ltbams-0.9.12/tests/test_andes_mats.py +61 -0
- ltbams-0.9.12/tests/test_benchmarks.py +149 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_case.py +2 -2
- ltbams-0.9.12/tests/test_cli.py +34 -0
- ltbams-0.9.10/tests/test_andes.py → ltbams-0.9.12/tests/test_interop.py +8 -63
- ltbams-0.9.12/tests/test_io.py +32 -0
- ltbams-0.9.12/tests/test_jumper.py +27 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_known_good.py +4 -2
- ltbams-0.9.10/tests/test_mats.py → ltbams-0.9.12/tests/test_matp.py +4 -0
- ltbams-0.9.12/tests/test_omodel.py +119 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_routine.py +3 -85
- ltbams-0.9.12/tests/test_rtn_dcopf.py +77 -0
- ltbams-0.9.12/tests/test_rtn_ed.py +184 -0
- ltbams-0.9.12/tests/test_rtn_pflow.py +219 -0
- ltbams-0.9.12/tests/test_rtn_rted.py +176 -0
- ltbams-0.9.12/tests/test_rtn_uc.py +165 -0
- ltbams-0.9.10/ams/__init__.py +0 -20
- ltbams-0.9.10/ams/interop/__init__.py +0 -18
- ltbams-0.9.10/ams/opt/__init__.py +0 -5
- ltbams-0.9.10/ams/opt/omodel.py +0 -927
- ltbams-0.9.10/ams/routines/dcopf.py +0 -360
- ltbams-0.9.10/ams/utils/__init__.py +0 -13
- ltbams-0.9.10/requirements-extra.txt +0 -23
- ltbams-0.9.10/tests/test_cli.py +0 -13
- ltbams-0.9.10/tests/test_dctypes.py +0 -111
- {ltbams-0.9.10 → ltbams-0.9.12}/CONTRIBUTING.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/MANIFEST.in +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/__main__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/5bus/pjm5bus_uced.json +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/5bus/pjm5bus_uced.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/5bus/pjm5bus_uced_ev.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee123/ieee123.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee14/ieee14.json +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee14/ieee14.raw +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee14/ieee14_uced.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee39/ieee39.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee39/ieee39_uced.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/benchmark.json +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case118.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case14.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case300.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case39.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case5.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/matpower/case_ACTIVSg2000.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/npcc/npcc.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/npcc/npcc_uced.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/pglib/pglib_opf_case39_epri__api.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/wecc/wecc.m +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/cases/wecc/wecc_uced.xlsx +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/model.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/core/var.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/extension/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/extension/eva.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/psse.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/io/pypower.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/area.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/bus.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/cost.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/distributed/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/distributed/esd1.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/distributed/ev.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/distributed/pvd1.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/info.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/region.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/renewable/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/renewable/regc.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/shunt.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/static/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/static/pq.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/models/timeslot.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/_compat.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/core/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/core/pips.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/core/ppoption.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/core/ppver.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/core/solver.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/eps.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/idx.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/io.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/make/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/make/matrices.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/make/pdv.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/cpf.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/cpf_callbacks.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/opffcns.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/routines/pflow.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/toggle.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/pypower/utils.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/cpf.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/routines/type.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ams/utils/paths.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/Makefile +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/make.bat +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/_templates/autosummary/base.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/_templates/autosummary/class.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/_templates/autosummary/module.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/_templates/autosummary/module_toctree.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/copyright.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/index.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/matpower.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/psse.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/pypower.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/xlsx.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/formats/xlsx.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/index.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/overview.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/testcase.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/getting_started/verification.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/images/dcopf_time.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/images/sponsors/doe.png +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/index.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/modeling/index.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/modeling/model.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/docs/source/modeling/system.rst +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ltbams.egg-info/dependency_links.txt +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ltbams.egg-info/entry_points.txt +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/ltbams.egg-info/top_level.txt +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/setup.cfg +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/setup.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/__init__.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_addressing.py +1 -1
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_export_csv.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_group.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_model.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_paths.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_report.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_repr.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/tests/test_service.py +0 -0
- {ltbams-0.9.10 → ltbams-0.9.12}/versioneer.py +0 -0
@@ -670,7 +670,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|
670
670
|
If the program does terminal interaction, make it output a short
|
671
671
|
notice like this when it starts in an interactive mode:
|
672
672
|
|
673
|
-
AMS Copyright (C) 2023 Jinning Wang
|
673
|
+
AMS Copyright (C) 2023 - 2024 Jinning Wang
|
674
674
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
675
675
|
This is free software, and you are welcome to redistribute it
|
676
676
|
under certain conditions; type `show c' for details.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ltbams
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.12
|
4
4
|
Summary: Python software for scheduling modeling and co-simulation with dynanics.
|
5
5
|
Home-page: https://github.com/CURENT/ams
|
6
6
|
Author: Jinning Wang
|
@@ -14,21 +14,23 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (G
|
|
14
14
|
Classifier: Environment :: Console
|
15
15
|
Description-Content-Type: text/markdown
|
16
16
|
Provides-Extra: all
|
17
|
-
Provides-Extra: coverage
|
17
|
+
Provides-Extra: coverage
|
18
18
|
Provides-Extra: dev
|
19
19
|
Provides-Extra: doc
|
20
|
-
Provides-Extra: flake8
|
21
|
-
Provides-Extra: ipython
|
22
|
-
Provides-Extra: myst-parser
|
23
|
-
Provides-Extra: nbsphinx
|
24
|
-
Provides-Extra: numpydoc
|
25
|
-
Provides-Extra:
|
26
|
-
Provides-Extra:
|
27
|
-
Provides-Extra:
|
28
|
-
Provides-Extra: pytest
|
29
|
-
Provides-Extra:
|
30
|
-
Provides-Extra: sphinx
|
31
|
-
Provides-Extra: sphinx-
|
20
|
+
Provides-Extra: flake8
|
21
|
+
Provides-Extra: ipython
|
22
|
+
Provides-Extra: myst-parser
|
23
|
+
Provides-Extra: nbsphinx
|
24
|
+
Provides-Extra: numpydoc
|
25
|
+
Provides-Extra: pandoc
|
26
|
+
Provides-Extra: pydata-sphinx-theme
|
27
|
+
Provides-Extra: pyscipopt
|
28
|
+
Provides-Extra: pytest
|
29
|
+
Provides-Extra: pytest-cov
|
30
|
+
Provides-Extra: sphinx
|
31
|
+
Provides-Extra: sphinx-copybutton
|
32
|
+
Provides-Extra: sphinx-panels
|
33
|
+
Provides-Extra: toml
|
32
34
|
License-File: LICENSE
|
33
35
|
|
34
36
|
# LTB AMS
|
@@ -37,7 +39,7 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
37
39
|
|
38
40
|
[](https://github.com/CURENT/ams/blob/master/LICENSE)
|
39
41
|

|
40
|
-
[](https://www.python.org/)
|
42
|
+
[](https://www.python.org/)
|
41
43
|

|
42
44
|
[](https://github.com/CURENT/ams/commits/master/)
|
43
45
|
[](https://github.com/CURENT/ams/commits/develop/)
|
@@ -61,7 +63,12 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
61
63
|
|
62
64
|
# Why AMS
|
63
65
|
|
64
|
-
With the built-in interface with
|
66
|
+
With the built-in interface with ANDES, AMS enables **Dynamics Incorporated**
|
67
|
+
**Stability-Constrained Scheduling**.
|
68
|
+
|
69
|
+
AMS is a **Modeling Framework** that provides a descriptive way to formulate
|
70
|
+
scheduling problems. The optimization problems are then handled by **CVXPY**
|
71
|
+
and solved with third-party solvers.
|
65
72
|
|
66
73
|
AMS produces credible scheduling results and competitive performance.
|
67
74
|
The following results show the comparison of DCOPF between AMS and other tools.
|
@@ -92,7 +99,7 @@ Use the following resources to get involved.
|
|
92
99
|
# Installation
|
93
100
|
|
94
101
|
***NOTE:***
|
95
|
-
- Version **0.9.9** has known issues
|
102
|
+
- Version **0.9.9** has known issues and has been yanked from PyPI
|
96
103
|
- `kvxopt` is recommended to install via `conda` as sometimes ``pip`` struggles to set the correct path for compiled libraries
|
97
104
|
- `cvxpy` versions **below 1.5** are incompatible with `numpy` versions **2.0 and above**
|
98
105
|
|
@@ -115,6 +122,19 @@ Install from GitHub source:
|
|
115
122
|
pip install git+https://github.com/CURENT/ams.git
|
116
123
|
```
|
117
124
|
|
125
|
+
# Example Usage
|
126
|
+
|
127
|
+
Using AMS to run a Real-Time Economic Dispatch (RTED) simulation:
|
128
|
+
|
129
|
+
```python
|
130
|
+
import ams
|
131
|
+
|
132
|
+
ss = ams.load(ams.get_case('ieee14_uced.xlsx'))
|
133
|
+
ss.RTED.run()
|
134
|
+
|
135
|
+
print(ss.RTED.pg.v)
|
136
|
+
```
|
137
|
+
|
118
138
|
# Sponsors and Contributors
|
119
139
|
AMS is the scheduling simulation engine for the CURENT Largescale Testbed (LTB).
|
120
140
|
More information about CURENT LTB can be found at the [LTB Repository][LTB Repository].
|
@@ -4,7 +4,7 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
4
4
|
|
5
5
|
[](https://github.com/CURENT/ams/blob/master/LICENSE)
|
6
6
|

|
7
|
-
[](https://www.python.org/)
|
7
|
+
[](https://www.python.org/)
|
8
8
|

|
9
9
|
[](https://github.com/CURENT/ams/commits/master/)
|
10
10
|
[](https://github.com/CURENT/ams/commits/develop/)
|
@@ -28,7 +28,12 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
28
28
|
|
29
29
|
# Why AMS
|
30
30
|
|
31
|
-
With the built-in interface with
|
31
|
+
With the built-in interface with ANDES, AMS enables **Dynamics Incorporated**
|
32
|
+
**Stability-Constrained Scheduling**.
|
33
|
+
|
34
|
+
AMS is a **Modeling Framework** that provides a descriptive way to formulate
|
35
|
+
scheduling problems. The optimization problems are then handled by **CVXPY**
|
36
|
+
and solved with third-party solvers.
|
32
37
|
|
33
38
|
AMS produces credible scheduling results and competitive performance.
|
34
39
|
The following results show the comparison of DCOPF between AMS and other tools.
|
@@ -59,7 +64,7 @@ Use the following resources to get involved.
|
|
59
64
|
# Installation
|
60
65
|
|
61
66
|
***NOTE:***
|
62
|
-
- Version **0.9.9** has known issues
|
67
|
+
- Version **0.9.9** has known issues and has been yanked from PyPI
|
63
68
|
- `kvxopt` is recommended to install via `conda` as sometimes ``pip`` struggles to set the correct path for compiled libraries
|
64
69
|
- `cvxpy` versions **below 1.5** are incompatible with `numpy` versions **2.0 and above**
|
65
70
|
|
@@ -82,6 +87,19 @@ Install from GitHub source:
|
|
82
87
|
pip install git+https://github.com/CURENT/ams.git
|
83
88
|
```
|
84
89
|
|
90
|
+
# Example Usage
|
91
|
+
|
92
|
+
Using AMS to run a Real-Time Economic Dispatch (RTED) simulation:
|
93
|
+
|
94
|
+
```python
|
95
|
+
import ams
|
96
|
+
|
97
|
+
ss = ams.load(ams.get_case('ieee14_uced.xlsx'))
|
98
|
+
ss.RTED.run()
|
99
|
+
|
100
|
+
print(ss.RTED.pg.v)
|
101
|
+
```
|
102
|
+
|
85
103
|
# Sponsors and Contributors
|
86
104
|
AMS is the scheduling simulation engine for the CURENT Largescale Testbed (LTB).
|
87
105
|
More information about CURENT LTB can be found at the [LTB Repository][LTB Repository].
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from . import _version
|
2
|
+
__version__ = _version.get_versions()['version']
|
3
|
+
|
4
|
+
from ams import opt # NOQA
|
5
|
+
from ams import benchmarks # NOQA
|
6
|
+
|
7
|
+
from ams.main import config_logger, load, run # NOQA
|
8
|
+
from ams.system import System # NOQA
|
9
|
+
from ams.utils.paths import get_case, list_cases # NOQA
|
10
|
+
from ams.shared import ppc2df # NOQA
|
11
|
+
|
12
|
+
__author__ = 'Jining Wang'
|
13
|
+
|
14
|
+
__all__ = ['System', 'get_case']
|
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2024-
|
11
|
+
"date": "2024-11-23T17:09:40-0500",
|
12
12
|
"dirty": false,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "0.9.
|
14
|
+
"full-revisionid": "377b36f113e1e88f8c2d21d3c6ab8ff3728cffb0",
|
15
|
+
"version": "0.9.12"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
@@ -0,0 +1,302 @@
|
|
1
|
+
"""
|
2
|
+
Benchmark functions.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import datetime
|
6
|
+
import sys
|
7
|
+
import importlib.metadata as importlib_metadata
|
8
|
+
import logging
|
9
|
+
|
10
|
+
try:
|
11
|
+
import pandapower as pdp
|
12
|
+
PANDAPOWER_AVAILABLE = True
|
13
|
+
except ImportError:
|
14
|
+
PANDAPOWER_AVAILABLE = False
|
15
|
+
logging.warning("pandapower is not available. Some functionalities will be disabled.")
|
16
|
+
|
17
|
+
from andes.utils.misc import elapsed
|
18
|
+
|
19
|
+
import ams
|
20
|
+
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
_failed_time = -1
|
24
|
+
_failed_obj = -1
|
25
|
+
|
26
|
+
cols_pre = ['ams_mats', 'ams_parse', 'ams_eval', 'ams_final', 'ams_postinit']
|
27
|
+
|
28
|
+
|
29
|
+
def get_tool_versions(tools=None):
|
30
|
+
"""
|
31
|
+
Get the current time, Python version, and versions of specified tools.
|
32
|
+
|
33
|
+
Parameters
|
34
|
+
----------
|
35
|
+
tools : list of str, optional
|
36
|
+
List of tool names to check versions. If None, a default list of tools is used.
|
37
|
+
|
38
|
+
Returns
|
39
|
+
-------
|
40
|
+
dict
|
41
|
+
A dictionary containing the tool names and their versions.
|
42
|
+
"""
|
43
|
+
if tools is None:
|
44
|
+
tools = ['ltbams', 'andes', 'cvxpy',
|
45
|
+
'gurobipy', 'mosek', 'piqp',
|
46
|
+
'pandapower', 'numba']
|
47
|
+
|
48
|
+
# Get current time and Python version
|
49
|
+
last_run_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
50
|
+
python_version = sys.version
|
51
|
+
|
52
|
+
# Collect tool versions
|
53
|
+
tool_versions = {}
|
54
|
+
for tool in tools:
|
55
|
+
try:
|
56
|
+
version = importlib_metadata.version(tool)
|
57
|
+
tool_versions[tool] = version
|
58
|
+
except importlib_metadata.PackageNotFoundError:
|
59
|
+
logger.error(f"Package {tool} not found.")
|
60
|
+
tool_versions[tool] = "Not installed"
|
61
|
+
|
62
|
+
# Print the results in a formatted way
|
63
|
+
logger.warning(f"Last run time: {last_run_time}")
|
64
|
+
logger.warning(f"Python: {python_version}\n")
|
65
|
+
|
66
|
+
# Calculate the width of the columns
|
67
|
+
max_tool_length = max(len(tool) for tool in tool_versions)
|
68
|
+
max_version_length = max(len(version) for version in tool_versions.values())
|
69
|
+
|
70
|
+
# Print the header
|
71
|
+
logger.warning(f"{'Tool':<{max_tool_length}} {'Version':<{max_version_length}}")
|
72
|
+
logger.warning(f"{'-' * max_tool_length} {'-' * max_version_length}")
|
73
|
+
|
74
|
+
# Print each tool and its version
|
75
|
+
for tool, version in tool_versions.items():
|
76
|
+
logger.warning(f"{tool:<{max_tool_length}} {version:<{max_version_length}}")
|
77
|
+
|
78
|
+
return tool_versions
|
79
|
+
|
80
|
+
|
81
|
+
def time_routine_solve(system, routine='DCOPF', **kwargs):
|
82
|
+
"""
|
83
|
+
Run the specified routine with the given solver and method.
|
84
|
+
|
85
|
+
Parameters
|
86
|
+
----------
|
87
|
+
system : ams.System
|
88
|
+
The system object containing the routine.
|
89
|
+
routine : str, optional
|
90
|
+
The name of the routine to run. Defaults to 'DCOPF'.
|
91
|
+
|
92
|
+
Other Parameters
|
93
|
+
----------------
|
94
|
+
solver : str, optional
|
95
|
+
The solver to use.
|
96
|
+
ignore_dpp : bool, optional
|
97
|
+
Whether to ignore DPP. Defaults to True.
|
98
|
+
|
99
|
+
Returns
|
100
|
+
-------
|
101
|
+
tuple
|
102
|
+
A tuple containing the elapsed time (s) and the objective value ($).
|
103
|
+
"""
|
104
|
+
rtn = system.routines[routine]
|
105
|
+
solver = kwargs.get('solver', None)
|
106
|
+
try:
|
107
|
+
t, _ = elapsed()
|
108
|
+
rtn.run(**kwargs)
|
109
|
+
_, s0 = elapsed(t)
|
110
|
+
elapsed_time = float(s0.split(' ')[0])
|
111
|
+
obj_value = rtn.obj.v
|
112
|
+
except Exception as e:
|
113
|
+
logger.error(f"Error running routine {routine} with solver {solver}: {e}")
|
114
|
+
elapsed_time = _failed_time
|
115
|
+
obj_value = _failed_obj
|
116
|
+
return elapsed_time, obj_value
|
117
|
+
|
118
|
+
|
119
|
+
def pre_solve(system, routine):
|
120
|
+
"""
|
121
|
+
Time the routine preparation process.
|
122
|
+
|
123
|
+
Parameters
|
124
|
+
----------
|
125
|
+
system : ams.System
|
126
|
+
The system object containing the routine.
|
127
|
+
routine : str
|
128
|
+
The name of the routine to prepare
|
129
|
+
|
130
|
+
Returns
|
131
|
+
-------
|
132
|
+
dict
|
133
|
+
A dictionary containing the preparation times in seconds for each step:
|
134
|
+
'mats', 'parse', 'evaluate', 'finalize', 'postinit'.
|
135
|
+
"""
|
136
|
+
rtn = system.routines[routine]
|
137
|
+
|
138
|
+
# Initialize AMS
|
139
|
+
# --- matrices build ---
|
140
|
+
t_mats, _ = elapsed()
|
141
|
+
system.mats.build(force=True)
|
142
|
+
_, s_mats = elapsed(t_mats)
|
143
|
+
|
144
|
+
# --- code generation ---
|
145
|
+
t_parse, _ = elapsed()
|
146
|
+
rtn.om.parse(force=True)
|
147
|
+
_, s_parse = elapsed(t_parse)
|
148
|
+
|
149
|
+
# --- code evaluation ---
|
150
|
+
t_evaluate, _ = elapsed()
|
151
|
+
rtn.om.evaluate(force=True)
|
152
|
+
_, s_evaluate = elapsed(t_evaluate)
|
153
|
+
|
154
|
+
# --- problem finalization ---
|
155
|
+
t_finalize, _ = elapsed()
|
156
|
+
rtn.om.finalize(force=True)
|
157
|
+
_, s_finalize = elapsed(t_finalize)
|
158
|
+
|
159
|
+
# --- rest init process ---
|
160
|
+
t_postinit, _ = elapsed()
|
161
|
+
rtn.init()
|
162
|
+
_, s_postinit = elapsed(t_postinit)
|
163
|
+
|
164
|
+
s_float = [float(s.split(' ')[0]) for s in [s_mats, s_parse, s_evaluate, s_finalize, s_postinit]]
|
165
|
+
|
166
|
+
pre_time = dict(zip(cols_pre, s_float))
|
167
|
+
return pre_time
|
168
|
+
|
169
|
+
|
170
|
+
def time_pdp_dcopf(ppn):
|
171
|
+
"""
|
172
|
+
Test the execution time of DCOPF using pandapower.
|
173
|
+
|
174
|
+
Parameters
|
175
|
+
----------
|
176
|
+
ppn : pandapowerNet
|
177
|
+
The pandapower network object.
|
178
|
+
|
179
|
+
Returns
|
180
|
+
-------
|
181
|
+
tuple
|
182
|
+
A tuple containing the elapsed time (s) and the objective value ($).
|
183
|
+
"""
|
184
|
+
try:
|
185
|
+
t_pdp, _ = elapsed()
|
186
|
+
pdp.rundcopp(ppn)
|
187
|
+
_, s_pdp = elapsed(t_pdp)
|
188
|
+
elapsed_time = float(s_pdp.split(' ')[0])
|
189
|
+
obj_value = ppn.res_cost
|
190
|
+
except Exception as e:
|
191
|
+
logger.error(f"Error running pandapower: {e}")
|
192
|
+
elapsed_time = _failed_time
|
193
|
+
obj_value = _failed_obj
|
194
|
+
return elapsed_time, obj_value
|
195
|
+
|
196
|
+
|
197
|
+
def time_routine(system, routine='DCOPF', solvers=['CLARABEL'],
|
198
|
+
**kwargs):
|
199
|
+
"""
|
200
|
+
Time the specified routine with the given solvers.
|
201
|
+
|
202
|
+
Parameters
|
203
|
+
----------
|
204
|
+
system : ams.System
|
205
|
+
The system object containing the routine.
|
206
|
+
routine : str, optional
|
207
|
+
The name of the routine to run. Defaults to 'DCOPF'.
|
208
|
+
solvers : list of str, optional
|
209
|
+
List of solvers to use. Defaults to ['CLARABEL'].
|
210
|
+
|
211
|
+
Other Parameters
|
212
|
+
----------------
|
213
|
+
ignore_dpp : bool, optional
|
214
|
+
Whether to ignore DPP. Defaults to True.
|
215
|
+
|
216
|
+
Returns
|
217
|
+
-------
|
218
|
+
tuple
|
219
|
+
A tuple containing the preparation times and the solution times in
|
220
|
+
seconds for each solver.
|
221
|
+
"""
|
222
|
+
pre_time = pre_solve(system, routine)
|
223
|
+
sol = {f'{solver}': {'time': 0, 'obj': 0} for solver in solvers}
|
224
|
+
|
225
|
+
for solver in solvers:
|
226
|
+
if solver != 'pandapower':
|
227
|
+
s, obj = time_routine_solve(system, routine, solver=solver, **kwargs)
|
228
|
+
sol[solver]['time'] = s
|
229
|
+
sol[solver]['obj'] = obj
|
230
|
+
elif solver == 'pandapower' and PANDAPOWER_AVAILABLE and routine == 'DCOPF':
|
231
|
+
ppc = ams.io.pypower.system2ppc(system)
|
232
|
+
ppn = pdp.converter.from_ppc(ppc, f_hz=system.config.freq)
|
233
|
+
s, obj = time_pdp_dcopf(ppn)
|
234
|
+
sol[solver]['time'] = s
|
235
|
+
sol[solver]['obj'] = obj
|
236
|
+
else:
|
237
|
+
sol[solver]['time'] = _failed_time
|
238
|
+
sol[solver]['obj'] = _failed_obj
|
239
|
+
|
240
|
+
return pre_time, sol
|
241
|
+
|
242
|
+
|
243
|
+
def time_dcopf_with_lf(system, solvers=['CLARABEL'], load_factors=[1], ignore_dpp=False):
|
244
|
+
"""
|
245
|
+
Time the execution of DCOPF with varying load factors.
|
246
|
+
|
247
|
+
Parameters
|
248
|
+
----------
|
249
|
+
system : ams.System
|
250
|
+
The system object containing the routine.
|
251
|
+
solvers : list of str, optional
|
252
|
+
List of solvers to use. Defaults to ['CLARABEL'].
|
253
|
+
load_factors : list of float, optional
|
254
|
+
List of load factors to apply. Defaults to None.
|
255
|
+
ignore_dpp : bool, optional
|
256
|
+
Whether to ignore DPP.
|
257
|
+
|
258
|
+
Returns
|
259
|
+
-------
|
260
|
+
tuple
|
261
|
+
A tuple containing the list of times and the list of objective values.
|
262
|
+
"""
|
263
|
+
pre_time = pre_solve(system, 'DCOPF')
|
264
|
+
sol = {f'{solver}': {'time': 0, 'obj': 0} for solver in solvers}
|
265
|
+
|
266
|
+
pd0 = system.PQ.p0.v.copy()
|
267
|
+
pq_idx = system.PQ.idx.v
|
268
|
+
|
269
|
+
for solver in solvers:
|
270
|
+
if solver != 'pandapower':
|
271
|
+
obj_all = 0
|
272
|
+
t_all, _ = elapsed()
|
273
|
+
for lf_k in load_factors:
|
274
|
+
system.PQ.set(src='p0', attr='v', idx=pq_idx, value=lf_k * pd0)
|
275
|
+
system.DCOPF.update(params=['pd'])
|
276
|
+
_, obj = time_routine_solve(system, 'DCOPF',
|
277
|
+
solver=solver, ignore_dpp=ignore_dpp)
|
278
|
+
obj_all += obj
|
279
|
+
_, s_all = elapsed(t_all)
|
280
|
+
system.PQ.set(src='p0', attr='v', idx=pq_idx, value=pd0)
|
281
|
+
s = float(s_all.split(' ')[0])
|
282
|
+
sol[solver]['time'] = s
|
283
|
+
sol[solver]['obj'] = obj_all
|
284
|
+
elif solver == 'pandapower' and PANDAPOWER_AVAILABLE:
|
285
|
+
ppc = ams.io.pypower.system2ppc(system)
|
286
|
+
ppn = pdp.converter.from_ppc(ppc, f_hz=system.config.freq)
|
287
|
+
p_mw0 = ppn.load['p_mw'].copy()
|
288
|
+
t_all, _ = elapsed()
|
289
|
+
obj_all = 0
|
290
|
+
for lf_k in load_factors:
|
291
|
+
ppn.load['p_mw'] = lf_k * p_mw0
|
292
|
+
_, obj = time_pdp_dcopf(ppn)
|
293
|
+
obj_all += obj
|
294
|
+
_, s_all = elapsed(t_all)
|
295
|
+
s = float(s_all.split(' ')[0])
|
296
|
+
sol[solver]['time'] = s
|
297
|
+
sol[solver]['obj'] = obj_all
|
298
|
+
else:
|
299
|
+
sol[solver]['time'] = _failed_time
|
300
|
+
sol[solver]['obj'] = _failed_obj
|
301
|
+
|
302
|
+
return pre_time, sol
|
Binary file
|
Binary file
|
@@ -29,6 +29,12 @@ def create_parser():
|
|
29
29
|
-------
|
30
30
|
argparse.ArgumentParser
|
31
31
|
Parser with all AMS options
|
32
|
+
|
33
|
+
Notes
|
34
|
+
-----
|
35
|
+
Revised from the ANDES project (https://github.com/CURENT/andes).
|
36
|
+
Original author: Hantao Cui
|
37
|
+
License: GPL3
|
32
38
|
"""
|
33
39
|
|
34
40
|
parser = argparse.ArgumentParser()
|
@@ -223,9 +223,10 @@ class RDocumenter:
|
|
223
223
|
# add tables
|
224
224
|
self.parent.syms.generate_symbols()
|
225
225
|
out += self._obj_doc(max_width=max_width, export=export)
|
226
|
-
out += self._constr_doc(max_width=max_width, export=export)
|
227
226
|
out += self._expr_doc(max_width=max_width, export=export)
|
227
|
+
out += self._constr_doc(max_width=max_width, export=export)
|
228
228
|
out += self._var_doc(max_width=max_width, export=export)
|
229
|
+
out += self._exprc_doc(max_width=max_width, export=export)
|
229
230
|
out += self._service_doc(max_width=max_width, export=export)
|
230
231
|
out += self._param_doc(max_width=max_width, export=export)
|
231
232
|
out += self.config.doc(max_width=max_width, export=export)
|
@@ -316,17 +317,26 @@ class RDocumenter:
|
|
316
317
|
rest_dict=rest_dict)
|
317
318
|
|
318
319
|
def _expr_doc(self, max_width=78, export='plain'):
|
319
|
-
#
|
320
|
+
# Expression documentation
|
320
321
|
if len(self.parent.exprs) == 0:
|
321
322
|
return ''
|
322
323
|
|
323
324
|
# prepare temporary lists
|
324
|
-
names,
|
325
|
+
names, info = list(), list()
|
326
|
+
units, sources, units_rest = list(), list(), list()
|
325
327
|
|
326
328
|
for p in self.parent.exprs.values():
|
327
329
|
names.append(p.name)
|
328
|
-
var_names.append(p.var)
|
329
330
|
info.append(p.info if p.info else '')
|
331
|
+
units.append(p.unit if p.unit else '')
|
332
|
+
units_rest.append(f'*{p.unit}*' if p.unit else '')
|
333
|
+
|
334
|
+
slist = []
|
335
|
+
if p.owner is not None and p.src is not None:
|
336
|
+
slist.append(f'{p.owner.class_name}.{p.src}')
|
337
|
+
elif p.owner is not None and p.src is None:
|
338
|
+
slist.append(f'{p.owner.class_name}')
|
339
|
+
sources.append(','.join(slist))
|
330
340
|
|
331
341
|
# expressions based on output format
|
332
342
|
expressions = []
|
@@ -342,13 +352,67 @@ class RDocumenter:
|
|
342
352
|
expressions = math_wrap(expressions, export=export)
|
343
353
|
|
344
354
|
plain_dict = OrderedDict([('Name', names),
|
345
|
-
('Variable', var_names),
|
346
355
|
('Description', info),
|
356
|
+
('Unit', units),
|
357
|
+
])
|
358
|
+
rest_dict = OrderedDict([('Name', names),
|
359
|
+
('Description', info),
|
360
|
+
('Expression', expressions),
|
361
|
+
('Unit', units_rest),
|
362
|
+
('Source', sources),
|
363
|
+
])
|
364
|
+
|
365
|
+
# convert to rows and export as table
|
366
|
+
return make_doc_table(title=title,
|
367
|
+
max_width=max_width,
|
368
|
+
export=export,
|
369
|
+
plain_dict=plain_dict,
|
370
|
+
rest_dict=rest_dict)
|
371
|
+
|
372
|
+
def _exprc_doc(self, max_width=78, export='plain'):
|
373
|
+
# ExpressionCalc documentation
|
374
|
+
if len(self.parent.exprcs) == 0:
|
375
|
+
return ''
|
376
|
+
|
377
|
+
# prepare temporary lists
|
378
|
+
names, info = list(), list()
|
379
|
+
units, sources, units_rest = list(), list(), list()
|
380
|
+
|
381
|
+
for p in self.parent.exprcs.values():
|
382
|
+
names.append(p.name)
|
383
|
+
info.append(p.info if p.info else '')
|
384
|
+
units.append(p.unit if p.unit else '')
|
385
|
+
units_rest.append(f'*{p.unit}*' if p.unit else '')
|
386
|
+
|
387
|
+
slist = []
|
388
|
+
if p.owner is not None and p.src is not None:
|
389
|
+
slist.append(f'{p.owner.class_name}.{p.src}')
|
390
|
+
elif p.owner is not None and p.src is None:
|
391
|
+
slist.append(f'{p.owner.class_name}')
|
392
|
+
sources.append(','.join(slist))
|
393
|
+
|
394
|
+
# expressions based on output format
|
395
|
+
expressions = []
|
396
|
+
if export == 'rest':
|
397
|
+
for p in self.parent.exprcs.values():
|
398
|
+
expr = _tex_pre(self, p, self.parent.syms.tex_map)
|
399
|
+
logger.debug(f'{p.name} math: {expr}')
|
400
|
+
expressions.append(expr)
|
401
|
+
|
402
|
+
title = 'ExpressionCalcs\n----------------------------------'
|
403
|
+
else:
|
404
|
+
title = 'ExpressionCalcs'
|
405
|
+
expressions = math_wrap(expressions, export=export)
|
406
|
+
|
407
|
+
plain_dict = OrderedDict([('Name', names),
|
408
|
+
('Description', info),
|
409
|
+
('Unit', units),
|
347
410
|
])
|
348
411
|
rest_dict = OrderedDict([('Name', names),
|
349
|
-
('Variable', var_names),
|
350
412
|
('Description', info),
|
351
413
|
('Expression', expressions),
|
414
|
+
('Unit', units_rest),
|
415
|
+
('Source', sources),
|
352
416
|
])
|
353
417
|
|
354
418
|
# convert to rows and export as table
|
@@ -423,6 +487,8 @@ class RDocumenter:
|
|
423
487
|
slist = []
|
424
488
|
if p.owner is not None and p.src is not None:
|
425
489
|
slist.append(f'{p.owner.class_name}.{p.src}')
|
490
|
+
elif p.owner is not None and p.src is None:
|
491
|
+
slist.append(f'{p.owner.class_name}')
|
426
492
|
sources.append(','.join(slist))
|
427
493
|
|
428
494
|
# symbols based on output format
|
@@ -490,6 +556,8 @@ class RDocumenter:
|
|
490
556
|
slist = []
|
491
557
|
if p.owner is not None and p.src is not None:
|
492
558
|
slist.append(f'{p.owner.class_name}.{p.src}')
|
559
|
+
elif p.owner is not None and p.src is None:
|
560
|
+
slist.append(f'{p.owner.class_name}')
|
493
561
|
sources.append(','.join(slist))
|
494
562
|
|
495
563
|
# symbols based on output format
|