Skip to content

Commit

Permalink
Merge pull request #124 from Kitware/xarray
Browse files Browse the repository at this point in the history
feat(xarray): porting pyvista-xarray to pure vtk
  • Loading branch information
jourdain authored Nov 15, 2024
2 parents 1cfaf87 + cd200b2 commit 33be9ae
Show file tree
Hide file tree
Showing 111 changed files with 5,201 additions and 6,310 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[codespell]
skip = CHANGELOG.md
skip = CHANGELOG.md,tests/data/*
34 changes: 17 additions & 17 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.10"

# Install and run pre-commit
- run: |
Expand Down Expand Up @@ -46,32 +46,32 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Set up NPM
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Vue component dependencies
run: npm ci
working-directory: pan3d-js
- name: Lint Vue components
run: npm run lint
working-directory: pan3d-js
- name: Build Vue components
run: npm run build
working-directory: pan3d-js

# Conditionally install pykdtree from source for MacOS only
- name: Install pykdtree from source on macOS
if: matrix.config.os == 'macos-latest'
run: |
export USE_OMP=0
pip install --no-binary pykdtree pykdtree>=1.3.13
- name: Install OSMesa for Linux
if: matrix.config.os == 'ubuntu-latest'
run: sudo apt-get install -y libosmesa6-dev

- name: Install and Run Tests (without viewer)
if: matrix.config.os == 'windows-latest'
run: |
pip install .
pip install -r tests/requirements.txt
pytest -s ./tests/test_xarray.py
pytest -s ./tests/test_builder.py
working-directory: .

- name: Install and Run Tests
- name: Install and Run Tests (with viewer)
if: matrix.config.os != 'windows-latest'
run: |
pip install .
pip install -r tests/requirements.txt
pytest -s ./tests/test_xarray.py
pytest -s ./tests/test_builder.py
pip install .[geotrame]
pip install .[viewer]
pytest -s ./tests/test_viewer.py
working-directory: .
39 changes: 8 additions & 31 deletions .github/workflows/test_and_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.10"

# Install and run pre-commit
- run: |
Expand All @@ -28,7 +28,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9"]
python-version: ["3.10"]
config:
- {
name: "Linux",
Expand Down Expand Up @@ -56,26 +56,17 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Set up NPM
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Vue component dependencies
run: npm ci
working-directory: pan3d-js
- name: Lint Vue components
run: npm run lint
working-directory: pan3d-js
- name: Build Vue components
run: npm run build
working-directory: pan3d-js
- name: Install OSMesa for Linux
if: matrix.config.os == 'ubuntu-latest'
run: sudo apt-get install -y libosmesa6-dev

- name: Install and Run Tests
run: |
pip install .
pip install -r tests/requirements.txt
pytest -s ./tests/test_xarray.py
pytest -s ./tests/test_builder.py
pip install .[geotrame]
pip install .[viewer]
pytest -s ./tests/test_viewer.py
working-directory: .

Expand All @@ -97,21 +88,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: "3.9"

- name: Set up NPM
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Vue component dependencies
run: npm ci
working-directory: pan3d-js
- name: Lint Vue components
run: npm run lint
working-directory: pan3d-js
- name: Build Vue components
run: npm run build
working-directory: pan3d-js
python-version: "3.10"

# https://python-semantic-release.readthedocs.io/en/latest/migrating_from_v7.html#repurposing-of-version-and-publish-commands
- name: Python Semantic Release
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.DS_Store
node_modules
.venv
.venv*
*.nc
*.data-origin.json

examples/jupyter/*.gif
site/*
Expand Down
39 changes: 19 additions & 20 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ For an introduction to this project, check out our [blog post][blog-post-link].

## Installation

To install requirements for the Pan3D DatasetBuilder class only:
To install requirements for the Pan3D VTK mesh builder class only:

pip install pan3d

To install requirements for the GeoTrame user interface:
To install requirements for the graphical user interface (viewers + explorers):

pip install "pan3d[geotrame]"
pip install "pan3d[viewer]"

**Optional**: to install requirements for Pangeo and ESGF catalogs, respectively:

Expand All @@ -39,43 +39,42 @@ To install requirements for the GeoTrame user interface:

## Quick Start

`geotrame` is the main entrypoint for launching GeoTrame locally. Below are some example usages.
`xr-viewer` is the main entrypoint for launching XArray Viewer locally. Below are some example usages.

To launch GeoTrame without a target dataset to browse XArray examples:
To launch XArray Viewer without a target dataset to browse XArray examples:

geotrame
xr-viewer

To launch GeoTrame with a local path to a target dataset:
To launch XArray Viewer with a local path to a target dataset:

geotrame --dataset=/path/to/dataset.zarr
xr-viewer --xarray-file ./examples/example_dataset.nc

To launch GeoTrame with a remote URL to a target dataset:
To launch XArray Viewer with a remote URL to a target dataset:

geotrame --dataset=https://host.org/link/to/dataset.zarr
xr-viewer --xarray-url https://host.org/link/to/dataset.zarr

To launch GeoTrame with a compatible configuration file (see [examples][examples-link]):
To launch XArray Viewer with a compatible configuration file (see [examples][examples-link]):

geotrame --config_path=/path/to/pan3d_state.json
xr-viewer --import-state ./examples/example_config_xarray.json

To launch GeoTrame with the option to browse the Pangeo and ESGF Dataset Catalogs (see [Catalogs Tutorial](tutorials/catalogs.md)):
To launch the Catalog browser will allow you to query the Pangeo and ESGF Dataset Catalogs (see [Catalogs Tutorial](tutorials/catalogs.md)) depending on the available dependencies:

geotrame --catalogs pangeo esgf
xr-catalog

Or you may specify only one catalog:
You may have to install the required dependencies:

geotrame --catalogs pangeo

geotrame --catalogs esgf
pip install "pan3d[pangeo]"
pip install "pan3d[esgf]"


> The `geotrame` entrypoint will automatically launch your default browser to open `localhost:8080`.
> The `xr-viewer` entrypoint will automatically launch your default browser to open `localhost:8080`.
>
> To launch without opening your browser, add the `--server` argument to your command.

## Tutorials

- [How to use GeoTrame](tutorials/dataset_viewer.md)
- [How to use XArray Viewer](tutorials/dataset_viewer.md)
- [GeoTrame command line](tutorials/command_line.md)
- [Catalogs Tutorial](tutorials/catalogs.md)
- [How to use Pan3D in a Jupyter notebook](tutorials/jupyter_notebook.md)
Expand Down
124 changes: 59 additions & 65 deletions docs/api/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,40 @@

## Introduction

Pan3D uses JSON files to save an application state for reuse. The GeoTrame UI and the Pan3D DatasetBuilder API include access to import and export functions which read and write these configuration files, respectively. This documentation provides guidelines for reading and writing these files manually.
Pan3D uses JSON files to save an application state for reuse. The XArray Viewer and the Pan3D Dataset builder enable import and export features to quickly get back to the data or state you've left off. This documentation provides guidelines for reading and writing these files manually.

There are five sections available in the configuration file format: `data_origin`, `data_array`, `data_slices`, `ui`, and `render`. The values in these sections will be passed to various attributes on the current `DatasetBuilder` instance and, if applicable, the corresponding `DatasetViewer` instance state.
There are two sections dedicated to configure the data access and VTK mesh extraction while the two remaining are specific for the viewer and rendering setup. The core and mandatory part is the `data_origin` section which provide information on where the data is located. Then we have the `dataset_config` which capture the pieces we want to load from the XArray dataset to produce a VTK mesh. The `preview` section is to configure the default viewer in term of color and scaling. Finally the `camera` gather any specific camera location so you can see the exact same thing as when you saved a given state. All of those sections are optional except the `data_origin` and `dataset_config` is the generated mesh is important to you.

## Example

```
{
"data_origin": "https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/noaa-coastwatch-geopolar-sst-feedstock/noaa-coastwatch-geopolar-sst.zarr",
"data_array": {
"name": "analysed_sst",
"data_origin": {
"source": "url",
"id": "https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/noaa-coastwatch-geopolar-sst-feedstock/noaa-coastwatch-geopolar-sst.zarr",
"order": "C"
},
"dataset_config": {
"x": "lon",
"y": "lat",
"t": "time",
"t_index": 5
},
"data_slices": {
"lon": [1000, 6000, 20],
"lat": [500, 3000, 20],
},
"ui": {
"main_drawer": false,
"axis_drawer": false,
"expanded_coordinates": []
"arrays": [
"analysed_sst"
],
"t_index": 5,
"slices": {
"lon": [1000, 6000, 20],
"lat": [500, 3000, 20]
}
},
"render": {
"auto": false,
"x_scale": 1,
"y_scale": 1,
"z_scale": 1,
"scalar_warp": false,
"cartographic": false,
"transparency": false,
"transparency_function": "linear",
"colormap": "viridis"
"preview": {
"color_by": "analysed_sst",
"color_preset": "Cool to Warm",
"color_min": 271.1499938964844,
"color_max": 307.25,
"scale_x": 1,
"scale_y": 1,
"scale_z": 1
}
}
```
Expand All @@ -45,61 +44,56 @@ For more example configuration files, visit our [Examples on Github](https://git


## `data_origin` (Required)
The value for this key may be a string or dictionary. If this value is a string, it should contain a local path or remote URL referencing a target dataset readable by `xarray.open_dataset`. If this value is a dictionary, it should adhere to the following schema.
The value for this key is a dictionary that should adhere to the following schema.

| Key | Required? | Type | Value Description |
|-----|-----------|------|-------------------|
| `source` | NO (default="default") | `str` | A string specifying a module to interpret the value for `id`. Options include "default", "xarray", "pangeo", "esgf". |
| `source` | YES | `str` | A string specifying a module to interpret the value for `id`. Options include "file", "url", "xarray", "pangeo", "esgf". |
| `id` | YES | `str` | A unique identifier of the target dataset. Depending on the value for `source`, this may be a path, url, name, or other unique id. |
| `order` | NO | `str` | Specify the order convention which can either be `F` (Fortran) or `C`. The default is `C` |

## `data_array` (Required)
## `dataset_config` (Optional)
The value for this key should be a mapping specifying how to interpret the information in the target dataset. The following table describes keys available in this mapping schema.

| Key | Required? | Type | Value Description |
|-----|-----------|------|-------------------|
|`name`|YES |`str` |The field that will be mapped onto a mesh for rendering. This should be a name of an array that exists in the current dataset. This value will be passed to `DatasetBuilder.data_array_name`. |
|`x` |NO (default=None) |`str`|The world coordinate value along X describing the grid/mesh. This should be the name of a coordinate that exists in the data array. This value will be passed to `DatasetBuilder.set_data_array_axis_names`.|
|`y` |NO (default=None) |`str`|The world coordinate value along Y describing the grid/mesh. This should be the name of a coordinate that exists in the data array. This value will be passed to `DatasetBuilder.set_data_array_axis_names`.|
|`z` |NO (default=None) |`str`|The world coordinate value along Z describing the grid/mesh. This should be the name of a coordinate that exists in the data array. This value will be passed to `DatasetBuilder.set_data_array_axis_names`.|
|`t` |NO (default=None) |`str`|The coordinate name that represents slices of data, which may be time. Unlike other axes, this axis can only show one index at a time. This should be the name of a coordinate that exists in the data array. This value will be passed to `DatasetBuilder.set_data_array_axis_names`.|
|`t_index` |NO (default=0)|`int`|The index of the current time slice. Must be an integer >= 0 and < the length of the current time coordinate.This value will be passed to `DatasetBuilder.set_data_array_time_index`.|

## `data_slices` (Optional)
The value for this key should be a mapping of coordinate names (which are likely used as values for `x` | `y` | `z` | `t` in the `data_array` section) to slicing arrays. This mapping will be formatted and passed to `DatasetBuilder.set_data_array_coordinates`.

Each slicing array should be a list of three values `[start, stop, step]`.
|`x` |NO (default=None) |`str`|The world coordinate value along X describing the grid/mesh. This should be the name of a coordinate that exists in the data array. |
|`y` |NO (default=None) |`str`|The world coordinate value along Y describing the grid/mesh. This should be the name of a coordinate that exists in the data array. |
|`z` |NO (default=None) |`str`|The world coordinate value along Z describing the grid/mesh. This should be the name of a coordinate that exists in the data array. |
|`t` |NO (default=None) |`str`|The coordinate name that represents slices of data, which may be time. Unlike other axes, this axis can only show one index at a time. This should be the name of a coordinate that exists in the data array. |
|`t_index` |NO (default=0)|`int`|The index of the current time slice. Must be an integer >= 0 and < the length of the current time coordinate. |
|`arrays` |NO (default=[])|`list[str]`|The set of array names we want the output mesh to contains. |
|`slices` |NO (default={})|`dict`|The set of slices and indexes performing a selection on the XArray dataset. It is a dictionary where keys are to the various coordinates array that we want to filter and the values can either define a slice (`[start, stop, step]`) or an index (`int`). |

`start`: the index at which the sliced data should start (inclusive)
__Slice explained:__
- `start`: the index at which the sliced data should start (inclusive)
- `stop`: the index at which the sliced data should stop (exclusive)
- `step`: an integer > 0 which represents the number of items to skip when slicing the data (e.g. step=2 represents 0.5 resolution)

`stop`: the index at which the sliced data should stop (exclusive)
## `preview` (Optional)

`step`: an integer > 0 which represents the number of items to skip when slicing the data (e.g. step=2 represents 0.5 resolution)

## `ui` (Optional)
The value for this key should be a mapping of any number of UI state values. The following table describes keys available in this mapping schema.
This section is only relevant when using the default XArray Viewer from Pan3D. It capture what to display and how.
The following table describes keys available in this mapping schema.


| Key | Required? | Type | Value Description |
|-----|-----------|------|-------------------|
|`main_drawer`|NO (default=False)|`bool`|If true, open the lefthand drawer for dataset and data array browsing/selection.|
|`axis_drawer`|NO (default=False)|`bool`|If true, open the righthand drawer for axis assignment/slicing. **Note:** By default, this becomes True when a data array is selected.|
|`unapplied_changes`|NO (default=False)|`bool`|If true, show "Apply and Render" button, which when clicked will apply any unapplied changes and rerender.|
|`error_message`|NO (default=None)|`str`|If not None, this string will show as the error message above the render area.|
|`more_info_link`|NO (default=None)|`str`|If not None, this string should contain a link to more information about the current dataset. This link will appear below the dataset selection box.|
|`expanded_coordinates`|NO (default=`[]`)|`list[str]`|This list should contain the names of all coordinates which should appear expanded in the righthand axis drawer. **Note:** By default, this list is populated with all available coordinate names once the data array is selected.|


## `render` (Optional)
The value for this key should be a mapping of any number of render state values. The following table describes keys available in this mapping schema.

|`view_3d`|NO (default=True)|`bool`|If true, the 3D interaction will rotate the dataset. Otherwise, a 2D interaction will be used (pan instead of rotate) along with parallel projection.|
|`color_by`|NO (default=None)|`str`|Name of a loaded array that we want to display.|
|`color_preset`|NO (default='Cool to Warm')|`str`|Name of a color preset for scalar mapping.|
|`color_min`|NO (default=None)|`float`|Scalar value that will be mapped to the lower end of the color scale.|
|`color_max`|NO (default=None)|`float`|Scalar value that will be mapped to the upper end of the color scale.|
|`scale_x`|NO (default=`1`)|`float`|Rendering scale to apply on the X axis.|
|`scale_y`|NO (default=`1`)|`float`|Rendering scale to apply on the Y axis.|
|`scale_z`|NO (default=`1`)|`float`|Rendering scale to apply on the Z axis.|


## `camera` (Optional)
The value for this key configure the VTK camera for any specific viewer or explorer.
| Key | Required? | Type | Value Description |
|-----|-----------|------|-------------------|
|`auto`|NO (default=True)|`bool`|If true, apply changes and rerender every time a configuration change is made.|
|`x_scale`|NO (default=1)|`int`|The relative scale of the X axis in the rendered scene.|
|`y_scale`|NO (default=1)|`int`|The relative scale of the Y axis in the rendered scene.|
|`z_scale`|NO (default=1)|`int`|The relative scale of the Z axis in the rendered scene.|
|`scalar_warp`|NO (default=False)|`bool`|If true, Apply scalar warping to the rendered mesh (extrude values in z-axis proportional to their magnitude).|
|`cartographic`|NO (default=False)|`bool`|If true, render the data wrapped around an earth sphere.|
|`transparency`|NO (default=False)|`bool`|If true, enable transparency mode for the rendered mesh, applying the current transparency function.|
|`transparency_function`|NO (default="linear")|`str`|The name of the transparency function to apply when transparency is enabled. Options are "linear", "linear_r", "geom", "geom_r", "sigmoid", and "sigmoid_r".|
|`colormap`|NO (default="viridis")|`str`|The name of the colormap to apply to the rendered mesh. Any matplotlib colormap name is a valid value.|
|`position`|NO (default=None)|`list[float]`|3D Coordinate of the camera position.|
|`view_up`|NO (default=None)|`list[float]`|Vector defining the vertival axis.|
|`focal_point`|NO (default=None)|`list[float]`|3D Coordinate of where the camera is looking at.|
|`parallel_projection`|NO (default=0)|`int`|Either 1 or 0 to define if the camera should use perpective or parallel projection.|
|`parallel_scale`|NO (default=None)|`float`|Zooming factor when `parallel_projection=1`.|
6 changes: 3 additions & 3 deletions docs/api/dataset_builder.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# [DatasetBuilder][module-link] API Reference
# [vtkXArrayRectilinearSource][module-link] API Reference

[module-link]: https://github.com/Kitware/pan3d/blob/main/pan3d/dataset_builder.py
[module-link]: https://github.com/Kitware/pan3d/blob/main/pan3d/xarray/algorithm.py

::: pan3d.dataset_builder.DatasetBuilder
::: pan3d.xarray.algorithm.vtkXArrayRectilinearSource
handler: python
Loading

0 comments on commit 33be9ae

Please sign in to comment.