geospacelab 0.10.0__py3-none-any.whl → 0.10.2__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 CHANGED
@@ -6,7 +6,7 @@ __author__ = "Lei Cai"
6
6
  __copyright__ = "Copyright 2021, GeospaceLAB"
7
7
  __credits__ = ["Lei Cai"]
8
8
  __license__ = "BSD-3-Clause License"
9
- __version__ = "0.10.0"
9
+ __version__ = "0.10.2"
10
10
  __maintainer__ = "Lei Cai"
11
11
  __email__ = "lei.cai@oulu.fi"
12
12
  __status__ = "Developing"
@@ -72,7 +72,8 @@ class Dataset(datahub.DatasetSourced):
72
72
  self.data_file_type = kwargs.pop('data_file_type', '')
73
73
  self.affiliation = kwargs.pop('affiliation', '')
74
74
  self.allow_download = kwargs.pop('allow_download', True)
75
- self.metadata = None
75
+ self.gate_num = kwargs.pop('gate_num', None)
76
+ self.metadata = {}
76
77
  self.add_AACGM = kwargs.pop('add_AACGM', True)
77
78
  self.add_APEX = kwargs.pop('add_APEX', False)
78
79
 
@@ -116,7 +117,9 @@ class Dataset(datahub.DatasetSourced):
116
117
  self.check_data_files(**kwargs)
117
118
 
118
119
  for file_path in self.data_file_paths:
119
- load_obj = self.loader(file_path, file_type=self.data_file_type)
120
+ load_obj = self.loader(file_path, file_type=self.data_file_type, gate_num=self.gate_num)
121
+ if self.gate_num is None:
122
+ self.gate_num = load_obj.gate_num
120
123
 
121
124
  for var_name in self._variables.keys():
122
125
  self._variables[var_name].join(load_obj.variables[var_name])
@@ -130,6 +133,12 @@ class Dataset(datahub.DatasetSourced):
130
133
  self.experiment = rawdata_path.split('/')[-1].split('@')[0]
131
134
  self.affiliation = load_obj.metadata['affiliation']
132
135
  self.metadata = load_obj.metadata
136
+
137
+ inds_cmb = np.argsort(self['DATETIME'].flatten())
138
+ if any(np.diff(np.array(inds_cmb))<0):
139
+ for var_name in self.keys():
140
+ self[var_name].value = self[var_name].value[inds_cmb, :]
141
+
133
142
  if self.add_AACGM or self.add_APEX:
134
143
  self.calc_lat_lon()
135
144
  # self.select_beams(field_aligned=True)
@@ -357,21 +366,23 @@ class Dataset(datahub.DatasetSourced):
357
366
  fps_sub = []
358
367
  for ii in inds_id:
359
368
  fp = file_paths[ii]
360
- rc = re.compile(r".*_([\d]{8}T[\d]{6}).*_([\d]{8}T[\d]{6}).*[\d]{4}\-[\d]{2}\-[\d]{2}_([\w]+)@.*")
369
+ rc = re.compile(r".*_([\d]{8}T[\d]{6}).*_([\d]{8}T[\d]{6}).*[\d]{4}\-[\d]{2}\-[\d]{2}_([\w.]+)@.*")
361
370
  res = rc.search(str(fp))
362
371
  dt_0 = datetime.datetime.strptime(res.groups()[0], '%Y%m%dT%H%M%S')
363
372
  dt_1 = datetime.datetime.strptime(res.groups()[1], '%Y%m%dT%H%M%S')
364
373
  if (dt_0 >= self.dt_to) or (dt_1<=self.dt_fr):
365
374
  continue
366
375
  if str(self.pulse_code):
367
- if self.pulse_code not in res.groups()[2]:
376
+ if self.pulse_code not in res.groups()[2].lower():
368
377
  continue
369
378
  if str(self.modulation):
370
- if self.modulation not in res.groups()[2]:
379
+ if self.modulation not in res.groups()[2].lower():
371
380
  continue
381
+ if '_v' in res.groups()[2].lower():
382
+ continue
372
383
  fps_sub.extend([fp])
373
384
  if len(fps_sub) > 1:
374
- mylog.StreamLogger.warning("Multiple data files for a single experiment detected! Only the first one is selected.")
385
+ mylog.StreamLogger.warning("Multiple data files for a single experiment detected!")
375
386
  # for fp in fps_sub:
376
387
  # mylog.simpleinfo.info(str(fp))
377
388
  # fps_sub = fps_sub[0]
@@ -207,8 +207,8 @@ class Downloader(DownloaderBase):
207
207
  dt_to_exp = datetime.datetime(
208
208
  exp.endyear, exp.endmonth, exp.endday, exp.endhour, exp.endmin, exp.endsec
209
209
  )
210
- if (dt_fr_exp >= self.dt_to) or (dt_to_exp <= self.dt_fr):
211
- continue
210
+ # if (dt_fr_exp >= self.dt_to) or (dt_to_exp <= self.dt_fr):
211
+ # continue
212
212
  for file in list(exp.files):
213
213
 
214
214
  file_path_remote = pathlib.Path(file.name)
@@ -13,6 +13,7 @@ import h5py
13
13
  import numpy as np
14
14
  import pathlib
15
15
  import re
16
+ import scipy.interpolate as si
16
17
 
17
18
  from geospacelab.config import pref as prf
18
19
 
