Library for parameter processing and validation with a focus on computational modeling projects
Project description
ParamTools
ParamTools defines the parameter input space for computational modeling projects.
- Defines the default parameter space.
- Facilitates adjusting that space.
- Performs validation on the default space and the adjusted space.
How to use ParamTools
Subclass the Parameters
class and set your specification schema and default specification files:
from paramtools import Parameters
from paramtools import get_example_paths
schema_, defaults_ = get_example_paths('taxparams-demo')
class TaxParams(Parameters):
schema = schema_ # schema.json
defaults = defaults_ # defaults.json
params = TaxParams(
initial_state={"year": [2024, 2025, 2026]},
array_first=True
)
print("# output ", params.view_state())
# output {'year': [2024, 2025, 2026]}
Parameters are available via instance attributes:
params.standard_deduction
# output: [[13673.68 27347.36 13673.68 20510.52 27347.36]
# [13967.66 27935.33 13967.66 20951.49 27935.33]
# [ 7690. 15380. 7690. 11323. 15380. ]]
Get the parameter's value object:
params.from_array("standard_deduction")
# output: [{'year': 2024, 'marital_status': 'single', 'value': 13673.68}, {'year': 2024, 'marital_status': 'joint', 'value': 27347.36}, {'year': 2024, 'marital_status': 'separate', 'value': 13673.68}, {'year': 2024, 'marital_status': 'headhousehold', 'value': 20510.52}, {'year': 2024, 'marital_status': 'widow', 'value': 27347.36}, {'year': 2025, 'marital_status': 'single', 'value': 13967.66}, {'year': 2025, 'marital_status': 'joint', 'value': 27935.33}, {'year': 2025, 'marital_status': 'separate', 'value': 13967.66}, {'year': 2025, 'marital_status': 'headhousehold', 'value': 20951.49}, {'year': 2025, 'marital_status': 'widow', 'value': 27935.33}, {'year': 2026, 'marital_status': 'single', 'value': 7690.0}, {'year': 2026, 'marital_status': 'joint', 'value': 15380.0}, {'year': 2026, 'marital_status': 'separate', 'value': 7690.0}, {'year': 2026, 'marital_status': 'headhousehold', 'value': 11323.0}, {'year': 2026, 'marital_status': 'widow', 'value': 15380.0}]
Adjust the default specification:
adjustment = {
"standard_deduction": [
{"year": 2026, "marital_status": "single", "value": 10000.0}
],
"social_security_tax_rate": [
{"year": 2026, "value": 0.14}
]
}
params.adjust(adjustment)
params.standard_deduction
# output: [[13673.68 27347.36 13673.68 20510.52 27347.36]
# [13967.66 27935.33 13967.66 20951.49 27935.33]
# [10000. 15380. 7690. 11323. 15380. ]]
print(params.social_security_tax_rate)
# output: [0.124 0.124 0.14 ]
Errors on invalid input:
adjustment["standard_deduction"] = [{
"year": 2026,
"marital_status": "single",
"value": "higher"
}]
params.adjust(adjustment)
# output:
Traceback (most recent call last):
File "doc_ex.py", line 60, in <module>
raise saved_exc
File "doc_ex.py", line 33, in <module>
params.adjust(adjustment)
File "/home/henrydoupe/Documents/ParamTools/paramtools/parameters.py", line 123, in adjust
raise self.validation_error
paramtools.exceptions.ValidationError: {'standard_deduction': ['Not a valid number: higher.']}
Errors on input that's out of range:
# get value of ii_bracket_2 at year 2026, marital status "single".
spec = params.specification(year=2026, marital_status="single", use_state=False)
spec
# output: OrderedDict([('standard_deduction', [{'year': 2026, 'value': 10000.0, 'marital_status': 'single'}]), ('ii_bracket_1', [{'year': 2026, 'value': 11293.0, 'marital_status': 'single'}]), ('ii_bracket_2', [{'year': 2026, 'value': 45957.0, 'marital_status': 'single'}]), ('social_security_tax_rate', [{'year': 2026, 'value': 0.14}])])
ii_bracket_2_val = spec["ii_bracket_2"][0]["value"]
ii_bracket_2_val
# output: 45957.0
adjustment = {
"standard_deduction": [{
"year": 2026,
"marital_status": "single",
"value": -1
}],
"ii_bracket_1": [{
"year": 2026,
"marital_status": "single",
"value": ii_bracket_2_val + 1}
]
}
params.adjust(adjustment, raise_errors=False)
params.errors
# output:
# {
# 'standard_deduction': ['standard_deduction -1.0 must be greater than 0 for dimensions marital_status=single , year=2026'],
# 'ii_bracket_1': ['ii_bracket_1 45958.0 must be less than 45957.0 for dimensions marital_status=single , year=2026']
# }
How to install ParamTools
Install from PyPI:
conda install paramtools -c pslmodels
Install from source:
git clone https://github.com/PSLmodels/ParamTools
cd ParamTools
conda env create
conda activate paramtools-dev
pip install -e .
# optionally run tests:
py.test -v
Documentation
Full documentation available at https://paramtools.readthedocs.io/.
Contributing
Contributions are welcome! Checkout CONTRIBUTING.md to get started.
Credits
ParamTools is built on top of the excellent marshmallow JSON schema and validation framework. I encourage everyone to checkout their repo and documentation. ParamTools was modeled off of Tax-Calculator's parameter processing and validation engine due to its maturity and sophisticated capabilities.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for paramtools-0.4.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a7e0efe193599f4bc49686334dfa49eb20950c84e00ad221e0055da8ea868a23 |
|
MD5 | b4e84883d5f7845e309eed2f88fb8ed7 |
|
BLAKE2b-256 | 5d9f52e88207d830b43ea37ed68a4c639451e5aac25d2b1d0df9f5916100bb3a |