grdwindinversion 0.2.6__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. grdwindinversion-0.3.1/.github/workflows/ci.yml +105 -0
  2. grdwindinversion-0.3.1/PKG-INFO +67 -0
  3. grdwindinversion-0.3.1/README.md +37 -0
  4. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/conf.py +23 -8
  5. grdwindinversion-0.3.1/docs/examples/streaks-display.ipynb +324 -0
  6. grdwindinversion-0.3.1/docs/examples/wind-inversion-from-grd.ipynb +133 -0
  7. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/index.rst +3 -1
  8. grdwindinversion-0.3.1/grdwindinversion/config_prod.yaml +52 -0
  9. grdwindinversion-0.3.1/grdwindinversion/config_prod_recal.yaml +49 -0
  10. grdwindinversion-0.2.6/grdwindinversion/config_prod_recal.yaml → grdwindinversion-0.3.1/grdwindinversion/config_prod_recal_streaks_nrcsmod.yaml +3 -0
  11. grdwindinversion-0.2.6/tests/config_test.yaml → grdwindinversion-0.3.1/grdwindinversion/config_prod_streaks.yaml +7 -1
  12. grdwindinversion-0.2.6/grdwindinversion/config_prod.yaml → grdwindinversion-0.3.1/grdwindinversion/config_prod_streaks_nrcsmod.yaml +6 -0
  13. grdwindinversion-0.3.1/grdwindinversion/data_config.yaml +8 -0
  14. grdwindinversion-0.3.1/grdwindinversion/gradientFeatures.py +448 -0
  15. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/inversion.py +270 -86
  16. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/load_config.py +7 -4
  17. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/utils.py +41 -1
  18. grdwindinversion-0.3.1/grdwindinversion.egg-info/PKG-INFO +67 -0
  19. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion.egg-info/SOURCES.txt +5 -2
  20. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion.egg-info/requires.txt +0 -3
  21. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/pyproject.toml +28 -18
  22. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/recipe/meta.yaml +4 -5
  23. grdwindinversion-0.3.1/tests/config_test.yaml +52 -0
  24. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/tests/test_grdwindinversion_ci.py +12 -5
  25. grdwindinversion-0.2.6/.github/workflows/ci.yml +0 -101
  26. grdwindinversion-0.2.6/PKG-INFO +0 -83
  27. grdwindinversion-0.2.6/README.md +0 -50
  28. grdwindinversion-0.2.6/docs/examples/wind-inversion-from-grd.ipynb +0 -196
  29. grdwindinversion-0.2.6/docs/readme.rst +0 -1
  30. grdwindinversion-0.2.6/grdwindinversion/data_config.yaml +0 -5
  31. grdwindinversion-0.2.6/grdwindinversion/streaks.py +0 -79
  32. grdwindinversion-0.2.6/grdwindinversion.egg-info/PKG-INFO +0 -83
  33. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.editorconfig +0 -0
  34. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.github/dependabot.yml +0 -0
  35. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.github/workflows/build.yml +0 -0
  36. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.github/workflows/publish.yml +0 -0
  37. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.gitignore +0 -0
  38. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/.pre-commit-config.yaml +0 -0
  39. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/AUTHORS.rst +0 -0
  40. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/CONTRIBUTING.rst +0 -0
  41. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/HISTORY.rst +0 -0
  42. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/LICENSE +0 -0
  43. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/MANIFEST.in +0 -0
  44. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/Makefile +0 -0
  45. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/ci/requirements/docs.yaml +0 -0
  46. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/ci/requirements/environment.yaml +0 -0
  47. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/Makefile +0 -0
  48. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/_static/css/grdwindinversion.css +0 -0
  49. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/algorithm.rst +0 -0
  50. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/authors.rst +0 -0
  51. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/contributing.rst +0 -0
  52. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/history.rst +0 -0
  53. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/installation.rst +0 -0
  54. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/make.bat +0 -0
  55. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/modules.rst +0 -0
  56. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/docs/usage.rst +0 -0
  57. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/.github/ISSUE_TEMPLATE.md +0 -0
  58. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/.gitignore +0 -0
  59. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/__init__.py +0 -0
  60. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/main.py +0 -0
  61. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion/utils_memory.py +0 -0
  62. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion.egg-info/dependency_links.txt +0 -0
  63. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion.egg-info/entry_points.txt +0 -0
  64. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/grdwindinversion.egg-info/top_level.txt +0 -0
  65. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/requirements_dev.txt +0 -0
  66. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/requirements_doc.txt +0 -0
  67. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/setup.cfg +0 -0
  68. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/tests/__init__.py +0 -0
  69. {grdwindinversion-0.2.6 → grdwindinversion-0.3.1}/tox.ini +0 -0
