Metadata-Version: 2.4
Name: fable-pyculator
Version: 0.1.0a1
Summary: FABLE Calculator-specific notebook controls for Modelwright-generated Python models.
Author: UBC FRESH Lab
License-Expression: MIT
Project-URL: Homepage, https://github.com/UBC-FRESH/fable-pyculator
Project-URL: Documentation, https://ubc-fresh.github.io/fable-pyculator/
Project-URL: Repository, https://github.com/UBC-FRESH/fable-pyculator
Project-URL: Issues, https://github.com/UBC-FRESH/fable-pyculator/issues
Project-URL: Changelog, https://github.com/UBC-FRESH/fable-pyculator/blob/main/CHANGE_LOG.md
Keywords: fable,spreadsheet-models,jupyter,modelwright,scenario-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: modelwright[notebook]>=0.1.0a6
Requires-Dist: openpyxl>=3.1
Requires-Dist: pandas>=2
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: sphinx>=7; extra == "dev"
Requires-Dist: sphinx-rtd-theme>=2; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=7; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=2; extra == "docs"
Provides-Extra: notebook
Requires-Dist: ipykernel>=6; extra == "notebook"
Requires-Dist: ipywidgets>=8; extra == "notebook"
Requires-Dist: matplotlib>=3.8; extra == "notebook"
Provides-Extra: quality
Requires-Dist: ruff>=0.8; extra == "quality"
Provides-Extra: release
Requires-Dist: build>=1.2; extra == "release"
Requires-Dist: twine>=5; extra == "release"
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

# FABLE Pyculator

FABLE Pyculator is a FABLE Calculator-specific notebook layer built on top of
Modelwright-generated Python models.

The goal is to keep Modelwright generic while collecting FABLE-C conventions in one public package:

- discover likely FABLE scenario input controls from workbook structure;
- declare those controls as named scenario parameters;
- expose a Jupyter-friendly control surface for scenario changes;
- run a generated Modelwright model with the selected scenario inputs;
- render standard FABLE outputs as pandas tables and matplotlib figures.

This repository does not store original FABLE Calculator workbooks, generated Python clones, or raw
validation outputs. Keep those under ignored `tmp/` paths.

## Development Workflow

This project uses the same agent-assisted workflow as Modelwright:

- read `AGENTS.md`, `ROADMAP.md`, and `CHANGE_LOG.md` before project-shaping work;
- keep the current plan in `ROADMAP.md`;
- record completed deliverables in `CHANGE_LOG.md`;
- use `planning/` for focused investigations and contracts;
- keep source workbooks, generated models, extracts, logs, and validation reports under ignored
  `tmp/`;
- once the public GitHub repo and `gh` access exist, map roadmap phases to GitHub parent issues and
  roadmap tasks to child issues;
- close every phase through a PR back to `main`, with Sphinx docs rebuilt in CI and deployed to
  GitHub Pages after merge.

The local remote is expected to be:

```text
https://github.com/UBC-FRESH/fable-pyculator.git
```

## Install For Development

Recommended VSCode/Jupyter setup from the `fable-pyculator` repo root:

```bash
scripts/bootstrap_dev_env.sh
```

Then select this interpreter as the VSCode notebook kernel:

```text
.venv/bin/python
```

Manual equivalent:

```bash
python -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -e '.[dev,notebook,docs]'
```

## Download FABLE Calculators

The current Modelwright benchmark metadata points to this public FABLE Calculator Dropbox folder:

```text
https://www.dropbox.com/scl/fo/ndgldfnq81v794mm8yebe/ADusMz23xtmYKDXoEkiNtJM?rlkey=d87qhjf5zd0pcowd5pfl5qdu7&st=qijm4tta&e=2&dl=0
```

In this checkout, the three public FABLE-C workbooks are stored under `tmp/private-workbooks/`.
They are ignored local benchmark artifacts. Verify them with:

```bash
sha256sum -c benchmarks/fable-calculator/checksums.sha256
```

The public 2020 FABLE Calculator documentation PDF is tracked under `reference/fable-calculator/`.

The core FABLE-C output data surfaces are the consecutive workbook sheets `FOOD`, `PRODUCTION`,
`TRADE`, `BIODIVERSITY`, `LAND`, `GHG`, and `WATER`.

## Early Notebook Shape