@@ -32,12 +33,12 @@ default_variable_names = [
32
33
 
33
34
 
34
35
  class Loader:
35
- def __init__(self, file_path, file_type="eiscat-hdf5"):
36
+ def __init__(self, file_path, file_type="eiscat-hdf5", gate_num=None):
36
37
  self.variables = {}
37
38
  self.metadata = {}
38
39
  self.file_path = file_path
39
40
  self.file_type = file_type
40
-
41
+ self.gate_num = gate_num
41
42
  self.load_data()
42
43
 
43
44
  def load_data(self):
@@ -131,8 +132,20 @@ class Loader:
131
132
  if num_col != nrec[0]:
132
133
  print("Note: the number of range gates doesn't match nrec!")
133
134
  var = var.reshape(num_row, num_col)
135
+ if self.gate_num is None:
136
+ num_gates=self.gate_num = num_col
137
+ else:
138
+ num_gates = self.gate_num
139
+ var_array = np.empty((num_row, num_gates))
140
+ var_array[::] = np.nan
141
+ for i in range(num_row):
142
+ var_array[i, 0:num_col] = var[i, :]
143
+ var = var_array
134
144
  elif nrec_group == 'par1d':
135
- num_gates = int(np.max(nrec))
145
+ if self.gate_num is None:
146
+ self.gate_num = num_gates = int(np.max(nrec))
147
+ else:
148
+ num_gates = self.gate_num
136
149
  var_array = np.empty((num_row, num_gates))
137
150
  var_array[:, :] = np.nan
138
151
  rec_ind_1 = 0
@@ -201,21 +214,30 @@ class Loader:
201
214
  # check height and range
202
215
  vars['HEIGHT'] = vars['HEIGHT'] / 1000.
203
216
  vars['RANGE'] = vars['RANGE'] / 1000.
204
- inds = np.where(np.isnan(vars['HEIGHT']))
205
- for i in range(len(inds[0])):
206
- ind_0 = inds[0][i]
207
- ind_1 = inds[1][i]
208
- x0 = np.arange(vars['HEIGHT'].shape[0])
209
- y0 = vars['HEIGHT'][:, ind_1]
210
- xp = x0[np.where(np.isfinite(y0))[0]]
211
- yp = y0[np.isfinite(y0)]
212
- vars['HEIGHT'][ind_0, ind_1] = np.interp(x0[ind_0], xp, yp)
213
-
214
- x0 = np.arange(vars['RANGE'].shape[0])
215
- y0 = vars['RANGE'][:, ind_1]
216
- xp = x0[np.isfinite(y0)]
217
- yp = y0[np.isfinite(y0)]
218
- vars['RANGE'][ind_0, ind_1] = np.interp(x0[ind_0], xp, yp)
217
+
218
+ inds_nan = np.where(np.isnan(vars['HEIGHT']))
219
+ if list(inds_nan):
220
+ m, n = vars['HEIGHT'].shape
221
+ for i in range(m):
222
+ yy = vars['HEIGHT'][i, :].flatten()
223
+ iii = np.where(~np.isfinite(yy))
224
+ if not list(iii):
225
+ continue
226
+ iii = np.where(np.isfinite(yy))[0]
227
+ xx = np.arange(0, n)
228
+ f = si.interp1d(xx[iii], yy[iii], kind='linear', bounds_error=False, fill_value='extrapolate')
229
+ yy_new = f(xx)
230
+ vars['HEIGHT'][i, :] = yy_new
231
+
232
+ yy = vars['RANGE'][i, :].flatten()
233
+ iii = np.where(~np.isfinite(yy))
234
+ if not list(iii):
235
+ continue
236
+ iii = np.where(np.isfinite(yy))[0]
237
+ xx = np.arange(0, n)
238
+ f = si.interp1d(xx[iii], yy[iii], kind='linear', bounds_error=False, fill_value='extrapolate')
239
+ yy_new = f(xx)
240
+ vars['RANGE'][i, :] = yy_new
219
241
 
220
242
  if np.isscalar(vars['AZ']):
221
243
  az = np.empty((vars['DATETIME_1'].shape[0], 1))
@@ -336,8 +358,12 @@ class Loader:
336
358
  inds_ran_max = np.append(inds_ran_max, len(ran)-1)
337
359
  inds_ran_max.sort()
338
360
 
339
- ngates_max = np.max(np.diff(inds_ran_max))
340
- data_array = np.empty((nvar_h5, inds_ran_min.shape[0], ngates_max))
361
+ if self.gate_num is None:
362
+ self.gate_num = ngates_max = np.max(np.diff(inds_ran_max))
363
+ else:
364
+ ngates_max = self.gate_num
365
+ num_row = inds_ran_min.shape[0]
366
+ data_array = np.empty((nvar_h5, num_row, ngates_max))
341
367
  data_array[::] = np.nan
342
368
  for ip in range(nvar_h5):
343
369
  var_tmp = np.array(data[ip])
@@ -345,7 +371,7 @@ class Loader:
345
371
  ind1 = inds_ran_min[i]
346
372
  ind2 = inds_ran_max[i]
347
373
  data_array[ip, i, 0: ind2-ind1+1] = var_tmp[ind1: ind2+1]
348
- num_row = inds_ran_min.shape[0]
374
+
349
375
  vars_h5 = {}
350
376
  for ip in range(nvar_h5):
351
377
 
@@ -382,21 +408,31 @@ class Loader:
382
408
  vars['T_e_err'] = vars['T_e'] * np.sqrt((vars['T_i_err'] / vars['T_i']) ** 2
383
409
  + (vars['T_r_err'] / vars['T_r']) ** 2)
384
410
  vars['AZ'] = vars['AZ'] % 360.
385
- inds = np.where(np.isnan(vars['HEIGHT']))
386
- for i in range(len(inds[0])):
387
- ind_0 = inds[0][i]
388
- ind_1 = inds[1][i]
389
- x0 = np.arange(vars['HEIGHT'].shape[0])
390
- y0 = vars['HEIGHT'][:, ind_1]
391
- xp = x0[np.where(np.isfinite(y0))[0]]
392
- yp = y0[np.isfinite(y0)]
393
- vars['HEIGHT'][ind_0, ind_1] = np.interp(x0[ind_0], xp, yp)
394
-
395
- x0 = np.arange(vars['RANGE'].shape[0])
396
- y0 = vars['RANGE'][:, ind_1]
397
- xp = x0[np.isfinite(y0)]
398
- yp = y0[np.isfinite(y0)]
399
- vars['RANGE'][ind_0, ind_1] = np.interp(x0[ind_0], xp, yp)
411
+
412
+ inds_nan = np.where(np.isnan(vars['HEIGHT']))
413
+ if list(inds_nan):
414
+ m, n = vars['HEIGHT'].shape
415
+ for i in range(m):
416
+ yy = vars['HEIGHT'][i, :].flatten()
417
+ iii = np.where(~np.isfinite(yy))
418
+ if not list(iii):
419
+ continue
420
+ iii = np.where(np.isfinite(yy))[0]
421
+ xx = np.arange(0, n)
422
+ f = si.interp1d(xx[iii], yy[iii], kind='linear', bounds_error=False, fill_value='extrapolate')
423
+ yy_new = f(xx)
424
+ vars['HEIGHT'][i, :] = yy_new
425
+
426
+ yy = vars['RANGE'][i, :].flatten()
427
+ iii = np.where(~np.isfinite(yy))
428
+ if not list(iii):
429
+ continue
430
+ iii = np.where(np.isfinite(yy))[0]
431
+ xx = np.arange(0, n)
432
+ f = si.interp1d(xx[iii], yy[iii], kind='linear', bounds_error=False, fill_value='extrapolate')
433
+ yy_new = f(xx)
434
+ vars['RANGE'][i, :] = yy_new
435
+
400
436
 
401
437
  self.variables = vars
402
438
  self.metadata = metadata
@@ -46,7 +46,7 @@ default_variable_names = [
46
46
  'DATETIME', 'AZ', 'EL', 'PULSE_LENGTH',
47
47
  'P_Tx', 'n_e', 'n_e_err', 'T_i', 'T_i_err', 'T_e', 'T_e_err',
48
48
  'v_i_los', 'v_i_los_err', 'comp_mix', 'comp_mix_err',
49
- 'HEIGHT', 'RANGE', 'CGM_LAT', 'CGM_LON'
49
+ 'HEIGHT', 'RANGE', 'CGM_LAT', 'CGM_LON', 'BEAM_ID', 'CHISQ'
50
50
  ]
51
51
 
52
52
  # default_data_search_recursive = True
@@ -55,7 +55,7 @@ default_attrs_required = []
55
55
 
56
56
  pulse_code_dict = {
57
57
  'alternating code': 'AC',
58
- 'long pulse': 'PL',
58
+ 'long pulse': 'LP',
59
59
  }
60
60
 
61
61
 
@@ -138,8 +138,8 @@ class Dataset(datahub.DatasetSourced):
138
138
  self.beam_az = load_obj.beam_az
139
139
  self.beam_el = load_obj.beam_el
140
140
 
141
- if self.add_APEX or self.add_AACGM:
142
- self.calc_lat_lon()
141
+ # if self.add_APEX or self.add_AACGM:
142
+ self.calc_lat_lon()
143
143
 
144
144
  if self['HEIGHT'].value is None:
145
145
  self['HEIGHT'] = self['GEO_ALT']
@@ -353,7 +353,7 @@ class Dataset(datahub.DatasetSourced):
353
353
  pulse_code=self.pulse_code,
354
354
  dry_run=dry_run,
355
355
  data_file_root_dir=self.data_root_dir,
356
- include_exp_ids=self.exp_ids,
356
+ include_exp_ids=self.experiment_ids,
357
357
  include_exp_name_patterns=include_exp_name_patterns)