@@ -0,0 +1,105 @@
1
+ name: CI Workflow for grdwindinversion
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ timeout-minutes: 360 # 6 hours limit for the job
15
+
16
+ steps:
17
+ # Checkout the code
18
+ - name: Checkout code
19
+ uses: actions/checkout@v4
20
+
21
+ - uses: mamba-org/setup-micromamba@v1
22
+ with:
23
+ micromamba-version: "1.5.9-1" # any version from https://github.com/mamba-org/micromamba-releases
24
+ channels: tcevaer, conda-forge
25
+ init-shell: bash
26
+ post-cleanup: "all"
27
+
28
+ - name: Configure Conda channel priority to disabled
29
+ run: |
30
+ conda config --set channel_priority disabled
31
+
32
+ - name: Create environment and install tools
33
+ run: micromamba create -n grdwind_env pytest conda-build boa python=3.10 -y
34
+
35
+ - name: Build package
36
+ run: |
37
+ cd recipe
38
+ eval "$(micromamba shell hook --shell bash)"
39
+ micromamba activate grdwind_env
40
+ conda mambabuild .
41
+
42
+ # Install the built package into the environment
43
+ - name: Install the built package
44
+ run: |
45
+ eval "$(micromamba shell hook --shell bash)"
46
+ micromamba activate grdwind_env
47
+ conda install --use-local grdwindinversion -y
48
+
49
+ # Cache the test data if previously downloaded (up to 10 GB limit for the cache)
50
+ # WARNING : modify the key if the data is modified !!
51
+ - name: Cache test data
52
+ uses: actions/cache@v4
53
+ id: cache
54
+ with:
55
+ path: ./test_data
56
+ key: test-data-v3
57
+ restore-keys: test-data-v3
58
+
59
+ # Download test data if not already cached
60
+ - name: Download test data
61
+ if: steps.cache.outputs.cache-hit != 'true' # Only download if cache miss
62
+ run: |
63
+ mkdir -p ./test_data/
64
+ wget https://cloud.ifremer.fr/index.php/s/ExLQ2TnYAqozPWE/download -O /tmp/ecmwf.zip
65
+ unzip /tmp/ecmwf.zip -d ./test_data/
66
+ wget https://cloud.ifremer.fr/index.php/s/kRgdOOPsjoZieZR/download -O /tmp/l1.zip
67
+ unzip /tmp/l1.zip -d ./test_data/
68
+ timeout-minutes: 200 # Adjust depending on the size of your data
69
+
70
+ # Set up xsar configuration
71
+ - name: Setup xsar configuration
72
+ run: |
73
+ mkdir -p ~/.xsar
74
+ echo "data_dir: /tmp" > ~/.xsar/config.yaml
75
+ echo "auxiliary_dir: ./test_data/auxiliary" >> ~/.xsar/config.yaml
76
+ echo "path_dataframe_aux: ./test_data/auxiliary/active_aux.csv" >> ~/.xsar/config.yaml
77
+
78
+ # Set up grdwindinversion configuration
79
+ - name: Setup grdwindinversion configuration
80
+ run: |
81
+ mkdir -p ~/.grdwindinversion
82
+ echo "'ecmwf_0100_1h': ./test_data/ECMWF/forecast/hourly/0100deg/netcdf_light/%Y/%j/ECMWF_FORECAST_0100_%Y%m%d%H%M_10U_10V.nc" > ~/.grdwindinversion/data_config.yaml
83
+ echo "'ecmwf_0125_1h': ./test_data/ECMWF/0.125deg/1h/forecasts/%Y/%j/ecmwf_%Y%m%d%H%M.nc" >> ~/.grdwindinversion/data_config.yaml
84
+ echo "unit_test_s1_product: './test_data/L1/S1A_IW_GRDH_1SDV_20210909T130650_20210909T130715_039605_04AE83_C34F.SAFE'" >> ~/.grdwindinversion/data_config.yaml
85
+ echo "unit_test_rcm_product: './test_data/L1/RCM1_OK2767220_PK2769320_1_SCLND_20230930_214014_VV_VH_GRD'" >> ~/.grdwindinversion/data_config.yaml
86
+ echo "unit_test_rs2_product: './test_data/L1/RS2_OK141302_PK1242223_DK1208537_SCWA_20220904_093402_VV_VH_SGF'" >> ~/.grdwindinversion/data_config.yaml
87
+
88
+ #echo "'nc_luts_path': ./test_data/GMFS/nc_luts" >> ~/.grdwindinversion/data_config.yaml
89
+ #echo "'lut_cmod7_path': './test_data/GMFS/v1.6/GMF_cmod7_official/cmod7_and_python_script'" >> ~/.grdwindinversion/data_config.yaml
90
+ #echo "'lut_ms1ahw_path': './test_data/GMFS/v1.6/GMF_cmodms1ahw'" >> ~/.grdwindinversion/data_config.yaml
91
+
92
+ # Run the tests
93
+ - name: Run tests
94
+ run: |
95
+ eval "$(micromamba shell hook --shell bash)"
96
+ micromamba activate grdwind_env
97
+ pytest
98
+
99
+ # Optionally, upload test artifacts (NetCDF files or logs) if needed
100
+ #- name: Upload test artifacts
101
+ # if: failure() # Only upload on failure
102
+ # uses: actions/upload-artifact@v2
103
+ # with:
104
+ # name: test-output
105
+ # path: ./test_output/
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.1
2
+ Name: grdwindinversion
3
+ Version: 0.3.1
4
+ Summary: Package to perform Wind inversion from GRD Level-1 SAR images
5
+ Author-email: Antoine Grouazel <antoine.grouazel@ifremer.fr>
6
+ License: MIT
7
+ Keywords: xarray,earth-observation,remote-sensing,satellite-imagery,Sentinel-1,RCM,RadarSat2,sar,synthetic-aperture-radar
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ License-File: AUTHORS.rst
21
+ Requires-Dist: xsar
22
+ Requires-Dist: xsarsea
23
+ Requires-Dist: xarray
24
+ Requires-Dist: xarray-datatree
25
+ Requires-Dist: pyyaml
26
+ Requires-Dist: numpy
27
+ Requires-Dist: scipy
28
+ Requires-Dist: fsspec
29
+ Requires-Dist: aiohttp
30
+
31
+
32
+ [![Python Version](https://img.shields.io/pypi/pyversions/grdwindinversion.svg)](https://pypi.org/project/grdwindinversion/)
33
+ [![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/umr-lops/grdwindinversion/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
34
+
35
+ Package to perform Wind inversion from GRD Level-1 SAR images
36
+
37
+ - Free software: MIT license
38
+ - Documentation: https://grdwindinversion.readthedocs.io.
39
+
40
+ ## Usage
41
+
42
+ ```python
43
+
44
+ SAR_L1-to-L2_wind_processor -h
45
+ usage: SAR_L1-to-L2_wind_processor [-h] --input_file INPUT_FILE [--config_file CONFIG_FILE] --outputdir OUTPUTDIR [--verbose] [--overwrite]
46
+
47
+ Perform inversion from S1(L1-GRD) SAFE, L1-RCM, L1-RS2 ; using xsar/xsarsea tools
48
+
49
+ options:
50
+ -h, --help show this help message and exit
51
+ --input_file INPUT_FILE
52
+ input file path
53
+ --config_file CONFIG_FILE
54
+ config file path [if not provided will take config file based on input file]
55
+ --outputdir OUTPUTDIR
56
+ --verbose
57
+ --overwrite overwrite existing .nc files [default is False]
58
+ ```
59
+
60
+ ## Features
61
+
62
+ This Python library (based on `xarray`) allows to perform wind inversion from level-1 GRD (projected magnitude image).
63
+ Mission supported:
64
+
65
+ - Sentinel-1
66
+ - RCM
67
+ - RadarSat-2
@@ -0,0 +1,37 @@
1
+
2
+ [![Python Version](https://img.shields.io/pypi/pyversions/grdwindinversion.svg)](https://pypi.org/project/grdwindinversion/)
3
+ [![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/umr-lops/grdwindinversion/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
4
+
5
+ Package to perform Wind inversion from GRD Level-1 SAR images
6
+
7
+ - Free software: MIT license
8
+ - Documentation: https://grdwindinversion.readthedocs.io.
9
+
10
+ ## Usage
11
+
12
+ ```python
13
+
14
+ SAR_L1-to-L2_wind_processor -h
15
+ usage: SAR_L1-to-L2_wind_processor [-h] --input_file INPUT_FILE [--config_file CONFIG_FILE] --outputdir OUTPUTDIR [--verbose] [--overwrite]
16
+
17
+ Perform inversion from S1(L1-GRD) SAFE, L1-RCM, L1-RS2 ; using xsar/xsarsea tools
18
+
19
+ options:
20
+ -h, --help show this help message and exit
21
+ --input_file INPUT_FILE
22
+ input file path
23
+ --config_file CONFIG_FILE
24
+ config file path [if not provided will take config file based on input file]
25
+ --outputdir OUTPUTDIR
26
+ --verbose
27
+ --overwrite overwrite existing .nc files [default is False]
28
+ ```
29
+
30
+ ## Features
31
+
32
+ This Python library (based on `xarray`) allows to perform wind inversion from level-1 GRD (projected magnitude image).
33
+ Mission supported:
34
+
35
+ - Sentinel-1
36
+ - RCM
37
+ - RadarSat-2
@@ -17,11 +17,11 @@
17
17
  # relative to the documentation root, use os.path.abspath to make it
18
18
  # absolute, like shown here.
19
19
  #
20
+ import grdwindinversion
20
21
  import os
21
22
  import sys
22
23
  sys.path.insert(0, os.path.abspath('..'))
23
24
 
24
- import grdwindinversion
25
25
 
26
26
  # -- General configuration ---------------------------------------------
27
27
 
@@ -43,6 +43,12 @@ extensions = [
43
43
  'sphinxcontrib.mermaid',
44
44
  'nbsphinx',
45
45
  'jupyter_sphinx',
46
+ 'myst_parser'
47
+ ]
48
+ myst_enable_extensions = [
49
+ "deflist", # Pour les listes de définitions
50
+ "linkify", # Pour rendre les URLs cliquables automatiquement
51
+ "colon_fence", # Pour activer des blocs ::: comme Markdown GFM
46
52
  ]
47
53
  # order by source
48
54
  autodoc_member_order = 'bysource'
@@ -69,7 +75,12 @@ templates_path = ['_templates']
69
75
  # You can specify multiple suffix as a list of string:
70
76
  #
71
77
  # source_suffix = ['.rst', '.md']
72
- source_suffix = '.rst'
78
+ # source_suffix = '.rst'
79
+
80
+ source_suffix = {
81
+ '.rst': 'restructuredtext',
82
+ '.md': 'markdown',
83
+ }
73
84
 
74
85
  # The master toctree document.
75
86
  master_doc = 'index'
@@ -112,8 +123,11 @@ todo_include_todos = False
112
123
  # The theme to use for HTML and HTML Help pages. See the documentation for
113
124
  # a list of builtin themes.
114
125
  #
115
- html_theme = 'alabaster'
116
- #html_theme = 'sphinx_rtd_theme'
126
+ # html_theme = 'alabaster'
127
+ # html_theme = 'sphinx_rtd_theme'
128
+ # html_theme = 'furo'
129
+ html_theme = 'sphinx_rtd_theme'
130
+
117
131
 
118
132
  # Theme options are theme-specific and customize the look and feel of a
119
133
  # theme further. For a list of options available for each theme, see the
@@ -125,8 +139,12 @@ html_theme = 'alabaster'
125
139
  # relative to this directory. They are copied after the builtin static files,
126
140
  # so a file named "default.css" will overwrite the builtin "default.css".
127
141
  html_static_path = ['_static']
128
- #html_style = 'css/grdwindinversion.css'
142
+ html_style = 'css/grdwindinversion.css'
143
+ # html_style = 'css/xsarsea.css'
129
144
 
145
+ html_theme_options = {
146
+ 'logo_only': False,
147
+ }
130
148
  # -- Options for HTMLHelp output ---------------------------------------
131
149
 
132
150
  # Output file base name for HTML help builder.
@@ -187,6 +205,3 @@ texinfo_documents = [
187
205
  'One line description of project.',
188
206
  'Miscellaneous'),
189
207
  ]
190
-
191
-
192
-
@@ -0,0 +1,324 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Compute and display streaks"
8
+ ]
9
+ },
10
+ {
11
+ "cell_type": "code",
12
+ "execution_count": null,
13
+ "metadata": {},
14
+ "outputs": [],
15
+ "source": [
16
+ "# test on an dummy GRD IW product\n",
17
+ "import xsar,os\n",
18
+ "import grdwindinversion \n",
19
+ "filename = xsar.get_test_file('S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE')\n",
20
+ "outdir = \"/tmp/\"\n",
21
+ "config_path = os.path.join(os.path.dirname(grdwindinversion.__file__),'config_prod_streaks.yaml')\n",
22
+ "assert os.path.exists(config_path)\n",
23
+ "overwrite = True\n",
24
+ "resolution = '1000m'"
25
+ ]
26
+ },
27
+ {
28
+ "cell_type": "code",
29
+ "execution_count": null,
30
+ "metadata": {},
31
+ "outputs": [],
32
+ "source": [
33
+ "import logging\n",
34
+ "logger = logging.getLogger('grdwindinversion.gradientFeatures')\n",
35
+ "logger.setLevel(logging.DEBUG)"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "markdown",
40
+ "metadata": {},
41
+ "source": [
42
+ "## preprocess & load config"
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "code",
47
+ "execution_count": null,
48
+ "metadata": {},
49
+ "outputs": [],
50
+ "source": [
51
+ "from grdwindinversion.inversion import preprocess "
52
+ ]
53
+ },
54
+ {
55
+ "cell_type": "code",
56
+ "execution_count": null,
57
+ "metadata": {},
58
+ "outputs": [],
59
+ "source": [
60
+ "xr_dataset, out_file, config = preprocess(\n",
61
+ " filename, outdir, config_path, overwrite, False, resolution)\n",
62
+ "\n",
63
+ "model_co = config[\"l2_params\"][\"model_co\"]\n",
64
+ "model_cross = config[\"l2_params\"][\"model_cross\"]\n",
65
+ "copol = config[\"l2_params\"][\"copol\"]\n",
66
+ "crosspol = config[\"l2_params\"][\"crosspol\"]\n",
67
+ "copol_gmf = config[\"l2_params\"][\"copol_gmf\"]\n",
68
+ "crosspol_gmf = config[\"l2_params\"][\"crosspol_gmf\"]\n",
69
+ "dual_pol = config[\"l2_params\"][\"dual_pol\"]\n",
70
+ "ancillary_name = config[\"ancillary\"]\n",
71
+ "sensor_longname = config[\"sensor_longname\"]\n"
72
+ ]
73
+ },
74
+ {
75
+ "cell_type": "markdown",
76
+ "metadata": {},
77
+ "source": [
78
+ "## process gradients\n",
79
+ "- in xr_dataset, it will add variables related to heterogeneity mask an\n",
80
+ "- it will create xr_dataset_streaks"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": null,
86
+ "metadata": {},
87
+ "outputs": [],
88
+ "source": [
89
+ "from grdwindinversion.inversion import process_gradients\n",
90
+ "\n",
91
+ "if config[\"add_gradientsfeatures\"]:\n",
92
+ " xr_dataset, xr_dataset_streaks = process_gradients(\n",
93
+ " xr_dataset, config)\n",
94
+ "else:\n",
95
+ " xr_dataset_streaks = None"
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": null,
101
+ "metadata": {},
102
+ "outputs": [],
103
+ "source": [
104
+ "xr_dataset_streaks"
105
+ ]
106
+ },
107
+ {
108
+ "cell_type": "markdown",
109
+ "metadata": {},
110
+ "source": [
111
+ "## Plotting the results"
112
+ ]
113
+ },
114
+ {
115
+ "cell_type": "code",
116
+ "execution_count": null,
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": [
120
+ "import numpy as np\n",
121
+ "def get_uv_from_dir(wdir):\n",
122
+ " \"\"\"\n",
123
+ " Get u, v from wind direction\n",
124
+ " \n",
125
+ " Parameters\n",
126
+ " ----------\n",
127
+ " wdir : float\n",
128
+ " Wind direction in degrees, meteo convention\n",
129
+ " \n",
130
+ " Returns\n",
131
+ " -------\n",
132
+ " u : float\n",
133
+ " u component of the wind\n",
134
+ " v : float\n",
135
+ " v component of the wind\n",
136
+ " u_norm : float\n",
137
+ " Normalized u component of the wind\n",
138
+ " v_norm : float\n",
139
+ " Normalized v component of the wind \n",
140
+ " \"\"\"\n",
141
+ " u = np.cos(np.radians(270-wdir))\n",
142
+ " v = np.sin(np.radians(270-wdir))\n",
143
+ " sq_mean = np.sqrt(u**2+v**2)\n",
144
+ " return u, v, u/sq_mean, v/sq_mean"
145
+ ]
146
+ },
147
+ {
148
+ "cell_type": "code",
149
+ "execution_count": null,
150
+ "metadata": {},
151
+ "outputs": [],
152
+ "source": [
153
+ "import matplotlib.pyplot as plt\n",
154
+ "import numpy as np\n",
155
+ "import cartopy.crs as ccrs\n",
156
+ "from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER\n",
157
+ "import matplotlib\n",
158
+ "cmin=0;cmax=30\n",
159
+ "norm = matplotlib.colors.Normalize(vmin=cmin,vmax=cmax,clip=False)\n",
160
+ "import os \n",
161
+ "\n",
162
+ "#ancillary \n",
163
+ "ds = xr_dataset\n",
164
+ "p1 = int(ds.line.size/16)\n",
165
+ "p2 = int(ds.sample.size/16)\n",
166
+ "\n",
167
+ "lons = ds.longitude[::p1,::p2].values.flatten()\n",
168
+ "lats = ds.latitude[::p1,::p2].values.flatten()\n",
169
+ "winddir_ancillary = ds.ancillary_wind_direction[::p1,::p2]\n",
170
+ "u_ancillary, v_ancllary, u_norm_ancillary, v_norm_ancillary = get_uv_from_dir(winddir_ancillary)\n",
171
+ "\n",
172
+ "longitude = xr_dataset_streaks['longitude'].values\n",
173
+ "latitude = xr_dataset_streaks['latitude'].values"
174
+ ]
175
+ },
176
+ {
177
+ "cell_type": "code",
178
+ "execution_count": null,
179
+ "metadata": {},
180
+ "outputs": [],
181
+ "source": [
182
+ "def plot_wind_from_streaks(streaks_dir, **kwargs):\n",
183
+ " \"\"\"\n",
184
+ " Plot wind from streaks\n",
185
+ " \n",
186
+ " Parameters\n",
187
+ " ----------\n",
188
+ " streaks_dir : xr.Dataset\n",
189
+ " Dataset containing streaks direction in degrees in meteo convention\n",
190
+ " \n",
191
+ " **kwargs : dict\n",
192
+ " window_size : int\n",
193
+ " Size of the window for smoothing the streaks\n",
194
+ " downscale_factor : int\n",
195
+ " Downscale factor for smoothing the streaks\n",
196
+ " pol : str\n",
197
+ " Polarization to plot\n",
198
+ " varname : str\n",
199
+ " Variable name to plot\n",
200
+ " \"\"\"\n",
201
+ " \n",
202
+ " \n",
203
+ " # handle kwargs\n",
204
+ " window_size = kwargs.get('window_size', None)\n",
205
+ " downscale_factor = kwargs.get('downscale_factor', None)\n",
206
+ " pol = kwargs.get('pol', None)\n",
207
+ " pol_display = kwargs.get('pol', 'VV')\n",
208
+ " varname = kwargs.get('varname', None)\n",
209
+ " savefig = kwargs.get('savefig', False)\n",
210
+ " savedir = kwargs.get('savedir', './tmp')\n",
211
+ " \n",
212
+ " # Plot\n",
213
+ " fig = plt.figure(figsize=(10, 9))\n",
214
+ " ax = plt.axes(projection=ccrs.PlateCarree())\n",
215
+ "\n",
216
+ " # Calculer les composantes u et v à partir des angles streaks_dir\n",
217
+ " u, v, u_norm, v_norm = get_uv_from_dir(streaks_dir)\n",
218
+ "\n",
219
+ " # Display streaks direction\n",
220
+ " #ax.quiver(longitude, latitude, u_norm, v_norm, edgecolors='k', norm=norm, pivot= 'mid', scale_units='xy', scale=4., zorder=10, width=0.1/25,transform = ccrs.PlateCarree(), color = 'red', label = 'owiWindStreaks')\n",
221
+ " ax.quiver(longitude, latitude, u_norm, v_norm, edgecolors='k', norm=norm, pivot= 'mid', scale_units='xy', scale=8., zorder=10, width=0.1/25,transform = ccrs.PlateCarree(), color = 'red', label = 'owiWindStreaks')\n",
222
+ "\n",
223
+ " # Display ancillary wind direction\n",
224
+ " #ax.quiver(lons, lats, u_norm_ancillary, v_norm_ancillary, edgecolors='k', norm=norm, pivot= 'mid', scale_units='xy', scale=4., zorder=10, width=0.1/25,transform = ccrs.PlateCarree(), color='blue', label = \"owiAncillaryWindDirection\")\n",
225
+ " ax.quiver(lons, lats, u_norm_ancillary, v_norm_ancillary, edgecolors='k', norm=norm, pivot= 'mid', scale_units='xy', scale=8., zorder=10, width=0.1/25,transform = ccrs.PlateCarree(), color='blue', label = \"owiAncillaryWindDirection\")\n",
226
+ "\n",
227
+ " # Display sigma0 copol\n",
228
+ " im = ax.pcolormesh(xr_dataset.longitude,xr_dataset.latitude, xr_dataset.sigma0.sel(pol=pol_display),cmap='gray')\n",
229
+ " cbar = plt.colorbar(im, ax =ax)\n",
230
+ " cbar.set_label(f'Sigma0, pol = {pol_display}')\n",
231
+ " \n",
232
+ " # Expand the map by 1 degree in height\n",
233
+ " lon_min, lon_max = np.nanmin(lons) - .2, np.nanmax(lons) + .2 \n",
234
+ " lat_min, lat_max = np.nanmin(lats) - .2, np.nanmax(lats) + .7\n",
235
+ " ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree())\n",
236
+ "\n",
237
+ "\n",
238
+ " # Configurer les axes\n",
239
+ " ax.set_xlabel('Longitude')\n",
240
+ " ax.set_ylabel('Latitude')\n",
241
+ " ax.set_aspect('equal', adjustable='box')\n",
242
+ "\n",
243
+ " gl = ax.gridlines(draw_labels=True)\n",
244
+ " gl.top_labels = False\n",
245
+ " gl.right_labels = False\n",
246
+ " gl.xformatter = LONGITUDE_FORMATTER\n",
247
+ " gl.yformatter = LATITUDE_FORMATTER\n",
248
+ " ax.set_title(f\"{os.path.basename(filename)}\\nvarname = {varname}\\nwindow size = {window_size} ; downscale_factor = {downscale_factor} ; pol= {pol}\")\n",
249
+ " legend = ax.legend(facecolor='white', loc = 'upper right')\n",
250
+ " legend.set_zorder(100)\n",
251
+ " if savefig:\n",
252
+ " os.makedirs(savedir, exist_ok=True)\n",
253
+ " plt.savefig(os.path.join(savedir, f\"wind_streaks_{varname}_{window_size}_{downscale_factor}_{pol}.png\"))"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": null,
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "savefig = False\n",
263
+ "\n",
264
+ "varname = 'dir_mean_smooth'\n",
265
+ "kwargs = {'varname' : varname, 'savefig': savefig, 'savedir': \"./tmp\"}\n",
266
+ "plot_wind_from_streaks(xr_dataset_streaks[varname], **kwargs)\n",
267
+ "\n",
268
+ "varname = 'dir_smooth_mean'\n",
269
+ "kwargs = {'varname' : varname, 'savefig': savefig, 'savedir': \"./tmp\"}\n",
270
+ "plot_wind_from_streaks(xr_dataset_streaks[varname], **kwargs)\n",
271
+ "\n",
272
+ "\n",
273
+ "# plot individual solutions \n",
274
+ "varname = 'dir_smooth'\n",
275
+ "for downscale_factor in xr_dataset_streaks.downscale_factor.values:\n",
276
+ " for pol in xr_dataset_streaks.pol.values:\n",
277
+ " for window_size in xr_dataset_streaks.window_size.values:\n",
278
+ " streaks_dir = xr_dataset_streaks[varname].sel(\n",
279
+ " downscale_factor=downscale_factor, pol=pol, window_size=window_size).values\n",
280
+ " kwargs = {'varname' : varname , 'window_size': window_size, 'downscale_factor': downscale_factor, 'pol': pol, 'savefig': savefig, 'savedir': \"./tmp\"}\n",
281
+ " plot_wind_from_streaks(streaks_dir, **kwargs)\n",
282
+ "\n",
283
+ "# plot one individual solution\n",
284
+ "# downscale_factor = 1\n",
285
+ "# pol = 'VV'\n",
286
+ "# window_size = 3200\n",
287
+ "\n",
288
+ "# streaks_dir = xr_dataset_streaks[varname].sel(\n",
289
+ "# downscale_factor=downscale_factor, pol=pol, window_size=window_size).values\n",
290
+ "# kwargs = {'varname' : varname , 'window_size': window_size, 'downscale_factor': downscale_factor, 'pol': pol, 'savefig': True, 'savedir': \"./tmp\"}\n",
291
+ "# plot_wind_from_streaks(streaks_dir, **kwargs)\n",
292
+ "\n"
293
+ ]
294
+ },
295
+ {
296
+ "cell_type": "code",
297
+ "execution_count": null,
298
+ "metadata": {},
299
+ "outputs": [],
300
+ "source": []
301
+ }
302
+ ],
303
+ "metadata": {
304
+ "kernelspec": {
305
+ "display_name": "Python 3 (ipykernel)",
306
+ "language": "python",
307
+ "name": "python3"
308
+ },
309
+ "language_info": {
310
+ "codemirror_mode": {
311
+ "name": "ipython",
312
+ "version": 3
313
+ },
314
+ "file_extension": ".py",
315
+ "mimetype": "text/x-python",
316
+ "name": "python",
317
+ "nbconvert_exporter": "python",
318
+ "pygments_lexer": "ipython3",
319
+ "version": "3.11.0"
320
+ }
321
+ },
322
+ "nbformat": 4,
323
+ "nbformat_minor": 4
324
+ }