vivarium-validation 0.1.0__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.
Files changed (63) hide show
  1. vivarium_validation-0.1.0/.readthedocs.yaml +37 -0
  2. vivarium_validation-0.1.0/CHANGELOG.rst +4 -0
  3. vivarium_validation-0.1.0/Jenkinsfile +40 -0
  4. vivarium_validation-0.1.0/LICENSE +27 -0
  5. vivarium_validation-0.1.0/Makefile +101 -0
  6. vivarium_validation-0.1.0/PKG-INFO +97 -0
  7. vivarium_validation-0.1.0/README.rst +38 -0
  8. vivarium_validation-0.1.0/docs/Makefile +22 -0
  9. vivarium_validation-0.1.0/docs/nitpick-exceptions +4 -0
  10. vivarium_validation-0.1.0/docs/source/_static/.gitkeep +0 -0
  11. vivarium_validation-0.1.0/docs/source/automated_v_and_v/index.rst +168 -0
  12. vivarium_validation-0.1.0/docs/source/conf.py +237 -0
  13. vivarium_validation-0.1.0/docs/source/index.rst +16 -0
  14. vivarium_validation-0.1.0/pyproject.toml +162 -0
  15. vivarium_validation-0.1.0/python_versions.json +1 -0
  16. vivarium_validation-0.1.0/setup.cfg +4 -0
  17. vivarium_validation-0.1.0/src/vivarium/validation/__init__.py +12 -0
  18. vivarium_validation-0.1.0/src/vivarium/validation/bundle.py +193 -0
  19. vivarium_validation-0.1.0/src/vivarium/validation/comparison.py +375 -0
  20. vivarium_validation-0.1.0/src/vivarium/validation/constants.py +51 -0
  21. vivarium_validation-0.1.0/src/vivarium/validation/data_loader.py +298 -0
  22. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/__init__.py +0 -0
  23. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/age_groups.py +710 -0
  24. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/calculations.py +284 -0
  25. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/data_schema.py +44 -0
  26. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/formatting.py +133 -0
  27. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/measures.py +594 -0
  28. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/rate_aggregation.py +30 -0
  29. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/report.py +117 -0
  30. vivarium_validation-0.1.0/src/vivarium/validation/data_transformation/utils.py +155 -0
  31. vivarium_validation-0.1.0/src/vivarium/validation/interface.py +955 -0
  32. vivarium_validation-0.1.0/src/vivarium/validation/py.typed +0 -0
  33. vivarium_validation-0.1.0/src/vivarium/validation/results.py +17 -0
  34. vivarium_validation-0.1.0/src/vivarium/validation/templates/report_template.html +919 -0
  35. vivarium_validation-0.1.0/src/vivarium/validation/visualization/__init__.py +0 -0
  36. vivarium_validation-0.1.0/src/vivarium/validation/visualization/dataframe_utils.py +120 -0
  37. vivarium_validation-0.1.0/src/vivarium/validation/visualization/plot_utils.py +321 -0
  38. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/PKG-INFO +97 -0
  39. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/SOURCES.txt +61 -0
  40. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/dependency_links.txt +1 -0
  41. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/requires.txt +43 -0
  42. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/scm_file_list.json +58 -0
  43. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/scm_version.json +8 -0
  44. vivarium_validation-0.1.0/src/vivarium_validation.egg-info/top_level.txt +1 -0
  45. vivarium_validation-0.1.0/tests/__init__.py +0 -0
  46. vivarium_validation-0.1.0/tests/automated_validation/conftest.py +779 -0
  47. vivarium_validation-0.1.0/tests/automated_validation/data_transformation/test_age_groups.py +634 -0
  48. vivarium_validation-0.1.0/tests/automated_validation/data_transformation/test_calculations.py +419 -0
  49. vivarium_validation-0.1.0/tests/automated_validation/data_transformation/test_data_schema.py +93 -0
  50. vivarium_validation-0.1.0/tests/automated_validation/data_transformation/test_formatting.py +279 -0
  51. vivarium_validation-0.1.0/tests/automated_validation/data_transformation/test_measures.py +710 -0
  52. vivarium_validation-0.1.0/tests/automated_validation/gbd_data/exposure.csv +17 -0
  53. vivarium_validation-0.1.0/tests/automated_validation/gbd_data/incidence.csv +13 -0
  54. vivarium_validation-0.1.0/tests/automated_validation/gbd_data/population_structure.csv +5 -0
  55. vivarium_validation-0.1.0/tests/automated_validation/gbd_data/relative_risks.csv +113 -0
  56. vivarium_validation-0.1.0/tests/automated_validation/gbd_data/remission_rate.csv +401 -0
  57. vivarium_validation-0.1.0/tests/automated_validation/test_comparison.py +405 -0
  58. vivarium_validation-0.1.0/tests/automated_validation/test_data_bundle.py +298 -0
  59. vivarium_validation-0.1.0/tests/automated_validation/test_data_loader.py +402 -0
  60. vivarium_validation-0.1.0/tests/automated_validation/test_interface.py +1115 -0
  61. vivarium_validation-0.1.0/tests/automated_validation/visualization/test_dataframe_utils.py +121 -0
  62. vivarium_validation-0.1.0/tests/automated_validation/visualization/test_plot_utils.py +450 -0
  63. vivarium_validation-0.1.0/tests/test_package.py +48 -0