358
358
  return download_obj.data_file_paths
359
359
 
@@ -15,7 +15,7 @@ EXCLUDE_FILE_TYPE_PATTERNS = [['from power'], ['velocity'], ['uncorrected']]
15
15
 
16
16
  pulse_code_dict = {
17
17
  'alternating code': 'AC',
18
- 'long pulse': 'PL',
18
+ 'long pulse': 'LP',
19
19
  }
20
20
 
21
21
 
@@ -37,6 +37,8 @@ var_name_dict = {
37
37
  'CGM_LAT': 'cgm_lat',
38
38
  'CGM_LON': 'cgm_long',
39
39
  'HEIGHT': 'gdalt',
40
+ 'BEAM_ID': 'beamid',
41
+ 'CHISQ': 'chisq',
40
42
  }
41
43
 
42
44
 
@@ -205,8 +205,8 @@ class Dataset(datahub.DatasetSourced):
205
205
  sin_glon_1 = np.sin(glon_1 * factor)
206
206
  sin_glon_2 = np.sin(glon_2 * factor)
207
207
  cos_glon_2 = np.cos(glon_2 * factor)
208
- itpf_sin = interp1d(sectime_2, sin_glon_2, kind='cubic', bounds_error=False, fill_value='extrapolate')
209
- itpf_cos = interp1d(sectime_2, cos_glon_2, kind='cubic', bounds_error=False, fill_value='extrapolate')
208
+ itpf_sin = interp1d(sectime_2, sin_glon_2, kind='linear', bounds_error=False, fill_value='extrapolate')
209
+ itpf_cos = interp1d(sectime_2, cos_glon_2, kind='linear', bounds_error=False, fill_value='extrapolate')
210
210
  sin_glon_2_i = itpf_sin(sectime_1)
211
211
  sin_glon_2_i = np.where(sin_glon_2_i > 1., 1., sin_glon_2_i)
212
212
  sin_glon_2_i = np.where(sin_glon_2_i < -1., -1., sin_glon_2_i)
@@ -177,8 +177,8 @@ class Dataset(datahub.DatasetSourced):
177
177
  sin_glon_1 = np.sin(glon_1 * factor)
178
178
  sin_glon_2 = np.sin(glon_2 * factor)
179
179
  cos_glon_2 = np.cos(glon_2 * factor)
180
- itpf_sin = interp1d(sectime_2, sin_glon_2, kind='cubic', bounds_error=False, fill_value='extrapolate')
181
- itpf_cos = interp1d(sectime_2, cos_glon_2, kind='cubic', bounds_error=False, fill_value='extrapolate')
180
+ itpf_sin = interp1d(sectime_2, sin_glon_2, kind='linear', bounds_error=False, fill_value='extrapolate')
181
+ itpf_cos = interp1d(sectime_2, cos_glon_2, kind='linear', bounds_error=False, fill_value='extrapolate')
182
182
  sin_glon_2_i = itpf_sin(sectime_1)
183
183
  cos_glon_2_i = itpf_cos(sectime_1)
184
184
  rad = np.sign(sin_glon_2_i) * (np.pi / 2 - np.arcsin(cos_glon_2_i))
@@ -10,9 +10,11 @@ __docformat__ = "reStructureText"
10
10
 
11
11
 
12
12
  import numpy
13
- from scipy.interpolate import interp1d
13
+ import numpy as np
14
+ from scipy.interpolate import interp1d, griddata
14
15
  import geospacelab.toolbox.utilities.pydatetime as dttool
15
16
  import geospacelab.toolbox.utilities.pybasic as basic
17
+ import geospacelab.toolbox.utilities.pylogging as mylog
16
18
  import datetime
17
19
 
18
20
 
