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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- BREAKING: `isku.ExtractionWorkflow` is now `isku.ExtractionTemplate`.
- BREAKING: `isku.ProjectionWorkflow` is now `isku.ProjectionTemplate`.
- BREAKING: `isku.build_extraction_workflow` is now `isku.build_extraction_template`.
- BREAKING: `isku.build_projection_workflow` is now `isku.build_projection_template`.
- BREAKING: In `isku.extract_regions`, the `workflow` argument is now `template`.
- Improved README.
- Improved CONTRIBUTING.
- Add project URLs to package metadata.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def _postprocess(ds):
return ds[["impact"]] + 10


test_impact_model = isku.build_projection_workflow(
test_impact_model = isku.build_projection_template(
pre=_preprocess,
project=_linear_impact_model,
post=_postprocess,
Expand All @@ -71,7 +71,7 @@ test_impact_model = isku.build_projection_workflow(
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
This example uses pure functions to define workflow, or template, 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.

Expand Down Expand Up @@ -126,7 +126,7 @@ def _add_ten(ds):
return ds[["variable1"]] + 10


my_extraction_workflow = isku.build_extraction_workflow(
my_extraction_workflow = isku.build_extraction_template(
pre=_add_one, # Before regionalization.
post=_add_ten, # After regionalization.
)
Expand All @@ -135,7 +135,7 @@ my_extraction_workflow = isku.build_extraction_workflow(
# Put it all together to extract regions from gridded data.
transformed = isku.extract_regions(
gridded_data,
workflow=my_extraction_workflow,
template=my_extraction_workflow,
regions=my_regions,
)
```
Expand Down
8 changes: 4 additions & 4 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def _postprocess(ds):
return ds[["impact"]] + 10


test_impact_model = isku.build_projection_workflow(
test_impact_model = isku.build_projection_template(
pre=_preprocess,
project=_linear_impact_model,
post=_postprocess,
Expand All @@ -49,7 +49,7 @@ test_impact_model = isku.build_projection_workflow(
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
This example uses pure functions to define workflow, or "template", 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.

Expand Down Expand Up @@ -104,7 +104,7 @@ def _add_ten(ds):
return ds[["variable1"]] + 10


my_extraction_workflow = isku.build_extraction_workflow(
my_extraction_workflow = isku.build_extraction_template(
pre=_add_one, # Before regionalization.
post=_add_ten, # After regionalization.
)
Expand All @@ -113,7 +113,7 @@ my_extraction_workflow = isku.build_extraction_workflow(
# Put it all together to extract regions from gridded data.
transformed = isku.extract_regions(
gridded_data,
workflow=my_extraction_workflow,
template=my_extraction_workflow,
regions=my_regions,
)
```
74 changes: 37 additions & 37 deletions src/isku/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
import xarray as xr

__all__ = [
"ExtractionWorkflow",
"ExtractionTemplate",
"GridWeightingRegions",
"ProjectionWorkflow",
"ProjectionTemplate",
"RegionExtractor",
"build_extraction_workflow",
"build_projection_workflow",
"build_extraction_template",
"build_projection_template",
"extract_regions",
"project",
]


class ExtractionWorkflow(Protocol):
class ExtractionTemplate(Protocol):
"""
Template for pre and post region extraction transformation

See Also
--------
build_extraction_workflow: Quickly build extraction workflow from functions for regionalization with pre/post transformations.
extract_regions: Apply a workflow to extract a new regionalized dataset from gridded data.
build_extraction_template: Quickly build extraction template from functions for regionalization with pre/post transformations.
extract_regions: Apply a template to extract a new regionalized dataset from gridded data.
RegionExtractor: Protocol for regionalizing, or extracting regions from a dataset.
"""

Expand All @@ -46,8 +46,8 @@ class RegionExtractor(Protocol):

See Also
--------
extract_regions: Apply a workflow to extract a new regionalized dataset from gridded data with pre/post transformations.
ExtractionWorkflow: Technical protocol for a workflow with pre/post regionalization transformations.
extract_regions: Apply a template to extract a new regionalized dataset from gridded data with pre/post transformations.
ExtractionTemplate: Technical protocol for a workflow with pre/post regionalization transformations.
"""

def extract_regions(self, ds: xr.Dataset) -> xr.Dataset:
Expand All @@ -59,18 +59,18 @@ def extract_regions(self, ds: xr.Dataset) -> xr.Dataset:

# This dataclass is a quick and simple way to get a concrete instance of the protocol.
@dataclass(frozen=True)
class _SimpleExtractionWorkflow(ExtractionWorkflow):
class _SimpleExtractionTemplate(ExtractionTemplate):
pre_extract: Callable[[xr.Dataset], xr.Dataset]
post_extract: Callable[[xr.Dataset], xr.Dataset]


def build_extraction_workflow(
def build_extraction_template(
*, pre: Callable[[xr.Dataset], xr.Dataset], post: Callable[[xr.Dataset], xr.Dataset]
) -> ExtractionWorkflow:
) -> ExtractionTemplate:
"""
Build a workflow of tranformation steps applied to input gridded data, pre/post regionalization, to create a derived variable as output
Build a template of tranformation steps applied to input gridded data, pre/post regionalization, to create a derived variable as output

This function is a quick and simple way to build an ExtractionWorkflow from two simple functions.
This function is a quick and simple way to build an ExtractionTemplate from two simple functions.

These steps should be general. They may contain logic for sanity checks
on inputs and outputs, calculating derived variables and climate indices,
Expand All @@ -81,11 +81,11 @@ def build_extraction_workflow(

See Also
--------
extract_regions: Apply a workflow to extract a new regionalized dataset from gridded data.
build_extraction_workflow: Quickly build extraction workflow from functions for regionalization.
ExtractionWorkflow: The underlaying protocol for a workflow that extracts a regionalized dataset.
extract_regions: Apply a template to extract a new regionalized dataset from gridded data.
build_extraction_template: Quickly build extraction template from functions for regionalization.
ExtractionTemplate: The underlaying protocol for a workflow that extracts a regionalized dataset.
"""
return _SimpleExtractionWorkflow(pre_extract=pre, post_extract=post)
return _SimpleExtractionTemplate(pre_extract=pre, post_extract=post)


# Use class for segment weights because we're making assumptions/enforcements about the weight data's content and interactions...
Expand All @@ -102,8 +102,8 @@ class GridWeightingRegions(RegionExtractor):

See Also
--------
extract_regions: Use SegmentWeights in a workflow to extract new regionalized dataset.
build_extraction_workflow: Quickly build extraction workflow from functions for regionalization.
extract_regions: Extract new regionalized dataset.
build_extraction_template: Quickly build extraction template from functions for regionalization.
RegionExtractor: Protocol for regionalizing, or extracting regions from a dataset.
"""

Expand Down Expand Up @@ -133,27 +133,27 @@ def extract_regions(self, ds: xr.Dataset) -> xr.Dataset:


def extract_regions(
ds: xr.Dataset, *, workflow: ExtractionWorkflow, regions: RegionExtractor
ds: xr.Dataset, *, template: ExtractionTemplate, regions: RegionExtractor
) -> xr.Dataset:
"""
Use transformations in 'workflow' to extract 'regions' from gridded dataset, 'ds', returning a regionalized dataset
Use transformations in 'template' to extract 'regions' from gridded dataset, 'ds', returning a regionalized dataset

This function specifically does not just regionalize through zonal aggregation. It uses 'workflow' to apply pre/post regionalization transformations to create new datasets and variables.
This function specifically does not just regionalize through zonal aggregation. It uses 'template' to apply pre/post regionalization transformations to create new datasets and variables.

See Also
--------
build_extraction_workflow: Quickly build extraction workflow from functions for regionalization.
build_extraction_template: Quickly build extraction workflow from functions for regionalization.
"""
return workflow.post_extract(regions.extract_regions(workflow.pre_extract(ds)))
return template.post_extract(regions.extract_regions(template.pre_extract(ds)))


class ProjectionWorkflow(Protocol):
class ProjectionTemplate(Protocol):
"""
Template for projecting a model with pre and post processing.

See Also
--------
build_projection_workflow: Build a projection workflow from simple functions.
build_projection_template: Build a projection template from simple functions.
"""

def pre_project(self, d: xr.Dataset) -> xr.Dataset:
Expand All @@ -177,43 +177,43 @@ def post_project(self, d: xr.Dataset) -> xr.Dataset:

# This dataclass is a quick and simple way to get a concrete instance of the protocol.
@dataclass(frozen=True)
class _SimpleProjectionWorkflow(ProjectionWorkflow):
class _SimpleProjectionTemplate(ProjectionTemplate):
pre_project: Callable[[xr.Dataset], xr.Dataset]
project: Callable[[xr.Dataset], xr.Dataset]
post_project: Callable[[xr.Dataset], xr.Dataset]


def build_projection_workflow(
def build_projection_template(
*,
pre: Callable[[xr.Dataset], xr.Dataset],
project: Callable[[xr.Dataset], xr.Dataset],
post: Callable[[xr.Dataset], xr.Dataset],
) -> ProjectionWorkflow:
) -> ProjectionTemplate:
"""
Use simple functions to quickly build a model to project effects, impacts and/or damages.

This function is a quick and simple way to build an ProjectionWorkflow from three simple functions.
This function is a quick and simple way to build an ProjectionTemplate from three simple functions.

See Also
--------
project: Apply a projection workflow to a dataset.
ProjectionWorkflow: Technical ProjectionWorkflow protocol.
project: Apply a projection template to a dataset.
ProjectionTemplate: Technical ProjectionTemplate protocol.
"""
return _SimpleProjectionWorkflow(
return _SimpleProjectionTemplate(
pre_project=pre,
project=project,
post_project=post,
)


def project(d: xr.Dataset, *, model: ProjectionWorkflow) -> xr.Dataset:
def project(d: xr.Dataset, *, model: ProjectionTemplate) -> xr.Dataset:
"""
Project a dataset of predictors, 'd', with 'model' to return a projected dataset

See Also
--------
build_projection_workflow: Build a projection workflow from simple functions.
ProjectionWorkflow: Technical ProjectionWorkflow protocol.
build_projection_template: Build a projection template from simple functions.
ProjectionTemplate: Technical ProjectionTemplate protocol.
"""
preprocessed = model.pre_project(d)
projected = model.project(preprocessed)
Expand Down
4 changes: 2 additions & 2 deletions tests/smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

def test_basic_projection():
"""
Basic test running build_projection_workflow() with project().
Basic test running build_projection_template() with project().
"""
predictors = xr.Dataset({"foobar": (["idx"], [0, 0, 0])})
params = xr.Dataset({"ni": (["idx"], [1, 2, 3])})
Expand All @@ -27,7 +27,7 @@ def _post(x):
def _model(x):
return (x["foobar"] * 2 + x["ni"]).to_dataset(name="impact")

test_impact_model = isku.build_projection_workflow(
test_impact_model = isku.build_projection_template(
pre=_pre,
project=_model,
post=_post,
Expand Down
6 changes: 3 additions & 3 deletions tests/test_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

def test_extract_regions():
"""
Create simple extraction workflow and test basic region extraction.
Create simple extraction template and test basic region extraction.
"""
input_ds = xr.Dataset({"variable1": (["idx"], [0, 0, 0])})
expected = xr.Dataset({"variable1": (["idx"], [13.5, 13.5, 13.5])})
Expand All @@ -23,7 +23,7 @@ def _pre(x):
def _post(x):
return x[["variable1"]] + 10

test_transform = isku.build_extraction_workflow(pre=_pre, post=_post)
test_transform = isku.build_extraction_template(pre=_pre, post=_post)

class FakeRegionalization(isku.RegionExtractor):
"""
Expand All @@ -35,7 +35,7 @@ def extract_regions(self, ds):

output = isku.extract_regions(
input_ds,
workflow=test_transform,
template=test_transform,
regions=FakeRegionalization(),
)

Expand Down
6 changes: 3 additions & 3 deletions tests/test_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import xarray as xr

from isku import build_projection_workflow, project
from isku import build_projection_template, project


def test_basic_projection():
"""
Basic test running build_projection_workflow() with project().
Basic test running build_projection_template() with project().
"""
predictors = xr.Dataset({"foobar": (["idx"], [0, 0, 0])})
params = xr.Dataset({"ni": (["idx"], [1, 2, 3])})
Expand All @@ -27,7 +27,7 @@ def _post(x):
def _model(x):
return (x["foobar"] * 2 + x["ni"]).to_dataset(name="impact")

test_impact_model = build_projection_workflow(
test_impact_model = build_projection_template(
pre=_pre,
project=_model,
post=_post,
Expand Down