Skip to content

Commit

Permalink
Merge pull request #78 from vincelhx/master
Browse files Browse the repository at this point in the history
angles funcs
  • Loading branch information
vincelhx authored Sep 23, 2024
2 parents 3d47ea1 + d1fe85d commit 72673b7
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 38 deletions.
5 changes: 3 additions & 2 deletions docs/examples/streaks.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"metadata": {},
"outputs": [],
"source": [
"xsarsea.windspeed.gmfs.GmfModel.activate_gmfs_impl()\n",
"xsarsea.windspeed.available_models()"
]
},
Expand Down Expand Up @@ -138,7 +139,7 @@
"streaks_geo['weight'] = streaks['weight']\n",
"\n",
"# convert directions from image convention to geographic convention\n",
"streaks_geo['streaks_dir'] = xsarsea.dir_sample_to_geo(np.rad2deg(streaks['angle']), streaks_geo['ground_heading']) \n",
"streaks_geo['streaks_dir'] = xsarsea.dir_sample_to_meteo(np.rad2deg(streaks['angle']), streaks_geo['ground_heading']) \n",
"\n",
"streaks_geo = streaks_geo.compute()\n",
"\n",
Expand Down Expand Up @@ -228,7 +229,7 @@
"source": [
"#### Convertion between image convention and geographic convention\n",
"\n",
"see [xsarsea.dir_geo_to_sample](../basic_api.rst#xsarsea.dir_geo_to_sample) and [xsarsea.dir_sample_to_geo](../basic_api.rst#xsarsea.dir_sample_to_geo)\n",
"see [xsarsea.dir_meteo_to_sample](../basic_api.rst#xsarsea.dir_meteo_to_sample) and [xsarsea.dir_sample_to_meteo](../basic_api.rst#xsarsea.dir_sample_to_meteo)\n",
"\n"
]
},
Expand Down
12 changes: 6 additions & 6 deletions docs/examples/windspeed_inversion.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"> .. warning::\n",
" **Use of ancillary wind**\n",
"\n",
"> We suggest to go from `ancillary_wind = -np.conj(sarwing_ds.owi_ancillary_wind)` to `sarwing_ds.owi_ancillary_wind`` ; then it won't match sarwing results anymore\n",
"> We suggest to go from `ancillary_wind = -np.conj(sarwing_ds.owi_ancillary_wind)` to `ancillary_wind = sarwing_ds.owi_ancillary_wind` ; then it won't match sarwing results anymore\n",
"\n"
]
},
Expand Down Expand Up @@ -82,7 +82,7 @@
"\n",
"Ecmwf wind is stored in owi file in *geographical* (deg N/S) convention. `xsarsea.windspeed` need it relative to *sample* (ie antenna), as a complex number.\n",
"\n",
"We use [xsarsea.dir_geo_to_sample](../basic_api.rst#xsarsea.dir_geo_to_sample) to convert `sarwing_ds.owiEcmwfWindDirection` (deg) to radians, relative to sample, using `sarwing_ds.owiHeading`\n"
"We use [xsarsea.dir_meteo_to_sample](../basic_api.rst#xsarsea.dir_meteo_to_sample) to convert `sarwing_ds.owiEcmwfWindDirection` (deg) to radians, relative to sample, using `sarwing_ds.owiHeading`\n"
]
},
{
Expand All @@ -92,7 +92,7 @@
"metadata": {},
"outputs": [],
"source": [
"owi_ecmwf_wind = sarwing_ds.owiEcmwfWindSpeed * np.exp(1j* xsarsea.dir_geo_to_sample(sarwing_ds.owiEcmwfWindDirection, sarwing_ds.owiHeading))\n",
"owi_ecmwf_wind = sarwing_ds.owiEcmwfWindSpeed * np.exp(1j* xsarsea.dir_meteo_to_sample(sarwing_ds.owiEcmwfWindDirection, sarwing_ds.owiHeading))\n",
"sarwing_ds = xr.merge([\n",
" sarwing_ds,\n",
" owi_ecmwf_wind.to_dataset(name='owi_ancillary_wind'),\n",
Expand Down Expand Up @@ -127,7 +127,7 @@
"vectorfield = hv.VectorField(\n",
" (\n",
" sub_sarwing_ds.sample, sub_sarwing_ds.line,\n",
" xsarsea.dir_geo_to_sample(sub_sarwing_ds.owiEcmwfWindDirection, sub_sarwing_ds.owiHeading),\n",
" xsarsea.dir_meteo_to_sample(sub_sarwing_ds.owiEcmwfWindDirection, sub_sarwing_ds.owiHeading),\n",
" sub_sarwing_ds.owiEcmwfWindSpeed\n",
" )\n",
")\n",
Expand Down Expand Up @@ -478,7 +478,7 @@
"vectorfield = hv.VectorField(\n",
" (\n",
" sub_sarwing_ds.sample, sub_sarwing_ds.line,\n",
" xsarsea.dir_geo_to_sample(sarwing_ds[\"winddir_dual\"] ,sub_sarwing_ds.owiHeading),\n",
" xsarsea.dir_meteo_to_sample(sarwing_ds[\"winddir_dual\"] ,sub_sarwing_ds.owiHeading),\n",
" np.abs(wind_dual).isel(line=slice(None, None, 10), sample=slice(None, None, 10))\n",
" )\n",
")\n",
Expand Down Expand Up @@ -506,7 +506,7 @@
"vectorfield = hv.VectorField(\n",
" (\n",
" sub_sarwing_ds.sample, sub_sarwing_ds.line,\n",
" xsarsea.dir_geo_to_sample(sub_sarwing_ds.owiWindDirection ,sub_sarwing_ds.owiHeading),\n",
" xsarsea.dir_meteo_to_sample(sub_sarwing_ds.owiWindDirection ,sub_sarwing_ds.owiHeading),\n",
" sub_sarwing_ds.owiWindSpeed\n",
" )\n",
")\n",
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/windspeed_retrieval_L1.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@
"dataset['sigma0_ocean'] = xr.where(dataset['sigma0'] <= 0, 1e-15, xsar_obj.dataset['sigma0'])\n",
"dataset['ancillary_wind_direction'] = (90. - np.rad2deg(np.arctan2(dataset.model_V10, dataset.model_U10)) + 180) % 360\n",
"dataset['ancillary_wind_speed'] = np.sqrt(dataset['model_U10']**2+dataset['model_V10']**2)\n",
"dataset['ancillary_wind'] = dataset.ancillary_wind_speed * np.exp(1j * xsarsea.dir_geo_to_sample(dataset.ancillary_wind_direction, dataset.ground_heading)) # ref antenna"
"dataset['ancillary_wind'] = dataset.ancillary_wind_speed * np.exp(1j * xsarsea.dir_meteo_to_sample(dataset.ancillary_wind_direction, dataset.ground_heading)) # ref antenna"
]
},
{
Expand Down Expand Up @@ -471,7 +471,7 @@
"vectorfield = hv.VectorField(\n",
" (\n",
" sub_ds.sample, sub_ds.line,\n",
" xsarsea.dir_geo_to_sample(sub_ds.winddir_dual,sub_ds.ground_heading),\n",
" xsarsea.dir_meteo_to_sample(sub_ds.winddir_dual,sub_ds.ground_heading),\n",
" sub_ds.windspeed_dual\n",
" )\n",
")\n",
Expand All @@ -491,7 +491,7 @@
"vectorfield = hv.VectorField(\n",
" (\n",
" sub_ds.sample, sub_ds.line,\n",
" xsarsea.dir_geo_to_sample(sub_ds.ancillary_wind_direction,sub_ds.ground_heading),\n",
" xsarsea.dir_meteo_to_sample(sub_ds.ancillary_wind_direction,sub_ds.ground_heading),\n",
" sub_ds.ancillary_wind_speed\n",
" )\n",
")\n",
Expand Down
6 changes: 3 additions & 3 deletions src/xsarsea/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
__all__ = ['sigma0_detrend', 'dir_geo_to_sample', 'dir_sample_to_geo', 'get_test_file']
__all__ = ['sigma0_detrend', 'dir_meteo_to_sample',
'dir_sample_to_meteo', 'dir_meteo_to_oceano', 'dir_oceano_to_meteo', 'dir_to_180', 'dir_to_360', 'get_test_file']

from .utils import get_test_file
from .xsarsea import dir_geo_to_sample, dir_sample_to_geo, sigma0_detrend, read_sarwing_owi
from .xsarsea import dir_meteo_to_sample, dir_sample_to_meteo, sigma0_detrend, dir_meteo_to_oceano, dir_oceano_to_meteo, dir_to_180, dir_to_360, read_sarwing_owi
try:
from importlib import metadata
except ImportError: # for Python<3.8
import importlib_metadata as metadata
__version__ = metadata.version('xsarsea')

6 changes: 5 additions & 1 deletion src/xsarsea/gradients.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
__all__ = ['Gradients', 'Gradients2D',
'circ_smooth', 'PlotGradients', 'circ_hist']

import cv2
try:
import cv2
except:
import cv2

import numpy as np
from scipy import signal, ndimage
import xarray as xr
Expand Down
4 changes: 2 additions & 2 deletions src/xsarsea/windspeed/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
windspeed module, for retrieving wind speed from sigma0 and models.
"""
__all__ = ['invert_from_model', 'available_models', 'get_model', 'register_cmod7',
'register_sarwing_luts', 'register_nc_luts', 'nesz_flattening', 'GmfModel']
'register_sarwing_luts', 'register_nc_luts', 'register_luts', 'nesz_flattening', 'GmfModel']
from .windspeed import invert_from_model
from .models import available_models, get_model, register_nc_luts
from .models import available_models, get_model, register_nc_luts, register_luts
from .sarwing_luts import register_sarwing_luts
from .cmod7 import register_cmod7
from .utils import nesz_flattening, get_dsig
Expand Down
33 changes: 31 additions & 2 deletions src/xsarsea/windspeed/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def __call__(self, inc, wspd, phi=None, broadcast=False):
wspd: array-like
windspeed
phi: array-like or None
wind direction, in **gmf convention**
wind direction relative to antenna
broadcast: bool
| If True, input arrays will be broadcasted to the same dimensions, and output will have the same dimension.
| This option is only available for :func:`~xsarsea.windspeed.gmfs.GmfModel`
Expand Down Expand Up @@ -397,7 +397,7 @@ def _raw_lut(self, **kwargs):
return lut


def register_nc_luts(topdir, gmf_names=None, **kwargs):
def register_nc_luts(topdir, gmf_names=None):
"""
Register all netcdf luts found under `topdir`.
Expand Down Expand Up @@ -518,3 +518,32 @@ def get_model(name):
raise KeyError('model %s not found' % name)

return model


def register_luts(topdir=None, topdir_cmod7=None):
"""
Register gmfModel luts and ncLutModel luts
Parameters
----------
topdir: str
top dir path to nc luts.
topdir_cmod7: str
top dir path to cmod7 luts.
kwargs: dict
kwargs to pass to register_nc_luts
"""

# register gmf luts
import xsarsea.windspeed as windspeed
windspeed.GmfModel.activate_gmfs_impl()

# register nc luts
if topdir != None:
register_nc_luts(topdir)

# register cmod7
if topdir_cmod7 != None:
windspeed.register_cmod7(topdir_cmod7)
12 changes: 2 additions & 10 deletions src/xsarsea/windspeed/windspeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ def invert_from_model(inc, sigma0, sigma0_dual=None, /, ancillary_wind=None, dsi
sigma0 in cross pol for dualpol invertion
ancillary_wind=: xarray.DataArray (numpy.complex28)
ancillary wind
| (for example ecmwf winds), in **model convention**
| (for example ecmwf winds), in **antenna convention**
model=: str or tuple
model to use.
Expand All @@ -46,8 +45,7 @@ def invert_from_model(inc, sigma0, sigma0_dual=None, /, ancillary_wind=None, dsi
-------
xarray.DataArray or tuple
If available (copol or dualpol), the returned array is `np.complex64`, with the angle of the returned array is
inverted direction in **gmf convention** (use `-np.conj(result))` to get it in standard convention)
inverted direction in **antenna convention**
See Also
--------
xsarsea.windspeed.available_models
Expand Down Expand Up @@ -170,12 +168,6 @@ def __invert_from_model_1d(inc_1d, sigma0_co_db_1d, sigma0_cr_db_1d, dsig_cr_1d,
# this function will be vectorized with 'numba.guvectorize' or 'numpy.frompyfunc'
# set debug=True below to force 'numpy.frompyfunc', so you can debug this code

# gmf and lut doesn't have the same direction convention than xsarsea in the sample direction
# for xsarsea, positive sample means in the sample increasing direction
# for gmf and lut, positive means in the sample decreasing direction
# we switch ancillary wind to the gmf convention
# ancillary_wind_1d = -np.conj(ancillary_wind_1d)

for i in range(len(inc_1d)):
one_inc = inc_1d[i]
one_sigma0_co_db = sigma0_co_db_1d[i]
Expand Down
88 changes: 80 additions & 8 deletions src/xsarsea/xsarsea.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ def read_sarwing_owi(owi_file):
return sarwing_ds


def dir_geo_to_sample(geo_dir, ground_heading):
def dir_meteo_to_sample(meteo_dir, ground_heading):
"""
Convert geographical N/S direction to image convention
Convert meteorological N/S direction to image convention
Parameters
----------
geo_dir: geographical direction in degrees north
meteo_dir: meteorological direction in degrees north
ground_heading: azimuth at position, in degrees north
Returns
Expand All @@ -104,22 +104,94 @@ def dir_geo_to_sample(geo_dir, ground_heading):
same shape as input. angle in radian, relative to sample, anticlockwise
"""

return np.pi / 2 - np.deg2rad(geo_dir - ground_heading)
return np.pi / 2 - np.deg2rad(meteo_dir - ground_heading)


def dir_sample_to_geo(sample_dir, ground_heading):
def dir_sample_to_meteo(sample_dir, ground_heading):
"""
Convert image direction relative to antenna to geographical direction
Convert image direction relative to antenna to meteorological direction
Parameters
----------
sample_dir: geographical direction in degrees north
sample_dir: angle in degrees, relative to sample, anticlockwise
ground_heading: azimuth at position, in degrees north
Returns
-------
np.float64
same shape as input. angle in degrees, relative to sample, anticlockwise
same shape as input. meteorological direction in degrees north
"""

return 90 - sample_dir + ground_heading


def dir_meteo_to_oceano(meteo_dir):
"""
Convert meteorological direction to oceanographic direction
Parameters
----------
meteo_dir: float
Wind direction in meteorological convention (clockwise, from), ex: 0°=from north, 90°=from east
Returns
-------
float
Wind direction in oceanographic convention (clockwise, to), ex: 0°=to north, 90°=to east
"""
oceano_dir = (meteo_dir + 180) % 360
return oceano_dir


def dir_oceano_to_meteo(oceano_dir):
"""
Convert oceanographic direction to meteorological direction
Parameters
----------
oceano_dir: float
Wind direction in oceanographic convention (clockwise, to), ex: 0°=to north, 90°=to east
Returns
-------
float
Wind direction in meteorological convention (clockwise, from), ex: 0°=from north, 90°=from east
"""
meteo_dir = (oceano_dir - 180) % 360
return meteo_dir


def dir_to_180(angle):
"""
Convert angle to [-180;180]
Parameters
----------
angle: float
angle in degrees
Returns
-------
float
angle in degrees
"""
angle_180 = (angle + 180) % 360 - 180
return angle_180


def dir_to_360(angle):
"""
Convert angle to [0;360]
Parameters
----------
angle: float
angle in degrees
Returns
-------
float
angle in degrees
"""
angle_360 = (angle + 360) % 360
return angle_360
2 changes: 1 addition & 1 deletion test/test_xsarsea.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_inversion():
line=slice(0, 50), sample=slice(0, 60))

owi_ecmwf_wind = sarwing_ds.owiEcmwfWindSpeed * np.exp(
1j * xsarsea.dir_geo_to_sample(sarwing_ds.owiEcmwfWindDirection, sarwing_ds.owiHeading))
1j * xsarsea.dir_meteo_to_sample(sarwing_ds.owiEcmwfWindDirection, sarwing_ds.owiHeading))
sarwing_ds = xr.merge([
sarwing_ds,
owi_ecmwf_wind.to_dataset(name='owi_ancillary_wind'),
Expand Down

0 comments on commit 72673b7

Please sign in to comment.