Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 5 additions & 17 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
paths:
- '**.yml'
- '**.toml'
- '**.ini'
- '**.py'
- '**.json'
- '**.csv'
Expand All @@ -14,7 +13,6 @@ on:
paths:
- '**.yml'
- '**.toml'
- '**.ini'
- '**.py'
- '**.json'
- '**.csv'
Expand All @@ -33,24 +31,14 @@ jobs:
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Miniconda using Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v3
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
miniconda-version: "latest"
auto-update-conda: true
activate-environment: ogcore-dev
environment-file: environment.yml
python-version: ${{ matrix.python-version }}
auto-activate-base: false
- name: Build
shell: bash -l {0}
run: |
pip install -e .
- name: Install package and dependencies
run: uv sync --extra dev
- name: Test
shell: bash -l {0}
working-directory: ./
run: |
python -m pytest -m "not local and not benchmark" --cov=./ --cov-report=xml
run: uv run python -m pytest -m "not local and not benchmark" --cov=./ --cov-report=xml
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest' && contains(github.repository, 'PSLmodels/OG-Core')
uses: codecov/codecov-action@v4
Expand Down
15 changes: 0 additions & 15 deletions .github/workflows/check_black.yml

This file was deleted.

14 changes: 14 additions & 0 deletions .github/workflows/check_ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Check Ruff formatting and linting

on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- name: Check formatting with Ruff
run: uvx ruff format --check .
- name: Check linting with Ruff
run: uvx ruff check .
17 changes: 7 additions & 10 deletions .github/workflows/deploy_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,18 @@ jobs:
with:
persist-credentials: false

- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
miniconda-version: "latest"
activate-environment: ogcore-dev
environment-file: environment.yml
python-version: "3.13"
auto-activate-base: false

- name: Install package and dependencies
run: uv sync --extra dev --extra docs

- name: Build # Build Jupyter Book
shell: bash -l {0}
run: |
pip install -e .
python -m ipykernel install --user --name=ogcore-dev
make build-docs
uv run python -m ipykernel install --user --name=ogcore-dev
uv run make build-docs

- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4
Expand Down
17 changes: 7 additions & 10 deletions .github/workflows/docs_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@ jobs:
with:
persist-credentials: false

- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
miniconda-version: "latest"
activate-environment: ogcore-dev
environment-file: environment.yml
python-version: "3.13"
auto-activate-base: false

- name: Install package and dependencies
run: uv sync --extra dev --extra docs

- name: Build # Build Jupyter Book
shell: bash -l {0}
run: |
pip install -e .
python -m ipykernel install --user --name=ogcore-dev
make build-docs
uv run python -m ipykernel install --user --name=ogcore-dev
uv run make build-docs
6 changes: 3 additions & 3 deletions .github/workflows/publish_to_pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
python-version: "3.13"
- name: Build package
run: make pip-package
run: uv build
- name: Publish a Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
Expand Down
7 changes: 3 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,9 @@ build-docs:
@cd ./docs ; python make_params.py; python make_vars.py; jb build ./book

format:
black . -l 79
ruff format .
ruff check . --fix
linecheck . --fix

pip-package:
pip install wheel
pip install setuptools
python setup.py sdist bdist_wheel
uv build
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
| | |
| --- | --- |
| Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://raw.githubusercontent.com/jupyter-book/jupyter-book/next/docs/media/images/badge.svg)](https://pslmodels.github.io/OG-Core/) |
| Package | [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3137/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |
| Package | [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3137/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) |
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_ruff.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |


OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core).
Expand All @@ -24,13 +24,12 @@ The model is constantly under development, and model components could change sig

## Using/contributing to OG-Core

