Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a786085
Add JOSS paper and bibliography for submission
vahid-ahmadi Mar 23, 2026
7fb0128
Add Pavel Makarchuk as author in JOSS paper
vahid-ahmadi Mar 23, 2026
7aedc2f
Adapt JOSS paper from UK-only to multi-country policyengine.py
vahid-ahmadi Mar 23, 2026
ac8a602
Add US research impact citations to JOSS paper
vahid-ahmadi Mar 23, 2026
0e61eda
Fix citations, convert to American spelling, and fix grammar
vahid-ahmadi Mar 23, 2026
f893bd3
Reorder authors: Pavel Makarchuk before Vahid Ahmadi
vahid-ahmadi Mar 23, 2026
95e114c
Edit Summary and Statement of Need per review feedback
vahid-ahmadi Mar 23, 2026
fb1eb93
Update install docs, remove code styling, reorder US before UK
vahid-ahmadi Mar 23, 2026
2c3ff23
Merge framework bullets, add US program count, remove web app bullet
vahid-ahmadi Mar 23, 2026
0603547
Merge analysis bullets, use .py package name, remove 10ds-microsim
vahid-ahmadi Mar 23, 2026
452862e
Add US academic/policy citations and US funders
vahid-ahmadi Mar 23, 2026
3dafc7e
Remove all code-style backtick formatting from prose text
vahid-ahmadi Mar 23, 2026
51db607
Remove 'Multi-Country' from paper title
vahid-ahmadi Mar 23, 2026
0964bd5
Remove 'Open-Source' from paper title
vahid-ahmadi Mar 23, 2026
ba4c107
Remove dev install command from Statement of Need
vahid-ahmadi Mar 23, 2026
7752427
Add Atlanta Fed PRD, NSF POSE award; use external reference URLs
vahid-ahmadi Mar 23, 2026
e01d3ae
Reorder all sections: US before UK throughout
vahid-ahmadi Mar 23, 2026
190ebdc
Fix double parentheses in AI disclosure, remove test scaffolding, pip…
vahid-ahmadi Mar 23, 2026
d70aa4d
Remove pip install commands from Statement of Need
vahid-ahmadi Mar 23, 2026
018056d
Consolidate to 3 bullets, delete cross-country comparison sentence
vahid-ahmadi Mar 23, 2026
805fb08
Remove TaxBenefitModelVersion and RegionRegistry from paper text
vahid-ahmadi Mar 23, 2026
d0571e0
Replace PE self-links with external URLs, remove country model paragraph
vahid-ahmadi Mar 23, 2026
d0976d5
Update Nikhil ORCID, reorder authors, quote affiliation values
vahid-ahmadi Mar 30, 2026
e2b96b0
Add Pavel's ORCID
vahid-ahmadi Mar 30, 2026
f79aa07
Tighten JOSS paper, add architecture diagram, code example, and align…
vahid-ahmadi Mar 31, 2026
e8e4af4
Revise JOSS paper rationale and preview
MaxGhenis Apr 1, 2026
675ac4f
Restore styled JOSS preview
MaxGhenis Apr 2, 2026
e02e911
Replace fake data repo citations with real Enhanced CPS paper
vahid-ahmadi Apr 2, 2026
915e553
Add proper figure reference for architecture diagram in paper
vahid-ahmadi Apr 2, 2026
4ac4206
Update HTML previews to match paper.md citation and figure changes
vahid-ahmadi Apr 2, 2026
b88f067
Populate Max Ghenis ORCID
MaxGhenis Apr 2, 2026
1f13b81
Fix Claude year to 2026, move figure position, fix Atlanta Fed URL
vahid-ahmadi Apr 2, 2026
6e21a8a
Sync HTML previews with paper.md changes
vahid-ahmadi Apr 2, 2026
11ad6c9
Add code example and foundational microsimulation references
vahid-ahmadi Apr 2, 2026
e1e397d
Update paper date to 2 April 2026
vahid-ahmadi Apr 2, 2026
7e2f556
Remove 'and drafting of this paper' from AI disclosure
vahid-ahmadi Apr 2, 2026
b5d0810
Shorten architecture figure caption
vahid-ahmadi Apr 2, 2026
f781c8d
Polish paper: reorder authors, fix figure, update output labels, gram…
vahid-ahmadi Apr 7, 2026
e62c46d
Remove non-runnable paper example
MaxGhenis Apr 7, 2026
0f075dc
Clarify policyengine.py JOSS positioning
MaxGhenis Apr 7, 2026
01a317d
Tighten JOSS reviewer documentation
MaxGhenis Apr 7, 2026
bc48c4e
Tighten JOSS reviewer path and scope
MaxGhenis Apr 7, 2026
134c861
Add model references and package naming
MaxGhenis Apr 9, 2026
c16c837
Add JOSS draft PDF compilation workflow
vahid-ahmadi Apr 9, 2026
76f057d
date
vahid-ahmadi Apr 9, 2026
1b008c0
Refine state of field references
MaxGhenis Apr 9, 2026
9c943f0
Soften comparative paper tone
MaxGhenis Apr 9, 2026
6c9352f
Improve JOSS paper writing style: neutral tone, active voice, new cit…
MaxGhenis Apr 9, 2026
b99f2be
Merge remote-tracking branch 'origin/main' into joss-paper
MaxGhenis Apr 9, 2026
fc61815
Address simulated JOSS reviewer feedback
MaxGhenis Apr 9, 2026
337fdaf
Address second referee feedback
MaxGhenis Apr 9, 2026
1825426
Address Codex referee feedback
MaxGhenis Apr 9, 2026
5f24285
Address third referee feedback: factual accuracy in Table 1 and code …
MaxGhenis Apr 9, 2026
cf83dc9
Document reproducibility boundary in JOSS paper
MaxGhenis Apr 12, 2026
3578b6a
Trim JOSS manuscript to fit word limit
MaxGhenis Apr 12, 2026
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
71 changes: 60 additions & 11 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,63 @@
## Updating the versioning
# Contributing