@@ -133,6 +135,140 @@ def data_resample(
133
135
 
134
136
  return xnew, ynew
135
137
 
138
+ # def resample_2d(
139
+ # x_data, y_data, z_data,
140
+ # x_data_type=None,
141
+ # x_data_res=None,
142
+ # x_data_res_scale=1.,
143
+ # x_grid_res=None,
144
+ # x_grid_res_scale=1,
145
+ # x_grid_min=None,
146
+ # x_grid_max=None,
147
+ # along_x_interp=True,
148
+ # along_x_interp_method='nearest',
149
+ # along_x_binning=False,
150
+ # y_data_res=None,
151
+ # y_data_res_scale=1.,
152
+ # y_grid_res=None,
153
+ # y_grid_res_scale=1.,
154
+ # y_grid_min=None,
155
+ # y_grid_max=None,
156
+ # along_y_interp=True,
157
+ # along_y_interp_method='nearest',
158
+ # along_y_binning=False,
159
+ # ):
160
+ # if along_x_interp==True and along_x_binning==True:
161
+ # mylog.StreamLogger.error('The keywords "along_x_interp" and "along_x_binning" cannot be True at the same time!')
162
+ # raise ValueError
163
+ # if along_y_interp==True and along_y_binning==True:
164
+ # mylog.StreamLogger.error('The keywords "along_y_interp" and "along_y_binning" cannot be True at the same time!')
165
+ # raise ValueError
166
+ #
167
+ # num_x, num_y = z_data.shape
168
+ # if x_data_type == 'datetime':
169
+ # dt0 = dttool.get_start_of_the_day(numpy.nanmin(x_data.flatten()))
170
+ # sectime, dt0 = dttool.convert_datetime_to_sectime(x_data, dt0=dt0)
171
+ # x_data = sectime
172
+ #
173
+ # # check x dim:
174
+ # if len(x_data.shape) == 1:
175
+ # x_dim = 1
176
+ # elif len(x_data.shape) == 2:
177
+ # if x_data.shape[1] == num_y:
178
+ # x_dim = 2
179
+ # else:
180
+ # x_dim = 1
181
+ # else:
182
+ # raise ValueError
183
+ # if x_dim == 1:
184
+ # xd = np.tile(x_data.flatten(), (1, num_y))
185
+ # else:
186
+ # xd = x_data
187
+ # min_x = np.nanmin(xd.flatten())
188
+ # max_x = np.nanmax(xd.flatten())
189
+ # # check y dim:
190
+ # if len(y_data.shape) == 1:
191
+ # y_dim = 1
192
+ # elif len(y_data.shape) == 2:
193
+ # if y_data.shape[1] == num_y:
194
+ # y_dim = 2
195
+ # else:
196
+ # y_dim = 1
197
+ # else:
198
+ # raise ValueError
199
+ # if y_dim == 1:
200
+ # yd = np.tile(x_data.flatten(), (num_x, 1))
201
+ # else:
202
+ # yd = y_data
203
+ # min_y = np.nanmin(yd.flatten())
204
+ # max_y = np.nanmax(yd.flatten())
205
+ #
206
+ # if x_data_res is None:
207
+ # x_data_res_ = np.median(np.diff(xd[:, 0].flatten()))
208
+ # else:
209
+ # x_data_res_ = x_data_res
210
+ # if y_data_res is None:
211
+ # y_data_res_ = np.median(np.diff(yd[0, :].flatten()))
212
+ # else:
213
+ # y_data_res_ = y_data_res
214
+ #
215
+ # if x_grid_res is None:
216
+ # xx = xd[:, 0].flatten()
217
+ # # along_x_interp=False
218
+ # # along_x_binning=False
219
+ # # x_grid_res=x_data_res
220
+ # else:
221
+ # if x_grid_min is None:
222
+ # x_grid_min = np.floor((min_x / x_grid_res)) * x_grid_res
223
+ # if x_grid_max is None:
224
+ # x_grid_max = np.ceil((max_x / x_grid_res)) * x_grid_res
225
+ # xx = np.arange(x_grid_min, x_grid_max+x_grid_res, x_grid_res)
226
+ # if y_grid_res is None:
227
+ # yy = yd[0, :].flatten()
228
+ # # along_y_interp=False
229
+ # # along_y_binning=False
230
+ # # y_grid_res=y_data_res
231
+ # else:
232
+ # if y_grid_min is None:
233
+ # y_grid_min = np.floor((min_y / y_grid_res)) * y_grid_res
234
+ # if y_grid_max is None:
235
+ # y_grid_max = np.ceil((max_y / y_grid_res)) * y_grid_res
236
+ # yy = np.arange(y_grid_min, y_grid_max+y_grid_res, y_grid_res)
237
+ #
238
+ # grid_x, grid_y = numpy.meshgrid(xx,yy)
239
+ # grid_z = np.empty_like(grid_x)
240
+ # grid_z[::] = np.nan
241
+ #
242
+ # if along_y_interp:
243
+ # grid_x_1 = np.empty_like((num_x, grid_z.shape[1])) * np.nan
244
+ # grid_y_1 = np.empty_like((num_x, grid_z.shape[1])) * np.nan
245
+ # grid_z_1 = np.empty_like((num_x, grid_z.shape[1])) * np.nan
246
+ # for i in range(num_x):
247
+ # x1 = xd[i, :].flatten()
248
+ # y1 = yd[i, :].flatten()
249
+ # z1 = z_data[i, :].flatten()
250
+ #
251
+ # inds_finite = np.where(np.isfinite(x1) & np.isfinite(y1) & np.isfinite(z1))[0]
252
+ # if not list(inds_finite):
253
+ # continue
254
+ #
255
+ # f = interp1d(y1[inds_finite], x1[inds_finite],
256
+ # kind='nearest', bounds_error=False, fill_value=np.nan)
257
+ # x_i = f(grid_y[i, :].flatten())
258
+ # grid_x_1[i, :] = x_i
259
+ #
260
+ # f = interp1d(y1[inds_finite], y1[inds_finite],
261
+ # kind='nearest', bounds_error=False, fill_value=np.nan)
262
+ # y_i = f(grid_y[i, :].flatten())
263
+ # grid_y_1[i, :] = y_i
264
+ #
265
+ # f = interp1d(
266
+ # y1[inds_finite], z1[inds_finite],
267
+ # kind=along_y_interp_method, bounds_error=False, fill_value=np.nan)
268
+ # z_i = f(grid_y[i, :].flatten())
269
+ #
270
+ # grid_z_1[i, :] = z_i
271
+
136
272
 
137
273
  def regridding_2d_xgaps(
138
274
  x, y, z,
@@ -736,6 +736,7 @@ class TSPanel(Panel):
736
736
  time_gap = var.visual.axis[0].mask_gap
737
737
  if time_gap is None:
738
738
  time_gap = self.time_gap
739
+ y_data = self._check_ydata(y_data)
739
740
  if time_gap:
740
741
  # x, y, z = arraytool.data_resample_2d(
741
742
  # x=x_data, y=y_data, z=z_data, xtype='datetime', xres=x_data_res, method='Null', axis=0)
@@ -748,6 +749,21 @@ class TSPanel(Panel):
748
749
  data = {'x': x, 'y': y, 'z': z}
749
750
  return data
750
751
 
752
+ def _check_ydata(self, ydata):
753
+ inds_infinite = np.where(~np.isfinite(ydata))
754
+ if list(inds_infinite):
755
+ m, n = ydata.shape
756
+ for i in range(m):
757
+ yy = ydata[i, :].flatten()
758
+ iii = np.where(~np.isfinite(yy))
759
+ if not list(iii):
760
+ continue
761
+ iii = np.where(np.isfinite(yy))[0]
762
+ xx = np.arange(0, n)
763
+ f = interp1d(xx[iii], yy[iii], kind='linear', bounds_error=False, fill_value='extrapolate')
764
+ yy_new = f(xx)
765
+ ydata[i, :] = yy_new
766
+ return ydata
751
767
  @staticmethod
752
768
  def generate_label(label: str, unit: str='', style: str='double'):
753
769
  label = label
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geospacelab
3
- Version: 0.10.0
3
+ Version: 0.10.2
4
4
  Summary: Collect, manage, and visualize geospace data.
5
5
  Home-page: https://github.com/JouleCai/geospacelab
6
6
  Author: Lei Cai
@@ -378,14 +378,9 @@ Output:
378
378
  From then on, the data source has been switched from JHUAPL to CDAWeb.
379
379
 
380
380
  ```python
381
- import datetime
382
- import matplotlib.pyplot as plt
383
-
384
- import geospacelab.visualization.mpl.geomap.geodashboards as geomap
385
-
386
381
  dt_fr = datetime.datetime(2015, 9, 8, 8)
387
382
  dt_to = datetime.datetime(2015, 9, 8, 23, 59)
388
- time1 = datetime.datetime(2015, 9, 8, 20, 21)
383
+ time_c = datetime.datetime(2015, 9, 8, 20, 21)
389
384
  pole = 'N'
390
385
  sat_id = 'f16'
391
386
  band = 'LBHS'
@@ -396,49 +391,51 @@ dashboard = geomap.GeoDashboard(dt_fr=dt_fr, dt_to=dt_to, figure_config={'figsiz
396
391
  # If the orbit_id is specified, only one file will be downloaded. This option saves the downloading time.
397
392
  # dashboard.dock(datasource_contents=['jhuapl', 'dmsp', 'ssusi', 'edraur'], pole='N', sat_id='f17', orbit_id='46863')
398
393
  # If not specified, the data during the whole day will be downloaded.
399
- dashboard.dock(
400
- datasource_contents=dashboard.dock(datasource_contents=['cdaweb', 'dmsp', 'ssusi', 'edr_aur'],
401
- pole=pole, sat_id=sat_id, orbit_id=None
402
- )
394
+ ds_ssusi = dashboard.dock(datasource_contents=['cdaweb', 'dmsp', 'ssusi', 'edr_aur'], pole=pole, sat_id=sat_id, orbit_id=None)
403
395
  ds_s1 = dashboard.dock(
404
396
  datasource_contents=['madrigal', 'satellites', 'dmsp', 's1'],
405
- dt_fr=time1 - datetime.timedelta(minutes=45),
406
- dt_to=time1 + datetime.timedelta(minutes=45),
407
- sat_id=sat_id
408
- )
397
+ dt_fr=time_c - datetime.timedelta(minutes=45),
398
+ dt_to=time_c + datetime.timedelta(minutes=45),
399
+ sat_id=sat_id, replace_orbit=True)
409
400
 
410
401
  dashboard.set_layout(1, 1)
411
402
 
412
403
  # Get the variables: LBHS emission intensiy, corresponding times and locations
413
- lbhs = dashboard.assign_variable('GRID_AUR_' + band, dataset_index=0)
414
- dts = dashboard.assign_variable('DATETIME', dataset_index=0).value.flatten()
415
- mlat = dashboard.assign_variable('GRID_MLAT', dataset_index=0).value
416
- mlon = dashboard.assign_variable('GRID_MLON', dataset_index=0).value
417
- mlt = dashboard.assign_variable(('GRID_MLT'), dataset_index=0).value
404
+ lbhs = ds_ssusi['GRID_AUR_' + band]
405
+ dts = ds_ssusi['DATETIME'].flatten()
406
+ mlat = ds_ssusi['GRID_MLAT']
407
+ mlon = ds_ssusi['GRID_MLON']
408
+ mlt = ds_ssusi['GRID_MLT']
418
409
 
419
410
  # Search the index for the time to plot, used as an input to the following polar map
420
- ind_t = dashboard.datasets[0].get_time_ind(ut=time1)
411
+ ind_t = dashboard.datasets[0].get_time_ind(ut=time_c)
412
+ if (dts[ind_t] - time_c).total_seconds()/60 > 60: # in minutes
413
+ raise ValueError("The time does not match any SSUSI data!")
421
414
  lbhs_ = lbhs.value[ind_t]
422
- mlat_ = mlat[ind_t]
423
- mlon_ = mlon[ind_t]
424
- mlt_ = mlt[ind_t]
415
+ mlat_ = mlat.value[ind_t]
416
+ mlon_ = mlon.value[ind_t]
417
+ mlt_ = mlt.value[ind_t]
425
418
  # Add a polar map panel to the dashboard. Currently the style is the fixed MLT at mlt_c=0. See the keywords below:
426
- panel1 = dashboard.add_polar_map(row_ind=0, col_ind=0, style='mlt-fixed', cs='AACGM', mlt_c=0., pole=pole, ut=time1, boundary_lat=65., mirror_south=True)
419
+ panel = dashboard.add_polar_map(
420
+ row_ind=0, col_ind=0, style='mlt-fixed', cs='AACGM',
421
+ mlt_c=0., pole=pole, ut=time_c, boundary_lat=55., mirror_south=True
422
+ )
427
423
 
428
424
  # Some settings for plotting.
429
425
  pcolormesh_config = lbhs.visual.plot_config.pcolormesh
430
426
  # Overlay the SSUSI image in the map.
431
- ipm = panel1.overlay_pcolormesh(data=lbhs_, coords={'lat': mlat_, 'lon': mlon_, 'mlt': mlt_}, cs='AACGM',
432
- regridding=True, **pcolormesh_config)
427
+ ipc = panel.overlay_pcolormesh(
428
+ data=lbhs_, coords={'lat': mlat_, 'lon': mlon_, 'mlt': mlt_}, cs='AACGM',
429
+ regridding=False, **pcolormesh_config)
433
430
  # Add a color bar
434
- panel1.add_colorbar(ipm, c_label=band + " (R)", c_scale=pcolormesh_config['c_scale'], left=1.1, bottom=0.1,
431
+ panel.add_colorbar(ipc, c_label=band + " (R)", c_scale=pcolormesh_config['c_scale'], left=1.1, bottom=0.1,
435
432
  width=0.05, height=0.7)
436
433
 
437
434
  # Overlay the gridlines
438
- panel1.overlay_gridlines(lat_res=5, lon_label_separator=5)
435
+ panel.overlay_gridlines(lat_res=5, lon_label_separator=5)
439
436
 
440
437
  # Overlay the coastlines in the AACGM coordinate
441
- panel1.overlay_coastlines()
438
+ panel.overlay_coastlines()
442
439
 
443
440
  # Overlay cross-track velocity along satellite trajectory
444
441
  sc_dt = ds_s1['SC_DATETIME'].value.flatten()
@@ -448,14 +445,22 @@ sc_alt = ds_s1['SC_GEO_ALT'].value.flatten()
448
445
  sc_coords = {'lat': sc_lat, 'lon': sc_lon, 'height': sc_alt}
449
446
 
450
447
  v_H = ds_s1['v_i_H'].value.flatten()
451
- panel1.overlay_cross_track_vector(vector=v_H, unit_vector=1000, alpha=0.5, color='r', sc_coords=sc_coords, sc_ut=sc_dt, cs='GEOC')
448
+ panel.overlay_cross_track_vector(
449
+ vector=v_H, unit_vector=1000, vector_unit='m/s', alpha=0.3, color='red',
450
+ sc_coords=sc_coords, sc_ut=sc_dt, cs='GEO',
451
+ )
452
452
  # Overlay the satellite trajectory with ticks
453
- panel1.overlay_sc_trajectory(sc_ut=sc_dt, sc_coords=sc_coords, cs='GEOC')
453
+ panel.overlay_sc_trajectory(sc_ut=sc_dt, sc_coords=sc_coords, cs='GEO')
454
+
455
+ # Overlay sites
456
+ panel.overlay_sites(
457
+ site_ids=['TRO', 'ESR'], coords={'lat': [69.58, 78.15], 'lon': [19.23, 16.02], 'height': 0.},
458
+ cs='GEO', marker='^', markersize=2)
454
459
 
455
460
  # Add the title and save the figure
456
461
  polestr = 'North' if pole == 'N' else 'South'
457
- panel1.add_title(title='DMSP/SSUSI, ' + band + ', ' + sat_id.upper() + ', ' + polestr + ', ' + time1.strftime('%Y-%m-%d %H%M UT'))
458
- plt.savefig('DMSP_SSUSI_' + time1.strftime('%Y%m%d-%H%M') + '_' + band + '_' + sat_id.upper() + '_' + pole, dpi=300)
462
+ panel.add_title(title='DMSP/SSUSI, ' + band + ', ' + sat_id.upper() + ', ' + polestr + ', ' + time_c.strftime('%Y-%m-%d %H%M UT'))
463
+ plt.savefig('DMSP_SSUSI_' + time_c.strftime('%Y%m%d-%H%M') + '_' + band + '_' + sat_id.upper() + '_' + pole, dpi=300)
459
464
 
460
465
  # show the figure
461
466
  plt.show()
@@ -1,4 +1,4 @@
1
- geospacelab/__init__.py,sha256=f4iwnBOYn05XseQui8vNYJ279570jPZKwy0eTnws92Y,801
1
+ geospacelab/__init__.py,sha256=ERG2N0CIY6iNLEbC9RPSn3k4KdxrXlMj4BI9U9Tzsg0,801
2
2
  geospacelab/config/__init__.py,sha256=D5A0ORTubSaLEXGqPmg-mLH_KNqINicOeeNFqkGpXrk,641
3
3
  geospacelab/config/_preferences.py,sha256=DakPjKJQ0VRe2Mgc8bakw585u4N8qVqYYvqnoLdyvH4,4726
4
4
  geospacelab/coords/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -154,9 +154,9 @@ geospacelab/datahub/sources/madrigal/gnss/tecmap/downloader.py,sha256=9Z4zZm-xNS
154
154
  geospacelab/datahub/sources/madrigal/gnss/tecmap/loader.py,sha256=JytJZfzUp2ijn0w1ADoA5-aRP1c674T4wz0mRSFSvPg,2895
155
155
  geospacelab/datahub/sources/madrigal/gnss/tecmap/variable_config.py,sha256=d-1XeMMZOyYFQAOYjPwIS2USBY9B8YjRfIww1TowVqE,1517
156
156
  geospacelab/datahub/sources/madrigal/isr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
- geospacelab/datahub/sources/madrigal/isr/eiscat/__init__.py,sha256=XsRlb-89n4SoP0lELoYeHBFpKLLFmTnPwkTEXsCb1H0,19963
158
- geospacelab/datahub/sources/madrigal/isr/eiscat/downloader.py,sha256=UDIVMuFmNsC97F-nTYib5FyU3ag41wUHnDDmGZ0Bcec,26140
159
- geospacelab/datahub/sources/madrigal/isr/eiscat/loader.py,sha256=YbpbFtVyk15ejqPq9O1VeUZKyK95Epmv2LsMwsQ3bf0,16337
157
+ geospacelab/datahub/sources/madrigal/isr/eiscat/__init__.py,sha256=sxHcvgMy_Kjnl9TppU-jVw7yPoPtUZwxsieuCOBr2aY,20413
158
+ geospacelab/datahub/sources/madrigal/isr/eiscat/downloader.py,sha256=d-oUtCh8NHbkmEKfbe1oGb0-DzZsQH0CQXAedncMfTU,26144
159
+ geospacelab/datahub/sources/madrigal/isr/eiscat/loader.py,sha256=vxip8UcPqA0S4H3aFSVoT8BgMi6J9Q3noaMIjbIuNy4,17953
160
160
  geospacelab/datahub/sources/madrigal/isr/eiscat/utilities.py,sha256=TImaJSVDyqvXezSCTAzMgAQ7CmrgD5YjyUiRl-K_dWk,2514
161
161
  geospacelab/datahub/sources/madrigal/isr/eiscat/variable_config.py,sha256=Lny8eVbtE7wxcYtRcfUrVDY6vkzfxD5hb29mc3ytENI,9153
162
162
  geospacelab/datahub/sources/madrigal/isr/eiscat/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -174,9 +174,9 @@ geospacelab/datahub/sources/madrigal/isr/millstonehill/vi/loader.py,sha256=kgV5c
174
174
  geospacelab/datahub/sources/madrigal/isr/millstonehill/vi/variable_config.py,sha256=tz650AGv4XedOEnB-DoN6VgIk6SNkEjnBOweACuXbwc,8951
175
175
  geospacelab/datahub/sources/madrigal/isr/pfisr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
176
  geospacelab/datahub/sources/madrigal/isr/pfisr/downloader.py,sha256=uCrJR-MJ_LJ2JyQ971VkiN56_Kl2C9y8RhdvG9B0vX8,6521
177
- geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/__init__.py,sha256=v5Wx2NfFX3GsOfNNJ26sRjDBT-8T_gG1Sne_NR3hXiE,16177
178
- geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/downloader.py,sha256=oO8QpDGw7XFSbJjtNtBES5vA4g1HGFUMkYteX6h17xE,2763
179
- geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/loader.py,sha256=jN95YU11l0PuJZ7k08lh5-4h2-Mhn_p-2VgCghnd_mQ,8495
177
+ geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/__init__.py,sha256=twxLco9U0-qZrZspe2LBokIkmG-8bHDlu_mZVMrPHY0,16202
178
+ geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/downloader.py,sha256=-2y1BRdQOmNjnXoWHIHh1PCRbeuKZh0Bn3LIMYw0yV4,2763
179
+ geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/loader.py,sha256=JsZwNSsEly__FxT1Px57Te5pKbteymE3j7B0oLBgKWc,8542
180
180
  geospacelab/datahub/sources/madrigal/isr/pfisr/fitted/variable_config.py,sha256=D4xdYFk--ll0ATqNtjoX9pwrsCryVV3TuPSbGR92drI,8167
181
181
  geospacelab/datahub/sources/madrigal/isr/pfisr/vi/__init__.py,sha256=rHx79V0gFwC4ZsSt79QkKaCE6XtdWWoQUaFaXVq49LY,12719
182
182
  geospacelab/datahub/sources/madrigal/isr/pfisr/vi/downloader.py,sha256=az1OxIa6-F4pvTAJGTqjuc6rfza1e3qyAiRf6sEje7c,2413
@@ -188,10 +188,10 @@ geospacelab/datahub/sources/madrigal/satellites/dmsp/downloader.py,sha256=jnA8Xp
188
188
  geospacelab/datahub/sources/madrigal/satellites/dmsp/e/__init__.py,sha256=2LmuPOzOH9lhMqXkrb4gj9Wxsmdq2mXSA0phTlrK0eU,10309
189
189
  geospacelab/datahub/sources/madrigal/satellites/dmsp/e/loader.py,sha256=kZ9AeI0LsNWS26Kwfp6azvDl2IutcWKBPDd6o0tKASc,4902
190
190
  geospacelab/datahub/sources/madrigal/satellites/dmsp/e/variable_config.py,sha256=exp1bYVmDBVlIbraeNgAuVEnjxg5IC2ED1cZIEiPj1U,10280
191
- geospacelab/datahub/sources/madrigal/satellites/dmsp/s1/__init__.py,sha256=FcSeOfcymCcqDukxSvHTEpdxa-r2ZpZXC-dbb0t7M7I,11534
191
+ geospacelab/datahub/sources/madrigal/satellites/dmsp/s1/__init__.py,sha256=u7Z0SFUaLNzPV7aIqcaEUTyIIYPHHJF3rXMWCDYbSUY,11536
192
192
  geospacelab/datahub/sources/madrigal/satellites/dmsp/s1/loader.py,sha256=o5zEkosq7LyNlBIjlefKUpYpePCDbyL_yd3HrrUrk5Q,3360
193
193
  geospacelab/datahub/sources/madrigal/satellites/dmsp/s1/variable_config.py,sha256=Amp90wHogRQOESLH2b4D0jfeBozIKvvOnwx-_waU0us,6745
194
- geospacelab/datahub/sources/madrigal/satellites/dmsp/s4/__init__.py,sha256=YIVUE3rrOs67KCBUTfExoHz-EoVx2OoJqEfPGClp8Tk,10196
194
+ geospacelab/datahub/sources/madrigal/satellites/dmsp/s4/__init__.py,sha256=0Qkn18pmVBmc0y0Kk6TRJBynoU_ysYMsXLzAAXB37M8,10198
195
195
  geospacelab/datahub/sources/madrigal/satellites/dmsp/s4/loader.py,sha256=LL8IAMwmgQX06lgVECh6Rx6TGXEoHmAkFDmouJ6kQOo,3229
196
196
  geospacelab/datahub/sources/madrigal/satellites/dmsp/s4/variable_config.py,sha256=4DhvQxFonoYiU_3f9ObE2OkJOXDkHfw0RUMHa3FLTv4,4054
197
197
  geospacelab/datahub/sources/ncei/__init__.py,sha256=MHpNJ-PJBjywheG5CZDgj89fsxVG5qSxi_vkTsxibd8,658
@@ -320,7 +320,7 @@ geospacelab/toolbox/io/__init__.py,sha256=YcFkmOGWXNiOXWsMFxFPhn32UnbxmeSrluTp6O
320
320
  geospacelab/toolbox/io/dialog.py,sha256=y87PKCXQS5_axbrNuVrcYN2uIfr-ZHICr7yMQ0yH1M4,1067
321
321
  geospacelab/toolbox/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
322
322
  geospacelab/toolbox/utilities/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
323
- geospacelab/toolbox/utilities/numpyarray.py,sha256=Xa9YBYOgIu9gUHnmyB-j1TmmPyt4KSukVmA4Y1dwxDA,7063
323
+ geospacelab/toolbox/utilities/numpyarray.py,sha256=olclT06DRPFSYaEdiD1uqwHvM0vHNDFjkLstck6_clE,11862
324
324
  geospacelab/toolbox/utilities/numpymath.py,sha256=xr-u9vsN5UMZ6pjomJ2O3A1n00Eg3yH5fN4lcY7rR_Q,3810
325
325
  geospacelab/toolbox/utilities/pybasic.py,sha256=-wLWoQMTroJ49nn8H_-hsFxDSiHXMiea86U6u0W8_cM,3310
326
326
  geospacelab/toolbox/utilities/pyclass.py,sha256=DnnzLH1ovlxArtqCpywZUfDoNzYi7HmMW2s17Xd30LI,2813
@@ -341,7 +341,7 @@ geospacelab/visualization/mpl/axis_ticks.py,sha256=vkS7eqSop5MNsxZ8l3EqdJEW7obF7
341
341
  geospacelab/visualization/mpl/colormaps.py,sha256=o4NfZPZK29Lefc4Jw-9OAN5VveqLuEEHKbP3JjUFSFI,17685
342
342
  geospacelab/visualization/mpl/dashboards.py,sha256=jk8W_j1SzCfUUYeTm5e7uA3xjlXpUIINdJPmBc53t-E,17232
343
343
  geospacelab/visualization/mpl/figure.py,sha256=stHgAG_qH-b87-rIXBfFnG9p3cyD2oDnx3MA6kDgX3A,3335
344
- geospacelab/visualization/mpl/panels.py,sha256=3vAIjP0iE08Xa7fxmwbxu0vO4sokKGZryypzcXo1BUs,35151
344
+ geospacelab/visualization/mpl/panels.py,sha256=uYC18Nxk_WjAJmv827D89znY9sqSSsDRAE23wG8c6xc,35817
345
345
  geospacelab/visualization/mpl/ts_viewer.py,sha256=4sOwXeWkdn5Z0BA6c-zxj4dAYxHP9tbuFwsbuJz4_ag,67416
346
346
  geospacelab/visualization/mpl/geomap/__base__.py,sha256=v3lVV5NVQMi0csNxq1ioORyizULqGN92M0DrlGjjBRQ,2940
347
347
  geospacelab/visualization/mpl/geomap/__init__.py,sha256=lsCyNIg5d5ZiMyRvE1zIuCnIhL47x8aYbOKZUX5E8fE,327
@@ -371,7 +371,7 @@ geospacelab/wrapper/geopack/geopack/t89.py,sha256=zDVNPrmtK1NnNHgohQEPqOOJDsm2Z-
371
371
  geospacelab/wrapper/geopack/geopack/t96.py,sha256=ktcoo1R7Z3NtkWHENuseu48ub4-JfQGqFV0ZOtd0zH8,65292
372
372
  geospacelab/wrapper/geopack/geopack/test_geopack1.md,sha256=dMUY0O1BgZsKpmJ6BLSQ80B6p6DZcB7OceFeyPOlFK0,15324
373
373
  geospacelab/wrapper/geopack/geopack/test_geopack1.py,sha256=qjLz6O3BAk3H58IpmxXyftwZTkh3vPGp49C-al4hjf0,6669
374
- geospacelab-0.10.0.dist-info/licenses/LICENSE,sha256=2yRlwLt4o5Z6OZAGcyvBj-zfFX1Uw7E6CzqODg7khqs,1515
374
+ geospacelab-0.10.2.dist-info/licenses/LICENSE,sha256=2yRlwLt4o5Z6OZAGcyvBj-zfFX1Uw7E6CzqODg7khqs,1515
375
375
  test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
376
376
  test/test_ampere.py,sha256=0-HZURubpv1mBK3bJ_qTqx39L1jezgRoU5neXMPYgZQ,2968
377
377
  test/test_dmsp_s1.py,sha256=5m_7mjdDGja8ovshNPV3LKW_6q6mIwT9XKqoyRiH79A,3588
@@ -381,7 +381,7 @@ test/test_omni.py,sha256=Zk1LZozPiY5V0aSRmK6GTQuB01hHn_j2j3Brm6Ea_po,1632
381
381
  test/test_superdarn.py,sha256=uP55muvXryPzNGHinWkiGv2PxvRs4f9M9h1WIBEBW7k,2846
382
382
  test/test_swarm.py,sha256=PDDE9nUshhQpXZbV_ZwcsjbMhI73fRaojTZv9rtRzZE,15568
383
383
  test/test_swarm_new.py,sha256=mzhMAx-M9W3Ue5noTyfBx4c3Vtc3b_ZUEvGgL9v8UE4,853
384
- geospacelab-0.10.0.dist-info/METADATA,sha256=HylyGl0glST5fjah47v0EQxqqmga1iI8iM2JKZO0DvQ,24337
385
- geospacelab-0.10.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
386
- geospacelab-0.10.0.dist-info/top_level.txt,sha256=98eDwrSNgyQFAtSA06QMP71gw9BzgIj0uvkTudpGly4,12
387
- geospacelab-0.10.0.dist-info/RECORD,,
384
+ geospacelab-0.10.2.dist-info/METADATA,sha256=qZZNzZ0LIB9gD7DVcJA0gbis5euI8GLsseAEGSgFl6I,24351
385
+ geospacelab-0.10.2.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
386
+ geospacelab-0.10.2.dist-info/top_level.txt,sha256=98eDwrSNgyQFAtSA06QMP71gw9BzgIj0uvkTudpGly4,12
387
+ geospacelab-0.10.2.dist-info/RECORD,,