{"id":13948971,"url":"https://github.com/ArcticSnow/TopoPyScale","last_synced_at":"2025-07-20T11:30:29.477Z","repository":{"id":62899003,"uuid":"411249045","full_name":"ArcticSnow/TopoPyScale","owner":"ArcticSnow","description":"TopoPyScale: a Python library to perform simplistic climate downscaling at the hillslope scale","archived":false,"fork":false,"pushed_at":"2025-07-11T14:58:06.000Z","size":15554,"stargazers_count":48,"open_issues_count":27,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-07-17T07:38:59.292Z","etag":null,"topics":["climate","climate-science","clustering","dem","downscaling","era5","geoscience","joss","science","timeseries","xarray"],"latest_commit_sha":null,"homepage":"https://topopyscale.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArcticSnow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-09-28T11:13:15.000Z","updated_at":"2025-07-11T14:58:09.000Z","dependencies_parsed_at":"2023-09-24T12:52:43.497Z","dependency_job_id":"efcd3319-b82c-4cb0-8c60-5e0772d0644d","html_url":"https://github.com/ArcticSnow/TopoPyScale","commit_stats":{"total_commits":544,"total_committers":8,"mean_commits":68.0,"dds":0.2720588235294118,"last_synced_commit":"ac8d71adc73b4d14501e2211abbd44a4b78a05d3"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/ArcticSnow/TopoPyScale","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcticSnow%2FTopoPyScale","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcticSnow%2FTopoPyScale/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcticSnow%2FTopoPyScale/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcticSnow%2FTopoPyScale/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArcticSnow","download_url":"https://codeload.github.com/ArcticSnow/TopoPyScale/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcticSnow%2FTopoPyScale/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265606783,"owners_count":23797006,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["climate","climate-science","clustering","dem","downscaling","era5","geoscience","joss","science","timeseries","xarray"],"created_at":"2024-08-08T05:01:35.443Z","updated_at":"2025-07-20T11:30:29.469Z","avatar_url":"https://github.com/ArcticSnow.png","language":"Python","readme":"\u003ca style=\"border-width:0\" href=\"https://doi.org/10.21105/joss.05059\"\u003e\n  \u003cimg src=\"https://joss.theoj.org/papers/10.21105/joss.05059/status.svg\" alt=\"DOI badge\" \u003e\u003c/a\u003e\n  \n[![DOI](https://zenodo.org/badge/411249045.svg)](https://zenodo.org/badge/latestdoi/411249045)\n[![GitHub license](https://img.shields.io/github/license/ArcticSnow/TopoPyScale)](https://github.com/ArcticSnow/TopoPyScale/blob/main/LICENSE)\n![GitHub release (latest by date)](https://img.shields.io/github/v/release/ArcticSnow/TopoPyScale)\n[![][docs-dev-img]][docs-dev-url]\n[![PyPI Downloads](https://static.pepy.tech/badge/topopyscale)](https://pepy.tech/projects/topopyscale)\n![Test](https://github.com/ArcticSnow/TopoPyScale/actions/workflows/test_topopyscale.yml/badge.svg)\n\nBinder Notebooks Examples: [![Binder](https://mybinder.org/badge_logo.svg)](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![](https://github.com/ArcticSnow/TopoPyScale/blob/main/JOSS/temperature_comparison_crop_scaled.jpg)\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–405, 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–1257, 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\n**Please follow these simple rules:**\n1. All contribution welcome!\n2. Found a bug -\u003e Check the issue page. If you have a solution let us know. \n2. No idea on moving furhter -\u003e then create a new [issue](https://github.com/ArcticSnow/TopoPyScale/issues) \n3. Wanna develop a new feature/idea? -\u003e 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=3.9 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```\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    ├── inputs/\n        ├── dem/ \n            ├── my_dem.tif\n            └── pts_list.csv  (optional)\n        └── climate/\n            ├── PLEV*.nc\n            └── SURF*.nc\n    ├── outputs/\n    └── config.ini\n```\n","funding_links":[],"categories":["Climate Change"],"sub_categories":["Climate Downscaling"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FArcticSnow%2FTopoPyScale","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FArcticSnow%2FTopoPyScale","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FArcticSnow%2FTopoPyScale/lists"}