Please add to `changelog_entry.yaml` an entry in the format:
Thanks for contributing to PolicyEngine.py.

```yaml
- bump: minor
changes:
added:
- New feature.
fixed:
- Bug fix.
changed:
- Change.
## Ways to contribute

- Open an issue for bugs, documentation gaps, or feature requests.
- Submit a pull request for code, tests, documentation, or examples.
- If you are unsure where to start, open an issue describing the workflow or analysis problem you want to improve.

## Development setup

```bash
git clone https://github.com/PolicyEngine/policyengine.py.git
cd policyengine.py
uv pip install -e ".[dev]"
```

This installs the package, both country models, and the development tools used in CI.

## Running checks

Before opening a pull request, run the checks relevant to your change:

```bash
make format
ruff check .
mypy src/policyengine
make test
```

Documentation changes can be checked with:

```bash
make docs
```

Tests that download representative datasets require a `HUGGING_FACE_TOKEN`:

```bash
export HUGGING_FACE_TOKEN=hf_...
```

## Changelog fragments

Pull requests that change user-facing behaviour should include a changelog fragment in `changelog.d/`:

```bash
echo "Describe the change." > changelog.d/my-change.fixed
```

Valid fragment types are `breaking`, `added`, `changed`, `fixed`, and `removed`.

## Pull requests

- Keep pull requests focused and explain the user-facing impact.
- Add or update tests when behaviour changes.
- Update documentation and examples when the public workflow changes.

## Getting help

- Use GitHub issues for bugs, regressions, and feature requests.
- For questions that do not fit a public issue, contact `hello@policyengine.org`.
25 changes: 25 additions & 0 deletions .github/workflows/draft-pdf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
on:
push:
paths:
- paper.md
- paper.bib
- architecture.png
pull_request:
paths:
- paper.md
- paper.bib
- architecture.png

jobs:
paper:
runs-on: ubuntu-latest
name: Draft PDF
steps:
- uses: actions/checkout@v4
- uses: openjournals/openjournals-draft-action@master
with:
journal: joss
- uses: actions/upload-artifact@v4
with:
name: paper
path: paper.pdf
33 changes: 33 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
type: software
title: policyengine
version: 3.4.0
date-released: "2026-04-09"
url: "https://github.com/PolicyEngine/policyengine.py"
abstract: "An open-source Python package that provides a common analysis layer for tax-benefit microsimulation across the US and the UK."
license: AGPL-3.0
authors:
- family-names: Ghenis
given-names: Max
orcid: "https://orcid.org/0000-0002-1335-8277"
affiliation: PolicyEngine
- family-names: Ahmadi
given-names: Vahid
orcid: "https://orcid.org/0009-0004-1093-6272"
affiliation: PolicyEngine
- family-names: Woodruff
given-names: Nikhil
orcid: "https://orcid.org/0009-0009-5004-4910"
affiliation: PolicyEngine
- family-names: Makarchuk
given-names: Pavel
orcid: "https://orcid.org/0009-0003-4869-7409"
affiliation: PolicyEngine
keywords:
- microsimulation
- tax
- benefit
- public policy
- Python
repository-code: "https://github.com/PolicyEngine/policyengine.py"
64 changes: 64 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Contributor covenant code of conduct

## Our pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Enforcement responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
hello@policyengine.org. All complaints will be reviewed and investigated
promptly and fairly.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

[homepage]: https://www.contributor-covenant.org
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
all: build-package

docs:
cd docs && jupyter book start
cd docs && npx mystmd build --html

install:
uv pip install -e .[dev]
uv pip install -e ".[dev]"

format:
ruff format .
Expand All @@ -27,4 +27,4 @@ build-package:
python -m build

test:
pytest tests --cov=policyengine --cov-report=term-missing
pytest tests --cov=policyengine --cov-report=term-missing
67 changes: 43 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,31 @@ A Python package for tax-benefit microsimulation analysis. Run policy simulation

## Quick start

Install the UK country model first:

```bash
pip install "policyengine[uk]"
```

```python
from policyengine.core import Simulation
from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset, uk_latest
from policyengine.outputs.aggregate import Aggregate, AggregateType
from policyengine.tax_benefit_models.uk import ensure_datasets, uk_latest