@@ -0,0 +1,37 @@
1
+ # Paths are repo-root-relative even when this file lives in a subdirectory,
2
+ # so the package path must be qualified with libs/validation/.
3
+ #
4
+ # This file is read by RTD only when the vivarium-validation RTD
5
+ # project's Admin > Advanced Settings > "Path for .readthedocs.yaml" points
6
+ # here. The root-level /.readthedocs.yaml is a placeholder used by the
7
+ # import wizard and ignored for any project that has overridden the path.
8
+ version: 2
9
+
10
+ sphinx:
11
+ configuration: libs/validation/docs/source/conf.py
12
+ fail_on_warning: true
13
+
14
+ build:
15
+ os: ubuntu-22.04
16
+ tools:
17
+ python: "3.13"
18
+ jobs:
19
+ post_checkout:
20
+ - git fetch --unshallow origin 2>/dev/null || git fetch origin main
21
+ # Cancel PR (external) builds that don't touch this lib (Exit 183 is RTD's
22
+ # signal to cancel the build immediately).
23
+ - |
24
+ if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet "origin/main...HEAD" -- libs/validation/; then
25
+ echo "Skipping docs build: this PR changes nothing under libs/validation/."
26
+ exit 183
27
+ fi
28
+
29
+ python:
30
+ install:
31
+ - method: pip
32
+ path: libs/validation
33
+ extra_requirements:
34
+ - docs
35
+
36
+ formats:
37
+ - pdf
@@ -0,0 +1,4 @@
1
+ **0.1.0 - 07/21/26**
2
+
3
+ - Initial release: automated verification and validation (V&V) tooling split out
4
+ of ``vivarium-testing-utils`` into its own package.
@@ -0,0 +1,40 @@
1
+ /* This Jenkinsfile simply loads the `reusable_pipeline` pipeline from the
2
+ vivarium-build-utils package, which lives at ``libs/build-utils/`` inside the
3
+ ``ihmeuw/vivarium-suite`` monorepo (https://github.com/ihmeuw/vivarium-suite).
4
+
5
+ vivarium-build-utils is loaded as a Jenkins shared library
6
+ (https://www.jenkins.io/doc/book/pipeline/shared-libraries/).
7
+ Jenkins shared library convention dictates that importable modules must be stored
8
+ in the 'vars' folder.
9
+
10
+ Jenkins shared libraries can be configured in the Jenkins UI:
11
+ * Manage Jenkins
12
+ * Configure System
13
+ * Global Pipeline Libraries section
14
+ * Library subsection
15
+ * Name: The Name for the lib
16
+ * Version: The branch you want to use. Throws an error
17
+ for nonexistent branches.
18
+ * Project Repository: Url to the shared lib
19
+ * Credentials: SSH key to access the repo
20
+
21
+ Note that updating the shared repo will take effect on the next pipeline invocation.
22
+ */
23
+
24
+ // Load the get_vbu_version function from build-utils/bootstrap/
25
+ // (the directory to load from is defined in the Jenkins shared library configuration)
26
+ @Library("get_vbu_version@main") _
27
+
28
+ // Load the full vivarium_build_utils library at the expected version
29
+ library("vivarium_build_utils@${get_vbu_version()}")
30
+
31
+ reusable_pipeline(
32
+ scheduled_branches: [
33
+ // Add additional branches for cron jobs below.
34
+ // Note: Newly added branches will require a manual trigger of the first build
35
+ // for subsequent scheduled builds to run.
36
+ "main",
37
+ ],
38
+ skip_doc_build: true,
39
+ env_reqs: "ci_jenkins",
40
+ )
@@ -0,0 +1,27 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright 2024 Institute for Health Metrics and Evaluation
4
+
5
+ Redistribution and use in source and binary forms, with or without modification,
6
+ are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this list
9
+ of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice, this
12
+ list of conditions and the following disclaimer in the documentation and/or other
13
+ materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its contributors may
16
+ be used to endorse or promote products derived from this software without specific
17
+ prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY
20
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22
+ SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,101 @@
1
+ # Check if we're running in Jenkins
2
+ ifdef JENKINS_URL
3
+ # Files are already in workspace from shared library
4
+ MAKE_INCLUDES := .
5
+ else
6
+ # For local dev, use the installed vivarium.build_utils package if it exists
7
+ # First, check if we can import vivarium.build_utils and assign 'yes' or 'no'.
8
+ # We do this by importing the package in python and redirecting stderr to the null device.
9
+ # If the import is successful (&&), it will print 'yes', otherwise (||) it will print 'no'.
10
+ VIVARIUM_BUILD_UTILS_AVAILABLE := $(shell python -c "import vivarium.build_utils" 2>/dev/null && echo "yes" || echo "no")
11
+ # If vivarium.build_utils is available, get the makefiles path or else set it to empty
12
+ ifeq ($(VIVARIUM_BUILD_UTILS_AVAILABLE),yes)
13
+ MAKE_INCLUDES := $(shell python -c "from vivarium.build_utils.resources import get_makefiles_path; print(get_makefiles_path())")
14
+ else
15
+ MAKE_INCLUDES :=
16
+ endif
17
+ endif
18
+
19
+ # Set the package name as the last part of this file's parent directory path
20
+ PACKAGE_NAME = $(notdir $(CURDIR))
21
+
22
+ ifneq ($(MAKE_INCLUDES),) # not empty
23
+ # Include makefiles from vivarium.build_utils
24
+ include $(MAKE_INCLUDES)/base.mk
25
+ include $(MAKE_INCLUDES)/test.mk
26
+ else # empty
27
+ # Use this help message (since the vivarium.build_utils version is not available)
28
+ help:
29
+ @echo
30
+ @echo "For Make's standard help, run 'make --help'."
31
+ @echo
32
+ @echo "Most of our Makefile targets are provided by the vivarium.build_utils"
33
+ @echo "package. To access them, you need to create a development environment first."
34
+ @echo
35
+ @echo "make build-env"
36
+ @echo
37
+ @echo "USAGE:"
38
+ @echo " make build-env [name=<environment name>] [py=<python version>] [artifactory_access=<yes|no>]"
39
+ @echo
40
+ @echo "ARGUMENTS:"
41
+ @echo " name [optional]"
42
+ @echo " Name of the conda environment to create (defaults to <PACKAGE_NAME>)"
43
+ @echo " py [optional]"
44
+ @echo " Python version (defaults to latest supported)"
45
+ @echo " artifactory_access [optional]"
46
+ @echo " Whether the build host can reach the IHME artifactory. Either 'yes'"
47
+ @echo " (default) or 'no'; use 'no' to build off-VPN without artifactory."
48
+ @echo
49
+ @echo "After creating the environment:"
50
+ @echo " 1. Activate it: 'conda activate <environment_name>'"
51
+ @echo " 2. Run 'make help' again to see all newly available targets"
52
+ @echo
53
+ endif
54
+
55
+ build-env: # Create a new environment with installed packages
56
+ # Validate arguments - exit if unsupported arguments are passed
57
+ @allowed="name py artifactory_access"; \
58
+ for arg in $(filter-out build-env,$(MAKECMDGOALS)) $(MAKEFLAGS); do \
59
+ case $$arg in \
60
+ *=*) \
61
+ arg_name=$${arg%%=*}; \
62
+ if ! echo " $$allowed " | grep -q " $$arg_name "; then \
63
+ allowed_list=$$(echo $$allowed | sed 's/ /, /g'); \
64
+ echo "Error: Invalid argument '$$arg_name'. Allowed arguments are: $$allowed_list" >&2; \
65
+ exit 1; \
66
+ fi \
67
+ ;; \
68
+ esac; \
69
+ done
70
+
71
+ # Handle arguments and set defaults
72
+ # name
73
+ @$(eval name ?= $(PACKAGE_NAME))
74
+ # python version - validate if specified, else get default from json file
75
+ @supported_versions=$$(python -c "import json; print(' '.join(json.load(open('python_versions.json'))))" 2>/dev/null || echo ""); \
76
+ if [ -n "$(py)" ] && ! echo "$$supported_versions" | grep -q "$(py)"; then \
77
+ echo "Error: Python version '$(py)' is not supported. Available: $$(echo $$supported_versions | sed 's/ /, /g')" >&2; \
78
+ exit 1; \
79
+ fi
80
+ @$(eval py ?= $(shell python -c "import json; print(max(json.load(open('python_versions.json')), key=lambda x: tuple(map(int, x.split('.')))))"))
81
+ # artifactory_access
82
+ @$(eval artifactory_access ?= yes)
83
+ @case "$(artifactory_access)" in \
84
+ yes|no) ;; \
85
+ *) echo "Error: 'artifactory_access' must be 'yes' or 'no', got '$(artifactory_access)'" >&2; exit 1 ;; \
86
+ esac
87
+
88
+ conda create -n $(name) python=$(py) --yes
89
+ # Bootstrap vivarium.build_utils into the new environment
90
+ conda run -n $(name) pip install vivarium-build-utils
91
+ # artifactory_access=no passes an empty IHME_PYPI, which clears base.mk's EXTRA_INDEX_FLAGS
92
+ conda run -n $(name) make install $(if $(filter no,$(artifactory_access)),IHME_PYPI=)
93
+
94
+ @echo
95
+ @echo "Finished building environment"
96
+ @echo " name: $(name)"
97
+ @echo " python version: $(py)"
98
+ @echo
99
+ @echo "Don't forget to activate it with:"
100
+ @echo "conda activate $(name)"
101
+ @echo
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: vivarium-validation
3
+ Version: 0.1.0
4
+ Summary: Automated verification and validation tooling for Vivarium simulations.
5
+ Author-email: The vivarium developers <vivarium.dev@gmail.com>
6
+ License: BSD-3-Clause
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Intended Audience :: Education
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Natural Language :: English
12
+ Classifier: Operating System :: MacOS :: MacOS X
13
+ Classifier: Operating System :: POSIX
14
+ Classifier: Operating System :: POSIX :: BSD
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: Implementation :: CPython
19
+ Classifier: Topic :: Education
20
+ Classifier: Topic :: Scientific/Engineering
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/x-rst
24
+ License-File: LICENSE
25
+ Requires-Dist: vivarium-dependencies[loguru,numpy,pandas,pyyaml]
26
+ Requires-Dist: vivarium-build-utils<5.0.0,>=4.0.0
27
+ Requires-Dist: vivarium-config-tree
28
+ Requires-Dist: vivarium-fuzzy-checker
29
+ Provides-Extra: cluster
30
+ Provides-Extra: test
31
+ Requires-Dist: vivarium-dependencies[pytest]; extra == "test"
32
+ Requires-Dist: pytest-check; extra == "test"
33
+ Requires-Dist: vivarium-testing-utils; extra == "test"
34
+ Provides-Extra: docs
35
+ Requires-Dist: vivarium-dependencies[docutils,ipython,matplotlib,sphinx,sphinx-click]; extra == "docs"
36
+ Provides-Extra: interactive
37
+ Requires-Dist: vivarium-dependencies[interactive]; extra == "interactive"
38
+ Provides-Extra: pandera
39
+ Requires-Dist: pandera<0.23.0; extra == "pandera"
40
+ Provides-Extra: lint
41
+ Requires-Dist: vivarium-dependencies[lint]; extra == "lint"
42
+ Requires-Dist: vivarium-validation[pandera]; extra == "lint"
43
+ Provides-Extra: validation
44
+ Requires-Dist: vivarium-artifact; extra == "validation"
45
+ Requires-Dist: vivarium-gbd-mapping; extra == "validation"
46
+ Requires-Dist: vivarium-inputs<9.0.0,>=8.0.0; extra == "validation"
47
+ Requires-Dist: vivarium-validation[pandera]; extra == "validation"
48
+ Requires-Dist: pyarrow; extra == "validation"
49
+ Requires-Dist: seaborn; extra == "validation"
50
+ Requires-Dist: jinja2>=3.0.0; extra == "validation"
51
+ Requires-Dist: vivarium-dependencies[ipython,matplotlib]; extra == "validation"
52
+ Provides-Extra: dev
53
+ Requires-Dist: vivarium-validation[docs,interactive,lint,test,validation]; extra == "dev"
54
+ Provides-Extra: ci-github
55
+ Requires-Dist: vivarium-validation[docs,lint,test]; extra == "ci-github"
56
+ Provides-Extra: ci-jenkins
57
+ Requires-Dist: vivarium-validation[ci_github,cluster,validation]; extra == "ci-jenkins"
58
+ Dynamic: license-file
59
+
60
+ ============================
61
+ Vivarium Validation
62
+ ============================
63
+
64
+ .. image:: https://badge.fury.io/py/vivarium-validation.svg
65
+ :target: https://badge.fury.io/py/vivarium-validation
66
+
67
+ .. image:: https://readthedocs.org/projects/vivarium-validation/badge/?version=latest
68
+ :target: https://vivarium-validation.readthedocs.io/en/latest/?badge=latest
69
+ :alt: Documentation Status
70
+
71
+ This library provides tooling for automated verification and validation (V&V) of
72
+ Vivarium simulations, including data loading, measure comparison, and reporting.
73
+
74
+ **Supported Python versions: 3.10, 3.11**
75
+
76
+ You can install ``vivarium-validation`` from PyPI with pip:
77
+
78
+ .. code-block:: bash
79
+
80
+ pip install vivarium-validation
81
+
82
+ or build it from source by cloning the monorepo and installing this package:
83
+
84
+ .. code-block:: bash
85
+
86
+ git clone https://github.com/ihmeuw/vivarium-suite.git
87
+ cd vivarium-suite
88
+ pip install libs/validation
89
+
90
+ Note that the validation feature depends on ``vivarium-inputs``, which is only
91
+ available from the IHME artifactory.
92
+
93
+ For broader monorepo development setup, see the monorepo README at
94
+ https://github.com/ihmeuw/vivarium-suite.
95
+
96
+ `Check out the docs! <https://vivarium-validation.readthedocs.io/en/latest/>`_
97
+ -----------------------------------------------------------------------------------
@@ -0,0 +1,38 @@
1
+ ============================
2
+ Vivarium Validation
3
+ ============================
4
+
5
+ .. image:: https://badge.fury.io/py/vivarium-validation.svg
6
+ :target: https://badge.fury.io/py/vivarium-validation
7
+
8
+ .. image:: https://readthedocs.org/projects/vivarium-validation/badge/?version=latest
9
+ :target: https://vivarium-validation.readthedocs.io/en/latest/?badge=latest
10
+ :alt: Documentation Status
11
+
12
+ This library provides tooling for automated verification and validation (V&V) of
13
+ Vivarium simulations, including data loading, measure comparison, and reporting.
14
+
15
+ **Supported Python versions: 3.10, 3.11**
16
+
17
+ You can install ``vivarium-validation`` from PyPI with pip:
18
+
19
+ .. code-block:: bash
20
+
21
+ pip install vivarium-validation
22
+
23
+ or build it from source by cloning the monorepo and installing this package:
24
+
25
+ .. code-block:: bash
26
+
27
+ git clone https://github.com/ihmeuw/vivarium-suite.git
28
+ cd vivarium-suite
29
+ pip install libs/validation
30
+
31
+ Note that the validation feature depends on ``vivarium-inputs``, which is only
32
+ available from the IHME artifactory.
33
+
34
+ For broader monorepo development setup, see the monorepo README at
35
+ https://github.com/ihmeuw/vivarium-suite.
36
+
37
+ `Check out the docs! <https://vivarium-validation.readthedocs.io/en/latest/>`_
38
+ -----------------------------------------------------------------------------------
@@ -0,0 +1,22 @@
1
+ # Minimal makefile for Sphinx documentation
2
+
3
+ # You can set these variables from the command line.
4
+ SPHINXOPTS =
5
+ SPHINXBUILD = sphinx-build
6
+ SPHINXPROJ = vivarium.validation
7
+ SOURCEDIR = source
8
+ BUILDDIR = build
9
+
10
+ # Put it first so that "make" without argument is like "make help".
11
+ help:
12
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
13
+
14
+ .PHONY: help Makefile
15
+
16
+ # Catch-all target: route all unknown targets to Sphinx using the new
17
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
18
+ %: Makefile
19
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
20
+
21
+ clean:
22
+ rm -rf build/*
@@ -0,0 +1,4 @@
1
+ # Add "py:class <target>" entries here for cross-references that Sphinx's
2
+ # nitpicky mode cannot resolve. Empty for now: these docs are narrative-only,
3
+ # so no autodoc-generated type references need suppressing. Populate this when
4
+ # the package starts auto-documenting its API.
File without changes
@@ -0,0 +1,168 @@
1
+ ..
2
+ Section title decorators for this document:
3
+
4
+ ==============
5
+ Document Title
6
+ ==============
7
+ Section Level 1
8
+ ---------------
9
+ Section Level 2
10
+ +++++++++++++++
11
+ Section Level 3
12
+ ~~~~~~~~~~~~~~~
13
+ Section Level 4
14
+ ^^^^^^^^^^^^^^^
15
+ Section Level 5
16
+ '''''''''''''''
17
+
18
+ The depth of each section level is determined by the order in which each
19
+ decorator is encountered below. If you need an even deeper section level, just
20
+ choose a new decorator symbol from the list here:
21
+ https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#sections
22
+ And then add it to the list of decorators above.
23
+
24
+ .. _automated_v_and_v:
25
+
26
+ .. role:: underline
27
+ :class: underline
28
+
29
+ =========================================================
30
+ Automated verification and validation (V&V)
31
+ =========================================================
32
+
33
+ .. contents::
34
+ :local:
35
+
36
+ Background/Motivation
37
+ ---------------------
38
+
39
+ Our team uses :ref:`a process called verification and validation (V&V) <vivarium_best_practices_results_processing>`
40
+ to ensure that our models are behaving as we expect.
41
+ :ref:`The current process for V&V <vivarium_v_and_v_process>`
42
+ works well but can be quite labor intensive.
43
+ Due to the long runtime of simulations and the number of people involved,
44
+ each V&V cycle generally takes *at least* one day, which makes it difficult to find and fix issues quickly.
45
+
46
+ Automating more of the V&V process would help us catch issues faster and with less work.
47
+ We can **incrementally** automate V&V by building tools to do the repetitive parts,
48
+ and over time stitching these tools together to make the process more and more automatic.
49
+
50
+ As we develop the tools, there are also some process questions to work out about this transformation:
51
+
52
+ * Who investigates the cause of automated V&V failures?
53
+ If the answer is "it depends on the failure," how do we route the right failures to the right people?
54
+ * How and when do we run automated V&V?
55
+
56
+ Automated V&V comparisons
57
+ -------------------------
58
+
59
+ Automated V&V plots
60
+ -------------------
61
+
62
+ Automated V&V checks
63
+ --------------------
64
+
65
+ Automating V&V checks refers to replacing the manual process of looking at graphs (to check that simulation
66
+ results are close enough to known targets) with an automatic equivalent.
67
+ This requires transforming the manual process into something that can be executed by a computer
68
+ and generate an unambiguous verdict on whether or not there is an issue that needs to be investigated.
69
+
70
+ .. note::
71
+ In the future, we could explore having a result more complex than just "investigate" or
72
+ "don't investigate," such as multiple levels of priority for potential issues to be reviewed by a human.
73
+ For now, we stick to a binary result.
74
+
75
+ For checks where the expectation is that the simulation result should exactly match a target or respect
76
+ a constraint (e.g. 0% coverage of an intervention among those not eligible) it is fairly straightforward
77
+ to use a Python :code:`assert` statement in addition to, or instead of, a plot.
78
+ This approach can be used in notebooks or in automated tests run with :code:`pytest`.
79
+
80
+ The statistical methodology behind fuzzy checking lives in the
81
+ `vivarium-fuzzy-checker documentation
82
+ <https://vivarium-fuzzy-checker.readthedocs.io/en/latest/fuzzy_checking.html>`_.
83
+
84
+ Automated V&V runs
85
+ ------------------
86
+
87
+ .. todo::
88
+ Due to technical limitations in the :code:`pytest` tool, integration tests currently must select a simulation
89
+ "size" (population, draws, time span), run it completely, and then check the results.
90
+ It would likely lead to a much quicker iteration cycle if we ran a small simulation, checked the results,
91
+ then added more population/draws/time and checked the results again, etc, similar to how we expand runs with
92
+ :code:`psimulate`.
93
+ This way, egregious bugs could be caught very quickly.
94
+
95
+ History/case studies
96
+ --------------------
97
+
98
+ Probabilistic record linkage (PRL) synthetic population simulation
99
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
100
+
101
+ The :ref:`PRL synthetic population simulation <vivarium_census_prl_synth_data>`
102
+ used an atypical V&V process,
103
+ and was used as a testbed for some of these automation ideas.
104
+
105
+ Rather than researchers performing V&V in notebooks, V&V for this simulation
106
+ was entirely done via `integration tests <https://en.wikipedia.org/wiki/Integration_testing>`_,
107
+ which ran the simulation for a given number of time steps and checked certain conditions.
108
+ When the model exhibited unexpected behavior,
109
+ the tests failed.
110
+ For example, there was a test that checked that each non-GQ household in the simulation had exactly one
111
+ living reference person, a condition which should always be true.
112
+
113
+ These tests have access to intermediate simulation states, not only simulation outputs, and can check
114
+ conditions at each time step.
115
+ Therefore, they are quite similar to :ref:`interactive simulation V&V <vivarium_interactive_simulation>` we have done in the past.
116
+ Because not much changes over time in the PRL simulation (there is nothing like an intervention scale-up),
117
+ we test only the first 10 time steps.
118
+
119
+ Test coverage was not complete; notably, none of the observers had integration tests.
120
+ The test suite can be found `in the simulation repository's integration tests directory <https://github.com/ihmeuw/vivarium_census_prl_synth_pop/tree/main/tests/integration>`_.
121
+ The tests all ran in just a few minutes, so engineers were expected to run them before merging any pull request,
122
+ though we did not have continuous integration (CI).
123
+
124
+ These integration tests were the first place we used fuzzy checking,
125
+ specifically for rates of simulant migration into and within the US (fuzzy checking was not implemented for emigration).
126
+ These rates are stratified by a number
127
+ of demographic factors, and some of these factors (e.g. race/ethnicity) have highly imbalanced categories.
128
+ Therefore, verifying rates within each demographic combination would require a large population size.
129
+
130
+ Instead, the integration tests do a combination of verification and validation by checking
131
+ **population-level** migration rates against the corresponding rates in our data source (the American Communities Survey).
132
+ These should be similar, since the simulation's rates are calculated using this data source,
133
+ and the demographic composition of the population is initialized from the same data.
134
+ However, simulation rates can drift slightly from population-level rates in the data, without being indicative of a bug,
135
+ due to demographic change over the course of the simulation.
136
+ All these checks were implemented as proportion checks on the proportion of simulants experiencing the vent.
137
+ Checking at the population level makes use of the binomial approximation to the Poisson binomial,
138
+ as described in the proportions section of the `vivarium-fuzzy-checker documentation
139
+ <https://vivarium-fuzzy-checker.readthedocs.io/en/latest/fuzzy_checking.html>`_.
140
+
141
+ For rates of migration within the US, we check the migration rate at each time step, and overall.
142
+ We set the target range for each time step by assuming with 95% certainty that the drift will be at most 1% per time step that has elapsed
143
+ since initialization.
144
+ Overall, we set a UI of +/-10% the ACS value.
145
+
146
+ Migration into the US is a bit different; it is not an event with a rate of occurrence among
147
+ an at-risk population.
148
+ The only stochastic part of determining the number of immigration events is the
149
+ :ref:`"stochastic rounding" used <census_prl_international_immigration>`.
150
+ We check this rounding as a set of Bernoulli trials, one per time step:
151
+ whether to round up or down.
152
+
153
+ The PRL integration tests are run very frequently by the software engineering team.
154
+ Due to how frequently they are run and the difficulty of debugging a failed test
155
+ (perhaps requiring researcher input in some cases),
156
+ it is important for these tests to be highly **specific**;
157
+ they should very rarely fail by chance.
158
+ That is the main reason we have set the default Bayes factor cutoff to 100, commonly called "decisive,"
159
+ in *addition* to the generally conservative approximations described above.
160
+ In practice, by manually introducing bugs in the simulation, we have found that even with this very conservative approach, automated V&V is quite sensitive.
161
+
162
+ pseudopeople noise tests
163
+ ++++++++++++++++++++++++
164
+
165
+ Our `pseudopeople <https://pseudopeople.readthedocs.io/>`_ package applies random noise to data derived from the PRL synthetic population simulation.
166
+ We used fuzzy checking in both the `unit <https://github.com/ihmeuw/pseudopeople/tree/main/tests/unit>`_ and `integration <https://github.com/ihmeuw/pseudopeople/tree/main/tests/integration>`_ tests of pseudopeople to check that
167
+ noise was happening at the expected rates.
168
+ We did not have any false alarms, and fuzzy checking caught some `very subtle bugs <https://github.com/ihmeuw/pseudopeople/pull/373>`_.