<a style="border-width:0" href="https://doi.org/10.21105/joss.05059">
<img src="https://joss.theoj.org/papers/10.21105/joss.05059/status.svg" alt="DOI badge" ></a>
[](https://zenodo.org/badge/latestdoi/411249045)
[](https://github.com/ArcticSnow/TopoPyScale/blob/main/LICENSE)

[![][docs-dev-img]][docs-dev-url]
[](https://pepy.tech/projects/topopyscale)

Binder Notebooks Examples: [](https://mybinder.org/v2/gh/ArcticSnow/TopoPyScale_examples/HEAD)
[docs-dev-img]: https://img.shields.io/badge/docs-latest-blue.svg
[docs-dev-url]: https://topopyscale.readthedocs.io
# TopoPyScale
Python version of Toposcale packaged as a Pypi library. Toposcale is an original idea of Joel Fiddes to perform topography-based downscaling of climate data to the hillslope scale.
Documentation avalaible: https://topopyscale.readthedocs.io

**References:**
- Filhol et al., (2023). TopoPyScale: A Python Package for Hillslope Climate Downscaling. Journal of Open Source Software, 8(86), 5059, https://doi.org/10.21105/joss.05059
And the original method it relies on:
- Fiddes, J. and Gruber, S.: TopoSCALE v.1.0: downscaling gridded climate data in complex terrain, Geosci. Model Dev., 7, 387–405, https://doi.org/10.5194/gmd-7-387-2014, 2014.
- Fiddes, J. and Gruber, S.: TopoSUB: a tool for efficient large area numerical modelling in complex topography at sub-grid scales, Geosci. Model Dev., 5, 1245–1257, https://doi.org/10.5194/gmd-5-1245-2012, 2012.
Kristoffer Aalstad has a Matlab implementation: https://github.com/krisaalstad/TopoLAB
## Contribution Workflow
1. All contribution welcome!
2. Found a bug -> Check the issue page. If you have a solution let us know.
2. No idea on moving furhter -> then create a new [issue](https://github.com/ArcticSnow/TopoPyScale/issues)
3. Wanna develop a new feature/idea? -> create a new branch. Go wild. Merge with main branch when accomplished.
4. Create release version when significant improvements and bug fixes have been done. Coordinate with others on [Discussions](https://github.com/ArcticSnow/TopoPyScale/discussions)
**Create a new release:**
Follow procedure and conventions described in: https://www.youtube.com/watch?v=Ob9llA_QhQY
Our forum is now on [Github Discussions](https://github.com/ArcticSnow/TopoPyScale/discussions). Come visit!
## Design
1. Inputs
- Climate data from reanalysis (ERA5, etc)
- Climate data from future projections (CORDEX) (TBD)
- DEM from local source, or fetch from public repository: SRTM, ArcticDEM, ASTER
2. Run TopoScale
- compute derived values (from DEM)
- toposcale (k-mean clustering)
- interpolation (bilinear, inverse square dist.)
3. Output
- Cryogrid format
- FSM format
- CROCUS format
- Snowmodel format
- basic netcfd
- For each method, have the choice to output either the abstract cluster points, or the gridded product after interpolation
4. Validation toolset
- validation to local observation timeseries
- plotting
5. Gap filling algorithm
- random forest temporal gap filling (TBD)
Validation (4) and Gap filling (4) are future implementation.
## Installation
We have now added an environments.yml file to handle versions of depencencies that are tested with the current codebase, to use this run:
`conda env create -f environment.yml`
Alternatively you can follow this method for dependencies (to be deprecated):
```bash
conda create -n downscaling python ipython
conda activate downscaling
# Recomended way to install dependencies:
conda install -c conda-forge xarray matplotlib scikit-learn pandas numpy netcdf4 h5netcdf rasterio pyproj dask rioxarray
# install forked version of Topocalc compatible with Python >3.9 (tested with 3.13)
pip install pip@git+https://github.com/ArcticSnow/topocalc
```
Then install the code:
```
# OPTION 1 (Pypi release):
pip install TopoPyScale
# OPTION 2 (development):
cd github # navigate to where you want to clone TopoPyScale
git clone git@github.com:ArcticSnow/TopoPyScale.git
pip install -e TopoPyScale #install a development version
#----------------------------------------------------------
# OPTIONAL: if using jupyter lab
# add this new Python kernel to your jupyter lab PATH
python -m ipykernel install --user --name downscaling
# Tool for generating documentation from code docstring
pip install lazydocs
```
Then you need to setup your `cdsapi` with the Copernicus API key system. Follow [this tutorial](https://cds.climate.copernicus.eu/api-how-to#install-the-cds-api-key) after creating an account with [Copernicus](https://cds.climate.copernicus.eu/). On Linux, create a file `nano ~/.cdsapirc` with inside:
```
url: https://cds.climate.copernicus.eu/api/v2
key: {uid}:{api-key}
```
## Basic usage
1. Setup your Python environment
2. Create your project directory
3. Configure the file `config.ini` to fit your problem (see [`config.yml`](https://github.com/ArcticSnow/TopoPyScale_examples/blob/main/ex1_norway_finse/config_spatial.yml) for an example)
4. Run TopoPyScale
```python
import pandas as pd
from TopoPyScale import topoclass as tc
from matplotlib import pyplot as plt
# ========= STEP 1 ==========
# Load Configuration
config_file = './config.yml'
mp = tc.Topoclass(config_file)
# Compute parameters of the DEM (slope, aspect, sky view factor)
mp.get_era5()
mp.compute_dem_param()
# ========== STEP 2 ===========
# Extract DEM parameters for points of interest (centroids or physical points)
mp.extract_topo_param()
# ----- Option 1:
# Compute clustering of the input DEM and extract cluster centroids
#mp.extract_dem_cluster_param()
# plot clusters
#mp.toposub.plot_clusters_map()
# plot sky view factor
#mp.toposub.plot_clusters_map(var='svf', cmap=plt.cm.viridis)
# ------ Option 2:
# inidicate in the config file the .csv file containing a list of point coordinates (!!! must same coordinate system as DEM !!!)
#mp.extract_pts_param(method='linear',index_col=0)
# ========= STEP 3 ==========
# compute solar geometry and horizon angles
mp.compute_solar_geometry()
mp.compute_horizon()
# ========= STEP 4 ==========
# Perform the downscaling
mp.downscale_climate()
# ========= STEP 5 ==========
# explore the downscaled dataset. For instance the temperature difference between each point and the first one
(mp.downscaled_pts.t-mp.downscaled_pts.t.isel(point_id=0)).plot()
plt.show()
# ========= STEP 6 ==========
# Export output to desired format
mp.to_netcdf()
```
TopoClass will create a file structure in the project folder (see below). TopoPyScale assumes you have a DEM in GeoTiFF, and a set of climate data in netcdf (following ERA5 variable conventions).
TopoPyScale can easier segment the DEM using clustering (e.g. K-mean), or a list of predefined point coordinates in `pts_list.csv` can be provided. Make sure all parameters in `config.ini` are correct.
```
my_project/
├── inputs/
├── dem/
├── my_dem.tif
└── pts_list.csv (optional)
└── climate/
├── PLEV*.nc
└── SURF*.nc
├── outputs/
└── config.ini
```
Raw data
{
"_id": null,
"home_page": null,
"name": "TopoPyScale",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "climate, downscaling, meteorology, xarray",
"author": "Joel Fiddes, Kristoffer Aalstad",
"author_email": "Simon Filhol <simon.filhol@meteo.fr>",
"download_url": "https://files.pythonhosted.org/packages/5f/44/d23ce37cf2cb374cb3a12cd04b89f8bad168e1bd4ab14421c2e2091b10f3/topopyscale-0.3.1.tar.gz",
"platform": null,
"description": "<a style=\"border-width:0\" href=\"https://doi.org/10.21105/joss.05059\">\n <img src=\"https://joss.theoj.org/papers/10.21105/joss.05059/status.svg\" alt=\"DOI badge\" ></a>\n \n[](https://zenodo.org/badge/latestdoi/411249045)\n[](https://github.com/ArcticSnow/TopoPyScale/blob/main/LICENSE)\n\n[![][docs-dev-img]][docs-dev-url]\n[](https://pepy.tech/projects/topopyscale)\n\n\nBinder Notebooks Examples: [](https://mybinder.org/v2/gh/ArcticSnow/TopoPyScale_examples/HEAD)\n\n[docs-dev-img]: https://img.shields.io/badge/docs-latest-blue.svg\n[docs-dev-url]: https://topopyscale.readthedocs.io\n\n# TopoPyScale\nPython version of Toposcale packaged as a Pypi library. Toposcale is an original idea of Joel Fiddes to perform topography-based downscaling of climate data to the hillslope scale.\n\nDocumentation avalaible: https://topopyscale.readthedocs.io\n\n\n\n**References:**\n\n- Filhol et al., (2023). TopoPyScale: A Python Package for Hillslope Climate Downscaling. Journal of Open Source Software, 8(86), 5059, https://doi.org/10.21105/joss.05059\n\nAnd the original method it relies on:\n- Fiddes, J. and Gruber, S.: TopoSCALE v.1.0: downscaling gridded climate data in complex terrain, Geosci. Model Dev., 7, 387\u2013405, https://doi.org/10.5194/gmd-7-387-2014, 2014.\n- Fiddes, J. and Gruber, S.: TopoSUB: a tool for efficient large area numerical modelling in complex topography at sub-grid scales, Geosci. Model Dev., 5, 1245\u20131257, https://doi.org/10.5194/gmd-5-1245-2012, 2012. \n\nKristoffer Aalstad has a Matlab implementation: https://github.com/krisaalstad/TopoLAB\n\n## Contribution Workflow\n1. All contribution welcome!\n2. Found a bug -> Check the issue page. If you have a solution let us know. \n2. No idea on moving furhter -> then create a new [issue](https://github.com/ArcticSnow/TopoPyScale/issues) \n3. Wanna develop a new feature/idea? -> create a new branch. Go wild. Merge with main branch when accomplished.\n4. Create release version when significant improvements and bug fixes have been done. Coordinate with others on [Discussions](https://github.com/ArcticSnow/TopoPyScale/discussions)\n\n**Create a new release:**\nFollow procedure and conventions described in: https://www.youtube.com/watch?v=Ob9llA_QhQY\n\nOur forum is now on [Github Discussions](https://github.com/ArcticSnow/TopoPyScale/discussions). Come visit!\n\n\n## Design\n\n1. Inputs\n - Climate data from reanalysis (ERA5, etc)\n - Climate data from future projections (CORDEX) (TBD)\n - DEM from local source, or fetch from public repository: SRTM, ArcticDEM, ASTER\n2. Run TopoScale\n - compute derived values (from DEM)\n - toposcale (k-mean clustering)\n - interpolation (bilinear, inverse square dist.)\n3. Output\n - Cryogrid format\n - FSM format\n - CROCUS format\n - Snowmodel format\n - basic netcfd\n - For each method, have the choice to output either the abstract cluster points, or the gridded product after interpolation\n4. Validation toolset\n - validation to local observation timeseries\n - plotting\n5. Gap filling algorithm\n - random forest temporal gap filling (TBD)\n\nValidation (4) and Gap filling (4) are future implementation.\n\n## Installation\n\nWe have now added an environments.yml file to handle versions of depencencies that are tested with the current codebase, to use this run:\n\n`conda env create -f environment.yml`\n\nAlternatively you can follow this method for dependencies (to be deprecated):\n\n```bash\nconda create -n downscaling python ipython\nconda activate downscaling\n\n# Recomended way to install dependencies:\nconda install -c conda-forge xarray matplotlib scikit-learn pandas numpy netcdf4 h5netcdf rasterio pyproj dask rioxarray\n# install forked version of Topocalc compatible with Python >3.9 (tested with 3.13)\npip install pip@git+https://github.com/ArcticSnow/topocalc\n```\n\nThen install the code:\n\n```\n# OPTION 1 (Pypi release):\npip install TopoPyScale\n\n# OPTION 2 (development):\ncd github # navigate to where you want to clone TopoPyScale\ngit clone git@github.com:ArcticSnow/TopoPyScale.git\npip install -e TopoPyScale #install a development version\n\n#----------------------------------------------------------\n# OPTIONAL: if using jupyter lab\n# add this new Python kernel to your jupyter lab PATH\npython -m ipykernel install --user --name downscaling\n\n# Tool for generating documentation from code docstring\npip install lazydocs\n```\n\nThen you need to setup your `cdsapi` with the Copernicus API key system. Follow [this tutorial](https://cds.climate.copernicus.eu/api-how-to#install-the-cds-api-key) after creating an account with [Copernicus](https://cds.climate.copernicus.eu/). On Linux, create a file `nano ~/.cdsapirc` with inside:\n\n```\nurl: https://cds.climate.copernicus.eu/api/v2\nkey: {uid}:{api-key}\n```\n\n## Basic usage\n\n1. Setup your Python environment\n2. Create your project directory\n3. Configure the file `config.ini` to fit your problem (see [`config.yml`](https://github.com/ArcticSnow/TopoPyScale_examples/blob/main/ex1_norway_finse/config_spatial.yml) for an example)\n4. Run TopoPyScale\n\n```python\nimport pandas as pd\nfrom TopoPyScale import topoclass as tc\nfrom matplotlib import pyplot as plt\n\n# ========= STEP 1 ==========\n# Load Configuration\nconfig_file = './config.yml'\nmp = tc.Topoclass(config_file)\n# Compute parameters of the DEM (slope, aspect, sky view factor)\n\nmp.get_era5()\nmp.compute_dem_param()\n\n# ========== STEP 2 ===========\n# Extract DEM parameters for points of interest (centroids or physical points)\n\nmp.extract_topo_param()\n\n# ----- Option 1:\n# Compute clustering of the input DEM and extract cluster centroids\n#mp.extract_dem_cluster_param()\n# plot clusters\n#mp.toposub.plot_clusters_map()\n# plot sky view factor\n#mp.toposub.plot_clusters_map(var='svf', cmap=plt.cm.viridis)\n\n# ------ Option 2:\n# inidicate in the config file the .csv file containing a list of point coordinates (!!! must same coordinate system as DEM !!!)\n#mp.extract_pts_param(method='linear',index_col=0)\n\n# ========= STEP 3 ==========\n# compute solar geometry and horizon angles\nmp.compute_solar_geometry()\nmp.compute_horizon()\n\n# ========= STEP 4 ==========\n# Perform the downscaling\nmp.downscale_climate()\n\n# ========= STEP 5 ==========\n# explore the downscaled dataset. For instance the temperature difference between each point and the first one\n(mp.downscaled_pts.t-mp.downscaled_pts.t.isel(point_id=0)).plot()\nplt.show()\n\n# ========= STEP 6 ==========\n# Export output to desired format\nmp.to_netcdf()\n```\n\nTopoClass will create a file structure in the project folder (see below). TopoPyScale assumes you have a DEM in GeoTiFF, and a set of climate data in netcdf (following ERA5 variable conventions). \nTopoPyScale can easier segment the DEM using clustering (e.g. K-mean), or a list of predefined point coordinates in `pts_list.csv` can be provided. Make sure all parameters in `config.ini` are correct.\n```\nmy_project/\n \u251c\u2500\u2500 inputs/\n \u251c\u2500\u2500 dem/ \n \u251c\u2500\u2500 my_dem.tif\n \u2514\u2500\u2500 pts_list.csv (optional)\n \u2514\u2500\u2500 climate/\n \u251c\u2500\u2500 PLEV*.nc\n \u2514\u2500\u2500 SURF*.nc\n \u251c\u2500\u2500 outputs/\n \u2514\u2500\u2500 config.ini\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "TopoPyScale, a Python package to perform simplistic climate downscaling at the hillslope scale.",
"version": "0.3.1",
"project_urls": {
"Documentation": "https://topopyscale.readthedocs.io/en/latest/",
"Download": "https://github.com/ArcticSnow/TopoPyScale/releases/latest",
"Examples": "https://github.com/ArcticSnow/TopoPyScale_examples",
"Home": "https://topopyscale.readthedocs.io",
"Source": "https://github.com/ArcticSnow/TopoPyScale"
},
"split_keywords": [
"climate",
" downscaling",
" meteorology",
" xarray"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "88f66ffdbef9b852b7267b1fb65f1724509b4fde23b59cb2969f1da836842926",
"md5": "5625c927548f27c918e70ea589b9ebd4",
"sha256": "3f7bc081478f6e538ed94bb88a423242e2592428a5ba53bba005857bc2d1d942"
},
"downloads": -1,
"filename": "topopyscale-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5625c927548f27c918e70ea589b9ebd4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 100774,
"upload_time": "2025-09-03T15:20:39",
"upload_time_iso_8601": "2025-09-03T15:20:39.266187Z",
"url": "https://files.pythonhosted.org/packages/88/f6/6ffdbef9b852b7267b1fb65f1724509b4fde23b59cb2969f1da836842926/topopyscale-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5f44d23ce37cf2cb374cb3a12cd04b89f8bad168e1bd4ab14421c2e2091b10f3",
"md5": "cab9a0ee5d1a0844008620cc16cfc309",
"sha256": "4bf73ec7596d4e15cd0604c350425ddf84a38e3638034a8763c3235cd23b6827"
},
"downloads": -1,
"filename": "topopyscale-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "cab9a0ee5d1a0844008620cc16cfc309",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 14001668,
"upload_time": "2025-09-03T15:20:42",
"upload_time_iso_8601": "2025-09-03T15:20:42.325586Z",
"url": "https://files.pythonhosted.org/packages/5f/44/d23ce37cf2cb374cb3a12cd04b89f8bad168e1bd4ab14421c2e2091b10f3/topopyscale-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-03 15:20:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ArcticSnow",
"github_project": "TopoPyScale",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "topopyscale"
}