grdwindinversion 0.2.3.post7__tar.gz → 0.2.3.post9__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.
- {grdwindinversion-0.2.3.post7/grdwindinversion.egg-info → grdwindinversion-0.2.3.post9}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/__init__.py +2 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/config_prod.yaml +4 -4
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/config_prod_recal.yaml +4 -8
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/inversion.py +377 -213
- grdwindinversion-0.2.3.post9/grdwindinversion/load_config.py +24 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/main.py +3 -16
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9/grdwindinversion.egg-info}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/SOURCES.txt +0 -4
- grdwindinversion-0.2.3.post7/grdwindinversion/config_RCM.yaml +0 -6
- grdwindinversion-0.2.3.post7/grdwindinversion/config_RS2.yaml +0 -6
- grdwindinversion-0.2.3.post7/grdwindinversion/config_S1.yaml +0 -12
- grdwindinversion-0.2.3.post7/grdwindinversion/config_hy2b.yaml +0 -24
- grdwindinversion-0.2.3.post7/grdwindinversion/load_config.py +0 -22
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/.editorconfig +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/.github/dependabot.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/.github/workflows/publish.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/.gitignore +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/.pre-commit-config.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/AUTHORS.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/CONTRIBUTING.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/HISTORY.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/LICENSE +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/MANIFEST.in +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/Makefile +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/README.md +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/ci/requirements/docs.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/ci/requirements/environment.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/Makefile +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/_static/css/grdwindinversion.css +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/algorithm.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/authors.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/conf.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/contributing.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/examples/wind-inversion-from-grd.ipynb +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/history.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/index.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/installation.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/make.bat +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/modules.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/readme.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/usage.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/.github/ISSUE_TEMPLATE.md +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/.gitignore +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/.travis.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/data_config.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/utils.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/dependency_links.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/entry_points.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/requires.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/top_level.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/pyproject.toml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/requirements_dev.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/requirements_doc.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/setup.cfg +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/tests/__init__.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/tests/test_grdwindinversion.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/tox.ini +0 -0
|
@@ -6,6 +6,8 @@ __all__ = ['inversion']
|
|
|
6
6
|
# __version__ = metadata.version('grdwindinversion')
|
|
7
7
|
from grdwindinversion import *
|
|
8
8
|
from importlib.metadata import version
|
|
9
|
+
from grdwindinversion.inversion import inverse
|
|
10
|
+
|
|
9
11
|
try:
|
|
10
12
|
__version__ = version("grdwindinversion")
|
|
11
13
|
except Exception:
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/config_prod.yaml
RENAMED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
S1A:
|
|
2
|
-
GMF_VV_NAME: "
|
|
2
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
3
3
|
GMF_VH_NAME: "gmf_s1_v2"
|
|
4
4
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
5
5
|
apply_flattening: True
|
|
6
6
|
recalibration: False
|
|
7
7
|
S1B:
|
|
8
|
-
GMF_VV_NAME: "
|
|
8
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
9
9
|
GMF_VH_NAME: "gmf_s1_v2"
|
|
10
10
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
11
11
|
apply_flattening: True
|
|
12
12
|
recalibration: False
|
|
13
13
|
RS2:
|
|
14
|
-
GMF_VV_NAME: "
|
|
14
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
15
15
|
GMF_VH_NAME: "gmf_rs2_v2"
|
|
16
16
|
dsig_VH_NAME: "gmf_rs2_v2"
|
|
17
17
|
apply_flattening: False
|
|
18
18
|
recalibration: False
|
|
19
19
|
RCM:
|
|
20
|
-
GMF_VV_NAME: "
|
|
20
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
21
21
|
GMF_VH_NAME: "gmf_rcm_noaa"
|
|
22
22
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
23
23
|
apply_flattening: True
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
S1A:
|
|
2
|
-
GMF_VV_NAME: "
|
|
2
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
3
3
|
GMF_VH_NAME: "gmf_s1_v2"
|
|
4
4
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
5
5
|
apply_flattening: True
|
|
6
6
|
recalibration: True
|
|
7
|
-
aux_config_name: "v_IPF_36"
|
|
8
7
|
S1B:
|
|
9
|
-
GMF_VV_NAME: "
|
|
8
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
10
9
|
GMF_VH_NAME: "gmf_s1_v2"
|
|
11
10
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
12
11
|
apply_flattening: True
|
|
13
12
|
recalibration: True
|
|
14
|
-
aux_config_name: "v_IPF_36"
|
|
15
13
|
RS2:
|
|
16
|
-
GMF_VV_NAME: "
|
|
14
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
17
15
|
GMF_VH_NAME: "gmf_rs2_v2"
|
|
18
16
|
dsig_VH_NAME: "gmf_rs2_v2"
|
|
19
17
|
apply_flattening: False
|
|
20
18
|
recalibration: True
|
|
21
|
-
aux_config_name: "v_IPF_36"
|
|
22
19
|
RCM:
|
|
23
|
-
GMF_VV_NAME: "
|
|
20
|
+
GMF_VV_NAME: "gmf_cmod5n"
|
|
24
21
|
GMF_VH_NAME: "gmf_rcm_noaa"
|
|
25
22
|
dsig_VH_NAME: "gmf_s1_v2"
|
|
26
23
|
apply_flattening: True
|
|
27
24
|
recalibration: True
|
|
28
|
-
aux_config_name: "v_IPF_36"
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import pdb
|
|
3
1
|
import traceback
|
|
4
2
|
|
|
5
3
|
import xsar
|
|
@@ -21,24 +19,24 @@ import os
|
|
|
21
19
|
from grdwindinversion.load_config import getConf
|
|
22
20
|
# optional debug messages
|
|
23
21
|
import logging
|
|
24
|
-
|
|
25
22
|
logging.basicConfig()
|
|
26
23
|
logging.getLogger('xsarsea.windspeed').setLevel(
|
|
27
24
|
logging.INFO) # or .setLevel(logging.INFO)
|
|
28
|
-
# encode gcps as json string
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class JSONEncoder(json.JSONEncoder):
|
|
32
|
-
def default(self, obj):
|
|
33
|
-
if isinstance(obj, np.integer):
|
|
34
|
-
return int(obj)
|
|
35
25
|
|
|
36
26
|
|
|
37
27
|
def getSensorMetaDataset(filename):
|
|
38
28
|
"""
|
|
29
|
+
Find the sensor name and the corresponding meta and dataset functions
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
filename : str
|
|
34
|
+
input filename
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
tuple
|
|
39
|
+
sensor name, sensor long name, meta function, dataset function
|
|
42
40
|
"""
|
|
43
41
|
if ("S1A" in filename):
|
|
44
42
|
return "S1A", "SENTINEL-1 A", xsar.Sentinel1Meta, xsar.Sentinel1Dataset
|
|
@@ -54,12 +52,23 @@ def getSensorMetaDataset(filename):
|
|
|
54
52
|
|
|
55
53
|
def getOutputName2(input_file, out_folder, sensor, meta):
|
|
56
54
|
"""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
Create output filename for L2-GRD product
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
input_file : str
|
|
60
|
+
input filename
|
|
61
|
+
out_folder : str
|
|
62
|
+
output folder
|
|
63
|
+
sensor : str
|
|
64
|
+
sensor name
|
|
65
|
+
meta : obj `xsar.BaseMeta` (one of the supported SAR mission)
|
|
66
|
+
meta object
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
outfile : str
|
|
71
|
+
output filename
|
|
63
72
|
"""
|
|
64
73
|
basename = os.path.basename(input_file)
|
|
65
74
|
basename_match = basename
|
|
@@ -107,91 +116,203 @@ def getOutputName2(input_file, out_folder, sensor, meta):
|
|
|
107
116
|
"sensor must be S1A|S1B|RS2|RCM, got sensor %s" % sensor)
|
|
108
117
|
|
|
109
118
|
|
|
110
|
-
def getAncillary(meta):
|
|
119
|
+
def getAncillary(meta, ancillary_name='ecmwf'):
|
|
120
|
+
"""
|
|
121
|
+
Map ancillary wind from ECMWF or ERA5.
|
|
122
|
+
This function is used to check if the model files are available and to map the model to the SAR data.
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
meta: obj `xsar.BaseMeta` (one of the supported SAR mission)
|
|
111
127
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
meta.set_raster('ecmwf_0125_1h', ec0125)
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
dict
|
|
131
|
+
map model to SAR data
|
|
132
|
+
"""
|
|
118
133
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
134
|
+
if ancillary_name == 'ecmwf':
|
|
135
|
+
|
|
136
|
+
logging.debug('conf: %s', getConf())
|
|
137
|
+
ec01 = getConf()['ecmwf_0100_1h']
|
|
138
|
+
ec0125 = getConf()['ecmwf_0125_1h']
|
|
139
|
+
logging.debug('ec01 : %s', ec01)
|
|
140
|
+
meta.set_raster('ecmwf_0100_1h', ec01)
|
|
141
|
+
meta.set_raster('ecmwf_0125_1h', ec0125)
|
|
142
|
+
|
|
143
|
+
map_model = None
|
|
144
|
+
# only keep best ecmwf (FIXME: it's hacky, and xsar should provide a better method to handle this)
|
|
145
|
+
for ecmwf_name in ['ecmwf_0125_1h', 'ecmwf_0100_1h']:
|
|
146
|
+
ecmwf_infos = meta.rasters.loc[ecmwf_name]
|
|
147
|
+
try:
|
|
148
|
+
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
149
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
150
|
+
'%Y-%m-%d %H:%M:%S.%f'))[1]
|
|
151
|
+
# temporary for RCM issue https://github.com/umr-lops/xarray-safe-rcm/issues/34
|
|
152
|
+
except Exception as e:
|
|
153
|
+
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
154
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
155
|
+
'%Y-%m-%d %H:%M:%S'))[1]
|
|
156
|
+
if not os.path.isfile(ecmwf_file):
|
|
157
|
+
# temporary
|
|
158
|
+
# if repro does not exist we look at not repro folder (only one will exist after)
|
|
159
|
+
"""
|
|
160
|
+
if ecmwf_name == "ecmwf_0100_1h":
|
|
161
|
+
ecmwf_infos['resource'] = ecmwf_infos['resource'].replace(
|
|
162
|
+
"netcdf_light_REPRO_tree", "netcdf_light")
|
|
163
|
+
try:
|
|
164
|
+
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
165
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
166
|
+
'%Y-%m-%d %H:%M:%S.%f'))[1]
|
|
167
|
+
except Exception as e:
|
|
168
|
+
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
169
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
170
|
+
'%Y-%m-%d %H:%M:%S'))[1]
|
|
171
|
+
|
|
172
|
+
if not os.path.isfile(ecmwf_file):
|
|
173
|
+
meta.rasters = meta.rasters.drop([ecmwf_name])
|
|
174
|
+
else:
|
|
175
|
+
map_model = {'%s_%s' % (ecmwf_name, uv): 'model_%s' % uv for uv in [
|
|
176
|
+
'U10', 'V10']}
|
|
177
|
+
|
|
178
|
+
else:
|
|
179
|
+
"""
|
|
180
|
+
meta.rasters = meta.rasters.drop([ecmwf_name])
|
|
181
|
+
else:
|
|
182
|
+
map_model = {'%s_%s' % (ecmwf_name, uv): 'model_%s' %
|
|
183
|
+
uv for uv in ['U10', 'V10']}
|
|
184
|
+
|
|
185
|
+
return map_model
|
|
186
|
+
|
|
187
|
+
elif ancillary_name == 'era5':
|
|
188
|
+
era5_name = "era5_0250_1h"
|
|
189
|
+
logging.debug('conf: %s', getConf())
|
|
190
|
+
era0250 = getConf()[era5_name]
|
|
191
|
+
logging.debug('%s : %s', (era5_name, era0250))
|
|
192
|
+
meta.set_raster(era5_name, era0250)
|
|
193
|
+
|
|
194
|
+
era5_infos = meta.rasters.loc[era5_name]
|
|
123
195
|
try:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
# temporary for RCM issue https://github.com/umr-lops/xarray-safe-rcm/issues/34
|
|
196
|
+
era5_file = era5_infos['get_function'](era5_infos['resource'],
|
|
197
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
198
|
+
'%Y-%m-%d %H:%M:%S.%f'))[1]
|
|
128
199
|
except Exception as e:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# temporary
|
|
135
|
-
# if repro does not exist we look at not repro folder (only one will exist after)
|
|
136
|
-
if ecmwf_name == "ecmwf_0100_1h":
|
|
137
|
-
ecmwf_infos['resource'] = ecmwf_infos['resource'].replace(
|
|
138
|
-
"netcdf_light_REPRO_tree", "netcdf_light")
|
|
139
|
-
try:
|
|
140
|
-
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
141
|
-
date=datetime.datetime.strptime(meta.start_date,
|
|
142
|
-
'%Y-%m-%d %H:%M:%S.%f'))[1]
|
|
143
|
-
except Exception as e:
|
|
144
|
-
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
145
|
-
date=datetime.datetime.strptime(meta.start_date,
|
|
146
|
-
'%Y-%m-%d %H:%M:%S'))[1]
|
|
147
|
-
|
|
148
|
-
if not os.path.isfile(ecmwf_file):
|
|
149
|
-
meta.rasters = meta.rasters.drop([ecmwf_name])
|
|
150
|
-
else:
|
|
151
|
-
map_model = {'%s_%s' % (ecmwf_name, uv): 'model_%s' % uv for uv in [
|
|
152
|
-
'U10', 'V10']}
|
|
200
|
+
era5_file = era5_infos['get_function'](era5_infos['resource'],
|
|
201
|
+
date=datetime.datetime.strptime(meta.start_date,
|
|
202
|
+
'%Y-%m-%d %H:%M:%S'))[1]
|
|
203
|
+
if not os.path.isfile(era5_file):
|
|
204
|
+
raise ValueError(f"era5 file {era5_file} not found")
|
|
153
205
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
map_model = {'%s_%s' % (ecmwf_name, uv): 'model_%s' %
|
|
158
|
-
uv for uv in ['U10', 'V10']}
|
|
206
|
+
map_model = {'%s_%s' % (era5_name, uv): 'model_%s' %
|
|
207
|
+
uv for uv in ['U10', 'V10']}
|
|
208
|
+
return map_model
|
|
159
209
|
|
|
160
|
-
|
|
210
|
+
else:
|
|
211
|
+
raise ValueError("ancillary_name must be ecmwf/era5, got %s" %
|
|
212
|
+
ancillary_name)
|
|
161
213
|
|
|
162
214
|
|
|
163
215
|
def inverse(dual_pol, inc, sigma0, sigma0_dual, ancillary_wind, dsig_cr, model_vv, model_vh):
|
|
216
|
+
"""
|
|
217
|
+
Invert sigma0 to retrieve wind using model (lut or gmf).
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
dual_pol: bool
|
|
222
|
+
True if dualpol, False if singlepol
|
|
223
|
+
inc: xarray.DataArray
|
|
224
|
+
incidence angle
|
|
225
|
+
sigma0: xarray.DataArray
|
|
226
|
+
sigma0 to be inverted
|
|
227
|
+
sigma0_dual: xarray.DataArray
|
|
228
|
+
sigma0 to be inverted for dualpol
|
|
229
|
+
ancillary_wind=: xarray.DataArray (numpy.complex28)
|
|
230
|
+
ancillary wind
|
|
231
|
+
| (for example ecmwf winds), in **model convention**
|
|
232
|
+
dsig_cr=: float or xarray.DataArray
|
|
233
|
+
parameters used for
|
|
234
|
+
|
|
235
|
+
| `Jsig_cr=((sigma0_gmf - sigma0) / dsig_cr) ** 2`
|
|
236
|
+
model_vv=: str
|
|
237
|
+
model to use for VV or HH polarization.
|
|
238
|
+
model_vh=: str
|
|
239
|
+
model to use for VH or HV polarization.
|
|
240
|
+
|
|
241
|
+
Returns
|
|
242
|
+
-------
|
|
243
|
+
xarray.DataArray or tuple
|
|
244
|
+
inverted wind in **gmf convention** .
|
|
245
|
+
|
|
246
|
+
See Also
|
|
247
|
+
--------
|
|
248
|
+
xsarsea documentation
|
|
249
|
+
https://cyclobs.ifremer.fr/static/sarwing_datarmor/xsarsea/examples/windspeed_inversion.html
|
|
250
|
+
"""
|
|
164
251
|
logging.debug("inversion")
|
|
165
|
-
|
|
166
|
-
|
|
252
|
+
|
|
253
|
+
# add potential missing gmfs (only cmod7 & ms1ahw)
|
|
254
|
+
|
|
255
|
+
if (model_vv == "gmf_cmod7"):
|
|
256
|
+
windspeed.register_cmod7(getConf()["lut_cmod7_path"])
|
|
257
|
+
|
|
258
|
+
if (model_vh == "sarwing_lut_cmodms1ahw"):
|
|
259
|
+
windspeed.register_one_sarwing_lut(getConf()["lut_ms1ahw_path"])
|
|
260
|
+
|
|
261
|
+
winds = windspeed.invert_from_model(
|
|
167
262
|
inc,
|
|
168
263
|
sigma0,
|
|
169
264
|
sigma0_dual,
|
|
170
|
-
|
|
171
|
-
ancillary_wind=-ancillary_wind,
|
|
265
|
+
ancillary_wind=-np.conj(ancillary_wind),
|
|
172
266
|
dsig_cr=dsig_cr,
|
|
173
267
|
model=(model_vv, model_vh))
|
|
268
|
+
|
|
174
269
|
if dual_pol:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
270
|
+
wind_co, wind_dual = winds
|
|
271
|
+
|
|
272
|
+
wind_cross = windspeed.invert_from_model(
|
|
178
273
|
inc.values,
|
|
179
274
|
sigma0_dual.values,
|
|
180
|
-
# ancillary_wind=-np.conj(xsar_dataset.dataset['ancillary_wind']),
|
|
181
275
|
dsig_cr=dsig_cr.values,
|
|
182
276
|
model=model_vh)
|
|
183
277
|
|
|
184
|
-
return
|
|
278
|
+
return wind_co, wind_dual, wind_cross
|
|
185
279
|
else:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return np.abs(windspeed_co), None, None
|
|
189
|
-
|
|
280
|
+
wind_co = winds
|
|
190
281
|
|
|
282
|
+
return wind_co, None, None
|
|
191
283
|
|
|
192
284
|
|
|
193
285
|
def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config):
|
|
194
|
-
|
|
286
|
+
"""
|
|
287
|
+
Rename xr_dataset variables and attributes to match naming convention.
|
|
288
|
+
|
|
289
|
+
Parameters
|
|
290
|
+
----------
|
|
291
|
+
xr_dataset: xarray.Dataset
|
|
292
|
+
dataset to rename
|
|
293
|
+
dual_pol: bool
|
|
294
|
+
True if dualpol, False if singlepol
|
|
295
|
+
copol: str
|
|
296
|
+
copolarization name
|
|
297
|
+
crosspol: str
|
|
298
|
+
crosspolarization name
|
|
299
|
+
copol_gmf: str
|
|
300
|
+
copolarization GMF name
|
|
301
|
+
crosspol_gmf: str
|
|
302
|
+
crosspolarization GMF name
|
|
303
|
+
config: dict
|
|
304
|
+
configuration file
|
|
305
|
+
|
|
306
|
+
Returns
|
|
307
|
+
-------
|
|
308
|
+
xarray.Dataset
|
|
309
|
+
final dataset
|
|
310
|
+
dict
|
|
311
|
+
encoding dict
|
|
312
|
+
|
|
313
|
+
See Also
|
|
314
|
+
--------
|
|
315
|
+
"""
|
|
195
316
|
|
|
196
317
|
xr_dataset = xr_dataset.rename({
|
|
197
318
|
'longitude': 'owiLon',
|
|
@@ -200,12 +321,17 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
200
321
|
'elevation': 'owiElevationAngle',
|
|
201
322
|
'ground_heading': 'owiHeading',
|
|
202
323
|
'land_mask': 'owiLandFlag',
|
|
203
|
-
'
|
|
324
|
+
'offboresight': 'owiOffBoresightAngle',
|
|
325
|
+
'mask': 'owiMask',
|
|
204
326
|
'windspeed_co': 'owiWindSpeed_co',
|
|
205
327
|
'windspeed_cross': 'owiWindSpeed_cross',
|
|
206
|
-
'windspeed_dual': 'owiWindSpeed',
|
|
328
|
+
'windspeed_dual': 'owiWindSpeed',
|
|
329
|
+
'winddir_co': 'owiWindDirection_co',
|
|
330
|
+
'winddir_cross': 'owiWindDirection_cross',
|
|
331
|
+
'winddir_dual': 'owiWindDirection',
|
|
332
|
+
'ancillary_wind_speed': 'owiAncillaryWindSpeed',
|
|
333
|
+
'ancillary_wind_direction': 'owiAncillaryWindDirection',
|
|
207
334
|
})
|
|
208
|
-
|
|
209
335
|
xr_dataset['owiNrcs'] = xr_dataset['sigma0_ocean'].sel(pol=copol)
|
|
210
336
|
xr_dataset.owiNrcs.attrs = xr_dataset.sigma0_ocean.attrs
|
|
211
337
|
xr_dataset.owiNrcs.attrs['units'] = 'm^2 / m^2'
|
|
@@ -224,36 +350,33 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
224
350
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
225
351
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
226
352
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
227
|
-
|
|
228
|
-
|
|
353
|
+
'comment'] = 'owiNrcs_no_noise_correction ; no recalibration'
|
|
354
|
+
|
|
229
355
|
if 'swath_number' in xr_dataset:
|
|
230
356
|
xr_dataset = xr_dataset.rename({
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
357
|
+
'swath_number': 'owiSwathNumber',
|
|
358
|
+
'swath_number_flag': 'owiSwathNumberFlag'
|
|
359
|
+
})
|
|
360
|
+
|
|
235
361
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
236
|
-
xr_dataset['owiNrcs_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
362
|
+
xr_dataset['owiNrcs_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
363
|
+
pol=copol)
|
|
237
364
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
238
365
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
239
366
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs[
|
|
240
367
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
241
368
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs[
|
|
242
|
-
'comment'] = 'owiNrcs_no_noise_correction ; recalibrated with kersten method'
|
|
243
|
-
|
|
244
|
-
xr_dataset.owiNrcs.attrs['definition'] = 'owiNrcs_no_noise_correction_recalibrated - owiNesz'
|
|
245
|
-
|
|
246
|
-
|
|
369
|
+
'comment'] = 'owiNrcs_no_noise_correction ; recalibrated with kersten method'
|
|
247
370
|
|
|
371
|
+
xr_dataset.owiNrcs.attrs['definition'] = 'owiNrcs_no_noise_correction_recalibrated - owiNesz'
|
|
248
372
|
|
|
249
|
-
|
|
250
373
|
if dual_pol:
|
|
251
|
-
|
|
374
|
+
|
|
252
375
|
xr_dataset = xr_dataset.rename({
|
|
253
376
|
'dsig_cross': 'owiDsig_cross',
|
|
254
|
-
'nesz_cross_final'
|
|
255
|
-
})
|
|
256
|
-
|
|
377
|
+
'nesz_cross_final': 'owiNesz_cross_final'
|
|
378
|
+
})
|
|
379
|
+
|
|
257
380
|
xr_dataset['owiNrcs_cross'] = xr_dataset['sigma0_ocean'].sel(
|
|
258
381
|
pol=crosspol)
|
|
259
382
|
xr_dataset.owiNrcs_cross.attrs['units'] = 'm^2 / m^2'
|
|
@@ -272,37 +395,35 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
272
395
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
273
396
|
|
|
274
397
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
275
|
-
xr_dataset['owiNrcs_cross_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
398
|
+
xr_dataset['owiNrcs_cross_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
399
|
+
pol=crosspol)
|
|
276
400
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
277
401
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
278
402
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
279
403
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
280
404
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
281
|
-
|
|
282
|
-
|
|
405
|
+
'comment'] = 'owiNrcs_cross_no_noise_correction ; recalibrated with kersten method'
|
|
406
|
+
|
|
283
407
|
xr_dataset.owiNrcs_cross.attrs['definition'] = 'owiNrcs_cross_no_noise_correction_recalibrated - owiNesz_cross'
|
|
284
408
|
|
|
285
|
-
|
|
286
|
-
|
|
287
409
|
xr_dataset["owiWindSpeed_co"].attrs["comment"] = xr_dataset["owiWindSpeed_co"].attrs["comment"].replace(
|
|
288
410
|
"wind speed and direction", "wind speed")
|
|
289
411
|
|
|
412
|
+
xr_dataset["owiWindDirection_co"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
413
|
+
|
|
290
414
|
if dual_pol:
|
|
291
415
|
xr_dataset["owiWindSpeed"].attrs["comment"] = xr_dataset["owiWindSpeed"].attrs["comment"].replace(
|
|
292
416
|
"wind speed and direction", "wind speed")
|
|
417
|
+
xr_dataset["owiWindDirection"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
293
418
|
|
|
294
419
|
xr_dataset["owiWindSpeed_cross"].attrs['comment'] = "wind speed inverted from model %s (%s)" % (
|
|
295
420
|
crosspol_gmf, crosspol)
|
|
296
421
|
|
|
422
|
+
xr_dataset["owiWindDirection_cross"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East, copied from dualpol"
|
|
423
|
+
|
|
297
424
|
xr_dataset.owiWindSpeed_cross.attrs['model'] = crosspol_gmf
|
|
298
425
|
xr_dataset.owiWindSpeed_cross.attrs['units'] = 'm/s'
|
|
299
426
|
|
|
300
|
-
xr_dataset = xr_dataset.assign(
|
|
301
|
-
owiEcmwfWindSpeed=(['line', 'sample'], np.abs(xr_dataset['ancillary_wind'].data)))
|
|
302
|
-
xr_dataset = xr_dataset.assign(
|
|
303
|
-
owiEcmwfWindDirection=(['line', 'sample'], np.angle(xr_dataset['ancillary_wind'])))
|
|
304
|
-
xr_dataset['owiEcmwfWindDirection'].attrs['comment'] = 'angle in radians, anticlockwise, 0=sample'
|
|
305
|
-
|
|
306
427
|
xr_dataset['owiWindQuality'] = xr.full_like(xr_dataset.owiNrcs, 0)
|
|
307
428
|
xr_dataset['owiWindQuality'].attrs[
|
|
308
429
|
'long_name'] = "Quality flag taking into account the consistency_between_wind_inverted_and_NRCS_and_Doppler_measured"
|
|
@@ -323,14 +444,14 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
323
444
|
|
|
324
445
|
xr_dataset = xr_dataset.rename(
|
|
325
446
|
{"line": "owiAzSize", "sample": "owiRaSize"})
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
447
|
+
|
|
448
|
+
xr_dataset = xr_dataset.drop_vars(
|
|
449
|
+
['sigma0_ocean', 'sigma0', 'sigma0_ocean_raw', 'sigma0_raw', 'ancillary_wind', 'nesz', 'spatial_ref'])
|
|
329
450
|
if 'sigma0_raw__corrected' in xr_dataset:
|
|
330
451
|
xr_dataset = xr_dataset.drop_vars(["sigma0_raw__corrected"])
|
|
331
452
|
xr_dataset = xr_dataset.drop_dims(['pol'])
|
|
332
|
-
|
|
333
|
-
#attrs
|
|
453
|
+
|
|
454
|
+
# attrs
|
|
334
455
|
|
|
335
456
|
xr_dataset.compute()
|
|
336
457
|
|
|
@@ -340,50 +461,44 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
340
461
|
if "approx_transform" in xr_dataset.attrs:
|
|
341
462
|
del xr_dataset.attrs["approx_transform"]
|
|
342
463
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
464
|
+
xr_dataset.attrs["TITLE"] = "Sentinel-1 OWI Component"
|
|
465
|
+
xr_dataset.attrs["missionPhase"] = "Test"
|
|
466
|
+
xr_dataset.attrs["acquisitionStation"] = "/"
|
|
467
|
+
xr_dataset.attrs["softwareVersion"] = "/"
|
|
468
|
+
xr_dataset.attrs["pythonVersion"] = str(
|
|
469
|
+
sys.version_info.major)+'.'+str(sys.version_info.minor)
|
|
470
|
+
xr_dataset.attrs["polarisationRatio"] = "/"
|
|
471
|
+
xr_dataset.attrs["l2ProcessingUtcTime"] = datetime.datetime.now().strftime(
|
|
472
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
473
|
+
xr_dataset.attrs["processingCenter"] = "/"
|
|
474
|
+
try:
|
|
475
|
+
xr_dataset.attrs["firstMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['start_date'],
|
|
476
|
+
"%Y-%m-%d %H:%M:%S.%f").strftime(
|
|
352
477
|
"%Y-%m-%dT%H:%M:%SZ")
|
|
353
|
-
xr_dataset.attrs["
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
'_NAME'] + ", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
378
|
-
xr_dataset.attrs["wnf_3km_average"] = "/"
|
|
379
|
-
xr_dataset.attrs["owiWindSpeedSrc"] = "owiWindSpeed"
|
|
380
|
-
xr_dataset.attrs["owiWindDirectionSrc"] = "/"
|
|
381
|
-
|
|
382
|
-
for var in xr_dataset.variables:
|
|
383
|
-
if "history" in xr_dataset[var].attrs:
|
|
384
|
-
del xr_dataset[var].attrs["history"]
|
|
385
|
-
|
|
386
|
-
|
|
478
|
+
xr_dataset.attrs["lastMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['stop_date'],
|
|
479
|
+
"%Y-%m-%d %H:%M:%S.%f").strftime(
|
|
480
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
481
|
+
except:
|
|
482
|
+
xr_dataset.attrs["firstMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['start_date'],
|
|
483
|
+
"%Y-%m-%d %H:%M:%S").strftime(
|
|
484
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
485
|
+
xr_dataset.attrs["lastMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['stop_date'],
|
|
486
|
+
"%Y-%m-%d %H:%M:%S").strftime(
|
|
487
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
488
|
+
xr_dataset.attrs["clmSource"] = "/"
|
|
489
|
+
xr_dataset.attrs["bathySource"] = "/"
|
|
490
|
+
xr_dataset.attrs['oswAlgorithmName'] = 'grdwindinversion'
|
|
491
|
+
xr_dataset.attrs["owiAlgorithmVersion"] = grdwindinversion.__version__
|
|
492
|
+
xr_dataset.attrs["gmf"] = config['GMF_'+copol_gmf+'_NAME'] + \
|
|
493
|
+
", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
494
|
+
xr_dataset.attrs["iceSource"] = "/"
|
|
495
|
+
xr_dataset.attrs["owiNoiseCorrection"] = "False"
|
|
496
|
+
xr_dataset.attrs["inversionTabGMF"] = config['GMF_'+copol_gmf +
|
|
497
|
+
'_NAME'] + ", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
498
|
+
xr_dataset.attrs["wnf_3km_average"] = "/"
|
|
499
|
+
xr_dataset.attrs["owiWindSpeedSrc"] = "owiWindSpeed"
|
|
500
|
+
xr_dataset.attrs["owiWindDirectionSrc"] = "/"
|
|
501
|
+
|
|
387
502
|
table_fillValue = {
|
|
388
503
|
"owiWindQuality": -1,
|
|
389
504
|
"owiHeading": 9999.99,
|
|
@@ -396,43 +511,51 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
396
511
|
"owiWindSpeed_co": -9999.0,
|
|
397
512
|
"owiWindSpeed_cross": -9999.0,
|
|
398
513
|
}
|
|
399
|
-
|
|
514
|
+
|
|
400
515
|
encoding = {}
|
|
401
516
|
for var in list(set(xr_dataset.coords.keys()) | set(xr_dataset.keys())):
|
|
402
517
|
encoding[var] = {}
|
|
403
518
|
try:
|
|
404
|
-
# sarwing_ds[var].attrs["_FillValue"] = table_fillValue[var]
|
|
405
519
|
encoding[var].update({'_FillValue': table_fillValue[var]})
|
|
406
520
|
except:
|
|
407
|
-
# Nouvelles variables..
|
|
408
521
|
if (var in ["owiWindSpeed_co", "owiWindSpeed_cross", "owiWindSpeed"]):
|
|
409
|
-
# sarwing_ds[var].attrs["_FillValue"] = -9999.0
|
|
410
522
|
encoding[var].update({'_FillValue': -9999.0})
|
|
411
523
|
else:
|
|
412
524
|
encoding[var].update({'_FillValue': None})
|
|
413
525
|
|
|
414
526
|
xr_dataset.attrs["xsar_version"] = xsar.__version__
|
|
415
527
|
xr_dataset.attrs["xsarsea_version"] = xsarsea.__version__
|
|
416
|
-
|
|
528
|
+
|
|
417
529
|
return xr_dataset, encoding
|
|
418
530
|
|
|
419
531
|
|
|
420
532
|
def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True, resolution='1000m'):
|
|
421
533
|
"""
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
534
|
+
Main function to generate L2 product.
|
|
535
|
+
|
|
536
|
+
Parameters
|
|
537
|
+
----------
|
|
538
|
+
filename : str
|
|
539
|
+
input filename
|
|
540
|
+
out_folder : str
|
|
541
|
+
output folder
|
|
542
|
+
config_path : str
|
|
543
|
+
configuration file path
|
|
544
|
+
overwrite : bool, optional
|
|
545
|
+
overwrite existing file
|
|
546
|
+
generateCSV : bool, optional
|
|
547
|
+
generate CSV file
|
|
548
|
+
resolution : str, optional
|
|
549
|
+
working resolution
|
|
550
|
+
|
|
551
|
+
Returns
|
|
552
|
+
-------
|
|
553
|
+
str
|
|
554
|
+
output filename
|
|
555
|
+
xarray.Dataset
|
|
556
|
+
final dataset
|
|
430
557
|
"""
|
|
431
558
|
|
|
432
|
-
# final xr.Dataset
|
|
433
|
-
|
|
434
|
-
# Step 1 - load L1 product
|
|
435
|
-
|
|
436
559
|
sensor, sensor_longname, fct_meta, fct_dataset = getSensorMetaDataset(
|
|
437
560
|
filename)
|
|
438
561
|
|
|
@@ -448,58 +571,66 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
448
571
|
else:
|
|
449
572
|
raise FileNotFoundError(
|
|
450
573
|
'config_path do not exists, got %s ' % config_path)
|
|
451
|
-
|
|
574
|
+
|
|
452
575
|
recalibration = config["recalibration"]
|
|
453
|
-
if recalibration:
|
|
454
|
-
aux_config_name=config["aux_config_name"]
|
|
455
|
-
|
|
456
576
|
meta = fct_meta(filename)
|
|
457
577
|
out_file = getOutputName2(filename, out_folder, sensor, meta)
|
|
458
578
|
|
|
459
|
-
|
|
460
579
|
if os.path.exists(out_file) and overwrite is False:
|
|
461
|
-
logging.info("out_file %s exists" % out_file)
|
|
580
|
+
logging.info("out_file %s exists ; returning empty Dataset" % out_file)
|
|
462
581
|
return out_file, xr.Dataset()
|
|
463
582
|
|
|
464
|
-
|
|
465
|
-
map_model = getAncillary(meta)
|
|
583
|
+
ancillary_name = config["ancillary"]
|
|
584
|
+
map_model = getAncillary(meta, ancillary_name)
|
|
466
585
|
if map_model is None:
|
|
467
586
|
raise Exception(
|
|
468
|
-
'the weather model is not set `map_model` is None -> you probably don"t have access to
|
|
587
|
+
f'the weather model is not set `map_model` is None -> you probably don"t have access to f{ancillary_name} archive')
|
|
469
588
|
|
|
470
589
|
try:
|
|
471
590
|
if ((recalibration) & ("SENTINEL" in sensor_longname)):
|
|
472
|
-
logging.info(
|
|
591
|
+
logging.info(
|
|
592
|
+
f'recalibration is {recalibration} : Kersten formula is applied')
|
|
473
593
|
xsar_dataset = fct_dataset(
|
|
474
|
-
meta, resolution=resolution, recalibration=recalibration
|
|
594
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
475
595
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
476
|
-
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
477
|
-
|
|
596
|
+
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
597
|
+
['swath_number', 'swath_number_flag', 'sigma0_raw__corrected']])
|
|
598
|
+
|
|
478
599
|
else:
|
|
479
600
|
logging.info(
|
|
480
|
-
'recalibration is
|
|
601
|
+
f'recalibration is {recalibration} : Kersten formula is not applied')
|
|
481
602
|
if ("SENTINEL" in sensor_longname):
|
|
482
|
-
xsar_dataset = fct_dataset(
|
|
603
|
+
xsar_dataset = fct_dataset(
|
|
604
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
483
605
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
484
|
-
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
606
|
+
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
607
|
+
['swath_number', 'swath_number_flag']])
|
|
485
608
|
|
|
486
|
-
else:
|
|
609
|
+
else:
|
|
487
610
|
xsar_dataset = fct_dataset(meta, resolution=resolution)
|
|
488
611
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
489
612
|
|
|
490
|
-
|
|
491
613
|
xr_dataset = xr_dataset.rename(map_model)
|
|
492
614
|
# add attributes
|
|
493
615
|
xr_dataset.attrs = xsar_dataset.dataset.attrs
|
|
494
616
|
xr_dataset.attrs['L1_path'] = xr_dataset.attrs.pop('name')
|
|
495
617
|
xr_dataset.attrs["sourceProduct"] = sensor
|
|
496
618
|
xr_dataset.attrs["missionName"] = sensor_longname
|
|
497
|
-
|
|
619
|
+
if ((recalibration) & ("SENTINEL" in sensor_longname)):
|
|
620
|
+
xr_dataset.attrs["path_aux_pp1_new"] = os.path.basename(os.path.dirname(
|
|
621
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_pp1_new'])))
|
|
622
|
+
xr_dataset.attrs["path_aux_cal_new"] = os.path.basename(os.path.dirname(
|
|
623
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_cal_new'])))
|
|
624
|
+
|
|
625
|
+
xr_dataset.attrs["path_aux_pp1_old"] = os.path.basename(os.path.dirname(
|
|
626
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_pp1_old'])))
|
|
627
|
+
xr_dataset.attrs["path_aux_cal_old"] = os.path.basename(os.path.dirname(
|
|
628
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_cal_old'])))
|
|
629
|
+
|
|
498
630
|
except Exception as e:
|
|
499
631
|
logging.info('%s', traceback.format_exc())
|
|
500
632
|
logging.error(e)
|
|
501
633
|
sys.exit(-1)
|
|
502
|
-
|
|
503
634
|
|
|
504
635
|
# defining dual_pol, and gmfs by channel
|
|
505
636
|
if len(xr_dataset.pol.values) == 2:
|
|
@@ -553,11 +684,33 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
553
684
|
xr_dataset.mask.attrs['flag_meanings'] = 'valid land ice no_valid'
|
|
554
685
|
|
|
555
686
|
# ANCILLARY
|
|
556
|
-
xr_dataset['
|
|
557
|
-
|
|
687
|
+
xr_dataset['ancillary_wind_direction'] = (
|
|
688
|
+
90. - np.rad2deg(np.arctan2(xr_dataset.model_V10, xr_dataset.model_U10)) + 180) % 360
|
|
689
|
+
|
|
690
|
+
xr_dataset['ancillary_wind_direction'] = xr.where(xr_dataset['mask'], np.nan,
|
|
691
|
+
xr_dataset['ancillary_wind_direction'].compute()).transpose(
|
|
692
|
+
*xr_dataset['ancillary_wind_direction'].dims)
|
|
693
|
+
xr_dataset['ancillary_wind_direction'].attrs = {}
|
|
694
|
+
xr_dataset['ancillary_wind_direction'].attrs['units'] = 'degrees_north'
|
|
695
|
+
xr_dataset['ancillary_wind_direction'].attrs[
|
|
696
|
+
'long_name'] = f'{ancillary_name} Wind direction (meteorological convention)'
|
|
697
|
+
xr_dataset['ancillary_wind_direction'].attrs['standart_name'] = 'wind_direction'
|
|
698
|
+
|
|
699
|
+
xr_dataset['ancillary_wind_speed'] = np.sqrt(
|
|
700
|
+
xr_dataset['model_U10']**2+xr_dataset['model_V10']**2)
|
|
701
|
+
xr_dataset['ancillary_wind_speed'] = xr.where(xr_dataset['mask'], np.nan,
|
|
702
|
+
xr_dataset['ancillary_wind_speed'].compute()).transpose(
|
|
703
|
+
*xr_dataset['ancillary_wind_speed'].dims)
|
|
704
|
+
xr_dataset['ancillary_wind_speed'].attrs = {}
|
|
705
|
+
xr_dataset['ancillary_wind_speed'].attrs['units'] = 'm s^-1'
|
|
706
|
+
xr_dataset['ancillary_wind_speed'].attrs[
|
|
707
|
+
'long_name'] = f'{ancillary_name} Wind speed'
|
|
708
|
+
xr_dataset['ancillary_wind_speed'].attrs['standart_name'] = 'wind_speed'
|
|
709
|
+
|
|
558
710
|
xr_dataset['ancillary_wind'] = xr.where(xr_dataset['mask'], np.nan,
|
|
559
|
-
xr_dataset
|
|
560
|
-
*xr_dataset['
|
|
711
|
+
(xr_dataset.ancillary_wind_speed * np.exp(1j * xsarsea.dir_geo_to_sample(xr_dataset.ancillary_wind_direction, xr_dataset.ground_heading))).compute()).transpose(
|
|
712
|
+
*xr_dataset['ancillary_wind_speed'].dims)
|
|
713
|
+
|
|
561
714
|
xr_dataset.attrs['ancillary_source'] = xr_dataset['model_U10'].attrs['history'].split('decoded: ')[
|
|
562
715
|
1].strip()
|
|
563
716
|
xr_dataset = xr_dataset.drop_vars(['model_U10', 'model_V10'])
|
|
@@ -567,7 +720,7 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
567
720
|
xr_dataset['sigma0'].compute()).transpose(*xr_dataset['sigma0'].dims)
|
|
568
721
|
xr_dataset['sigma0_ocean'] = xr.where(
|
|
569
722
|
xr_dataset['sigma0_ocean'] <= 0, np.nan, xr_dataset['sigma0_ocean'])
|
|
570
|
-
|
|
723
|
+
|
|
571
724
|
xr_dataset['sigma0_ocean'].attrs = xr_dataset['sigma0'].attrs
|
|
572
725
|
|
|
573
726
|
xr_dataset['sigma0_ocean_raw'] = xr.where(xr_dataset['mask'], np.nan,
|
|
@@ -600,26 +753,37 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
600
753
|
sigma0_ocean_cross = None
|
|
601
754
|
dsig_cross = 0.1 # default value set in xsarsea
|
|
602
755
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
xr_dataset['
|
|
756
|
+
wind_co, wind_dual, windspeed_cr = inverse(dual_pol,
|
|
757
|
+
inc=xr_dataset.incidence,
|
|
758
|
+
sigma0=xr_dataset['sigma0_ocean'].sel(
|
|
759
|
+
pol=copol),
|
|
760
|
+
sigma0_dual=sigma0_ocean_cross,
|
|
761
|
+
ancillary_wind=xr_dataset['ancillary_wind'],
|
|
762
|
+
dsig_cr=dsig_cross,
|
|
763
|
+
model_vv=config["GMF_" +
|
|
764
|
+
copol_gmf+"_NAME"],
|
|
765
|
+
model_vh=config["GMF_"+crosspol_gmf+"_NAME"])
|
|
766
|
+
|
|
767
|
+
# get windspeeds
|
|
768
|
+
xr_dataset['windspeed_co'] = np.abs(wind_co)
|
|
769
|
+
xr_dataset['windspeed_dual'] = np.abs(wind_dual)
|
|
770
|
+
|
|
616
771
|
if dual_pol:
|
|
617
772
|
xr_dataset = xr_dataset.assign(
|
|
618
773
|
windspeed_cross=(['line', 'sample'], windspeed_cr))
|
|
619
|
-
else
|
|
774
|
+
else:
|
|
620
775
|
xr_dataset['windspeed_cross'] = windspeed_cr
|
|
621
776
|
|
|
622
|
-
|
|
777
|
+
# get winddirections
|
|
778
|
+
xr_dataset['winddir_co'] = (
|
|
779
|
+
90 - (np.angle(-np.conj(wind_co), deg=True)) + xr_dataset.ground_heading) % 360
|
|
780
|
+
|
|
781
|
+
xr_dataset['winddir_dual'] = (
|
|
782
|
+
90 - (np.angle(-np.conj(wind_dual), deg=True)) + xr_dataset.ground_heading) % 360
|
|
783
|
+
xr_dataset['winddir_cross'] = xr_dataset['winddir_dual'].copy()
|
|
784
|
+
|
|
785
|
+
xr_dataset, encoding = makeL2asOwi(
|
|
786
|
+
xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config)
|
|
623
787
|
|
|
624
788
|
os.makedirs(os.path.dirname(out_file), exist_ok=True)
|
|
625
789
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from yaml import load
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import grdwindinversion
|
|
5
|
+
from yaml import CLoader as Loader
|
|
6
|
+
local_config_potential_path = os.path.expanduser(
|
|
7
|
+
'~/.grdwindinversion/data_config.yaml')
|
|
8
|
+
|
|
9
|
+
if os.path.exists(local_config_potential_path):
|
|
10
|
+
config_path = local_config_potential_path
|
|
11
|
+
else:
|
|
12
|
+
config_path = os.path.join(os.path.dirname(
|
|
13
|
+
grdwindinversion.__file__), 'data_config.yaml')
|
|
14
|
+
logging.info('config path: %s', config_path)
|
|
15
|
+
stream = open(config_path, 'r')
|
|
16
|
+
conf = load(stream, Loader=Loader)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def getConf():
|
|
20
|
+
"""
|
|
21
|
+
if local_config_potential_path exists it will superseed config_path
|
|
22
|
+
:return:
|
|
23
|
+
"""
|
|
24
|
+
return conf
|
|
@@ -13,7 +13,7 @@ def processor_starting_point():
|
|
|
13
13
|
description='Perform inversion from S1(L1-GRD) SAFE, L1-RCM, L1-RS2 ; using xsar/xsarsea tools')
|
|
14
14
|
parser.add_argument('--input_file', help='input file path', required=True)
|
|
15
15
|
parser.add_argument('--config_file',
|
|
16
|
-
help='config file path [if not provided will take config file based on input file]',required=
|
|
16
|
+
help='config file path [if not provided will take config file based on input file]',required=True)
|
|
17
17
|
|
|
18
18
|
parser.add_argument('--resolution',required=False, default='1000m', help='set resolution ["full" | "1000m" | "xXxm"]')
|
|
19
19
|
|
|
@@ -43,21 +43,8 @@ def processor_starting_point():
|
|
|
43
43
|
# if '1SSH' in input_file or '1SDH' in input_file or '_HH_HV' in input_file:
|
|
44
44
|
# raise Exception('this processor only handle acquisitions with VV or VV+VH polarization for now.')
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
config_file = os.path.join(os.path.dirname(grdwindinversion.__file__),'config_S1.yaml')
|
|
49
|
-
elif 'RCM' in input_file:
|
|
50
|
-
config_file = os.path.join(os.path.dirname(grdwindinversion.__file__),'config_RCM.yaml')
|
|
51
|
-
elif 'RS2' in input_file:
|
|
52
|
-
config_file = os.path.join(os.path.dirname(grdwindinversion.__file__),'config_RS2.yaml')
|
|
53
|
-
elif 'hy2b' in input_file:
|
|
54
|
-
config_file = os.path.join(os.path.dirname(grdwindinversion.__file__),'config_hy2b.yaml')
|
|
55
|
-
else:
|
|
56
|
-
raise Exception('config data file cannot be defined using the input filename')
|
|
57
|
-
else:
|
|
58
|
-
config_file = args.config_file
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
|
|
47
|
+
config_file = args.config_file
|
|
61
48
|
out_folder = args.outputdir
|
|
62
49
|
resolution = args.resolution
|
|
63
50
|
if resolution == "full":
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/SOURCES.txt
RENAMED
|
@@ -33,10 +33,6 @@ docs/examples/wind-inversion-from-grd.ipynb
|
|
|
33
33
|
grdwindinversion/.gitignore
|
|
34
34
|
grdwindinversion/.travis.yml
|
|
35
35
|
grdwindinversion/__init__.py
|
|
36
|
-
grdwindinversion/config_RCM.yaml
|
|
37
|
-
grdwindinversion/config_RS2.yaml
|
|
38
|
-
grdwindinversion/config_S1.yaml
|
|
39
|
-
grdwindinversion/config_hy2b.yaml
|
|
40
36
|
grdwindinversion/config_prod.yaml
|
|
41
37
|
grdwindinversion/config_prod_recal.yaml
|
|
42
38
|
grdwindinversion/data_config.yaml
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
S1A:
|
|
2
|
-
GMF_VV_NAME: "cmod5n"
|
|
3
|
-
GMF_VH_NAME: "gmf_s1_v2"
|
|
4
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
5
|
-
apply_flattening: True
|
|
6
|
-
recalibration: False
|
|
7
|
-
S1B:
|
|
8
|
-
GMF_VV_NAME: "cmod5n"
|
|
9
|
-
GMF_VH_NAME: "gmf_s1_v2"
|
|
10
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
11
|
-
apply_flattening: True
|
|
12
|
-
recalibration: False
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
S1A:
|
|
2
|
-
GMF_VV_NAME: "cmod5n"
|
|
3
|
-
GMF_VH_NAME: "gmf_hy2B"
|
|
4
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
5
|
-
apply_flattening: True
|
|
6
|
-
recalibration: False
|
|
7
|
-
S1B:
|
|
8
|
-
GMF_VV_NAME: "cmod5n"
|
|
9
|
-
GMF_VH_NAME: "gmf_hy2B"
|
|
10
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
11
|
-
apply_flattening: True
|
|
12
|
-
recalibration: False
|
|
13
|
-
RS2:
|
|
14
|
-
GMF_VV_NAME: "cmod5n"
|
|
15
|
-
GMF_VH_NAME: "gmf_hy2B"
|
|
16
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
17
|
-
apply_flattening: False
|
|
18
|
-
recalibration: False
|
|
19
|
-
RCM:
|
|
20
|
-
GMF_VV_NAME: "cmod5n"
|
|
21
|
-
GMF_VH_NAME: "gmf_hy2B"
|
|
22
|
-
dsig_VH_NAME: "gmf_s1_v2"
|
|
23
|
-
apply_flattening: True
|
|
24
|
-
recalibration: False
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from yaml import load
|
|
2
|
-
import logging
|
|
3
|
-
import os
|
|
4
|
-
import grdwindinversion
|
|
5
|
-
from yaml import CLoader as Loader
|
|
6
|
-
local_config_potential_path = os.path.join(os.path.dirname(grdwindinversion.__file__), 'local_data_config.yaml')
|
|
7
|
-
|
|
8
|
-
if os.path.exists(local_config_potential_path):
|
|
9
|
-
config_path = local_config_potential_path
|
|
10
|
-
else:
|
|
11
|
-
config_path = os.path.join(os.path.dirname(grdwindinversion.__file__), 'data_config.yaml')
|
|
12
|
-
# config_path = "./data_config.yaml"
|
|
13
|
-
logging.info('config path: %s',config_path)
|
|
14
|
-
stream = open(config_path, 'r')
|
|
15
|
-
conf = load(stream, Loader=Loader)
|
|
16
|
-
def getConf():
|
|
17
|
-
|
|
18
|
-
"""
|
|
19
|
-
if grdwindinversion/local_data_config.yaml exists it will superseed grdwindinversion/data_config.yaml
|
|
20
|
-
:return:
|
|
21
|
-
"""
|
|
22
|
-
return conf
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/ci/requirements/environment.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/docs/_static/css/grdwindinversion.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion/data_config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/grdwindinversion.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post9}/tests/test_grdwindinversion.py
RENAMED
|
File without changes
|
|
File without changes
|