```python
from fable_pyculator import (
    FableCalculatorSpec,
    OutputIndicator,
    ScenarioControlSurface,
    ScenarioParameter,
    discover_output_tables,
    discover_scenario_definition_tables,
    discover_selection_controls,
    output_table_frame,
    run_scenario,
    scenario_definition_table_frame,
    scenario_definition_tables_for_location,
)

spec = FableCalculatorSpec(
    parameters=[
        ScenarioParameter(name="ambition", label="Scenario ambition", cell_ref="SCENARIOS selection!D20"),
    ],
    outputs=[
        OutputIndicator(name="ghg", label="GHG emissions", cell_ref="SCENARIOS selection!D22", unit="MtCO2e"),
    ],
)

controls = ScenarioControlSurface(spec)
controls

result = run_scenario(generated_model, spec, controls.values())
result.outputs
```

For real FABLE-C workbooks, discover the high-level selection controls, scenario-definition tables,
and output tables:

```python
selection_controls = discover_selection_controls("tmp/private-workbooks/2020_Open_FABLECalculator.xlsx")
definition_tables = discover_scenario_definition_tables("tmp/private-workbooks/2020_Open_FABLECalculator.xlsx")
output_tables = discover_output_tables("tmp/private-workbooks/2020_Open_FABLECalculator.xlsx")
spec = FableCalculatorSpec(
    selection_controls=selection_controls,
    scenario_definition_tables=definition_tables,
    output_tables=output_tables,
)

scenario_definition_table_frame(spec, "DietTarget")
scenario_definition_tables_for_location(spec, "S.3")

run = run_scenario(generated_model, spec, {"gdp_scen": "SSP1"})
output_table_frame(run, "ghg_resultsghg")
output_table_frame(run, "ghg_resultsghg", column_flavour_tags="OUTPUT-8")
output_table_frame(run, "ghg_resultsghg", column_flavour_tags="DATA")
output_table_frame(run, "ghg_resultsghg", column_flavour_tags="OUTPUT-*")
```

The first 2020 notebook loop helper uses ignored local artifacts by default:

```text
tmp/private-workbooks/2020_Open_FABLECalculator.xlsx
tmp/generated-models/fable-2020/generated_fable_2020_model.py
```

```python
from fable_pyculator import run_2020_notebook_loop

result = run_2020_notebook_loop({"gdp_scen": "SSP1"})
result.output_tables.keys()
result.output_tables["ghg_resultsghg"]
result.headline_frames["ghg_total_co2e"]
result.headline_figures["ghg_total_co2e"]
```

By default the loop renders every discovered output table and every curated headline frame from the
single generated-model run. Pass `output_table_names` or `headline_series_names` only when you want a
smaller rendered subset.

Tracked notebook example:

```text
examples/notebooks/fable-pyculator-2020-loop.ipynb
```

This notebook is intentionally committed after a successful 2020 benchmark run so GitHub can render
the example tables and figure directly in the browser.

In VSCode, point the notebook kernel at the `.venv` created in the `fable-pyculator` repo root.
The notebook setup cell prints the active environment prefix and warns if the selected kernel does
not appear to be that repo-local `.venv`.

The Sphinx guide expands this into a full workflow under
`docs/guides/2020-notebook-workflow.rst`, with validation boundaries recorded in
`docs/guides/validation-scope.rst`.

`fable-pyculator` is pre-release. The current alpha line is `0.1.0a1`; alpha releases must not be
described as stable public API compatibility, full editable scenario-definition widgets, production
readiness, full generated-model equivalence, or arbitrary country-calculator support.

The public API is intentionally small while the FABLE-specific conventions are being discovered from
real country calculators.

## Build Docs

```bash
.venv/bin/python -m pip install -e '.[dev,notebook,docs]'
.venv/bin/sphinx-build -b html docs _build/html -W
```

The `Docs Pages` GitHub Actions workflow builds Sphinx docs on pull requests to `main` and deploys
the built HTML to GitHub Pages after merges to `main`.

GitHub Pages URL:

```text
https://ubc-fresh.github.io/fable-pyculator/
```

See `docs/guides/release-deployment.rst` for the release and deployment runbook.

## Release Checks

Build and inspect release artifacts locally:

```bash
scripts/check_release_artifacts.sh
```

Release checks write build outputs under ignored `tmp/release-checks/`.

## Default Checks

```bash
.venv/bin/python -m ruff check .
.venv/bin/python -m pytest
.venv/bin/sphinx-build -b html docs _build/html -W
.venv/bin/python scripts/verify_docs_theme.py _build/html
scripts/check_release_artifacts.sh
sha256sum -c benchmarks/fable-calculator/checksums.sha256
```
