Skip to content
Merged
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
29 changes: 29 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Documentation
on:
push:
branches:
- master
- main
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/configure-pages@v6
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- run: pip install zensical
- run: zensical build --clean
- uses: actions/upload-pages-artifact@v5
with:
path: site
- uses: actions/deploy-pages@v5
id: deployment
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Test and test-coverage badges to README.
- Added documentation to docs/.

### Changed

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contributing to `isku`
# Contributing

Contributions are welcome, and they are greatly appreciated!
Every little bit helps, and credit will always be given.
Expand Down
124 changes: 124 additions & 0 deletions docs/1_user_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
icon: lucide/signpost
---

# User Guide

!!! warning
:lucide-construction: This page is under construction.

### Projecting models

Projecting data with a model in `isku` is similar to the preprocess/predict/postprocess workflow you might already be familar with.

In `isku`, we could do a linear model with pre/post-processing like:

```python
import isku

import numpy as np
import xarray as xr

# Some toy input data to work with.
input_data = xr.Dataset(
{
"coef": (["region"], [0, 0, 0]),
"tas": (["region"], [1, 2, 3]),
}
)

# Define a basic workflow for the projection model, pre/post-processing steps.
def _preprocess(ds):
my_coef = ds["coef"] + 1
my_tas = ds["tas"]
return xr.Dataset({"coef": my_coef, "tas": my_tas})


def _linear_impact_model(ds):
y = ds["coef"] * 2 + ds["tas"]
return xr.Dataset({"impact": y})


def _postprocess(ds):
return ds[["impact"]] + 10


test_impact_model = isku.build_projection_workflow(
pre=_preprocess,
project=_linear_impact_model,
post=_postprocess,
)

# Put it together and run the projection.
projected = isku.project(input_data, model=test_impact_model)
```

This example uses pure functions to define workflow steps. This can be useful for quick analysis but `isku` also accepts
custom objects adhering to the select protocols. The intent is that components can be quickly used, ignored, extended or
replaced as needed by a project.

### Extracting regions

The relationship between data transformations and region extraction can be complex in impact and damage research.

Say you have temperature data on a regular latitude-longitude grid. You need to extract regions from this grid, e.g.
political boundaries, but you need to weight each temperature grid point by the proportion of the region's population
exposed to temperature within each region. To make matters more complex you likely need to be specific about additional processing and transformation
before and after regionalization. This is a niche case but a common headache.

We can handle this type of transformation in `isku` like:

```python
import isku

import numpy as np
import xarray as xr


# Define some toy data to transform and regionalize.
gridded_data = xr.DataArray(
np.arange(25).reshape([5, 5]),
dims=("lon", "lat"),
coords={
"lon": np.arange(5),
"lat": np.arange(5),
},
name="variable1",
).to_dataset()

# Refine regions and how they weight each grid point in the gridded data.
# This is usually read from file, but we're making up a quick example dataset.
my_regions = isku.GridWeightingRegions(
xr.Dataset(
{
"region": (["idx"], ["a", "a", "a", "b"]),
"weight": (["idx"], [0.3, 0.3, 0.3, 1.0]),
"lon": (["idx"], [2, 3, 4, 1]),
"lat": (["idx"], [0, 0, 0, 2]),
},
)
)

# Define workflow with pre/post regionalization transformations.
def _add_one(ds):
return ds[["variable1"]] + 1


def _add_ten(ds):
return ds[["variable1"]] + 10


my_extraction_workflow = isku.build_extraction_workflow(
pre=_add_one, # Before regionalization.
post=_add_ten, # After regionalization.
)


# Put it all together to extract regions from gridded data.
transformed = isku.extract_regions(
gridded_data,
workflow=my_extraction_workflow,
regions=my_regions,
)
```

7 changes: 7 additions & 0 deletions docs/2_api_reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
icon: lucide/binary
---

# API reference

::: isku
5 changes: 5 additions & 0 deletions docs/3_changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
icon: lucide/scroll-text
---

--8<-- "CHANGELOG.md"
9 changes: 9 additions & 0 deletions docs/4_faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
icon: lucide/message-circle-question-mark
---

# FAQ

!!! warning
:lucide-construction: This page is under construction.

11 changes: 11 additions & 0 deletions docs/4_support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
icon: lucide/life-buoy
---

# Support

!!! warning
:lucide-construction: This page is under construction.

`isku` is open-source software made available under the terms of either the MIT License or the Apache License 2.0, at your option.

5 changes: 5 additions & 0 deletions docs/5_contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
icon: lucide/heart
---

--8<-- "CONTRIBUTING.md"
58 changes: 58 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
icon: lucide/sparkle
---

# Get started

!!! warning
:lucide-construction: This page is under construction.


## Why use isku?

`isku` is a minimalist Python + xarray-based climate impact projection framework for researchers with little time.

### Features

* Define and apply three-step models to project climate effects, impacts, and damages.

* Extract regionalized variables from regularly gridded data, such as downscaled general circulation model output.

* Minimalist.

* Loosely coupled components and protocols for quick scripts with functions or gnarly OOP-heavy applications.

* Designed around `xarray.Dataset` to work with larger-than-memory datasets and distributed computing (dask!), GPUs, TPUs, streaming datasets.

* Great for weird ad hoc projects and researchers that love rechunking big data!

## Installation

`isku` is a Python package [available for download from PyPI](https://pypi.org/project/isku/).

Using `pip` you can install this package with

```
pip install isku
```

best practice suggest installing the package into a virtual environment.

For a `uv` project this is

```
uv add isku
```

Install the unreleased and unstable bleeding-edge version of the package with:

```shell
pip install git+https://github.com/brews/isku
```

using `pip` or with a project in `uv`, do

```shell
uv add git+https://github.com/brews/isku
```

8 changes: 8 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ test:

# Format, lint, and test project
validate: format lint test

# Build docs site
build-docs:
uv run zensical build --clean

# Start local web server to serve docs site
serve-docs:
uv run zensical serve
11 changes: 9 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "isku"
version = "0.1.0"
description = "Minimalist Python + xarray-based climate impact/damage projection framework for researchers with little time."
description = "Minimalist Python + xarray-based climate impact projection framework for researchers with little time."
readme = "README.md"
authors = [
{ name = "Brewster Malevich", email = "bmalevich@rhg.com" }
Expand All @@ -16,11 +16,18 @@ requires = ["uv_build>=0.11.11,<0.12.0"]
build-backend = "uv_build"

[dependency-groups]
dev = [
tests = [
"numpy>=2.4.4",
"pytest>=9.0.3",
"pytest-cov>=7.1.0",
"ruff>=0.15.12",
"ty>=0.0.34",
]
docs = [
"mkdocstrings[python]>=1.0.4",
"zensical>=0.0.40",
]
dev = [
{ include-group = "docs"},
{ include-group = "tests"},
]
Loading
Loading