There are two primary methods for installing and running OG-Core on your computer locally. The first and simplest method is to download the most recent `ogcore` Python package from the Python Package Index ([PyPI.org]()). A second option is to fork and clone the most recent version of OG-Core from its GitHub repository and create the conda environment for the `ogcore` package. We detail both of these methods below.
There are two primary methods for installing and running OG-Core on your computer locally. The first and simplest method is to download the most recent `ogcore` Python package from the Python Package Index ([PyPI.org](https://pypi.org/project/ogcore/)). A second option is to fork and clone the most recent version of OG-Core from its GitHub repository and install the `ogcore` package with its development dependencies using `uv`. We detail both of these methods below.


### Installing and Running OG-Core from Python Package Index (PyPI.org)

* Open your terminal (or Conda command prompt), and make sure you have the most recent version of `pip` (the Python Index Package manager) by typing on a Unix/macOS machine `python3 -m pip install --upgrade pip` or on a Windows machine `py -m pip install --upgrade pip`.
* Install the [`ogcore`](https://pypi.org/project/ogcore/) package from the Python Package Index by typing `pip install ogcore`.
* Open your terminal and install the [`ogcore`](https://pypi.org/project/ogcore/) package from the Python Package Index by typing `pip install ogcore`.
* Navigate to a folder `./YourFolderName/` where you want to save scripts to run OG-Core and output from the simulations in those scripts.
* Save the python script [`run_ogcore_example.py`](https://github.com/PSLmodels/OG-Core/blob/master/run_examples/run_ogcore_example.py) from the OG-Core GitHub repository in the folder where you are working on your local machine `./YourFolderName/run_ogcore_example.py`.
* Run the model with an example reform from terminal/command prompt by typing `python run_ogcore_example.py`
Expand Down Expand Up @@ -60,11 +59,9 @@ The CSV output file `./ogcore_example_output.csv` can be compared to the [`./run

### Installing and Running OG-Core from GitHub repository

* Install the [Anaconda distribution](https://www.anaconda.com/distribution/) of Python
* Install [`uv`](https://docs.astral.sh/uv/) by following the [installation instructions](https://docs.astral.sh/uv/getting-started/installation/) for your platform (or simply run `pip install uv`)
* Clone this repository to a directory on your computer
* From the terminal (or Conda command prompt), navigate to the directory to which you cloned this repository and run `conda env create -f environment.yml`
* Then, `conda activate ogcore-dev`
* Then install by `pip install -e .`
* From the terminal, navigate to the directory to which you cloned this repository and run `uv pip install -e ".[dev]"` to install the package and all development dependencies
* Navigate to `./run_examples`
* Run the model with an example reform from terminal/command prompt by typing `python run_ogcore_example.py`
* You can adjust the `./run_examples/run_ogcore_example.py` script by modifying model parameters specified in the `og_spec` dictionary.
Expand Down
2 changes: 0 additions & 2 deletions docs/book/content/theory/images/SS_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

"""
Expand Down
1 change: 0 additions & 1 deletion docs/make_params.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import numpy as np
import pandas as pd
from collections import OrderedDict
import ogcore
import os
import sys
Expand Down
1 change: 0 additions & 1 deletion docs/make_vars.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import numpy as np
import pandas as pd
from collections import OrderedDict
import ogcore
import os
import sys
Expand Down
4 changes: 1 addition & 3 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ dependencies:
- python>3.11, <3.14
- numpy
- ipython
- setuptools
- scipy>=1.7.1
- pandas>=1.2.5
- numba
Expand All @@ -24,11 +23,10 @@ dependencies:
- pytest>=6.0
- pytest-cov
- pytest-xdist
- pylint
- coverage
- requests
- openpyxl>=3.1.2
- black>=24.1.1
- ruff
- pip
- pip:
- pygam
Expand Down
1 change: 0 additions & 1 deletion examples/multi_industry_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""

# import modules
from asyncio import base_events
import multiprocessing
from distributed import Client
import time
Expand Down
2 changes: 0 additions & 2 deletions examples/run_ogcore_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
from ogcore.parameters import Specifications
from ogcore.constants import REFORM_DIR, BASELINE_DIR
from ogcore.utils import safe_read_pickle
import ogcore
from ogcore import SS
import matplotlib.pyplot as plt

# Use a custom matplotlib style file for plots
Expand Down
25 changes: 11 additions & 14 deletions ogcore/SS.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
# imports
import numpy as np
import scipy.optimize as opt
from dask import delayed, compute
import dask.multiprocessing
from ogcore import tax, pensions, household, firm, utils, fiscal
from ogcore import aggregates as aggr
from ogcore.constants import SHOW_RUNTIME, DEV_FACTOR_LIST
from ogcore import config
import os
import warnings
import logging
Expand Down Expand Up @@ -39,7 +36,8 @@ def euler_equation_solver(guesses, *args):

Args:
guesses (Numpy array): initial guesses for b and n, length 2S
args (tuple): tuple of arguments (r, w, p_tilde, p_i, bq, TR, factor, j, p)
args (tuple): tuple of arguments (r, w, p_tilde, p_i, bq, TR,
factor, j, p)
r (scalar): real interest rate
w (scalar): real wage rate
p_tilde (scalar): composite good price
Expand Down Expand Up @@ -290,15 +288,14 @@ def inner_loop(outer_loop_vars, p, client):
# from dask.base import dask_sizeof

if client:

# Before scattering, temporarily remove unpicklable schema objects
schema_backup = {}
for attr in ["_defaults_schema", "_validator_schema", "sel"]:
if hasattr(p, attr):
schema_backup[attr] = getattr(p, attr)
try:
delattr(p, attr)
except:
except Exception:
pass

# Scatter the parameters
Expand All @@ -308,7 +305,7 @@ def inner_loop(outer_loop_vars, p, client):
for attr, value in schema_backup.items():
try:
setattr(p, attr, value)
except:
except Exception:
pass

# Launch in parallel with submit (or map)
Expand Down Expand Up @@ -1148,7 +1145,8 @@ def SS_solver(
euler_savings = euler_errors[: p.S, :]
euler_labor_leisure = euler_errors[p.S :, :]
logging.info(
f"Maximum error in labor FOC = {np.absolute(euler_labor_leisure).max()}"
"Maximum error in labor FOC = "
f"{np.absolute(euler_labor_leisure).max()}"
)
logging.info(
f"Maximum error in savings FOC = {np.absolute(euler_savings).max()}"
Expand Down Expand Up @@ -1437,9 +1435,7 @@ def run_SS(p, client=None):
if ss_solutions["b_sp1"].shape == (
p.S,
p.J,
) and np.squeeze(
ss_solutions["Y_m"].shape
) == (p.M):
) and np.squeeze(ss_solutions["Y_m"].shape) == (p.M):
logging.info("Using previous solutions for SS")
(
b_guess,
Expand Down Expand Up @@ -1509,14 +1505,15 @@ def run_SS(p, client=None):
logging.warning("KeyError: previous solutions for SS not found")
use_new_guesses = True
if p.baseline or not p.reform_use_baseline_solution or use_new_guesses:
# Loop over initial guesses of r and TR until find a solution or until have
# gone through all guesses. This should usually solve in the first guess
# Loop over initial guesses of r and TR until find a solution
# or until have gone through all guesses. This should usually
# solve in the first guess
SS_solved = False
k = 0
while not SS_solved and k < len(DEV_FACTOR_LIST) - 1:
for k, v in enumerate(DEV_FACTOR_LIST):
logging.info(
f"SS using initial guess factors for r and TR of "
"SS using initial guess factors for r and TR of "
+ f"{v[0]} and {v[1]} respectively."
)
guesses, b_guess, n_guess = SS_initial_guesses(
Expand Down
Loading
Loading