grdwindinversion 0.2.3.post7__tar.gz → 0.2.3.post8__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.post8}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/config_prod.yaml +4 -4
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/config_prod_recal.yaml +4 -8
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/inversion.py +353 -213
- grdwindinversion-0.2.3.post8/grdwindinversion/load_config.py +24 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/main.py +3 -16
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8/grdwindinversion.egg-info}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/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.post8}/.editorconfig +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/.github/dependabot.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/.github/workflows/publish.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/.gitignore +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/.pre-commit-config.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/AUTHORS.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/CONTRIBUTING.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/HISTORY.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/LICENSE +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/MANIFEST.in +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/Makefile +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/README.md +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/ci/requirements/docs.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/ci/requirements/environment.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/Makefile +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/_static/css/grdwindinversion.css +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/algorithm.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/authors.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/conf.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/contributing.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/examples/wind-inversion-from-grd.ipynb +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/history.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/index.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/installation.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/make.bat +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/modules.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/readme.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/docs/usage.rst +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/.github/ISSUE_TEMPLATE.md +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/.gitignore +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/.travis.yml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/__init__.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/data_config.yaml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion/utils.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/dependency_links.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/entry_points.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/requires.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/top_level.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/pyproject.toml +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/requirements_dev.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/requirements_doc.txt +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/setup.cfg +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/tests/__init__.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/tests/test_grdwindinversion.py +0 -0
- {grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/tox.ini +0 -0
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/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,180 @@ 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.
|
|
122
|
+
This function is used to check if the ECMWF files are available and to map the model to the SAR data.
|
|
111
123
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
logging.debug('ec01 : %s', ec01)
|
|
116
|
-
meta.set_raster('ecmwf_0100_1h', ec01)
|
|
117
|
-
meta.set_raster('ecmwf_0125_1h', ec0125)
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
meta: obj `xsar.BaseMeta` (one of the supported SAR mission)
|
|
118
127
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
125
|
-
date=datetime.datetime.strptime(meta.start_date,
|
|
126
|
-
'%Y-%m-%d %H:%M:%S.%f'))[1]
|
|
127
|
-
# temporary for RCM issue https://github.com/umr-lops/xarray-safe-rcm/issues/34
|
|
128
|
-
except Exception as e:
|
|
129
|
-
ecmwf_file = ecmwf_infos['get_function'](ecmwf_infos['resource'],
|
|
130
|
-
date=datetime.datetime.strptime(meta.start_date,
|
|
131
|
-
'%Y-%m-%d %H:%M:%S'))[1]
|
|
132
|
-
|
|
133
|
-
if not os.path.isfile(ecmwf_file):
|
|
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']}
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
dict
|
|
131
|
+
map model to SAR data
|
|
132
|
+
"""
|
|
153
133
|
|
|
154
|
-
|
|
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
|
+
"""
|
|
155
180
|
meta.rasters = meta.rasters.drop([ecmwf_name])
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
181
|
+
else:
|
|
182
|
+
map_model = {'%s_%s' % (ecmwf_name, uv): 'model_%s' %
|
|
183
|
+
uv for uv in ['U10', 'V10']}
|
|
159
184
|
|
|
160
|
-
|
|
185
|
+
return map_model
|
|
186
|
+
|
|
187
|
+
else:
|
|
188
|
+
raise ValueError("ancillary_name must be ecmwf, got %s" %
|
|
189
|
+
ancillary_name)
|
|
161
190
|
|
|
162
191
|
|
|
163
192
|
def inverse(dual_pol, inc, sigma0, sigma0_dual, ancillary_wind, dsig_cr, model_vv, model_vh):
|
|
193
|
+
"""
|
|
194
|
+
Invert sigma0 to retrieve wind using model (lut or gmf).
|
|
195
|
+
|
|
196
|
+
Parameters
|
|
197
|
+
----------
|
|
198
|
+
dual_pol: bool
|
|
199
|
+
True if dualpol, False if singlepol
|
|
200
|
+
inc: xarray.DataArray
|
|
201
|
+
incidence angle
|
|
202
|
+
sigma0: xarray.DataArray
|
|
203
|
+
sigma0 to be inverted
|
|
204
|
+
sigma0_dual: xarray.DataArray
|
|
205
|
+
sigma0 to be inverted for dualpol
|
|
206
|
+
ancillary_wind=: xarray.DataArray (numpy.complex28)
|
|
207
|
+
ancillary wind
|
|
208
|
+
| (for example ecmwf winds), in **model convention**
|
|
209
|
+
dsig_cr=: float or xarray.DataArray
|
|
210
|
+
parameters used for
|
|
211
|
+
|
|
212
|
+
| `Jsig_cr=((sigma0_gmf - sigma0) / dsig_cr) ** 2`
|
|
213
|
+
model_vv=: str
|
|
214
|
+
model to use for VV or HH polarization.
|
|
215
|
+
model_vh=: str
|
|
216
|
+
model to use for VH or HV polarization.
|
|
217
|
+
|
|
218
|
+
Returns
|
|
219
|
+
-------
|
|
220
|
+
xarray.DataArray or tuple
|
|
221
|
+
inverted wind in **gmf convention** .
|
|
222
|
+
|
|
223
|
+
See Also
|
|
224
|
+
--------
|
|
225
|
+
xsarsea documentation
|
|
226
|
+
https://cyclobs.ifremer.fr/static/sarwing_datarmor/xsarsea/examples/windspeed_inversion.html
|
|
227
|
+
"""
|
|
164
228
|
logging.debug("inversion")
|
|
165
|
-
|
|
166
|
-
|
|
229
|
+
|
|
230
|
+
# add potential missing gmfs (only cmod7 & ms1ahw)
|
|
231
|
+
|
|
232
|
+
if (model_vv == "gmf_cmod7"):
|
|
233
|
+
windspeed.register_cmod7(getConf()["lut_cmod7_path"])
|
|
234
|
+
|
|
235
|
+
if (model_vh == "sarwing_lut_cmodms1ahw"):
|
|
236
|
+
windspeed.register_one_sarwing_lut(getConf()["lut_ms1ahw_path"])
|
|
237
|
+
|
|
238
|
+
winds = windspeed.invert_from_model(
|
|
167
239
|
inc,
|
|
168
240
|
sigma0,
|
|
169
241
|
sigma0_dual,
|
|
170
|
-
|
|
171
|
-
ancillary_wind=-ancillary_wind,
|
|
242
|
+
ancillary_wind=-np.conj(ancillary_wind),
|
|
172
243
|
dsig_cr=dsig_cr,
|
|
173
244
|
model=(model_vv, model_vh))
|
|
245
|
+
|
|
174
246
|
if dual_pol:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
247
|
+
wind_co, wind_dual = winds
|
|
248
|
+
|
|
249
|
+
wind_cross = windspeed.invert_from_model(
|
|
178
250
|
inc.values,
|
|
179
251
|
sigma0_dual.values,
|
|
180
|
-
# ancillary_wind=-np.conj(xsar_dataset.dataset['ancillary_wind']),
|
|
181
252
|
dsig_cr=dsig_cr.values,
|
|
182
253
|
model=model_vh)
|
|
183
254
|
|
|
184
|
-
return
|
|
255
|
+
return wind_co, wind_dual, wind_cross
|
|
185
256
|
else:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return np.abs(windspeed_co), None, None
|
|
189
|
-
|
|
257
|
+
wind_co = winds
|
|
190
258
|
|
|
259
|
+
return wind_co, None, None
|
|
191
260
|
|
|
192
261
|
|
|
193
262
|
def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config):
|
|
194
|
-
|
|
263
|
+
"""
|
|
264
|
+
Rename xr_dataset variables and attributes to match naming convention.
|
|
265
|
+
|
|
266
|
+
Parameters
|
|
267
|
+
----------
|
|
268
|
+
xr_dataset: xarray.Dataset
|
|
269
|
+
dataset to rename
|
|
270
|
+
dual_pol: bool
|
|
271
|
+
True if dualpol, False if singlepol
|
|
272
|
+
copol: str
|
|
273
|
+
copolarization name
|
|
274
|
+
crosspol: str
|
|
275
|
+
crosspolarization name
|
|
276
|
+
copol_gmf: str
|
|
277
|
+
copolarization GMF name
|
|
278
|
+
crosspol_gmf: str
|
|
279
|
+
crosspolarization GMF name
|
|
280
|
+
config: dict
|
|
281
|
+
configuration file
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
xarray.Dataset
|
|
286
|
+
final dataset
|
|
287
|
+
dict
|
|
288
|
+
encoding dict
|
|
289
|
+
|
|
290
|
+
See Also
|
|
291
|
+
--------
|
|
292
|
+
"""
|
|
195
293
|
|
|
196
294
|
xr_dataset = xr_dataset.rename({
|
|
197
295
|
'longitude': 'owiLon',
|
|
@@ -200,12 +298,17 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
200
298
|
'elevation': 'owiElevationAngle',
|
|
201
299
|
'ground_heading': 'owiHeading',
|
|
202
300
|
'land_mask': 'owiLandFlag',
|
|
203
|
-
'
|
|
301
|
+
'offboresight': 'owiOffBoresightAngle',
|
|
302
|
+
'mask': 'owiMask',
|
|
204
303
|
'windspeed_co': 'owiWindSpeed_co',
|
|
205
304
|
'windspeed_cross': 'owiWindSpeed_cross',
|
|
206
|
-
'windspeed_dual': 'owiWindSpeed',
|
|
305
|
+
'windspeed_dual': 'owiWindSpeed',
|
|
306
|
+
'winddir_co': 'owiWindDirection_co',
|
|
307
|
+
'winddir_cross': 'owiWindDirection_cross',
|
|
308
|
+
'winddir_dual': 'owiWindDirection',
|
|
309
|
+
'ancillary_wind_speed': 'owiEcmwfWindSpeed',
|
|
310
|
+
'ancillary_wind_direction': 'owiEcmwfWindDirection',
|
|
207
311
|
})
|
|
208
|
-
|
|
209
312
|
xr_dataset['owiNrcs'] = xr_dataset['sigma0_ocean'].sel(pol=copol)
|
|
210
313
|
xr_dataset.owiNrcs.attrs = xr_dataset.sigma0_ocean.attrs
|
|
211
314
|
xr_dataset.owiNrcs.attrs['units'] = 'm^2 / m^2'
|
|
@@ -224,36 +327,33 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
224
327
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
225
328
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
226
329
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
227
|
-
|
|
228
|
-
|
|
330
|
+
'comment'] = 'owiNrcs_no_noise_correction ; no recalibration'
|
|
331
|
+
|
|
229
332
|
if 'swath_number' in xr_dataset:
|
|
230
333
|
xr_dataset = xr_dataset.rename({
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
334
|
+
'swath_number': 'owiSwathNumber',
|
|
335
|
+
'swath_number_flag': 'owiSwathNumberFlag'
|
|
336
|
+
})
|
|
337
|
+
|
|
235
338
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
236
|
-
xr_dataset['owiNrcs_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
339
|
+
xr_dataset['owiNrcs_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
340
|
+
pol=copol)
|
|
237
341
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
238
342
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
239
343
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs[
|
|
240
344
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
241
345
|
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
|
-
|
|
346
|
+
'comment'] = 'owiNrcs_no_noise_correction ; recalibrated with kersten method'
|
|
247
347
|
|
|
348
|
+
xr_dataset.owiNrcs.attrs['definition'] = 'owiNrcs_no_noise_correction_recalibrated - owiNesz'
|
|
248
349
|
|
|
249
|
-
|
|
250
350
|
if dual_pol:
|
|
251
|
-
|
|
351
|
+
|
|
252
352
|
xr_dataset = xr_dataset.rename({
|
|
253
353
|
'dsig_cross': 'owiDsig_cross',
|
|
254
|
-
'nesz_cross_final'
|
|
255
|
-
})
|
|
256
|
-
|
|
354
|
+
'nesz_cross_final': 'owiNesz_cross_final'
|
|
355
|
+
})
|
|
356
|
+
|
|
257
357
|
xr_dataset['owiNrcs_cross'] = xr_dataset['sigma0_ocean'].sel(
|
|
258
358
|
pol=crosspol)
|
|
259
359
|
xr_dataset.owiNrcs_cross.attrs['units'] = 'm^2 / m^2'
|
|
@@ -272,37 +372,35 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
272
372
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
273
373
|
|
|
274
374
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
275
|
-
xr_dataset['owiNrcs_cross_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
375
|
+
xr_dataset['owiNrcs_cross_no_noise_correction_recalibrated'] = xr_dataset['sigma0_raw__corrected'].sel(
|
|
376
|
+
pol=crosspol)
|
|
276
377
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
277
378
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
278
379
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
279
380
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
280
381
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
281
|
-
|
|
282
|
-
|
|
382
|
+
'comment'] = 'owiNrcs_cross_no_noise_correction ; recalibrated with kersten method'
|
|
383
|
+
|
|
283
384
|
xr_dataset.owiNrcs_cross.attrs['definition'] = 'owiNrcs_cross_no_noise_correction_recalibrated - owiNesz_cross'
|
|
284
385
|
|
|
285
|
-
|
|
286
|
-
|
|
287
386
|
xr_dataset["owiWindSpeed_co"].attrs["comment"] = xr_dataset["owiWindSpeed_co"].attrs["comment"].replace(
|
|
288
387
|
"wind speed and direction", "wind speed")
|
|
289
388
|
|
|
389
|
+
xr_dataset["owiWindDirection_co"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
390
|
+
|
|
290
391
|
if dual_pol:
|
|
291
392
|
xr_dataset["owiWindSpeed"].attrs["comment"] = xr_dataset["owiWindSpeed"].attrs["comment"].replace(
|
|
292
393
|
"wind speed and direction", "wind speed")
|
|
394
|
+
xr_dataset["owiWindDirection"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
293
395
|
|
|
294
396
|
xr_dataset["owiWindSpeed_cross"].attrs['comment'] = "wind speed inverted from model %s (%s)" % (
|
|
295
397
|
crosspol_gmf, crosspol)
|
|
296
398
|
|
|
399
|
+
xr_dataset["owiWindDirection_cross"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East, copied from dualpol"
|
|
400
|
+
|
|
297
401
|
xr_dataset.owiWindSpeed_cross.attrs['model'] = crosspol_gmf
|
|
298
402
|
xr_dataset.owiWindSpeed_cross.attrs['units'] = 'm/s'
|
|
299
403
|
|
|
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
404
|
xr_dataset['owiWindQuality'] = xr.full_like(xr_dataset.owiNrcs, 0)
|
|
307
405
|
xr_dataset['owiWindQuality'].attrs[
|
|
308
406
|
'long_name'] = "Quality flag taking into account the consistency_between_wind_inverted_and_NRCS_and_Doppler_measured"
|
|
@@ -323,14 +421,14 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
323
421
|
|
|
324
422
|
xr_dataset = xr_dataset.rename(
|
|
325
423
|
{"line": "owiAzSize", "sample": "owiRaSize"})
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
424
|
+
|
|
425
|
+
xr_dataset = xr_dataset.drop_vars(
|
|
426
|
+
['sigma0_ocean', 'sigma0', 'sigma0_ocean_raw', 'sigma0_raw', 'ancillary_wind', 'nesz', 'spatial_ref'])
|
|
329
427
|
if 'sigma0_raw__corrected' in xr_dataset:
|
|
330
428
|
xr_dataset = xr_dataset.drop_vars(["sigma0_raw__corrected"])
|
|
331
429
|
xr_dataset = xr_dataset.drop_dims(['pol'])
|
|
332
|
-
|
|
333
|
-
#attrs
|
|
430
|
+
|
|
431
|
+
# attrs
|
|
334
432
|
|
|
335
433
|
xr_dataset.compute()
|
|
336
434
|
|
|
@@ -340,50 +438,44 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
340
438
|
if "approx_transform" in xr_dataset.attrs:
|
|
341
439
|
del xr_dataset.attrs["approx_transform"]
|
|
342
440
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
441
|
+
xr_dataset.attrs["TITLE"] = "Sentinel-1 OWI Component"
|
|
442
|
+
xr_dataset.attrs["missionPhase"] = "Test"
|
|
443
|
+
xr_dataset.attrs["acquisitionStation"] = "/"
|
|
444
|
+
xr_dataset.attrs["softwareVersion"] = "/"
|
|
445
|
+
xr_dataset.attrs["pythonVersion"] = str(
|
|
446
|
+
sys.version_info.major)+'.'+str(sys.version_info.minor)
|
|
447
|
+
xr_dataset.attrs["polarisationRatio"] = "/"
|
|
448
|
+
xr_dataset.attrs["l2ProcessingUtcTime"] = datetime.datetime.now().strftime(
|
|
449
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
450
|
+
xr_dataset.attrs["processingCenter"] = "/"
|
|
451
|
+
try:
|
|
452
|
+
xr_dataset.attrs["firstMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['start_date'],
|
|
453
|
+
"%Y-%m-%d %H:%M:%S.%f").strftime(
|
|
352
454
|
"%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
|
-
|
|
455
|
+
xr_dataset.attrs["lastMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['stop_date'],
|
|
456
|
+
"%Y-%m-%d %H:%M:%S.%f").strftime(
|
|
457
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
458
|
+
except:
|
|
459
|
+
xr_dataset.attrs["firstMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['start_date'],
|
|
460
|
+
"%Y-%m-%d %H:%M:%S").strftime(
|
|
461
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
462
|
+
xr_dataset.attrs["lastMeasurementTime"] = datetime.datetime.strptime(xr_dataset.attrs['stop_date'],
|
|
463
|
+
"%Y-%m-%d %H:%M:%S").strftime(
|
|
464
|
+
"%Y-%m-%dT%H:%M:%SZ")
|
|
465
|
+
xr_dataset.attrs["clmSource"] = "/"
|
|
466
|
+
xr_dataset.attrs["bathySource"] = "/"
|
|
467
|
+
xr_dataset.attrs['oswAlgorithmName'] = 'grdwindinversion'
|
|
468
|
+
xr_dataset.attrs["owiAlgorithmVersion"] = grdwindinversion.__version__
|
|
469
|
+
xr_dataset.attrs["gmf"] = config['GMF_'+copol_gmf+'_NAME'] + \
|
|
470
|
+
", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
471
|
+
xr_dataset.attrs["iceSource"] = "/"
|
|
472
|
+
xr_dataset.attrs["owiNoiseCorrection"] = "False"
|
|
473
|
+
xr_dataset.attrs["inversionTabGMF"] = config['GMF_'+copol_gmf +
|
|
474
|
+
'_NAME'] + ", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
475
|
+
xr_dataset.attrs["wnf_3km_average"] = "/"
|
|
476
|
+
xr_dataset.attrs["owiWindSpeedSrc"] = "owiWindSpeed"
|
|
477
|
+
xr_dataset.attrs["owiWindDirectionSrc"] = "/"
|
|
478
|
+
|
|
387
479
|
table_fillValue = {
|
|
388
480
|
"owiWindQuality": -1,
|
|
389
481
|
"owiHeading": 9999.99,
|
|
@@ -396,43 +488,51 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
396
488
|
"owiWindSpeed_co": -9999.0,
|
|
397
489
|
"owiWindSpeed_cross": -9999.0,
|
|
398
490
|
}
|
|
399
|
-
|
|
491
|
+
|
|
400
492
|
encoding = {}
|
|
401
493
|
for var in list(set(xr_dataset.coords.keys()) | set(xr_dataset.keys())):
|
|
402
494
|
encoding[var] = {}
|
|
403
495
|
try:
|
|
404
|
-
# sarwing_ds[var].attrs["_FillValue"] = table_fillValue[var]
|
|
405
496
|
encoding[var].update({'_FillValue': table_fillValue[var]})
|
|
406
497
|
except:
|
|
407
|
-
# Nouvelles variables..
|
|
408
498
|
if (var in ["owiWindSpeed_co", "owiWindSpeed_cross", "owiWindSpeed"]):
|
|
409
|
-
# sarwing_ds[var].attrs["_FillValue"] = -9999.0
|
|
410
499
|
encoding[var].update({'_FillValue': -9999.0})
|
|
411
500
|
else:
|
|
412
501
|
encoding[var].update({'_FillValue': None})
|
|
413
502
|
|
|
414
503
|
xr_dataset.attrs["xsar_version"] = xsar.__version__
|
|
415
504
|
xr_dataset.attrs["xsarsea_version"] = xsarsea.__version__
|
|
416
|
-
|
|
505
|
+
|
|
417
506
|
return xr_dataset, encoding
|
|
418
507
|
|
|
419
508
|
|
|
420
509
|
def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True, resolution='1000m'):
|
|
421
510
|
"""
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
511
|
+
Main function to generate L2 product.
|
|
512
|
+
|
|
513
|
+
Parameters
|
|
514
|
+
----------
|
|
515
|
+
filename : str
|
|
516
|
+
input filename
|
|
517
|
+
out_folder : str
|
|
518
|
+
output folder
|
|
519
|
+
config_path : str
|
|
520
|
+
configuration file path
|
|
521
|
+
overwrite : bool, optional
|
|
522
|
+
overwrite existing file
|
|
523
|
+
generateCSV : bool, optional
|
|
524
|
+
generate CSV file
|
|
525
|
+
resolution : str, optional
|
|
526
|
+
working resolution
|
|
527
|
+
|
|
528
|
+
Returns
|
|
529
|
+
-------
|
|
530
|
+
str
|
|
531
|
+
output filename
|
|
532
|
+
xarray.Dataset
|
|
533
|
+
final dataset
|
|
430
534
|
"""
|
|
431
535
|
|
|
432
|
-
# final xr.Dataset
|
|
433
|
-
|
|
434
|
-
# Step 1 - load L1 product
|
|
435
|
-
|
|
436
536
|
sensor, sensor_longname, fct_meta, fct_dataset = getSensorMetaDataset(
|
|
437
537
|
filename)
|
|
438
538
|
|
|
@@ -448,58 +548,65 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
448
548
|
else:
|
|
449
549
|
raise FileNotFoundError(
|
|
450
550
|
'config_path do not exists, got %s ' % config_path)
|
|
451
|
-
|
|
551
|
+
|
|
452
552
|
recalibration = config["recalibration"]
|
|
453
|
-
if recalibration:
|
|
454
|
-
aux_config_name=config["aux_config_name"]
|
|
455
|
-
|
|
456
553
|
meta = fct_meta(filename)
|
|
457
554
|
out_file = getOutputName2(filename, out_folder, sensor, meta)
|
|
458
555
|
|
|
459
|
-
|
|
460
556
|
if os.path.exists(out_file) and overwrite is False:
|
|
461
|
-
logging.info("out_file %s exists" % out_file)
|
|
557
|
+
logging.info("out_file %s exists ; returning empty Dataset" % out_file)
|
|
462
558
|
return out_file, xr.Dataset()
|
|
463
559
|
|
|
464
|
-
|
|
465
|
-
map_model = getAncillary(meta)
|
|
560
|
+
map_model = getAncillary(meta, ancillary_name=config["ancillary"])
|
|
466
561
|
if map_model is None:
|
|
467
562
|
raise Exception(
|
|
468
563
|
'the weather model is not set `map_model` is None -> you probably don"t have access to ECMWF archive')
|
|
469
564
|
|
|
470
565
|
try:
|
|
471
566
|
if ((recalibration) & ("SENTINEL" in sensor_longname)):
|
|
472
|
-
logging.info(
|
|
567
|
+
logging.info(
|
|
568
|
+
f'recalibration is {recalibration} : Kersten formula is applied')
|
|
473
569
|
xsar_dataset = fct_dataset(
|
|
474
|
-
meta, resolution=resolution, recalibration=recalibration
|
|
570
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
475
571
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
476
|
-
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
477
|
-
|
|
572
|
+
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
573
|
+
['swath_number', 'swath_number_flag', 'sigma0_raw__corrected']])
|
|
574
|
+
|
|
478
575
|
else:
|
|
479
576
|
logging.info(
|
|
480
|
-
'recalibration is
|
|
577
|
+
f'recalibration is {recalibration} : Kersten formula is not applied')
|
|
481
578
|
if ("SENTINEL" in sensor_longname):
|
|
482
|
-
xsar_dataset = fct_dataset(
|
|
579
|
+
xsar_dataset = fct_dataset(
|
|
580
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
483
581
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
484
|
-
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
582
|
+
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
583
|
+
['swath_number', 'swath_number_flag']])
|
|
485
584
|
|
|
486
|
-
else:
|
|
585
|
+
else:
|
|
487
586
|
xsar_dataset = fct_dataset(meta, resolution=resolution)
|
|
488
587
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
489
588
|
|
|
490
|
-
|
|
491
589
|
xr_dataset = xr_dataset.rename(map_model)
|
|
492
590
|
# add attributes
|
|
493
591
|
xr_dataset.attrs = xsar_dataset.dataset.attrs
|
|
494
592
|
xr_dataset.attrs['L1_path'] = xr_dataset.attrs.pop('name')
|
|
495
593
|
xr_dataset.attrs["sourceProduct"] = sensor
|
|
496
594
|
xr_dataset.attrs["missionName"] = sensor_longname
|
|
497
|
-
|
|
595
|
+
if ((recalibration) & ("SENTINEL" in sensor_longname)):
|
|
596
|
+
xr_dataset.attrs["path_aux_pp1_new"] = os.path.basename(os.path.dirname(
|
|
597
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_pp1_new'])))
|
|
598
|
+
xr_dataset.attrs["path_aux_cal_new"] = os.path.basename(os.path.dirname(
|
|
599
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_cal_new'])))
|
|
600
|
+
|
|
601
|
+
xr_dataset.attrs["path_aux_pp1_old"] = os.path.basename(os.path.dirname(
|
|
602
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_pp1_old'])))
|
|
603
|
+
xr_dataset.attrs["path_aux_cal_old"] = os.path.basename(os.path.dirname(
|
|
604
|
+
os.path.dirname(xsar_dataset.datatree['recalibration'].attrs['path_aux_cal_old'])))
|
|
605
|
+
|
|
498
606
|
except Exception as e:
|
|
499
607
|
logging.info('%s', traceback.format_exc())
|
|
500
608
|
logging.error(e)
|
|
501
609
|
sys.exit(-1)
|
|
502
|
-
|
|
503
610
|
|
|
504
611
|
# defining dual_pol, and gmfs by channel
|
|
505
612
|
if len(xr_dataset.pol.values) == 2:
|
|
@@ -553,11 +660,33 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
553
660
|
xr_dataset.mask.attrs['flag_meanings'] = 'valid land ice no_valid'
|
|
554
661
|
|
|
555
662
|
# ANCILLARY
|
|
556
|
-
xr_dataset['
|
|
557
|
-
|
|
663
|
+
xr_dataset['ancillary_wind_direction'] = (
|
|
664
|
+
90. - np.rad2deg(np.arctan2(xr_dataset.model_V10, xr_dataset.model_U10)) + 180) % 360
|
|
665
|
+
|
|
666
|
+
xr_dataset['ancillary_wind_direction'] = xr.where(xr_dataset['mask'], np.nan,
|
|
667
|
+
xr_dataset['ancillary_wind_direction'].compute()).transpose(
|
|
668
|
+
*xr_dataset['ancillary_wind_direction'].dims)
|
|
669
|
+
xr_dataset['ancillary_wind_direction'].attrs = {}
|
|
670
|
+
xr_dataset['ancillary_wind_direction'].attrs['units'] = 'degrees_north'
|
|
671
|
+
xr_dataset['ancillary_wind_direction'].attrs[
|
|
672
|
+
'long_name'] = 'ECMWF Wind direction (meteorological convention)'
|
|
673
|
+
xr_dataset['ancillary_wind_direction'].attrs['standart_name'] = 'wind_direction'
|
|
674
|
+
|
|
675
|
+
xr_dataset['ancillary_wind_speed'] = np.sqrt(
|
|
676
|
+
xr_dataset['model_U10']**2+xr_dataset['model_V10']**2)
|
|
677
|
+
xr_dataset['ancillary_wind_speed'] = xr.where(xr_dataset['mask'], np.nan,
|
|
678
|
+
xr_dataset['ancillary_wind_speed'].compute()).transpose(
|
|
679
|
+
*xr_dataset['ancillary_wind_speed'].dims)
|
|
680
|
+
xr_dataset['ancillary_wind_speed'].attrs = {}
|
|
681
|
+
xr_dataset['ancillary_wind_speed'].attrs['units'] = 'm s^-1'
|
|
682
|
+
xr_dataset['ancillary_wind_speed'].attrs[
|
|
683
|
+
'long_name'] = 'ECMWF Wind speed'
|
|
684
|
+
xr_dataset['ancillary_wind_speed'].attrs['standart_name'] = 'wind_speed'
|
|
685
|
+
|
|
558
686
|
xr_dataset['ancillary_wind'] = xr.where(xr_dataset['mask'], np.nan,
|
|
559
|
-
xr_dataset
|
|
560
|
-
*xr_dataset['
|
|
687
|
+
(xr_dataset.ancillary_wind_speed * np.exp(1j * xsarsea.dir_geo_to_sample(xr_dataset.ancillary_wind_direction, xr_dataset.ground_heading))).compute()).transpose(
|
|
688
|
+
*xr_dataset['ancillary_wind_speed'].dims)
|
|
689
|
+
|
|
561
690
|
xr_dataset.attrs['ancillary_source'] = xr_dataset['model_U10'].attrs['history'].split('decoded: ')[
|
|
562
691
|
1].strip()
|
|
563
692
|
xr_dataset = xr_dataset.drop_vars(['model_U10', 'model_V10'])
|
|
@@ -567,7 +696,7 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
567
696
|
xr_dataset['sigma0'].compute()).transpose(*xr_dataset['sigma0'].dims)
|
|
568
697
|
xr_dataset['sigma0_ocean'] = xr.where(
|
|
569
698
|
xr_dataset['sigma0_ocean'] <= 0, np.nan, xr_dataset['sigma0_ocean'])
|
|
570
|
-
|
|
699
|
+
|
|
571
700
|
xr_dataset['sigma0_ocean'].attrs = xr_dataset['sigma0'].attrs
|
|
572
701
|
|
|
573
702
|
xr_dataset['sigma0_ocean_raw'] = xr.where(xr_dataset['mask'], np.nan,
|
|
@@ -600,26 +729,37 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
600
729
|
sigma0_ocean_cross = None
|
|
601
730
|
dsig_cross = 0.1 # default value set in xsarsea
|
|
602
731
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
xr_dataset['
|
|
732
|
+
wind_co, wind_dual, windspeed_cr = inverse(dual_pol,
|
|
733
|
+
inc=xr_dataset.incidence,
|
|
734
|
+
sigma0=xr_dataset['sigma0_ocean'].sel(
|
|
735
|
+
pol=copol),
|
|
736
|
+
sigma0_dual=sigma0_ocean_cross,
|
|
737
|
+
ancillary_wind=xr_dataset['ancillary_wind'],
|
|
738
|
+
dsig_cr=dsig_cross,
|
|
739
|
+
model_vv=config["GMF_" +
|
|
740
|
+
copol_gmf+"_NAME"],
|
|
741
|
+
model_vh=config["GMF_"+crosspol_gmf+"_NAME"])
|
|
742
|
+
|
|
743
|
+
# get windspeeds
|
|
744
|
+
xr_dataset['windspeed_co'] = np.abs(wind_co)
|
|
745
|
+
xr_dataset['windspeed_dual'] = np.abs(wind_dual)
|
|
746
|
+
|
|
616
747
|
if dual_pol:
|
|
617
748
|
xr_dataset = xr_dataset.assign(
|
|
618
749
|
windspeed_cross=(['line', 'sample'], windspeed_cr))
|
|
619
|
-
else
|
|
750
|
+
else:
|
|
620
751
|
xr_dataset['windspeed_cross'] = windspeed_cr
|
|
621
752
|
|
|
622
|
-
|
|
753
|
+
# get winddirections
|
|
754
|
+
xr_dataset['winddir_co'] = (
|
|
755
|
+
90 - (np.angle(-np.conj(wind_co), deg=True)) + xr_dataset.ground_heading) % 360
|
|
756
|
+
|
|
757
|
+
xr_dataset['winddir_dual'] = (
|
|
758
|
+
90 - (np.angle(-np.conj(wind_dual), deg=True)) + xr_dataset.ground_heading) % 360
|
|
759
|
+
xr_dataset['winddir_cross'] = xr_dataset['winddir_dual'].copy()
|
|
760
|
+
|
|
761
|
+
xr_dataset, encoding = makeL2asOwi(
|
|
762
|
+
xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config)
|
|
623
763
|
|
|
624
764
|
os.makedirs(os.path.dirname(out_file), exist_ok=True)
|
|
625
765
|
|
|
@@ -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.post8}/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.post8}/ci/requirements/environment.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/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
|
|
File without changes
|
{grdwindinversion-0.2.3.post7 → grdwindinversion-0.2.3.post8}/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.post8}/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.post8}/tests/test_grdwindinversion.py
RENAMED
|
File without changes
|
|
File without changes
|