grdwindinversion 0.2.3.post6__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.post6/grdwindinversion.egg-info → grdwindinversion-0.2.3.post8}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/config_prod.yaml +4 -4
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/config_prod_recal.yaml +4 -8
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/inversion.py +358 -209
- grdwindinversion-0.2.3.post8/grdwindinversion/load_config.py +24 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/main.py +3 -16
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8/grdwindinversion.egg-info}/PKG-INFO +1 -1
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/SOURCES.txt +0 -4
- grdwindinversion-0.2.3.post6/grdwindinversion/config_RCM.yaml +0 -6
- grdwindinversion-0.2.3.post6/grdwindinversion/config_RS2.yaml +0 -6
- grdwindinversion-0.2.3.post6/grdwindinversion/config_S1.yaml +0 -12
- grdwindinversion-0.2.3.post6/grdwindinversion/config_hy2b.yaml +0 -24
- grdwindinversion-0.2.3.post6/grdwindinversion/load_config.py +0 -22
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/.editorconfig +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/.github/dependabot.yml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/.github/workflows/publish.yml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/.gitignore +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/.pre-commit-config.yaml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/AUTHORS.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/CONTRIBUTING.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/HISTORY.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/LICENSE +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/MANIFEST.in +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/Makefile +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/README.md +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/ci/requirements/docs.yaml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/ci/requirements/environment.yaml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/Makefile +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/_static/css/grdwindinversion.css +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/algorithm.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/authors.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/conf.py +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/contributing.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/examples/wind-inversion-from-grd.ipynb +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/history.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/index.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/installation.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/make.bat +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/modules.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/readme.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/docs/usage.rst +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/.github/ISSUE_TEMPLATE.md +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/.gitignore +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/.travis.yml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/__init__.py +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/data_config.yaml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion/utils.py +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/dependency_links.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/entry_points.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/requires.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/grdwindinversion.egg-info/top_level.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/pyproject.toml +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/requirements_dev.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/requirements_doc.txt +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/setup.cfg +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/tests/__init__.py +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/tests/test_grdwindinversion.py +0 -0
- {grdwindinversion-0.2.3.post6 → grdwindinversion-0.2.3.post8}/tox.ini +0 -0
{grdwindinversion-0.2.3.post6 → 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,92 +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))
|
|
174
|
-
if dual_pol:
|
|
175
|
-
windspeed_co, windspeed_dual = windspeeds
|
|
176
|
-
else:
|
|
177
|
-
windspeed_co = windspeeds
|
|
178
245
|
|
|
179
246
|
if dual_pol:
|
|
180
|
-
|
|
247
|
+
wind_co, wind_dual = winds
|
|
248
|
+
|
|
249
|
+
wind_cross = windspeed.invert_from_model(
|
|
181
250
|
inc.values,
|
|
182
251
|
sigma0_dual.values,
|
|
183
|
-
# ancillary_wind=-np.conj(xsar_dataset.dataset['ancillary_wind']),
|
|
184
252
|
dsig_cr=dsig_cr.values,
|
|
185
253
|
model=model_vh)
|
|
186
254
|
|
|
187
|
-
return
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
255
|
+
return wind_co, wind_dual, wind_cross
|
|
256
|
+
else:
|
|
257
|
+
wind_co = winds
|
|
191
258
|
|
|
259
|
+
return wind_co, None, None
|
|
192
260
|
|
|
193
261
|
|
|
194
262
|
def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config):
|
|
195
|
-
|
|
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
|
+
"""
|
|
196
293
|
|
|
197
294
|
xr_dataset = xr_dataset.rename({
|
|
198
295
|
'longitude': 'owiLon',
|
|
@@ -201,14 +298,17 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
201
298
|
'elevation': 'owiElevationAngle',
|
|
202
299
|
'ground_heading': 'owiHeading',
|
|
203
300
|
'land_mask': 'owiLandFlag',
|
|
204
|
-
'
|
|
205
|
-
'
|
|
301
|
+
'offboresight': 'owiOffBoresightAngle',
|
|
302
|
+
'mask': 'owiMask',
|
|
206
303
|
'windspeed_co': 'owiWindSpeed_co',
|
|
207
304
|
'windspeed_cross': 'owiWindSpeed_cross',
|
|
208
305
|
'windspeed_dual': 'owiWindSpeed',
|
|
209
|
-
'
|
|
306
|
+
'winddir_co': 'owiWindDirection_co',
|
|
307
|
+
'winddir_cross': 'owiWindDirection_cross',
|
|
308
|
+
'winddir_dual': 'owiWindDirection',
|
|
309
|
+
'ancillary_wind_speed': 'owiEcmwfWindSpeed',
|
|
310
|
+
'ancillary_wind_direction': 'owiEcmwfWindDirection',
|
|
210
311
|
})
|
|
211
|
-
|
|
212
312
|
xr_dataset['owiNrcs'] = xr_dataset['sigma0_ocean'].sel(pol=copol)
|
|
213
313
|
xr_dataset.owiNrcs.attrs = xr_dataset.sigma0_ocean.attrs
|
|
214
314
|
xr_dataset.owiNrcs.attrs['units'] = 'm^2 / m^2'
|
|
@@ -227,27 +327,33 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
227
327
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
228
328
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
229
329
|
xr_dataset.owiNrcs_no_noise_correction.attrs[
|
|
230
|
-
|
|
231
|
-
|
|
330
|
+
'comment'] = 'owiNrcs_no_noise_correction ; no recalibration'
|
|
331
|
+
|
|
332
|
+
if 'swath_number' in xr_dataset:
|
|
333
|
+
xr_dataset = xr_dataset.rename({
|
|
334
|
+
'swath_number': 'owiSwathNumber',
|
|
335
|
+
'swath_number_flag': 'owiSwathNumberFlag'
|
|
336
|
+
})
|
|
337
|
+
|
|
232
338
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
233
|
-
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)
|
|
234
341
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
235
342
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
236
343
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs[
|
|
237
344
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
238
345
|
xr_dataset.owiNrcs_no_noise_correction_recalibrated.attrs[
|
|
239
|
-
'comment'] = 'owiNrcs_no_noise_correction ; recalibrated with kersten method'
|
|
240
|
-
|
|
346
|
+
'comment'] = 'owiNrcs_no_noise_correction ; recalibrated with kersten method'
|
|
347
|
+
|
|
241
348
|
xr_dataset.owiNrcs.attrs['definition'] = 'owiNrcs_no_noise_correction_recalibrated - owiNesz'
|
|
242
349
|
|
|
243
|
-
|
|
350
|
+
if dual_pol:
|
|
351
|
+
|
|
244
352
|
xr_dataset = xr_dataset.rename({
|
|
245
|
-
|
|
246
|
-
|
|
353
|
+
'dsig_cross': 'owiDsig_cross',
|
|
354
|
+
'nesz_cross_final': 'owiNesz_cross_final'
|
|
247
355
|
})
|
|
248
356
|
|
|
249
|
-
|
|
250
|
-
if dual_pol:
|
|
251
357
|
xr_dataset['owiNrcs_cross'] = xr_dataset['sigma0_ocean'].sel(
|
|
252
358
|
pol=crosspol)
|
|
253
359
|
xr_dataset.owiNrcs_cross.attrs['units'] = 'm^2 / m^2'
|
|
@@ -266,37 +372,35 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
266
372
|
'long_name'] = 'Normalized Radar Cross Section, no noise correction applied'
|
|
267
373
|
|
|
268
374
|
if "sigma0_raw__corrected" in xr_dataset:
|
|
269
|
-
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)
|
|
270
377
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs = xr_dataset.sigma0_raw__corrected.attrs
|
|
271
378
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs['units'] = 'm^2 / m^2'
|
|
272
379
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
273
380
|
'long_name'] = 'Normalized Radar Cross Section ; no noise correction applied'
|
|
274
381
|
xr_dataset.owiNrcs_cross_no_noise_correction_recalibrated.attrs[
|
|
275
|
-
|
|
276
|
-
|
|
382
|
+
'comment'] = 'owiNrcs_cross_no_noise_correction ; recalibrated with kersten method'
|
|
383
|
+
|
|
277
384
|
xr_dataset.owiNrcs_cross.attrs['definition'] = 'owiNrcs_cross_no_noise_correction_recalibrated - owiNesz_cross'
|
|
278
385
|
|
|
279
|
-
|
|
280
|
-
|
|
281
386
|
xr_dataset["owiWindSpeed_co"].attrs["comment"] = xr_dataset["owiWindSpeed_co"].attrs["comment"].replace(
|
|
282
387
|
"wind speed and direction", "wind speed")
|
|
283
388
|
|
|
389
|
+
xr_dataset["owiWindDirection_co"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
390
|
+
|
|
284
391
|
if dual_pol:
|
|
285
392
|
xr_dataset["owiWindSpeed"].attrs["comment"] = xr_dataset["owiWindSpeed"].attrs["comment"].replace(
|
|
286
393
|
"wind speed and direction", "wind speed")
|
|
394
|
+
xr_dataset["owiWindDirection"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East"
|
|
287
395
|
|
|
288
396
|
xr_dataset["owiWindSpeed_cross"].attrs['comment'] = "wind speed inverted from model %s (%s)" % (
|
|
289
397
|
crosspol_gmf, crosspol)
|
|
290
398
|
|
|
399
|
+
xr_dataset["owiWindDirection_cross"].attrs["comment"] = "wind direction in meteorological convention, 0=North, 90=East, copied from dualpol"
|
|
400
|
+
|
|
291
401
|
xr_dataset.owiWindSpeed_cross.attrs['model'] = crosspol_gmf
|
|
292
402
|
xr_dataset.owiWindSpeed_cross.attrs['units'] = 'm/s'
|
|
293
403
|
|
|
294
|
-
xr_dataset = xr_dataset.assign(
|
|
295
|
-
owiEcmwfWindSpeed=(['line', 'sample'], np.abs(xr_dataset['ancillary_wind'].data)))
|
|
296
|
-
xr_dataset = xr_dataset.assign(
|
|
297
|
-
owiEcmwfWindDirection=(['line', 'sample'], np.angle(xr_dataset['ancillary_wind'])))
|
|
298
|
-
xr_dataset['owiEcmwfWindDirection'].attrs['comment'] = 'angle in radians, anticlockwise, 0=sample'
|
|
299
|
-
|
|
300
404
|
xr_dataset['owiWindQuality'] = xr.full_like(xr_dataset.owiNrcs, 0)
|
|
301
405
|
xr_dataset['owiWindQuality'].attrs[
|
|
302
406
|
'long_name'] = "Quality flag taking into account the consistency_between_wind_inverted_and_NRCS_and_Doppler_measured"
|
|
@@ -317,14 +421,14 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
317
421
|
|
|
318
422
|
xr_dataset = xr_dataset.rename(
|
|
319
423
|
{"line": "owiAzSize", "sample": "owiRaSize"})
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
424
|
+
|
|
425
|
+
xr_dataset = xr_dataset.drop_vars(
|
|
426
|
+
['sigma0_ocean', 'sigma0', 'sigma0_ocean_raw', 'sigma0_raw', 'ancillary_wind', 'nesz', 'spatial_ref'])
|
|
323
427
|
if 'sigma0_raw__corrected' in xr_dataset:
|
|
324
428
|
xr_dataset = xr_dataset.drop_vars(["sigma0_raw__corrected"])
|
|
325
429
|
xr_dataset = xr_dataset.drop_dims(['pol'])
|
|
326
|
-
|
|
327
|
-
#attrs
|
|
430
|
+
|
|
431
|
+
# attrs
|
|
328
432
|
|
|
329
433
|
xr_dataset.compute()
|
|
330
434
|
|
|
@@ -334,50 +438,44 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
334
438
|
if "approx_transform" in xr_dataset.attrs:
|
|
335
439
|
del xr_dataset.attrs["approx_transform"]
|
|
336
440
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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(
|
|
346
454
|
"%Y-%m-%dT%H:%M:%SZ")
|
|
347
|
-
xr_dataset.attrs["
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
'_NAME'] + ", " + config["GMF_"+crosspol_gmf+"_NAME"]
|
|
372
|
-
xr_dataset.attrs["wnf_3km_average"] = "/"
|
|
373
|
-
xr_dataset.attrs["owiWindSpeedSrc"] = "owiWindSpeed"
|
|
374
|
-
xr_dataset.attrs["owiWindDirectionSrc"] = "/"
|
|
375
|
-
|
|
376
|
-
for var in xr_dataset.variables:
|
|
377
|
-
if "history" in xr_dataset[var].attrs:
|
|
378
|
-
del xr_dataset[var].attrs["history"]
|
|
379
|
-
|
|
380
|
-
|
|
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
|
+
|
|
381
479
|
table_fillValue = {
|
|
382
480
|
"owiWindQuality": -1,
|
|
383
481
|
"owiHeading": 9999.99,
|
|
@@ -390,43 +488,51 @@ def makeL2asOwi(xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf,
|
|
|
390
488
|
"owiWindSpeed_co": -9999.0,
|
|
391
489
|
"owiWindSpeed_cross": -9999.0,
|
|
392
490
|
}
|
|
393
|
-
|
|
491
|
+
|
|
394
492
|
encoding = {}
|
|
395
493
|
for var in list(set(xr_dataset.coords.keys()) | set(xr_dataset.keys())):
|
|
396
494
|
encoding[var] = {}
|
|
397
495
|
try:
|
|
398
|
-
# sarwing_ds[var].attrs["_FillValue"] = table_fillValue[var]
|
|
399
496
|
encoding[var].update({'_FillValue': table_fillValue[var]})
|
|
400
497
|
except:
|
|
401
|
-
# Nouvelles variables..
|
|
402
498
|
if (var in ["owiWindSpeed_co", "owiWindSpeed_cross", "owiWindSpeed"]):
|
|
403
|
-
# sarwing_ds[var].attrs["_FillValue"] = -9999.0
|
|
404
499
|
encoding[var].update({'_FillValue': -9999.0})
|
|
405
500
|
else:
|
|
406
501
|
encoding[var].update({'_FillValue': None})
|
|
407
502
|
|
|
408
503
|
xr_dataset.attrs["xsar_version"] = xsar.__version__
|
|
409
504
|
xr_dataset.attrs["xsarsea_version"] = xsarsea.__version__
|
|
410
|
-
|
|
505
|
+
|
|
411
506
|
return xr_dataset, encoding
|
|
412
507
|
|
|
413
508
|
|
|
414
509
|
def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True, resolution='1000m'):
|
|
415
510
|
"""
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
|
424
534
|
"""
|
|
425
535
|
|
|
426
|
-
# final xr.Dataset
|
|
427
|
-
|
|
428
|
-
# Step 1 - load L1 product
|
|
429
|
-
|
|
430
536
|
sensor, sensor_longname, fct_meta, fct_dataset = getSensorMetaDataset(
|
|
431
537
|
filename)
|
|
432
538
|
|
|
@@ -442,58 +548,65 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
442
548
|
else:
|
|
443
549
|
raise FileNotFoundError(
|
|
444
550
|
'config_path do not exists, got %s ' % config_path)
|
|
445
|
-
|
|
551
|
+
|
|
446
552
|
recalibration = config["recalibration"]
|
|
447
|
-
if recalibration:
|
|
448
|
-
aux_config_name=config["aux_config_name"]
|
|
449
|
-
|
|
450
553
|
meta = fct_meta(filename)
|
|
451
554
|
out_file = getOutputName2(filename, out_folder, sensor, meta)
|
|
452
555
|
|
|
453
|
-
|
|
454
556
|
if os.path.exists(out_file) and overwrite is False:
|
|
455
|
-
logging.info("out_file %s exists" % out_file)
|
|
557
|
+
logging.info("out_file %s exists ; returning empty Dataset" % out_file)
|
|
456
558
|
return out_file, xr.Dataset()
|
|
457
559
|
|
|
458
|
-
|
|
459
|
-
map_model = getAncillary(meta)
|
|
560
|
+
map_model = getAncillary(meta, ancillary_name=config["ancillary"])
|
|
460
561
|
if map_model is None:
|
|
461
562
|
raise Exception(
|
|
462
563
|
'the weather model is not set `map_model` is None -> you probably don"t have access to ECMWF archive')
|
|
463
564
|
|
|
464
565
|
try:
|
|
465
566
|
if ((recalibration) & ("SENTINEL" in sensor_longname)):
|
|
466
|
-
logging.info(
|
|
567
|
+
logging.info(
|
|
568
|
+
f'recalibration is {recalibration} : Kersten formula is applied')
|
|
467
569
|
xsar_dataset = fct_dataset(
|
|
468
|
-
meta, resolution=resolution, recalibration=recalibration
|
|
570
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
469
571
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
470
|
-
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
471
|
-
|
|
572
|
+
xr_dataset = xr_dataset.merge(xsar_dataset.datatree["recalibration"].to_dataset()[
|
|
573
|
+
['swath_number', 'swath_number_flag', 'sigma0_raw__corrected']])
|
|
574
|
+
|
|
472
575
|
else:
|
|
473
576
|
logging.info(
|
|
474
|
-
'recalibration is
|
|
577
|
+
f'recalibration is {recalibration} : Kersten formula is not applied')
|
|
475
578
|
if ("SENTINEL" in sensor_longname):
|
|
476
|
-
xsar_dataset = fct_dataset(
|
|
579
|
+
xsar_dataset = fct_dataset(
|
|
580
|
+
meta, resolution=resolution, recalibration=recalibration)
|
|
477
581
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
478
|
-
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']])
|
|
479
584
|
|
|
480
|
-
else:
|
|
585
|
+
else:
|
|
481
586
|
xsar_dataset = fct_dataset(meta, resolution=resolution)
|
|
482
587
|
xr_dataset = xsar_dataset.datatree['measurement'].to_dataset()
|
|
483
588
|
|
|
484
|
-
|
|
485
589
|
xr_dataset = xr_dataset.rename(map_model)
|
|
486
590
|
# add attributes
|
|
487
591
|
xr_dataset.attrs = xsar_dataset.dataset.attrs
|
|
488
592
|
xr_dataset.attrs['L1_path'] = xr_dataset.attrs.pop('name')
|
|
489
593
|
xr_dataset.attrs["sourceProduct"] = sensor
|
|
490
594
|
xr_dataset.attrs["missionName"] = sensor_longname
|
|
491
|
-
|
|
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
|
+
|
|
492
606
|
except Exception as e:
|
|
493
607
|
logging.info('%s', traceback.format_exc())
|
|
494
608
|
logging.error(e)
|
|
495
609
|
sys.exit(-1)
|
|
496
|
-
|
|
497
610
|
|
|
498
611
|
# defining dual_pol, and gmfs by channel
|
|
499
612
|
if len(xr_dataset.pol.values) == 2:
|
|
@@ -547,11 +660,33 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
547
660
|
xr_dataset.mask.attrs['flag_meanings'] = 'valid land ice no_valid'
|
|
548
661
|
|
|
549
662
|
# ANCILLARY
|
|
550
|
-
xr_dataset['
|
|
551
|
-
|
|
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
|
+
|
|
552
686
|
xr_dataset['ancillary_wind'] = xr.where(xr_dataset['mask'], np.nan,
|
|
553
|
-
xr_dataset
|
|
554
|
-
*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
|
+
|
|
555
690
|
xr_dataset.attrs['ancillary_source'] = xr_dataset['model_U10'].attrs['history'].split('decoded: ')[
|
|
556
691
|
1].strip()
|
|
557
692
|
xr_dataset = xr_dataset.drop_vars(['model_U10', 'model_V10'])
|
|
@@ -561,7 +696,7 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
561
696
|
xr_dataset['sigma0'].compute()).transpose(*xr_dataset['sigma0'].dims)
|
|
562
697
|
xr_dataset['sigma0_ocean'] = xr.where(
|
|
563
698
|
xr_dataset['sigma0_ocean'] <= 0, np.nan, xr_dataset['sigma0_ocean'])
|
|
564
|
-
|
|
699
|
+
|
|
565
700
|
xr_dataset['sigma0_ocean'].attrs = xr_dataset['sigma0'].attrs
|
|
566
701
|
|
|
567
702
|
xr_dataset['sigma0_ocean_raw'] = xr.where(xr_dataset['mask'], np.nan,
|
|
@@ -594,23 +729,37 @@ def makeL2(filename, out_folder, config_path, overwrite=False, generateCSV=True,
|
|
|
594
729
|
sigma0_ocean_cross = None
|
|
595
730
|
dsig_cross = 0.1 # default value set in xsarsea
|
|
596
731
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
xr_dataset['
|
|
610
|
-
xr_dataset =
|
|
611
|
-
|
|
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
|
+
|
|
747
|
+
if dual_pol:
|
|
748
|
+
xr_dataset = xr_dataset.assign(
|
|
749
|
+
windspeed_cross=(['line', 'sample'], windspeed_cr))
|
|
750
|
+
else:
|
|
751
|
+
xr_dataset['windspeed_cross'] = windspeed_cr
|
|
752
|
+
|
|
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()
|
|
612
760
|
|
|
613
|
-
xr_dataset, encoding = makeL2asOwi(
|
|
761
|
+
xr_dataset, encoding = makeL2asOwi(
|
|
762
|
+
xr_dataset, dual_pol, copol, crosspol, copol_gmf, crosspol_gmf, config)
|
|
614
763
|
|
|
615
764
|
os.makedirs(os.path.dirname(out_file), exist_ok=True)
|
|
616
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.post6 → 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.post6 → grdwindinversion-0.2.3.post8}/ci/requirements/environment.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{grdwindinversion-0.2.3.post6 → 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.post6 → 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.post6 → 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.post6 → grdwindinversion-0.2.3.post8}/tests/test_grdwindinversion.py
RENAMED
|
File without changes
|
|
File without changes
|