# Load representative microdata
dataset = PolicyEngineUKDataset(
name="FRS 2023-24",
filepath="./data/frs_2023_24_year_2026.h5",
year=2026,
# First run downloads representative microdata to ./data; later runs reuse it
datasets = ensure_datasets(
datasets=["hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"],
years=[2026],
data_folder="./data",
)
dataset = datasets["enhanced_frs_2023_24_2026"]

# Run simulation
simulation = Simulation(
dataset=dataset,
tax_benefit_model_version=uk_latest,
)
simulation.run()
simulation.ensure()

# Calculate total universal credit spending
agg = Aggregate(
Expand All @@ -34,6 +41,15 @@ agg.run()
print(f"Total UC spending: £{agg.result / 1e9:.1f}bn")
```

## Smoke test

To verify a fresh install without downloading representative datasets:

```bash
pip install "policyengine[uk,us]"
python examples/household_impact_example.py
```

## Documentation

**Core concepts:**
Expand All @@ -55,19 +71,21 @@ print(f"Total UC spending: £{agg.result / 1e9:.1f}bn")
pip install policyengine
```

This installs both UK and US country models. To install only one:
This installs the shared analysis layer only. Add country model extras for the
systems you want to analyze:

```bash
pip install policyengine[uk] # UK model only
pip install policyengine[us] # US model only
pip install "policyengine[uk]" # shared layer + UK model
pip install "policyengine[us]" # shared layer + US model
pip install "policyengine[uk,us]" # shared layer + both country models
```

### For development

```bash
git clone https://github.com/PolicyEngine/policyengine.py.git
cd policyengine.py
uv pip install -e .[dev] # install with dev dependencies (pytest, ruff, mypy, etc.)
uv pip install -e ".[dev]" # install with dev dependencies (pytest, ruff, mypy, etc.)
```

## Development
Expand All @@ -76,17 +94,18 @@ uv pip install -e .[dev] # install with dev dependencies (pytest, ruff, m

| Configuration | Install | Use case |
|---------------|---------|----------|
| **Library user** | `pip install policyengine` | Using the package in your own code |
| **UK only** | `pip install policyengine[uk]` | Only need UK simulations |
| **US only** | `pip install policyengine[us]` | Only need US simulations |
| **Developer** | `uv pip install -e .[dev]` | Contributing to the package |
| **Library user** | `pip install policyengine` | Shared analysis layer only |
| **UK only** | `pip install "policyengine[uk]"` | Shared layer plus UK simulations |
| **US only** | `pip install "policyengine[us]"` | Shared layer plus US simulations |
| **Both countries** | `pip install "policyengine[uk,us]"` | Shared layer plus UK and US simulations |
| **Developer** | `uv pip install -e ".[dev]"` | Contributing to the package |

### Common commands

```bash
make format # ruff format
make test # pytest with coverage
make docs # build Jupyter Book documentation
make docs # run the MyST docs build used in CI via npx
make clean # remove caches, build artifacts, .h5 files
```

Expand Down Expand Up @@ -124,7 +143,7 @@ PRs trigger the following checks:
| Tests (Python 3.13) | Required | `make test` |
| Tests (Python 3.14) | Required | `make test` |
| Mypy | Informational | `mypy src/policyengine` |
| Docs build | Required | Jupyter Book build |
| Docs build | Required | `make docs` |

### Versioning and releases

Expand Down Expand Up @@ -163,14 +182,14 @@ On first run this will create `./data/enhanced_frs_2023_24_year_2026.h5`.
Datasets contain microdata at entity level (person, household, tax unit). Load representative data or create custom scenarios:

```python
from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset
from policyengine.tax_benefit_models.uk import ensure_datasets

dataset = PolicyEngineUKDataset(
name="Representative data",
filepath="./data/frs_2023_24_year_2026.h5",
year=2026,
datasets = ensure_datasets(
datasets=["hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"],
years=[2026],
data_folder="./data",
)
dataset.load()
dataset = datasets["enhanced_frs_2023_24_2026"]
```

### Simulations
Expand Down Expand Up @@ -274,7 +293,7 @@ Key taxes: Federal income tax, payroll tax

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
See [.github/CONTRIBUTING.md](.github/CONTRIBUTING.md) for development setup and guidelines.

## License

Expand Down
Binary file added architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading