geospacelab 0.11.4__py3-none-any.whl → 0.12.1__py3-none-any.whl
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.
- geospacelab/__init__.py +1 -1
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/downloader.py +103 -0
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/edr_aur/__init__.py +17 -7
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/edr_aur/downloader.py +13 -62
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/sdr_disk/__init__.py +317 -0
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/sdr_disk/downloader.py +44 -0
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/sdr_disk/loader.py +198 -0
- geospacelab/datahub/sources/cdaweb/dmsp/ssusi/sdr_disk/variable_config.py +149 -0
- geospacelab/datahub/sources/cdaweb/downloader.py +396 -97
- geospacelab/datahub/sources/cdaweb/downloader_backup.py +93 -0
- geospacelab/datahub/sources/cdaweb/omni/__init__.py +26 -14
- geospacelab/datahub/sources/cdaweb/omni/downloader.py +97 -84
- geospacelab/datahub/sources/esa_eo/swarm/advanced/efi_tct02/__init__.py +1 -1
- geospacelab/datahub/sources/esa_eo/swarm/advanced/efi_tct02/downloader.py +1 -1
- geospacelab/datahub/sources/gfz/hpo/__init__.py +1 -1
- geospacelab/datahub/sources/gfz/hpo/variable_config.py +3 -1
- geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/loader.py +1 -1
- geospacelab/datahub/sources/madrigal/satellites/dmsp/downloader.py +2 -1
- geospacelab/datahub/sources/tud/champ/dns_acc/__init__.py +24 -7
- geospacelab/datahub/sources/tud/champ/dns_acc/downloader.py +29 -36
- geospacelab/datahub/sources/tud/champ/dns_acc/loader.py +28 -2
- geospacelab/datahub/sources/tud/champ/wnd_acc/__init__.py +68 -10
- geospacelab/datahub/sources/tud/champ/wnd_acc/downloader.py +29 -36
- geospacelab/datahub/sources/tud/champ/wnd_acc/loader.py +36 -7
- geospacelab/datahub/sources/tud/champ/wnd_acc/variable_config.py +3 -3
- geospacelab/datahub/sources/tud/downloader.py +288 -113
- geospacelab/datahub/sources/tud/goce/dns_acc/__init__.py +354 -0
- geospacelab/datahub/sources/tud/goce/dns_acc/downloader.py +42 -0
- geospacelab/datahub/sources/tud/goce/dns_acc/loader.py +66 -0
- geospacelab/datahub/sources/tud/goce/dns_acc/variable_config.py +139 -0
- geospacelab/datahub/sources/tud/goce/dns_wnd_acc/__init__.py +3 -3
- geospacelab/datahub/sources/tud/goce/dns_wnd_acc_v01/__init__.py +339 -0
- geospacelab/datahub/sources/tud/goce/dns_wnd_acc_v01/downloader.py +42 -0
- geospacelab/datahub/sources/tud/goce/dns_wnd_acc_v01/loader.py +84 -0
- geospacelab/datahub/sources/tud/goce/dns_wnd_acc_v01/variable_config.py +212 -0
- geospacelab/datahub/sources/tud/goce/wnd_acc/__init__.py +339 -0
- geospacelab/datahub/sources/tud/goce/wnd_acc/downloader.py +42 -0
- geospacelab/datahub/sources/tud/goce/wnd_acc/loader.py +65 -0
- geospacelab/datahub/sources/tud/goce/wnd_acc/variable_config.py +188 -0
- geospacelab/datahub/sources/tud/grace/dns_acc/__init__.py +6 -3
- geospacelab/datahub/sources/tud/grace/dns_acc/downloader.py +29 -37
- geospacelab/datahub/sources/tud/grace/wnd_acc/__init__.py +21 -4
- geospacelab/datahub/sources/tud/grace/wnd_acc/downloader.py +29 -39
- geospacelab/datahub/sources/tud/grace/wnd_acc/loader.py +5 -1
- geospacelab/datahub/sources/tud/grace/wnd_acc/variable_config.py +74 -0
- geospacelab/datahub/sources/tud/grace_fo/dns_acc/__init__.py +6 -3
- geospacelab/datahub/sources/tud/grace_fo/dns_acc/downloader.py +35 -40
- geospacelab/datahub/sources/tud/grace_fo/wnd_acc/__init__.py +20 -4
- geospacelab/datahub/sources/tud/grace_fo/wnd_acc/downloader.py +29 -44
- geospacelab/datahub/sources/tud/grace_fo/wnd_acc/loader.py +4 -0
- geospacelab/datahub/sources/tud/grace_fo/wnd_acc/variable_config.py +73 -0
- geospacelab/datahub/sources/tud/swarm/dns_acc/__init__.py +27 -5
- geospacelab/datahub/sources/tud/swarm/dns_acc/downloader.py +29 -38
- geospacelab/datahub/sources/tud/swarm/dns_pod/__init__.py +24 -5
- geospacelab/datahub/sources/tud/swarm/dns_pod/downloader.py +29 -38
- geospacelab/datahub/sources/tud/swarm/dns_pod/loader.py +3 -0
- geospacelab/datahub/sources/wdc/asysym/downloader.py +2 -2
- geospacelab/visualization/mpl/panels.py +7 -3
- {geospacelab-0.11.4.dist-info → geospacelab-0.12.1.dist-info}/METADATA +4 -5
- {geospacelab-0.11.4.dist-info → geospacelab-0.12.1.dist-info}/RECORD +63 -45
- {geospacelab-0.11.4.dist-info → geospacelab-0.12.1.dist-info}/WHEEL +1 -1
- {geospacelab-0.11.4.dist-info → geospacelab-0.12.1.dist-info}/licenses/LICENSE +0 -0
- {geospacelab-0.11.4.dist-info → geospacelab-0.12.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Licensed under the BSD 3-Clause License
|
|
2
|
+
# Copyright (C) 2021 GeospaceLab (geospacelab)
|
|
3
|
+
# Author: Lei Cai, Space Physics and Astronomy, University of Oulu
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import datetime
|
|
7
|
+
|
|
8
|
+
import geospacelab.datahub as datahub
|
|
9
|
+
from geospacelab.datahub import DatabaseModel, FacilityModel, InstrumentModel, ProductModel
|
|
10
|
+
from geospacelab.datahub.sources.tud import tud_database
|
|
11
|
+
from geospacelab.datahub.sources.tud.goce import goce_facility
|
|
12
|
+
from geospacelab.config import prf
|
|
13
|
+
import geospacelab.toolbox.utilities.pybasic as basic
|
|
14
|
+
import geospacelab.toolbox.utilities.pylogging as mylog
|
|
15
|
+
import geospacelab.toolbox.utilities.pydatetime as dttool
|
|
16
|
+
|
|
17
|
+
from geospacelab.datahub.sources.tud.goce.dns_wnd_acc_v01.loader import Loader as default_Loader
|
|
18
|
+
from geospacelab.datahub.sources.tud.goce.dns_wnd_acc_v01.downloader import Downloader as default_Downloader
|
|
19
|
+
import geospacelab.datahub.sources.tud.goce.dns_wnd_acc_v01.variable_config as var_config
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
default_dataset_attrs = {
|
|
23
|
+
'database': tud_database,
|
|
24
|
+
'facility': goce_facility,
|
|
25
|
+
'instrument': 'ACC',
|
|
26
|
+
'product': 'DNS-WND-ACC',
|
|
27
|
+
'data_file_ext': 'txt',
|
|
28
|
+
'product_version': 'v01',
|
|
29
|
+
'data_root_dir': prf.datahub_data_root_dir / 'TUD' / 'GOCE',
|
|
30
|
+
'allow_load': True,
|
|
31
|
+
'allow_download': True,
|
|
32
|
+
'force_download': False,
|
|
33
|
+
'data_search_recursive': False,
|
|
34
|
+
'add_AACGM': False,
|
|
35
|
+
'add_APEX': False,
|
|
36
|
+
'label_fields': ['database', 'facility', 'instrument', 'product', 'product_version'],
|
|
37
|
+
'load_mode': 'AUTO',
|
|
38
|
+
'time_clip': True,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
default_variable_names_v01 = [
|
|
42
|
+
'SC_DATETIME',
|
|
43
|
+
'SC_GEO_LAT',
|
|
44
|
+
'SC_GEO_LON',
|
|
45
|
+
'SC_GEO_ALT',
|
|
46
|
+
'SC_ARG_LAT',
|
|
47
|
+
'SC_GEO_LST',
|
|
48
|
+
'rho_n',
|
|
49
|
+
'u_CROSS_N',
|
|
50
|
+
'u_CROSS_E',
|
|
51
|
+
'u_CROSS_D',
|
|
52
|
+
'u_CROSS',
|
|
53
|
+
'UNIT_VECTOR_N',
|
|
54
|
+
'UNIT_VECTOR_E',
|
|
55
|
+
'UNIT_VECTOR_D',
|
|
56
|
+
'rho_n_err',
|
|
57
|
+
'u_CROSS_err',
|
|
58
|
+
'FLAG_1',
|
|
59
|
+
'FLAG_2',
|
|
60
|
+
'FLAG_3',
|
|
61
|
+
'FLAG_4',
|
|
62
|
+
]
|
|
63
|
+
default_variable_names_v02 = []
|
|
64
|
+
|
|
65
|
+
# default_data_search_recursive = True
|
|
66
|
+
|
|
67
|
+
default_attrs_required = []
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Dataset(datahub.DatasetSourced):
|
|
71
|
+
def __init__(self, **kwargs):
|
|
72
|
+
kwargs = basic.dict_set_default(kwargs, **default_dataset_attrs)
|
|
73
|
+
|
|
74
|
+
super().__init__(**kwargs)
|
|
75
|
+
|
|
76
|
+
self.database = kwargs.pop('database', 'TUD')
|
|
77
|
+
self.facility = kwargs.pop('facility', 'GOCE')
|
|
78
|
+
self.instrument = kwargs.pop('instrument', 'ACC')
|
|
79
|
+
self.product = kwargs.pop('product', 'DNS-WND-ACC')
|
|
80
|
+
self.product_version = kwargs.pop('product_version', 'v01')
|
|
81
|
+
self.local_latest_version = ''
|
|
82
|
+
self.allow_download = kwargs.pop('allow_download', False)
|
|
83
|
+
self.force_download = kwargs.pop('force_download', False)
|
|
84
|
+
self.download_dry_run = kwargs.pop('download_dry_run', False)
|
|
85
|
+
|
|
86
|
+
self.add_AACGM = kwargs.pop('add_AACGM', False)
|
|
87
|
+
self.add_APEX = kwargs.pop('add_APEX', False)
|
|
88
|
+
self._data_root_dir = self.data_root_dir # Record the initial root dir
|
|
89
|
+
|
|
90
|
+
self.metadata = {}
|
|
91
|
+
|
|
92
|
+
allow_load = kwargs.pop('allow_load', False)
|
|
93
|
+
|
|
94
|
+
# self.config(**kwargs)
|
|
95
|
+
|
|
96
|
+
if self.loader is None:
|
|
97
|
+
self.loader = default_Loader
|
|
98
|
+
|
|
99
|
+
if self.downloader is None:
|
|
100
|
+
self.downloader = default_Downloader
|
|
101
|
+
|
|
102
|
+
self._validate_attrs()
|
|
103
|
+
|
|
104
|
+
if allow_load:
|
|
105
|
+
self.load_data()
|
|
106
|
+
|
|
107
|
+
def _validate_attrs(self):
|
|
108
|
+
for attr_name in default_attrs_required:
|
|
109
|
+
attr = getattr(self, attr_name)
|
|
110
|
+
if not attr:
|
|
111
|
+
mylog.StreamLogger.warning("The parameter {} is required before loading data!".format(attr_name))
|
|
112
|
+
|
|
113
|
+
self.data_root_dir = self.data_root_dir / self.product.upper() / self.product_version
|
|
114
|
+
|
|
115
|
+
def label(self, **kwargs):
|
|
116
|
+
label = super().label()
|
|
117
|
+
return label
|
|
118
|
+
|
|
119
|
+
def load_data(self, **kwargs):
|
|
120
|
+
self.check_data_files(**kwargs)
|
|
121
|
+
if self.product_version == 'v01':
|
|
122
|
+
default_variable_names = default_variable_names_v01
|
|
123
|
+
else:
|
|
124
|
+
default_variable_names = default_variable_names_v02
|
|
125
|
+
self._set_default_variables(
|
|
126
|
+
default_variable_names,
|
|
127
|
+
configured_variables=var_config.configured_variables
|
|
128
|
+
)
|
|
129
|
+
for file_path in self.data_file_paths:
|
|
130
|
+
load_obj = self.loader(file_path, file_type='txt', version=self.product_version)
|
|
131
|
+
|
|
132
|
+
for var_name in self._variables.keys():
|
|
133
|
+
value = load_obj.variables[var_name]
|
|
134
|
+
self._variables[var_name].join(value)
|
|
135
|
+
|
|
136
|
+
# self.select_beams(field_aligned=True)
|
|
137
|
+
if self.time_clip:
|
|
138
|
+
self.time_filter_by_range(var_datetime_name='SC_DATETIME')
|
|
139
|
+
|
|
140
|
+
if self.add_AACGM:
|
|
141
|
+
self.convert_to_AACGM()
|
|
142
|
+
|
|
143
|
+
if self.add_APEX:
|
|
144
|
+
self.convert_to_APEX()
|
|
145
|
+
self._add_u_CT()
|
|
146
|
+
|
|
147
|
+
def _add_u_CT(self):
|
|
148
|
+
from geospacelab.observatory.orbit.utilities import LEOToolbox
|
|
149
|
+
ds_leo = LEOToolbox(self.dt_fr, self.dt_to)
|
|
150
|
+
ds_leo.clone_variables(self)
|
|
151
|
+
|
|
152
|
+
wind_unit_vector = np.concatenate(
|
|
153
|
+
(
|
|
154
|
+
self['UNIT_VECTOR_N'].value,
|
|
155
|
+
self['UNIT_VECTOR_E'].value,
|
|
156
|
+
self['UNIT_VECTOR_D'].value
|
|
157
|
+
),
|
|
158
|
+
axis=1
|
|
159
|
+
)
|
|
160
|
+
orbit_unit_vector = ds_leo.trajectory_local_unit_vector()
|
|
161
|
+
cp = np.cross(orbit_unit_vector, wind_unit_vector)
|
|
162
|
+
u_CT = -np.sign(cp[:, 2]) * (
|
|
163
|
+
(self['u_CROSS'].value.flatten() * self['UNIT_VECTOR_N'].flatten())**2 +
|
|
164
|
+
(self['u_CROSS'].value.flatten() * self['UNIT_VECTOR_E'].flatten())**2)**0.5
|
|
165
|
+
u_VCT = self['u_CROSS'].value.flatten() * self['UNIT_VECTOR_D'].flatten()
|
|
166
|
+
|
|
167
|
+
var = self['u_CROSS'].clone()
|
|
168
|
+
var.name = 'u_CT'
|
|
169
|
+
var.label = r'$u_{CT}$'
|
|
170
|
+
var.visual.axis[1].lim = [None, None]
|
|
171
|
+
var.value = u_CT[:, np.newaxis]
|
|
172
|
+
self['u_CT'] = var
|
|
173
|
+
|
|
174
|
+
var = self['u_CROSS'].clone()
|
|
175
|
+
var.name = 'u_VCT'
|
|
176
|
+
var.label = r'$u_{VCT}$'
|
|
177
|
+
var.visual.axis[1].lim = [None, None]
|
|
178
|
+
var.value = u_VCT[:, np.newaxis]
|
|
179
|
+
self['u_VCT'] = var
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def convert_to_APEX(self):
|
|
183
|
+
import geospacelab.cs as gsl_cs
|
|
184
|
+
|
|
185
|
+
coords_in = {
|
|
186
|
+
'lat': self['SC_GEO_LAT'].value.flatten(),
|
|
187
|
+
'lon': self['SC_GEO_LON'].value.flatten(),
|
|
188
|
+
'height': self['SC_GEO_ALT'].value.flatten()
|
|
189
|
+
}
|
|
190
|
+
dts = self['SC_DATETIME'].value.flatten()
|
|
191
|
+
cs_sph = gsl_cs.GEOCSpherical(coords=coords_in, ut=dts)
|
|
192
|
+
cs_apex = cs_sph.to_APEX(append_mlt=True)
|
|
193
|
+
self.add_variable('SC_APEX_LAT')
|
|
194
|
+
self.add_variable('SC_APEX_LON')
|
|
195
|
+
self.add_variable('SC_APEX_MLT')
|
|
196
|
+
self['SC_APEX_LAT'].value = cs_apex['lat'].reshape(self['SC_DATETIME'].value.shape)
|
|
197
|
+
self['SC_APEX_LON'].value = cs_apex['lon'].reshape(self['SC_DATETIME'].value.shape)
|
|
198
|
+
self['SC_APEX_MLT'].value = cs_apex['mlt'].reshape(self['SC_DATETIME'].value.shape)
|
|
199
|
+
|
|
200
|
+
def add_GEO_LST(self):
|
|
201
|
+
lons = self['SC_GEO_LON'].flatten()
|
|
202
|
+
uts = self['SC_DATETIME'].flatten()
|
|
203
|
+
lsts = [ut + datetime.timedelta(seconds=int(lon/15.*3600)) for ut, lon in zip(uts, lons)]
|
|
204
|
+
lsts = [lst.hour + lst.minute/60. + lst.second/3600. for lst in lsts]
|
|
205
|
+
var = self.add_variable(var_name='SC_GEO_LST')
|
|
206
|
+
var.value = np.array(lsts)[:, np.newaxis]
|
|
207
|
+
var.label = 'LST'
|
|
208
|
+
var.unit = 'h'
|
|
209
|
+
var.depends = self['SC_GEO_LON'].depends
|
|
210
|
+
return var
|
|
211
|
+
|
|
212
|
+
def convert_to_AACGM(self):
|
|
213
|
+
import geospacelab.cs as gsl_cs
|
|
214
|
+
|
|
215
|
+
coords_in = {
|
|
216
|
+
'lat': self['SC_GEO_LAT'].value.flatten(),
|
|
217
|
+
'lon': self['SC_GEO_LON'].value.flatten(),
|
|
218
|
+
'height': self['SC_GEO_ALT'].value.flatten()
|
|
219
|
+
}
|
|
220
|
+
dts = self['SC_DATETIME'].value.flatten()
|
|
221
|
+
cs_sph = gsl_cs.GEOCSpherical(coords=coords_in, ut=dts)
|
|
222
|
+
cs_aacgm = cs_sph.to_AACGM(append_mlt=True)
|
|
223
|
+
self.add_variable('SC_AACGM_LAT')
|
|
224
|
+
self.add_variable('SC_AACGM_LON')
|
|
225
|
+
self.add_variable('SC_AACGM_MLT')
|
|
226
|
+
self['SC_AACGM_LAT'].value = cs_aacgm['lat'].reshape(self['SC_DATETIME'].value.shape)
|
|
227
|
+
self['SC_AACGM_LON'].value = cs_aacgm['lon'].reshape(self['SC_DATETIME'].value.shape)
|
|
228
|
+
self['SC_AACGM_MLT'].value = cs_aacgm['mlt'].reshape(self['SC_DATETIME'].value.shape)
|
|
229
|
+
|
|
230
|
+
def search_data_files(self, **kwargs):
|
|
231
|
+
|
|
232
|
+
dt_fr = self.dt_fr
|
|
233
|
+
dt_to = self.dt_to
|
|
234
|
+
|
|
235
|
+
diff_months = dttool.get_diff_months(dt_fr, dt_to)
|
|
236
|
+
|
|
237
|
+
dt0 = dttool.get_first_day_of_month(self.dt_fr)
|
|
238
|
+
|
|
239
|
+
for i in range(diff_months + 1):
|
|
240
|
+
this_day = dttool.get_next_n_months(dt0, i)
|
|
241
|
+
|
|
242
|
+
initial_file_dir = kwargs.pop(
|
|
243
|
+
'initial_file_dir', self.data_root_dir
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
file_patterns = [
|
|
247
|
+
'GO',
|
|
248
|
+
self.product.upper().replace('-', '_'),
|
|
249
|
+
this_day.strftime('%Y_%m'),
|
|
250
|
+
]
|
|
251
|
+
# remove empty str
|
|
252
|
+
file_patterns = [pattern for pattern in file_patterns if str(pattern)]
|
|
253
|
+
search_pattern = '*' + '*'.join(file_patterns) + '*'
|
|
254
|
+
|
|
255
|
+
done = super().search_data_files(
|
|
256
|
+
initial_file_dir=initial_file_dir,
|
|
257
|
+
search_pattern=search_pattern,
|
|
258
|
+
allow_multiple_files=False,
|
|
259
|
+
)
|
|
260
|
+
# Validate file paths
|
|
261
|
+
|
|
262
|
+
if (not done and self.allow_download) or self.force_download:
|
|
263
|
+
done = self.download_data()
|
|
264
|
+
if done:
|
|
265
|
+
initial_file_dir = self.data_root_dir
|
|
266
|
+
done = super().search_data_files(
|
|
267
|
+
initial_file_dir=initial_file_dir,
|
|
268
|
+
search_pattern=search_pattern,
|
|
269
|
+
allow_multiple_files=False
|
|
270
|
+
)
|
|
271
|
+
self.data_file_paths = np.unique(self.data_file_paths)
|
|
272
|
+
return done
|
|
273
|
+
|
|
274
|
+
def download_data(self, dt_fr=None, dt_to=None):
|
|
275
|
+
if dt_fr is None:
|
|
276
|
+
dt_fr = self.dt_fr
|
|
277
|
+
if dt_to is None:
|
|
278
|
+
dt_to = self.dt_to
|
|
279
|
+
download_obj = self.downloader(
|
|
280
|
+
dt_fr, dt_to,
|
|
281
|
+
product=self.product,
|
|
282
|
+
version=self.product_version,
|
|
283
|
+
force_download=self.force_download,
|
|
284
|
+
dry_run=self.download_dry_run
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return any(download_obj.done)
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def database(self):
|
|
291
|
+
return self._database
|
|
292
|
+
|
|
293
|
+
@database.setter
|
|
294
|
+
def database(self, value):
|
|
295
|
+
if isinstance(value, str):
|
|
296
|
+
self._database = DatabaseModel(value)
|
|
297
|
+
elif issubclass(value.__class__, DatabaseModel):
|
|
298
|
+
self._database = value
|
|
299
|
+
else:
|
|
300
|
+
raise TypeError
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def product(self):
|
|
304
|
+
return self._product
|
|
305
|
+
|
|
306
|
+
@product.setter
|
|
307
|
+
def product(self, value):
|
|
308
|
+
if isinstance(value, str):
|
|
309
|
+
self._product = ProductModel(value)
|
|
310
|
+
elif issubclass(value.__class__, ProductModel):
|
|
311
|
+
self._product = value
|
|
312
|
+
else:
|
|
313
|
+
raise TypeError
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def facility(self):
|
|
317
|
+
return self._facility
|
|
318
|
+
|
|
319
|
+
@facility.setter
|
|
320
|
+
def facility(self, value):
|
|
321
|
+
if isinstance(value, str):
|
|
322
|
+
self._facility = FacilityModel(value)
|
|
323
|
+
elif issubclass(value.__class__, FacilityModel):
|
|
324
|
+
self._facility = value
|
|
325
|
+
else:
|
|
326
|
+
raise TypeError
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def instrument(self):
|
|
330
|
+
return self._instrument
|
|
331
|
+
|
|
332
|
+
@instrument.setter
|
|
333
|
+
def instrument(self, value):
|
|
334
|
+
if isinstance(value, str):
|
|
335
|
+
self._instrument = InstrumentModel(value)
|
|
336
|
+
elif issubclass(value.__class__, InstrumentModel):
|
|
337
|
+
self._instrument = value
|
|
338
|
+
else:
|
|
339
|
+
raise TypeError
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Licensed under the BSD 3-Clause License
|
|
2
|
+
# Copyright (C) 2021 GeospaceLab (geospacelab)
|
|
3
|
+
# Author: Lei Cai, Space Physics and Astronomy, University of Oulu
|
|
4
|
+
|
|
5
|
+
__author__ = "Lei Cai"
|
|
6
|
+
__copyright__ = "Copyright 2021, GeospaceLab"
|
|
7
|
+
__license__ = "BSD-3-Clause License"
|
|
8
|
+
__email__ = "lei.cai@oulu.fi"
|
|
9
|
+
__docformat__ = "reStructureText"
|
|
10
|
+
|
|
11
|
+
import datetime
|
|
12
|
+
from geospacelab.config import prf
|
|
13
|
+
|
|
14
|
+
from geospacelab.datahub.sources.tud.downloader import TUDownloader as DownloaderBase
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Downloader(DownloaderBase):
|
|
18
|
+
|
|
19
|
+
def __init__(self,
|
|
20
|
+
dt_fr, dt_to,
|
|
21
|
+
mission='GOCE',
|
|
22
|
+
sat_id='',
|
|
23
|
+
version='v01',
|
|
24
|
+
product='DNS-WND-ACC',
|
|
25
|
+
direct_download=True,
|
|
26
|
+
force_download=False,
|
|
27
|
+
dry_run=False,
|
|
28
|
+
):
|
|
29
|
+
self.mission = mission
|
|
30
|
+
self.version = version
|
|
31
|
+
|
|
32
|
+
super().__init__(
|
|
33
|
+
dt_fr, dt_to,
|
|
34
|
+
mission=mission,
|
|
35
|
+
sat_id=sat_id,
|
|
36
|
+
version=version,
|
|
37
|
+
product=product,
|
|
38
|
+
direct_download=direct_download,
|
|
39
|
+
force_download=force_download,
|
|
40
|
+
dry_run=dry_run
|
|
41
|
+
)
|
|
42
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Licensed under the BSD 3-Clause License
|
|
2
|
+
# Copyright (C) 2021 GeospaceLab (geospacelab)
|
|
3
|
+
# Author: Lei Cai, Space Physics and Astronomy, University of Oulu
|
|
4
|
+
|
|
5
|
+
__author__ = "Lei Cai"
|
|
6
|
+
__copyright__ = "Copyright 2021, GeospaceLab"
|
|
7
|
+
__license__ = "BSD-3-Clause License"
|
|
8
|
+
__email__ = "lei.cai@oulu.fi"
|
|
9
|
+
__docformat__ = "reStructureText"
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
import numpy as np
|
|
13
|
+
import datetime
|
|
14
|
+
import geospacelab.toolbox.utilities.pydatetime as dttool
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Loader(object):
|
|
18
|
+
|
|
19
|
+
def __init__(self, file_path, file_type='txt', version='v01', direct_load=True):
|
|
20
|
+
self.file_path = file_path
|
|
21
|
+
self.file_type = file_type
|
|
22
|
+
self.version = version
|
|
23
|
+
self.variables = {}
|
|
24
|
+
self.done = False
|
|
25
|
+
if direct_load:
|
|
26
|
+
self.load()
|
|
27
|
+
|
|
28
|
+
def load(self):
|
|
29
|
+
|
|
30
|
+
if self.version == 'v01':
|
|
31
|
+
self.load_v01()
|
|
32
|
+
elif self.version == 'v02':
|
|
33
|
+
raise NotImplementedError
|
|
34
|
+
else:
|
|
35
|
+
raise NotImplementedError
|
|
36
|
+
|
|
37
|
+
def load_v01(self):
|
|
38
|
+
with open(self.file_path, 'r') as f:
|
|
39
|
+
text = f.read()
|
|
40
|
+
results = re.findall(
|
|
41
|
+
r"^(\d{4}-\d{2}-\d{2}\s*\d{2}\:\d{2}\:\d{2}\.\d{3})\s*(\w{3})\s*"
|
|
42
|
+
+ r"([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*([+\-\d.Ee]+)\s*"
|
|
43
|
+
+ r"([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*([+\-\d.Ee]+)\s*([\-\d.]+)\s*"
|
|
44
|
+
+ r"([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*([\-\d.]+)\s*",
|
|
45
|
+
text,
|
|
46
|
+
re.M)
|
|
47
|
+
results = list(zip(*results))
|
|
48
|
+
dts = [datetime.datetime.strptime(dtstr + '000', "%Y-%m-%d %H:%M:%S.%f") for dtstr in results[0]]
|
|
49
|
+
if results[1][0] == 'GPS':
|
|
50
|
+
|
|
51
|
+
t_gps = [(dt - dttool._GPS_DATETIME_0).total_seconds() for dt in dts]
|
|
52
|
+
dts = dttool.convert_gps_time_to_datetime(t_gps, weeks=None)
|
|
53
|
+
|
|
54
|
+
num_rec = len(dts)
|
|
55
|
+
self.variables['SC_DATETIME'] = np.array(dts).reshape(num_rec, 1)
|
|
56
|
+
self.variables['SC_GEO_ALT'] = np.array(results[2]).astype(np.float32).reshape(num_rec, 1) * 1e-3 # in km
|
|
57
|
+
self.variables['SC_GEO_LON'] = np.array(results[3]).astype(np.float32).reshape(num_rec, 1)
|
|
58
|
+
self.variables['SC_GEO_LAT'] = np.array(results[4]).astype(np.float32).reshape(num_rec, 1)
|
|
59
|
+
self.variables['SC_GEO_LST'] = np.array(results[5]).astype(np.float32).reshape(num_rec, 1)
|
|
60
|
+
self.variables['SC_ARG_LAT'] = np.array(results[6]).astype(np.float32).reshape(num_rec, 1)
|
|
61
|
+
self.variables['rho_n'] = np.array(results[7]).astype(np.float32).reshape(num_rec, 1)
|
|
62
|
+
self.variables['u_CROSS_E'] = np.array(results[8]).astype(np.float32).reshape(num_rec, 1)
|
|
63
|
+
self.variables['u_CROSS_N'] = np.array(results[9]).astype(np.float32).reshape(num_rec, 1)
|
|
64
|
+
self.variables['u_CROSS_D'] = - np.array(results[10]).astype(np.float32).reshape(num_rec, 1)
|
|
65
|
+
self.variables['rho_n_err'] = np.array(results[11]).astype(np.float32).reshape(num_rec, 1)
|
|
66
|
+
self.variables['u_CROSS_err'] = np.array(results[12]).astype(np.float32).reshape(num_rec, 1)
|
|
67
|
+
self.variables['FLAG_1'] = np.array(results[13]).astype(np.float32).reshape(num_rec, 1)
|
|
68
|
+
self.variables['FLAG_2'] = np.array(results[14]).astype(np.float32).reshape(num_rec, 1)
|
|
69
|
+
self.variables['FLAG_3'] = np.array(results[15]).astype(np.float32).reshape(num_rec, 1)
|
|
70
|
+
self.variables['FLAG_4'] = np.array(results[16]).astype(np.float32).reshape(num_rec, 1)
|
|
71
|
+
|
|
72
|
+
self.variables['u_CROSS'] = np.sqrt(
|
|
73
|
+
self.variables['u_CROSS_E']**2
|
|
74
|
+
+ self.variables['u_CROSS_N']**2
|
|
75
|
+
+ self.variables['u_CROSS_D']**2
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
self.variables['UNIT_VECTOR_E'] = self.variables['u_CROSS_E'] / self.variables['u_CROSS']
|
|
79
|
+
self.variables['UNIT_VECTOR_N'] = self.variables['u_CROSS_N'] / self.variables['u_CROSS']
|
|
80
|
+
self.variables['UNIT_VECTOR_D'] = self.variables['u_CROSS_D'] / self.variables['u_CROSS']
|
|
81
|
+
|
|
82
|
+
self.variables['u_CROSS_E_err'] = self.variables['u_CROSS_err'] * self.variables['UNIT_VECTOR_E']
|
|
83
|
+
self.variables['u_CROSS_N_err'] = self.variables['u_CROSS_err'] * self.variables['UNIT_VECTOR_N']
|
|
84
|
+
self.variables['u_CROSS_D_err'] = self.variables['u_CROSS_err'] * self.variables['UNIT_VECTOR_D']
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Licensed under the BSD 3-Clause License
|
|
2
|
+
# Copyright (C) 2021 GeospaceLab (geospacelab)
|
|
3
|
+
# Author: Lei Cai, Space Physics and Astronomy, University of Oulu
|
|
4
|
+
|
|
5
|
+
__author__ = "Lei Cai"
|
|
6
|
+
__copyright__ = "Copyright 2021, GeospaceLab"
|
|
7
|
+
__license__ = "BSD-3-Clause License"
|
|
8
|
+
__email__ = "lei.cai@oulu.fi"
|
|
9
|
+
__docformat__ = "reStructureText"
|
|
10
|
+
|
|
11
|
+
from geospacelab.datahub import VariableModel as Var
|
|
12
|
+
import geospacelab.visualization.mpl.colormaps as cm
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
database = 'ESA/EarthOnline'
|
|
17
|
+
|
|
18
|
+
timestamps = {
|
|
19
|
+
'SC_DATETIME': 'SC_DATETIME',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
default_colormap = "gist_ncar"
|
|
24
|
+
|
|
25
|
+
default_plot_config = {
|
|
26
|
+
'line': {
|
|
27
|
+
'linestyle': '-',
|
|
28
|
+
'linewidth': 1.5,
|
|
29
|
+
'marker': '',
|
|
30
|
+
'markersize': 3,
|
|
31
|
+
},
|
|
32
|
+
'pcolormesh': {
|
|
33
|
+
'cmap': default_colormap,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
configured_variables = {}
|
|
38
|
+
visual = 'on'
|
|
39
|
+
|
|
40
|
+
depend_0 = {'UT': 'SC_DATETIME',
|
|
41
|
+
'GEO_LAT': 'SC_GEO_LAT', 'GEO_LON': 'SC_GEO_LON',
|
|
42
|
+
'AACGM_LAT': 'SC_AACGM_LAT', 'AACGM_LON': 'SC_AACGM_LON', 'AACGM_MLT': 'SC_AACGM_MLT'}
|
|
43
|
+
# depend_c = {'SPECTRA': 'EMISSION_SPECTRA'}
|
|
44
|
+
|
|
45
|
+
####################################################################################################################
|
|
46
|
+
var_name = 'rho_n'
|
|
47
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
48
|
+
# set variable attrs
|
|
49
|
+
var.fullname = 'Neutral mass density'
|
|
50
|
+
var.label = r'$\rho_n$'
|
|
51
|
+
var.unit = 'kg/m-3'
|
|
52
|
+
var.unit_label = r'kg$\cdot$m$^{-3}$'
|
|
53
|
+
var.group = r'$\rho$'
|
|
54
|
+
var.error = var_name + '_err'
|
|
55
|
+
var.depends = {0: depend_0}
|
|
56
|
+
# set plot attrs
|
|
57
|
+
plot_config = var.visual.plot_config
|
|
58
|
+
plot_config.config(**default_plot_config)
|
|
59
|
+
plot_config.style = '1E'
|
|
60
|
+
# set axis attrs
|
|
61
|
+
axis = var.visual.axis
|
|
62
|
+
axis[1].data = "@v.value"
|
|
63
|
+
# axis[1].lim = [np.nan, np.nan]
|
|
64
|
+
axis[2].label = '@v.label'
|
|
65
|
+
axis[1].unit = '@v.unit_label'
|
|
66
|
+
|
|
67
|
+
configured_variables[var_name] = var
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
####################################################################################################################
|
|
71
|
+
var_name = 'u_CROSS'
|
|
72
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
73
|
+
# set variable attrs
|
|
74
|
+
var.fullname = 'Cross neutral wind'
|
|
75
|
+
var.label = r'$u_{cross}$'
|
|
76
|
+
var.unit = 'm/s'
|
|
77
|
+
var.unit_label = r'm/s'
|
|
78
|
+
var.group = r'$u$'
|
|
79
|
+
var.error = var_name + '_err'
|
|
80
|
+
var.depends = {0: depend_0}
|
|
81
|
+
# set plot attrs
|
|
82
|
+
plot_config = var.visual.plot_config
|
|
83
|
+
plot_config.config(**default_plot_config)
|
|
84
|
+
plot_config.style = '1E'
|
|
85
|
+
# set axis attrs
|
|
86
|
+
axis = var.visual.axis
|
|
87
|
+
axis[1].data = "@v.value"
|
|
88
|
+
# axis[1].lim = [np.nan, np.nan]
|
|
89
|
+
axis[2].label = '@v.label'
|
|
90
|
+
axis[1].unit = '@v.unit_label'
|
|
91
|
+
|
|
92
|
+
configured_variables[var_name] = var
|
|
93
|
+
|
|
94
|
+
####################################################################################################################
|
|
95
|
+
var_name = 'u_CROSS_E'
|
|
96
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
97
|
+
# set variable attrs
|
|
98
|
+
var.fullname = 'Cross neutral wind (Eastward)'
|
|
99
|
+
var.label = r'$u_{E}$'
|
|
100
|
+
var.unit = 'm/s'
|
|
101
|
+
var.unit_label = r'm/s'
|
|
102
|
+
var.group = r'$u$'
|
|
103
|
+
# var.error = var_name + '_err'
|
|
104
|
+
var.depends = {0: depend_0}
|
|
105
|
+
# set plot attrs
|
|
106
|
+
plot_config = var.visual.plot_config
|
|
107
|
+
plot_config.config(**default_plot_config)
|
|
108
|
+
plot_config.style = '1noE'
|
|
109
|
+
# set axis attrs
|
|
110
|
+
axis = var.visual.axis
|
|
111
|
+
axis[1].data = "@v.value"
|
|
112
|
+
# axis[1].lim = [np.nan, np.nan]
|
|
113
|
+
axis[2].label = '@v.label'
|
|
114
|
+
axis[1].unit = '@v.unit_label'
|
|
115
|
+
|
|
116
|
+
configured_variables[var_name] = var
|
|
117
|
+
|
|
118
|
+
####################################################################################################################
|
|
119
|
+
var_name = 'u_CROSS_N'
|
|
120
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
121
|
+
# set variable attrs
|
|
122
|
+
var.fullname = 'Cross neutral wind (Northward)'
|
|
123
|
+
var.label = r'$u_{N}$'
|
|
124
|
+
var.unit = 'm/s'
|
|
125
|
+
var.unit_label = r'm/s'
|
|
126
|
+
var.group = r'$u$'
|
|
127
|
+
# var.error = var_name + '_err'
|
|
128
|
+
var.depends = {0: depend_0}
|
|
129
|
+
# set plot attrs
|
|
130
|
+
plot_config = var.visual.plot_config
|
|
131
|
+
plot_config.config(**default_plot_config)
|
|
132
|
+
plot_config.style = '1noE'
|
|
133
|
+
# set axis attrs
|
|
134
|
+
axis = var.visual.axis
|
|
135
|
+
axis[1].data = "@v.value"
|
|
136
|
+
# axis[1].lim = [np.nan, np.nan]
|
|
137
|
+
axis[2].label = '@v.label'
|
|
138
|
+
axis[1].unit = '@v.unit_label'
|
|
139
|
+
|
|
140
|
+
configured_variables[var_name] = var
|
|
141
|
+
|
|
142
|
+
####################################################################################################################
|
|
143
|
+
var_name = 'u_CROSS_D'
|
|
144
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
145
|
+
# set variable attrs
|
|
146
|
+
var.fullname = 'Cross neutral wind (Downward)'
|
|
147
|
+
var.label = r'$u_{Down}$'
|
|
148
|
+
var.unit = 'm/s'
|
|
149
|
+
var.unit_label = r'm/s'
|
|
150
|
+
var.group = r'$u$'
|
|
151
|
+
# var.error = var_name + '_err'
|
|
152
|
+
var.depends = {0: depend_0}
|
|
153
|
+
# set plot attrs
|
|
154
|
+
plot_config = var.visual.plot_config
|
|
155
|
+
plot_config.config(**default_plot_config)
|
|
156
|
+
plot_config.style = '1noE'
|
|
157
|
+
# set axis attrs
|
|
158
|
+
axis = var.visual.axis
|
|
159
|
+
axis[1].data = "@v.value"
|
|
160
|
+
# axis[1].lim = [np.nan, np.nan]
|
|
161
|
+
axis[2].label = '@v.label'
|
|
162
|
+
axis[1].unit = '@v.unit_label'
|
|
163
|
+
|
|
164
|
+
configured_variables[var_name] = var
|
|
165
|
+
|
|
166
|
+
####################################################################################################################
|
|
167
|
+
var_name = 'SC_GEO_LAT'
|
|
168
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
169
|
+
# set variable attrs
|
|
170
|
+
var.fullname = 'S/C geographic latitude'
|
|
171
|
+
var.label = r'GLAT'
|
|
172
|
+
var.unit = 'degree'
|
|
173
|
+
var.unit_label = r'$^\circ$'
|
|
174
|
+
var.group = r'GEO'
|
|
175
|
+
# var.error = var_name + '_err'
|
|
176
|
+
var.depends = {0: depend_0}
|
|
177
|
+
# set plot attrs
|
|
178
|
+
plot_config = var.visual.plot_config
|
|
179
|
+
plot_config.config(**default_plot_config)
|
|
180
|
+
plot_config.style = '1noE'
|
|
181
|
+
# set axis attrs
|
|
182
|
+
axis = var.visual.axis
|
|
183
|
+
axis[1].data = "@v.value"
|
|
184
|
+
# axis[1].lim = [-2000, 2000]
|
|
185
|
+
axis[1].label = '@v.label'
|
|
186
|
+
axis[1].unit = '@v.unit_label'
|
|
187
|
+
|
|
188
|
+
configured_variables[var_name] = var
|
|
189
|
+
|
|
190
|
+
####################################################################################################################
|
|
191
|
+
var_name = 'SC_GEO_LON'
|
|
192
|
+
var = Var(name=var_name, ndim=1, variable_type='scalar', visual=visual)
|
|
193
|
+
# set variable attrs
|
|
194
|
+
var.fullname = 'S/C geographic latitude'
|
|
195
|
+
var.label = r'GLON'
|
|
196
|
+
var.unit = 'degree'
|
|
197
|
+
var.unit_label = r'$^\circ$'
|
|
198
|
+
var.group = r'GEO'
|
|
199
|
+
# var.error = var_name + '_err'
|
|
200
|
+
var.depends = {0: depend_0}
|
|
201
|
+
# set plot attrs
|
|
202
|
+
plot_config = var.visual.plot_config
|
|
203
|
+
plot_config.config(**default_plot_config)
|
|
204
|
+
plot_config.style = '1noE'
|
|
205
|
+
# set axis attrs
|
|
206
|
+
axis = var.visual.axis
|
|
207
|
+
axis[1].data = "@v.value"
|
|
208
|
+
# axis[1].lim = [-2000, 2000]
|
|
209
|
+
axis[1].label = '@v.label'
|
|
210
|
+
axis[1].unit = '@v.unit_label'
|
|
211
|
+
|
|
212
|
+
configured_variables[var_name] = var
|