oafuncs 0.0.63__py2.py3-none-any.whl → 0.0.64__py2.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.
- oafuncs/oa_down/hycom_3hourly.py +431 -41
- oafuncs/oa_down/hycom_3hourly_wholeday.py +1173 -0
- {oafuncs-0.0.63.dist-info → oafuncs-0.0.64.dist-info}/METADATA +1 -1
- {oafuncs-0.0.63.dist-info → oafuncs-0.0.64.dist-info}/RECORD +7 -6
- {oafuncs-0.0.63.dist-info → oafuncs-0.0.64.dist-info}/LICENSE.txt +0 -0
- {oafuncs-0.0.63.dist-info → oafuncs-0.0.64.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.63.dist-info → oafuncs-0.0.64.dist-info}/top_level.txt +0 -0
oafuncs/oa_down/hycom_3hourly.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-11-01 10:31:09
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-11-
|
7
|
+
LastEditTime: 2024-11-29 19:00:47
|
8
8
|
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\hycom_3hourly.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
@@ -29,7 +29,7 @@ from rich.progress import Progress
|
|
29
29
|
|
30
30
|
warnings.filterwarnings("ignore", category=RuntimeWarning, message="Engine '.*' loading failed:.*")
|
31
31
|
|
32
|
-
__all__ = ['draw_time_range', 'download', 'how_to_use', 'get_time_list']
|
32
|
+
__all__ = ['draw_time_range', 'download', 'how_to_use', 'get_time_list', 'get_hour_list', 'get_day_list']
|
33
33
|
|
34
34
|
# time resolution
|
35
35
|
data_info = {'yearly': {}, 'monthly': {}, 'daily': {}, 'hourly': {}}
|
@@ -152,6 +152,12 @@ url_930_y = {
|
|
152
152
|
}
|
153
153
|
data_info['hourly']['dataset']['GLBy0.08']['version']['93.0']['url'] = url_930_y
|
154
154
|
|
155
|
+
var_group = {
|
156
|
+
'uv3z': ['u', 'v', 'u_b', 'v_b'],
|
157
|
+
'ts3z': ['temp', 'salt', 'temp_b', 'salt_b'],
|
158
|
+
'ssh': ['ssh'],
|
159
|
+
}
|
160
|
+
|
155
161
|
|
156
162
|
def draw_time_range(pic_save_folder=None):
|
157
163
|
if pic_save_folder is not None:
|
@@ -248,6 +254,44 @@ def get_time_list(time_s, time_e, delta_hour):
|
|
248
254
|
return dt_list
|
249
255
|
|
250
256
|
|
257
|
+
def get_hour_list(time_s, time_e, delta_hour):
|
258
|
+
'''
|
259
|
+
Description: get a list of time strings from time_s to time_e with delta_hour
|
260
|
+
Args:
|
261
|
+
time_s: start time string, e.g. '2023080203'
|
262
|
+
time_e: end time string, e.g. '2023080303'
|
263
|
+
delta_hour: interval of hours
|
264
|
+
Returns:
|
265
|
+
dt_list: a list of time strings
|
266
|
+
'''
|
267
|
+
dt = datetime.datetime.strptime(time_s, '%Y%m%d%H')
|
268
|
+
dt_list = []
|
269
|
+
while dt.strftime('%Y%m%d%H') <= time_e:
|
270
|
+
dt_list.append(dt.strftime('%Y%m%d%H'))
|
271
|
+
dt = dt + datetime.timedelta(hours=delta_hour)
|
272
|
+
return dt_list
|
273
|
+
|
274
|
+
|
275
|
+
def get_day_list(time_s, time_e, delta_day):
|
276
|
+
'''
|
277
|
+
Description: get a list of time strings from time_s to time_e with delta_hour
|
278
|
+
Args:
|
279
|
+
time_s: start time string, e.g. '20230802'
|
280
|
+
time_e: end time string, e.g. '20230803'
|
281
|
+
delta_hour: interval of hours
|
282
|
+
Returns:
|
283
|
+
dt_list: a list of time strings
|
284
|
+
'''
|
285
|
+
time_s = time_s[:8]
|
286
|
+
time_e = time_e[:8]
|
287
|
+
dt = datetime.datetime.strptime(time_s, '%Y%m%d')
|
288
|
+
dt_list = []
|
289
|
+
while dt.strftime('%Y%m%d') <= time_e:
|
290
|
+
dt_list.append(dt.strftime('%Y%m%d'))
|
291
|
+
dt = dt + datetime.timedelta(days=delta_day)
|
292
|
+
return dt_list
|
293
|
+
|
294
|
+
|
251
295
|
def get_nearest_level_index(depth):
|
252
296
|
level_depth = [0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 125.0, 150.0, 200.0, 250.0, 300.0, 350.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 1250.0, 1500.0, 2000.0, 2500.0, 3000.0, 4000.0, 5000]
|
253
297
|
return min(range(len(level_depth)), key=lambda i: abs(level_depth[i]-depth))
|
@@ -345,7 +389,7 @@ def get_query_dict_full_depth(var, lon_min, lon_max, lat_min, lat_max, time_str_
|
|
345
389
|
return query_dict
|
346
390
|
|
347
391
|
|
348
|
-
def
|
392
|
+
def ymdh_in_which_dataset_and_version(time_ymdh):
|
349
393
|
time_ymdh = int(time_ymdh)
|
350
394
|
d_list = []
|
351
395
|
v_list = []
|
@@ -372,6 +416,33 @@ def ymd_in_which_dataset_and_version(time_ymdh):
|
|
372
416
|
raise ValueError(f'[bold red]{time_ymdh} is not in any dataset and version')
|
373
417
|
|
374
418
|
|
419
|
+
def ymd_in_which_dataset_and_version(time_ymd):
|
420
|
+
time_ymd = int(str(time_ymd)[:8])
|
421
|
+
d_list = []
|
422
|
+
v_list = []
|
423
|
+
trange_list = []
|
424
|
+
have_data = False
|
425
|
+
for dataset_name in data_info['hourly']['dataset'].keys():
|
426
|
+
for version_name in data_info['hourly']['dataset'][dataset_name]['version'].keys():
|
427
|
+
time_s, time_e = list(data_info['hourly']['dataset'][dataset_name]['version'][version_name]['time_range'].values())
|
428
|
+
time_s, time_e = str(time_s), str(time_e)
|
429
|
+
if len(time_s) == 8:
|
430
|
+
time_s = time_s + '00'
|
431
|
+
if len(time_e) == 8:
|
432
|
+
time_e = time_e + '21'
|
433
|
+
if time_ymd*100 >= int(time_s) and time_ymd*100+21 <= int(time_e):
|
434
|
+
d_list.append(dataset_name)
|
435
|
+
v_list.append(version_name)
|
436
|
+
trange_list.append(f'{time_s}-{time_e}')
|
437
|
+
have_data = True
|
438
|
+
print(f'[bold red]{time_ymd} is in the following dataset and version:')
|
439
|
+
if have_data:
|
440
|
+
for d, v, trange in zip(d_list, v_list, trange_list):
|
441
|
+
print(f'[bold blue]{d} {v} {trange}')
|
442
|
+
else:
|
443
|
+
raise ValueError(f'[bold red]{time_ymd} is not in any dataset and version')
|
444
|
+
|
445
|
+
|
375
446
|
def direct_choose_dataset_and_version(time_ymdh):
|
376
447
|
time_ymdh = int(time_ymdh)
|
377
448
|
for dataset_name in data_info['hourly']['dataset'].keys():
|
@@ -387,6 +458,21 @@ def direct_choose_dataset_and_version(time_ymdh):
|
|
387
458
|
return dataset_name, version_name
|
388
459
|
|
389
460
|
|
461
|
+
def direct_choose_dataset_and_version_whole_day(time_ymd):
|
462
|
+
time_ymd = int(str(time_ymd)[:8])
|
463
|
+
for dataset_name in data_info['hourly']['dataset'].keys():
|
464
|
+
for version_name in data_info['hourly']['dataset'][dataset_name]['version'].keys():
|
465
|
+
[time_s, time_e] = list(data_info['hourly']['dataset'][dataset_name]['version'][version_name]['time_range'].values())
|
466
|
+
time_s, time_e = str(time_s), str(time_e)
|
467
|
+
if len(time_s) == 8:
|
468
|
+
time_s = time_s + '00'
|
469
|
+
if len(time_e) == 8:
|
470
|
+
time_e = time_e + '21'
|
471
|
+
if time_ymd*100 >= int(time_s) and time_ymd*100+21 <= int(time_e):
|
472
|
+
print(f'[bold purple]dataset: {dataset_name}, version: {version_name} is chosen')
|
473
|
+
return dataset_name, version_name
|
474
|
+
|
475
|
+
|
390
476
|
def get_base_url(dataset_name, version_name, var, year_str):
|
391
477
|
url_dict = data_info['hourly']['dataset'][dataset_name]['version'][version_name]['url']
|
392
478
|
classification_method = data_info['hourly']['dataset'][dataset_name]['version'][version_name]['classification']
|
@@ -395,29 +481,28 @@ def get_base_url(dataset_name, version_name, var, year_str):
|
|
395
481
|
elif classification_method == 'same_path':
|
396
482
|
base_url = url_dict
|
397
483
|
elif classification_method == 'var_different':
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
else:
|
484
|
+
base_url = None
|
485
|
+
for key, value in var_group.items():
|
486
|
+
if var in value:
|
487
|
+
base_url = url_dict[key]
|
488
|
+
break
|
489
|
+
if base_url is None:
|
405
490
|
print('Please ensure the var is in [u,v,temp,salt,ssh,u_b,v_b,temp_b,salt_b]')
|
406
491
|
elif classification_method == 'var_year_different':
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
else:
|
492
|
+
base_url = None
|
493
|
+
for key, value in var_group.items():
|
494
|
+
if var in value:
|
495
|
+
base_url = url_dict[key][str(year_str)]
|
496
|
+
break
|
497
|
+
if base_url is None:
|
414
498
|
print('Please ensure the var is in [u,v,temp,salt,ssh,u_b,v_b,temp_b,salt_b]')
|
415
499
|
return base_url
|
416
500
|
|
417
501
|
|
418
502
|
def get_submit_url(dataset_name, version_name, var, year_str, query_dict):
|
419
503
|
base_url = get_base_url(dataset_name, version_name, var, year_str)
|
420
|
-
query_dict['var']
|
504
|
+
if isinstance(query_dict['var'], str):
|
505
|
+
query_dict['var'] = [query_dict['var']]
|
421
506
|
target_url = base_url + '&'.join(f"var={var}" for var in query_dict['var']) + '&' + '&'.join(f"{key}={value}" for key, value in query_dict.items() if key != 'var')
|
422
507
|
return target_url
|
423
508
|
|
@@ -581,7 +666,7 @@ def check_hour_is_valid(ymdh_str):
|
|
581
666
|
return False
|
582
667
|
|
583
668
|
|
584
|
-
def
|
669
|
+
def check_dataset_version_single_time(dataset_name, version_name, download_time):
|
585
670
|
download_time = str(download_time)
|
586
671
|
if not check_hour_is_valid(download_time):
|
587
672
|
print('Please ensure the hour is 00, 03, 06, 09, 12, 15, 18, 21')
|
@@ -589,21 +674,25 @@ def direct_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, dow
|
|
589
674
|
if dataset_name is None and version_name is None:
|
590
675
|
print('The dataset_name and version_name are None, so the dataset and version will be chosen according to the download_time.\nIf there is more than one dataset and version in the time range, the first one will be chosen.')
|
591
676
|
print('If you wanna choose the dataset and version by yourself, please set the dataset_name and version_name together.')
|
592
|
-
|
677
|
+
ymdh_in_which_dataset_and_version(download_time)
|
593
678
|
dataset_name, version_name = direct_choose_dataset_and_version(download_time)
|
594
679
|
elif dataset_name is None and version_name is not None:
|
595
680
|
print('Please ensure the dataset_name is not None')
|
596
681
|
print('If you do not add the dataset_name, both the dataset and version will be chosen according to the download_time.')
|
597
|
-
|
682
|
+
ymdh_in_which_dataset_and_version(download_time)
|
598
683
|
dataset_name, version_name = direct_choose_dataset_and_version(download_time)
|
599
684
|
elif dataset_name is not None and version_name is None:
|
600
685
|
print('Please ensure the version_name is not None')
|
601
686
|
print('If you do not add the version_name, both the dataset and version will be chosen according to the download_time.')
|
602
|
-
|
687
|
+
ymdh_in_which_dataset_and_version(download_time)
|
603
688
|
dataset_name, version_name = direct_choose_dataset_and_version(download_time)
|
604
689
|
else:
|
605
690
|
print('The dataset_name and version_name are both set by yourself.')
|
606
691
|
|
692
|
+
return dataset_name, version_name
|
693
|
+
|
694
|
+
|
695
|
+
def get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time):
|
607
696
|
year_str = str(download_time)[:4]
|
608
697
|
if depth is not None and level_num is not None:
|
609
698
|
print('Please ensure the depth or level_num is None')
|
@@ -618,12 +707,128 @@ def direct_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, dow
|
|
618
707
|
query_dict = get_query_dict_full_level(var, lon_min, lon_max, lat_min, lat_max, download_time)
|
619
708
|
submit_url = get_submit_url(
|
620
709
|
dataset_name, version_name, var, year_str, query_dict)
|
621
|
-
|
710
|
+
return submit_url
|
711
|
+
|
712
|
+
|
713
|
+
def direct_download_single_time(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, download_time='2024083100', depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None, check=False):
|
714
|
+
download_time = str(download_time)
|
715
|
+
dataset_name, version_name = check_dataset_version_single_time(dataset_name, version_name, download_time)
|
716
|
+
|
622
717
|
if store_path is None:
|
623
718
|
store_path = str(Path.cwd())
|
624
719
|
else:
|
625
720
|
os.makedirs(str(store_path), exist_ok=True)
|
626
|
-
|
721
|
+
|
722
|
+
if isinstance(var, str):
|
723
|
+
var = [var]
|
724
|
+
|
725
|
+
if isinstance(var, list):
|
726
|
+
if len(var) == 1:
|
727
|
+
var = var[0]
|
728
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
729
|
+
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
730
|
+
dlownload_file(submit_url, store_path, file_name, check)
|
731
|
+
else:
|
732
|
+
varlist = [_ for _ in var]
|
733
|
+
for key, value in var_group.items():
|
734
|
+
current_group = []
|
735
|
+
for v in varlist:
|
736
|
+
if v in value:
|
737
|
+
current_group.append(v)
|
738
|
+
if len(current_group) == 0:
|
739
|
+
continue
|
740
|
+
|
741
|
+
var = current_group[0]
|
742
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
743
|
+
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
744
|
+
old_str = f'var={variable_info[var]["var_name"]}'
|
745
|
+
new_str = f'var={variable_info[var]["var_name"]}'
|
746
|
+
if len(current_group) > 1:
|
747
|
+
for v in current_group[1:]:
|
748
|
+
new_str = f'{new_str}&var={variable_info[v]["var_name"]}'
|
749
|
+
submit_url = submit_url.replace(old_str, new_str)
|
750
|
+
# file_name = f'HYCOM_{'-'.join([variable_info[v]["var_name"] for v in current_group])}_{download_time}.nc'
|
751
|
+
file_name = f'HYCOM_{key}_{download_time}.nc'
|
752
|
+
dlownload_file(submit_url, store_path, file_name, check)
|
753
|
+
|
754
|
+
|
755
|
+
def check_dataset_version_whold_day(dataset_name, version_name, download_time):
|
756
|
+
download_time = str(download_time)
|
757
|
+
if dataset_name is None and version_name is None:
|
758
|
+
print('The dataset_name and version_name are None, so the dataset and version will be chosen according to the download_time.\nIf there is more than one dataset and version in the time range, the first one will be chosen.')
|
759
|
+
print('If you wanna choose the dataset and version by yourself, please set the dataset_name and version_name together.')
|
760
|
+
ymd_in_which_dataset_and_version(download_time)
|
761
|
+
dataset_name, version_name = direct_choose_dataset_and_version_whole_day(download_time)
|
762
|
+
elif dataset_name is None and version_name is not None:
|
763
|
+
print('Please ensure the dataset_name is not None')
|
764
|
+
print('If you do not add the dataset_name, both the dataset and version will be chosen according to the download_time.')
|
765
|
+
ymd_in_which_dataset_and_version(download_time)
|
766
|
+
dataset_name, version_name = direct_choose_dataset_and_version_whole_day(download_time)
|
767
|
+
elif dataset_name is not None and version_name is None:
|
768
|
+
print('Please ensure the version_name is not None')
|
769
|
+
print('If you do not add the version_name, both the dataset and version will be chosen according to the download_time.')
|
770
|
+
ymd_in_which_dataset_and_version(download_time)
|
771
|
+
dataset_name, version_name = direct_choose_dataset_and_version_whole_day(download_time)
|
772
|
+
else:
|
773
|
+
print('The dataset_name and version_name are both set by yourself.')
|
774
|
+
|
775
|
+
return dataset_name, version_name
|
776
|
+
|
777
|
+
|
778
|
+
def direct_download_whole_day(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, download_time='20240831', depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None, check=False):
|
779
|
+
download_time = str(download_time)[:8]+'00'
|
780
|
+
dataset_name, version_name = check_dataset_version_whold_day(dataset_name, version_name, download_time[:8])
|
781
|
+
|
782
|
+
if store_path is None:
|
783
|
+
store_path = str(Path.cwd())
|
784
|
+
else:
|
785
|
+
os.makedirs(str(store_path), exist_ok=True)
|
786
|
+
|
787
|
+
if isinstance(var, str):
|
788
|
+
var = [var]
|
789
|
+
|
790
|
+
if isinstance(var, list):
|
791
|
+
if len(var) == 1:
|
792
|
+
var = var[0]
|
793
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
794
|
+
|
795
|
+
# https://ncss.hycom.org/thredds/ncss/GLBu0.08/expt_93.0/ts3z?var=salinity&disableLLSubset=on&disableProjSubset=on&horizStride=1&time=2018-12-09T09%3A00%3A00Z&vertCoord=&accept=netcdf4
|
796
|
+
# https://ncss.hycom.org/thredds/ncss/GLBu0.08/expt_93.0/ts3z?var=salinity&disableLLSubset=on&disableProjSubset=on&horizStride=1&time_start=2018-09-19T12%3A00%3A00Z&time_end=2018-12-09T09%3A00%3A00Z&timeStride=1&vertCoord=&accept=netcdf4
|
797
|
+
# 将time=2018-12-09T09%3A00%3A00Z替换为time_start=2018-09-19T12%3A00%3A00Z&time_end=2018-12-09T09%3A00%3A00Z&timeStride=1
|
798
|
+
daytime_s = transform_time(str(download_time)[:8]+'00')
|
799
|
+
daytime_e = transform_time(str(download_time)[:8]+'21')
|
800
|
+
submit_url = submit_url.replace(
|
801
|
+
f'time={daytime_s}', f'time_start={daytime_s}&time_end={daytime_e}&timeStride=1')
|
802
|
+
|
803
|
+
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
804
|
+
|
805
|
+
dlownload_file(submit_url, store_path, file_name, check)
|
806
|
+
else:
|
807
|
+
varlist = [_ for _ in var]
|
808
|
+
for key, value in var_group.items():
|
809
|
+
current_group = []
|
810
|
+
for v in varlist:
|
811
|
+
if v in value:
|
812
|
+
current_group.append(v)
|
813
|
+
if len(current_group) == 0:
|
814
|
+
continue
|
815
|
+
|
816
|
+
var = current_group[0]
|
817
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
818
|
+
daytime_s = transform_time(str(download_time)[:8]+'00')
|
819
|
+
daytime_e = transform_time(str(download_time)[:8]+'21')
|
820
|
+
submit_url = submit_url.replace(
|
821
|
+
f'time={daytime_s}', f'time_start={daytime_s}&time_end={daytime_e}&timeStride=1')
|
822
|
+
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
823
|
+
old_str = f'var={variable_info[var]["var_name"]}'
|
824
|
+
new_str = f'var={variable_info[var]["var_name"]}'
|
825
|
+
if len(current_group) > 1:
|
826
|
+
for v in current_group[1:]:
|
827
|
+
new_str = f'{new_str}&var={variable_info[v]["var_name"]}'
|
828
|
+
submit_url = submit_url.replace(old_str, new_str)
|
829
|
+
# file_name = f'HYCOM_{'-'.join([variable_info[v]["var_name"] for v in current_group])}_{download_time}.nc'
|
830
|
+
file_name = f'HYCOM_{key}_{download_time}.nc'
|
831
|
+
dlownload_file(submit_url, store_path, file_name, check)
|
627
832
|
|
628
833
|
|
629
834
|
def convert_full_name_to_short_name(full_name):
|
@@ -646,10 +851,151 @@ def download_task(var, time_str, lon_min, lon_max, lat_min, lat_max, depth, leve
|
|
646
851
|
这样,每个任务都是独立的,有自己的参数和数据,不会与其他任务共享或修改任何数据。
|
647
852
|
因此,即使多个任务同时执行,也不会出现数据交互错乱的问题。
|
648
853
|
'''
|
649
|
-
|
854
|
+
if len(time_str) == 8:
|
855
|
+
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
856
|
+
else:
|
857
|
+
direct_download_single_time(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
858
|
+
|
859
|
+
|
860
|
+
def download_single_hour(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level=None, store_path=None, dataset_name=None, version_name=None, num_workers=None, check=False):
|
861
|
+
'''
|
862
|
+
Description:
|
863
|
+
Download the data of single time or a series of time
|
864
|
+
|
865
|
+
Parameters:
|
866
|
+
var: str, the variable name, such as 'u', 'v', 'temp', 'salt', 'ssh', 'u_b', 'v_b', 'temp_b', 'salt_b' or 'water_u', 'water_v', 'water_temp', 'salinity', 'surf_el', 'water_u_bottom', 'water_v_bottom', 'water_temp_bottom', 'salinity_bottom'
|
867
|
+
time_s: str, the start time, such as '2024110100' or '20241101', if add hour, the hour should be 00, 03, 06, 09, 12, 15, 18, 21
|
868
|
+
time_e: str, the end time, such as '2024110221' or '20241102', if add hour, the hour should be 00, 03, 06, 09, 12, 15, 18, 21
|
869
|
+
lon_min: float, the minimum longitude, default is 0
|
870
|
+
lon_max: float, the maximum longitude, default is 359.92
|
871
|
+
lat_min: float, the minimum latitude, default is -80
|
872
|
+
lat_max: float, the maximum latitude, default is 90
|
873
|
+
depth: float, the depth, default is None
|
874
|
+
level: int, the level number, default is None
|
875
|
+
store_path: str, the path to store the data, default is None
|
876
|
+
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08'
|
877
|
+
version_name: str, the version name, default is None, example: '53.X', '56.3'
|
878
|
+
num_workers: int, the number of workers, default is None
|
879
|
+
|
880
|
+
Returns:
|
881
|
+
None
|
882
|
+
'''
|
883
|
+
if isinstance(var, list):
|
884
|
+
if len(var) == 1:
|
885
|
+
var = convert_full_name_to_short_name(var[0])
|
886
|
+
else:
|
887
|
+
var = [convert_full_name_to_short_name(v) for v in var]
|
888
|
+
elif isinstance(var, str):
|
889
|
+
var = convert_full_name_to_short_name(var)
|
890
|
+
else:
|
891
|
+
raise ValueError('The var is invalid')
|
892
|
+
if var is False:
|
893
|
+
raise ValueError('The var is invalid')
|
894
|
+
if lon_min < 0 or lon_min > 359.92 or lon_max < 0 or lon_max > 359.92 or lat_min < -80 or lat_min > 90 or lat_max < -80 or lat_max > 90:
|
895
|
+
print('Please ensure the lon_min, lon_max, lat_min, lat_max are in the range')
|
896
|
+
print('The range of lon_min, lon_max is 0~359.92')
|
897
|
+
print('The range of lat_min, lat_max is -80~90')
|
898
|
+
raise ValueError('The lon or lat is invalid')
|
899
|
+
ymdh_time_s = str(time_s)
|
900
|
+
if len(ymdh_time_s) == 8:
|
901
|
+
ymdh_time_s += '00'
|
902
|
+
ymdh_time_e = str(time_e)
|
903
|
+
if len(ymdh_time_e) == 8:
|
904
|
+
ymdh_time_e += '21'
|
905
|
+
if ymdh_time_s == ymdh_time_e:
|
906
|
+
direct_download_single_time(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, depth, level, store_path, dataset_name, version_name)
|
907
|
+
elif int(ymdh_time_s) < int(ymdh_time_e):
|
908
|
+
print('Downloading a series of files...')
|
909
|
+
time_list = get_hour_list(ymdh_time_s, ymdh_time_e, 3)
|
910
|
+
with Progress() as progress:
|
911
|
+
task = progress.add_task("[cyan]Downloading...", total=len(time_list))
|
912
|
+
if num_workers is None or num_workers <= 1:
|
913
|
+
# 串行方式
|
914
|
+
for time_str in time_list:
|
915
|
+
direct_download_single_time(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
916
|
+
progress.update(task, advance=1)
|
917
|
+
else:
|
918
|
+
# 并行方式
|
919
|
+
if num_workers > 10:
|
920
|
+
print('The number of workers is too large!')
|
921
|
+
print('In order to avoid the server being blocked, the number of workers is set to 10')
|
922
|
+
num_workers = 10
|
923
|
+
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
924
|
+
futures = [executor.submit(download_task, var, time_str, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for time_str in time_list]
|
925
|
+
for future in futures:
|
926
|
+
future.add_done_callback(lambda _: progress.update(task, advance=1))
|
927
|
+
else:
|
928
|
+
print('Please ensure the time_s is less than the time_e')
|
650
929
|
|
651
930
|
|
652
|
-
def
|
931
|
+
def download_whole_day(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level=None, store_path=None, dataset_name=None, version_name=None, num_workers=None, check=False):
|
932
|
+
'''
|
933
|
+
Description:
|
934
|
+
Download the data of single time or a series of time
|
935
|
+
|
936
|
+
Parameters:
|
937
|
+
var: str, the variable name, such as 'u', 'v', 'temp', 'salt', 'ssh', 'u_b', 'v_b', 'temp_b', 'salt_b' or 'water_u', 'water_v', 'water_temp', 'salinity', 'surf_el', 'water_u_bottom', 'water_v_bottom', 'water_temp_bottom', 'salinity_bottom'
|
938
|
+
time_s: str, the start time, such as '20241101', without hour
|
939
|
+
time_e: str, the end time, such as '20241102', without hour
|
940
|
+
lon_min: float, the minimum longitude, default is 0
|
941
|
+
lon_max: float, the maximum longitude, default is 359.92
|
942
|
+
lat_min: float, the minimum latitude, default is -80
|
943
|
+
lat_max: float, the maximum latitude, default is 90
|
944
|
+
depth: float, the depth, default is None
|
945
|
+
level: int, the level number, default is None
|
946
|
+
store_path: str, the path to store the data, default is None
|
947
|
+
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08'
|
948
|
+
version_name: str, the version name, default is None, example: '53.X', '56.3'
|
949
|
+
num_workers: int, the number of workers, default is None
|
950
|
+
|
951
|
+
Returns:
|
952
|
+
None
|
953
|
+
'''
|
954
|
+
if isinstance(var, list):
|
955
|
+
if len(var) == 1:
|
956
|
+
var = convert_full_name_to_short_name(var[0])
|
957
|
+
else:
|
958
|
+
var = [convert_full_name_to_short_name(v) for v in var]
|
959
|
+
elif isinstance(var, str):
|
960
|
+
var = convert_full_name_to_short_name(var)
|
961
|
+
else:
|
962
|
+
raise ValueError('The var is invalid')
|
963
|
+
if var is False:
|
964
|
+
raise ValueError('The var is invalid')
|
965
|
+
if lon_min < 0 or lon_min > 359.92 or lon_max < 0 or lon_max > 359.92 or lat_min < -80 or lat_min > 90 or lat_max < -80 or lat_max > 90:
|
966
|
+
print('Please ensure the lon_min, lon_max, lat_min, lat_max are in the range')
|
967
|
+
print('The range of lon_min, lon_max is 0~359.92')
|
968
|
+
print('The range of lat_min, lat_max is -80~90')
|
969
|
+
raise ValueError('The lon or lat is invalid')
|
970
|
+
time_s, time_e = str(time_s)[:8], str(time_e)[:8]
|
971
|
+
|
972
|
+
if time_s == time_e:
|
973
|
+
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_s, depth, level, store_path, dataset_name, version_name)
|
974
|
+
elif int(time_s) < int(time_e):
|
975
|
+
print('Downloading a series of files...')
|
976
|
+
time_list = get_day_list(time_s, time_e, 1)
|
977
|
+
with Progress() as progress:
|
978
|
+
task = progress.add_task("[cyan]Downloading...", total=len(time_list))
|
979
|
+
if num_workers is None or num_workers <= 1:
|
980
|
+
# 串行方式
|
981
|
+
for time_str in time_list:
|
982
|
+
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
983
|
+
progress.update(task, advance=1)
|
984
|
+
else:
|
985
|
+
# 并行方式
|
986
|
+
if num_workers > 10:
|
987
|
+
print('The number of workers is too large!')
|
988
|
+
print('In order to avoid the server being blocked, the number of workers is set to 10')
|
989
|
+
num_workers = 10
|
990
|
+
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
991
|
+
futures = [executor.submit(download_task, var, time_str, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for time_str in time_list]
|
992
|
+
for future in futures:
|
993
|
+
future.add_done_callback(lambda _: progress.update(task, advance=1))
|
994
|
+
else:
|
995
|
+
print('Please ensure the time_s is less than the time_e')
|
996
|
+
|
997
|
+
|
998
|
+
def download_his1(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level=None, store_path=None, dataset_name=None, version_name=None, num_workers=None, check=False):
|
653
999
|
'''
|
654
1000
|
Description:
|
655
1001
|
Download the data of single time or a series of time
|
@@ -672,6 +1018,8 @@ def download(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_ma
|
|
672
1018
|
Returns:
|
673
1019
|
None
|
674
1020
|
'''
|
1021
|
+
if isinstance(var, list):
|
1022
|
+
var = var[0]
|
675
1023
|
var = convert_full_name_to_short_name(var)
|
676
1024
|
if var is False:
|
677
1025
|
raise ValueError('The var is invalid')
|
@@ -687,16 +1035,16 @@ def download(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_ma
|
|
687
1035
|
if len(ymdh_time_e) == 8:
|
688
1036
|
ymdh_time_e += '21'
|
689
1037
|
if ymdh_time_s == ymdh_time_e:
|
690
|
-
|
1038
|
+
direct_download_single_time(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, depth, level, store_path, dataset_name, version_name)
|
691
1039
|
elif int(ymdh_time_s) < int(ymdh_time_e):
|
692
1040
|
print('Downloading a series of files...')
|
693
|
-
time_list =
|
1041
|
+
time_list = get_hour_list(ymdh_time_s, ymdh_time_e, 3)
|
694
1042
|
with Progress() as progress:
|
695
1043
|
task = progress.add_task("[cyan]Downloading...", total=len(time_list))
|
696
1044
|
if num_workers is None or num_workers <= 1:
|
697
1045
|
# 串行方式
|
698
1046
|
for time_str in time_list:
|
699
|
-
|
1047
|
+
direct_download_single_time(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
700
1048
|
progress.update(task, advance=1)
|
701
1049
|
else:
|
702
1050
|
# 并行方式
|
@@ -713,6 +1061,40 @@ def download(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_ma
|
|
713
1061
|
print('Please ensure the ymdh_time_s is less than the ymdh_time_e')
|
714
1062
|
|
715
1063
|
|
1064
|
+
def download(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level=None, store_path=None, dataset_name=None, version_name=None, num_workers=None, check=False, resolution='hour'):
|
1065
|
+
'''
|
1066
|
+
Description:
|
1067
|
+
Download the data of single time or a series of time
|
1068
|
+
|
1069
|
+
Parameters:
|
1070
|
+
var: str, the variable name, such as 'u', 'v', 'temp', 'salt', 'ssh', 'u_b', 'v_b', 'temp_b', 'salt_b' or 'water_u', 'water_v', 'water_temp', 'salinity', 'surf_el', 'water_u_bottom', 'water_v_bottom', 'water_temp_bottom', 'salinity_bottom'
|
1071
|
+
time_s: str, the start time, such as '2024110100' or '20241101', if add hour, the hour should be 00, 03, 06, 09, 12, 15, 18, 21
|
1072
|
+
time_e: str, the end time, such as '2024110221' or '20241102', if add hour, the hour should be 00, 03, 06, 09, 12, 15, 18, 21
|
1073
|
+
lon_min: float, the minimum longitude, default is 0
|
1074
|
+
lon_max: float, the maximum longitude, default is 359.92
|
1075
|
+
lat_min: float, the minimum latitude, default is -80
|
1076
|
+
lat_max: float, the maximum latitude, default is 90
|
1077
|
+
depth: float, the depth, default is None
|
1078
|
+
level: int, the level number, default is None
|
1079
|
+
store_path: str, the path to store the data, default is None
|
1080
|
+
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08'
|
1081
|
+
version_name: str, the version name, default is None, example: '53.X', '56.3'
|
1082
|
+
num_workers: int, the number of workers, default is None
|
1083
|
+
|
1084
|
+
Returns:
|
1085
|
+
None
|
1086
|
+
'''
|
1087
|
+
if resolution == 'hour':
|
1088
|
+
download_single_hour(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check)
|
1089
|
+
elif resolution == 'day':
|
1090
|
+
print('Currently can not download the data of whole day...')
|
1091
|
+
# download_whole_day(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check)
|
1092
|
+
download_single_hour(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check)
|
1093
|
+
else:
|
1094
|
+
print('Please ensure the resolution is in [hour, day]\n This will be set to hour')
|
1095
|
+
download_single_hour(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check)
|
1096
|
+
|
1097
|
+
|
716
1098
|
def how_to_use():
|
717
1099
|
print('''
|
718
1100
|
# 1. Choose the dataset and version according to the time:
|
@@ -763,33 +1145,36 @@ def how_to_use():
|
|
763
1145
|
|
764
1146
|
|
765
1147
|
if __name__ == '__main__':
|
766
|
-
time_s, time_e = '
|
1148
|
+
time_s, time_e = '2018010512', '2018010800'
|
767
1149
|
merge_name = '201801'
|
768
1150
|
root_path = r'I:\hycom_data_2018'
|
769
1151
|
location_dict = {'west': 115, 'east': 130, 'south': 33, 'north': 45}
|
770
1152
|
download_dict = {
|
771
1153
|
'water_u': {'simple_name': 'u', 'download': 1},
|
772
|
-
'water_v': {'simple_name': 'v', 'download':
|
773
|
-
'surf_el': {'simple_name': 'ssh', 'download':
|
774
|
-
'water_temp': {'simple_name': 'temp', 'download':
|
1154
|
+
'water_v': {'simple_name': 'v', 'download': 1},
|
1155
|
+
'surf_el': {'simple_name': 'ssh', 'download': 1},
|
1156
|
+
'water_temp': {'simple_name': 'temp', 'download': 1},
|
775
1157
|
'salinity': {'simple_name': 'salt', 'download': 1},
|
776
1158
|
}
|
777
1159
|
|
1160
|
+
var_list = []
|
1161
|
+
for var_name in download_dict.keys():
|
1162
|
+
if download_dict[var_name]['download'] == 1:
|
1163
|
+
var_list.append(download_dict[var_name]['simple_name'])
|
1164
|
+
|
778
1165
|
# set depth or level, only one can be True
|
779
1166
|
# if you wanna download all depth or level, set both False
|
780
1167
|
set_depth, depth = False, 0 # 0-4000 meters
|
781
1168
|
set_level, level = False, 1 # 1-40 levels
|
782
|
-
num_workers =
|
1169
|
+
num_workers = 1
|
783
1170
|
check = True
|
784
1171
|
|
785
1172
|
download_switch = True
|
786
1173
|
combine_switch = False
|
1174
|
+
|
1175
|
+
single_var = True
|
787
1176
|
|
788
|
-
def download_var(
|
789
|
-
var = download_dict[var_name]['simple_name']
|
790
|
-
if_download = download_dict[var_name]['download']
|
791
|
-
if if_download == 0:
|
792
|
-
return
|
1177
|
+
def download_var(var):
|
793
1178
|
if set_depth:
|
794
1179
|
download(var=var, time_s=time_s, time_e=time_e, store_path=Path(root_path)/var, lon_min=location_dict[
|
795
1180
|
'west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], depth=depth, num_workers=num_workers, check=check)
|
@@ -801,8 +1186,13 @@ if __name__ == '__main__':
|
|
801
1186
|
'west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], num_workers=num_workers, check=check)
|
802
1187
|
|
803
1188
|
if download_switch:
|
804
|
-
|
805
|
-
|
1189
|
+
if single_var:
|
1190
|
+
# single var
|
1191
|
+
for var_name in var_list:
|
1192
|
+
download_var(var_name)
|
1193
|
+
else:
|
1194
|
+
# multiple var
|
1195
|
+
download_var(var_list)
|
806
1196
|
|
807
1197
|
# draw_time_range(r'I:\Delete')
|
808
1198
|
|