oafuncs 0.0.69__py2.py3-none-any.whl → 0.0.71__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 +125 -213
- {oafuncs-0.0.69.dist-info → oafuncs-0.0.71.dist-info}/METADATA +1 -1
- {oafuncs-0.0.69.dist-info → oafuncs-0.0.71.dist-info}/RECORD +6 -6
- {oafuncs-0.0.69.dist-info → oafuncs-0.0.71.dist-info}/LICENSE.txt +0 -0
- {oafuncs-0.0.69.dist-info → oafuncs-0.0.71.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.69.dist-info → oafuncs-0.0.71.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-
|
7
|
+
LastEditTime: 2024-12-01 11:21:49
|
8
8
|
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\hycom_3hourly.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
@@ -268,7 +268,7 @@ def transform_time(time_str):
|
|
268
268
|
return time_new
|
269
269
|
|
270
270
|
|
271
|
-
def get_query_dict(var, lon_min, lon_max, lat_min, lat_max, time_str_ymdh, mode='single_depth', depth=None, level_num=None):
|
271
|
+
def get_query_dict(var, lon_min, lon_max, lat_min, lat_max, time_str_ymdh, time_str_end=None, mode='single_depth', depth=None, level_num=None):
|
272
272
|
query_dict = {
|
273
273
|
'var': variable_info[var]['var_name'],
|
274
274
|
'north': lat_max,
|
@@ -276,13 +276,23 @@ def get_query_dict(var, lon_min, lon_max, lat_min, lat_max, time_str_ymdh, mode=
|
|
276
276
|
'east': lon_max,
|
277
277
|
'south': lat_min,
|
278
278
|
'horizStride': 1,
|
279
|
-
'time':
|
279
|
+
'time': None,
|
280
|
+
'time_start': None,
|
281
|
+
'time_end': None,
|
282
|
+
'timeStride': None,
|
280
283
|
'vertCoord': None,
|
281
284
|
'vertStride': None,
|
282
285
|
'addLatLon': 'true',
|
283
286
|
'accept': 'netcdf4',
|
284
287
|
}
|
285
288
|
|
289
|
+
if time_str_end is not None:
|
290
|
+
query_dict['time_start'] = transform_time(time_str_ymdh)
|
291
|
+
query_dict['time_end'] = transform_time(time_str_end)
|
292
|
+
query_dict['timeStride'] = 1
|
293
|
+
else:
|
294
|
+
query_dict['time'] = transform_time(time_str_ymdh)
|
295
|
+
|
286
296
|
def get_nearest_level_index(depth):
|
287
297
|
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]
|
288
298
|
return min(range(len(level_depth)), key=lambda i: abs(level_depth[i]-depth))
|
@@ -419,6 +429,8 @@ def direct_choose_dataset_and_version(time_input, time_end=None):
|
|
419
429
|
# 处理开始和结束时间,确保它们是完整的 ymdh 格式
|
420
430
|
time_start, time_end = int(str(time_input)[:10]), int(str(time_end)[:10])
|
421
431
|
|
432
|
+
dataset_name_out, version_name_out = None, None
|
433
|
+
|
422
434
|
for dataset_name in data_info['hourly']['dataset'].keys():
|
423
435
|
for version_name in data_info['hourly']['dataset'][dataset_name]['version'].keys():
|
424
436
|
[time_s, time_e] = list(data_info['hourly']['dataset'][dataset_name]['version'][version_name]['time_range'].values())
|
@@ -431,11 +443,15 @@ def direct_choose_dataset_and_version(time_input, time_end=None):
|
|
431
443
|
|
432
444
|
# 检查时间是否在数据集版本的时间范围内
|
433
445
|
if time_start >= time_s and time_end <= time_e:
|
434
|
-
print(f'[bold purple]dataset: {dataset_name}, version: {version_name} is chosen')
|
435
|
-
return dataset_name, version_name
|
446
|
+
# print(f'[bold purple]dataset: {dataset_name}, version: {version_name} is chosen')
|
447
|
+
# return dataset_name, version_name
|
448
|
+
dataset_name_out, version_name_out = dataset_name, version_name
|
436
449
|
|
437
|
-
|
438
|
-
|
450
|
+
if dataset_name_out is not None and version_name_out is not None:
|
451
|
+
print(f'[bold purple]dataset: {dataset_name_out}, version: {version_name_out} is chosen')
|
452
|
+
|
453
|
+
# 如果没有找到匹配的数据集和版本,会返回 None
|
454
|
+
return dataset_name_out, version_name_out
|
439
455
|
|
440
456
|
|
441
457
|
def get_base_url(dataset_name, version_name, var, year_str):
|
@@ -592,6 +608,7 @@ def dlownload_file(target_url, store_path, file_name, check=False):
|
|
592
608
|
clear_existing_file(filename)
|
593
609
|
# print(f'Download_start_time: {datetime.datetime.now()}')
|
594
610
|
download_time_s = datetime.datetime.now()
|
611
|
+
order_list = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th']
|
595
612
|
while not download_success:
|
596
613
|
if request_times >= 10:
|
597
614
|
# print(f'下载失败,已重试 {request_times} 次\n可先跳过,后续再试')
|
@@ -599,11 +616,11 @@ def dlownload_file(target_url, store_path, file_name, check=False):
|
|
599
616
|
break
|
600
617
|
if request_times > 0:
|
601
618
|
# print(f'\r正在重试第 {request_times} 次', end="")
|
602
|
-
print(f'[bold #ffe5c0]Retrying the {request_times} time...')
|
619
|
+
print(f'[bold #ffe5c0]Retrying the {order_list[request_times-1]} time...')
|
603
620
|
# 尝试下载文件
|
604
621
|
try:
|
605
622
|
headers = {'User-Agent': get_ua()}
|
606
|
-
response = s.get(target_url, headers=headers, timeout=5)
|
623
|
+
response = s.get(target_url, headers=headers, timeout=random.randint(5, 15))
|
607
624
|
response.raise_for_status() # 如果请求返回的不是200,将抛出HTTPError异常
|
608
625
|
|
609
626
|
# 保存文件
|
@@ -673,7 +690,7 @@ def check_dataset_version(dataset_name, version_name, download_time, download_ti
|
|
673
690
|
return None, None
|
674
691
|
|
675
692
|
|
676
|
-
def get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time):
|
693
|
+
def get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time, download_time_end=None):
|
677
694
|
year_str = str(download_time)[:4]
|
678
695
|
if depth is not None and level_num is not None:
|
679
696
|
print('Please ensure the depth or level_num is None')
|
@@ -688,87 +705,33 @@ def get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max
|
|
688
705
|
else:
|
689
706
|
print('Full depth or full level data will be downloaded...')
|
690
707
|
which_mode = 'full'
|
691
|
-
query_dict = get_query_dict(var, lon_min, lon_max, lat_min, lat_max, download_time, which_mode, depth, level_num)
|
708
|
+
query_dict = get_query_dict(var, lon_min, lon_max, lat_min, lat_max, download_time, download_time_end, which_mode, depth, level_num)
|
692
709
|
submit_url = get_submit_url(
|
693
710
|
dataset_name, version_name, var, year_str, query_dict)
|
694
711
|
return submit_url
|
695
712
|
|
696
713
|
|
697
|
-
def
|
714
|
+
def prepare_url_to_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, download_time='2024083100', download_time_end=None, depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None, check=False):
|
698
715
|
print('[bold #ecdbfe]-'*150)
|
699
716
|
download_time = str(download_time)
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
if store_path is None:
|
705
|
-
store_path = str(Path.cwd())
|
717
|
+
if download_time_end is not None:
|
718
|
+
download_time_end = str(download_time_end)
|
719
|
+
dataset_name, version_name = check_dataset_version(dataset_name, version_name, download_time, download_time_end)
|
706
720
|
else:
|
707
|
-
|
708
|
-
|
709
|
-
if isinstance(var, str):
|
710
|
-
var = [var]
|
711
|
-
|
712
|
-
if isinstance(var, list):
|
713
|
-
if len(var) == 1:
|
714
|
-
var = var[0]
|
715
|
-
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
716
|
-
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
717
|
-
dlownload_file(submit_url, store_path, file_name, check)
|
718
|
-
else:
|
719
|
-
varlist = [_ for _ in var]
|
720
|
-
for key, value in var_group.items():
|
721
|
-
current_group = []
|
722
|
-
for v in varlist:
|
723
|
-
if v in value:
|
724
|
-
current_group.append(v)
|
725
|
-
if len(current_group) == 0:
|
726
|
-
continue
|
727
|
-
|
728
|
-
var = current_group[0]
|
729
|
-
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
730
|
-
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
731
|
-
old_str = f'var={variable_info[var]["var_name"]}'
|
732
|
-
new_str = f'var={variable_info[var]["var_name"]}'
|
733
|
-
if len(current_group) > 1:
|
734
|
-
for v in current_group[1:]:
|
735
|
-
new_str = f'{new_str}&var={variable_info[v]["var_name"]}'
|
736
|
-
submit_url = submit_url.replace(old_str, new_str)
|
737
|
-
# file_name = f'HYCOM_{'-'.join([variable_info[v]["var_name"] for v in current_group])}_{download_time}.nc'
|
738
|
-
file_name = f'HYCOM_{key}_{download_time}.nc'
|
739
|
-
dlownload_file(submit_url, store_path, file_name, check)
|
740
|
-
|
741
|
-
|
742
|
-
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):
|
743
|
-
print('[bold #ecdbfe]-'*150)
|
744
|
-
download_time = str(download_time)[:8]+'00'
|
745
|
-
dataset_name, version_name = check_dataset_version(dataset_name, version_name, download_time, str(download_time)[:8]+'21')
|
721
|
+
dataset_name, version_name = check_dataset_version(dataset_name, version_name, download_time)
|
746
722
|
if dataset_name is None and version_name is None:
|
747
723
|
return
|
748
724
|
|
749
|
-
if store_path is None:
|
750
|
-
store_path = str(Path.cwd())
|
751
|
-
else:
|
752
|
-
os.makedirs(str(store_path), exist_ok=True)
|
753
|
-
|
754
725
|
if isinstance(var, str):
|
755
726
|
var = [var]
|
756
727
|
|
757
728
|
if isinstance(var, list):
|
758
729
|
if len(var) == 1:
|
759
730
|
var = var[0]
|
760
|
-
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
761
|
-
|
762
|
-
# 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
|
763
|
-
# 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
|
764
|
-
# 将time=2018-12-09T09%3A00%3A00Z替换为time_start=2018-09-19T12%3A00%3A00Z&time_end=2018-12-09T09%3A00%3A00Z&timeStride=1
|
765
|
-
daytime_s = transform_time(str(download_time)[:8]+'00')
|
766
|
-
daytime_e = transform_time(str(download_time)[:8]+'21')
|
767
|
-
submit_url = submit_url.replace(
|
768
|
-
f'time={daytime_s}', f'time_start={daytime_s}&time_end={daytime_e}&timeStride=1')
|
769
|
-
|
731
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time, download_time_end)
|
770
732
|
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
771
|
-
|
733
|
+
if download_time_end is not None:
|
734
|
+
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}_{download_time_end}.nc"
|
772
735
|
dlownload_file(submit_url, store_path, file_name, check)
|
773
736
|
else:
|
774
737
|
varlist = [_ for _ in var]
|
@@ -781,11 +744,7 @@ def direct_download_whole_day(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_m
|
|
781
744
|
continue
|
782
745
|
|
783
746
|
var = current_group[0]
|
784
|
-
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time)
|
785
|
-
daytime_s = transform_time(str(download_time)[:8]+'00')
|
786
|
-
daytime_e = transform_time(str(download_time)[:8]+'21')
|
787
|
-
submit_url = submit_url.replace(
|
788
|
-
f'time={daytime_s}', f'time_start={daytime_s}&time_end={daytime_e}&timeStride=1')
|
747
|
+
submit_url = get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time, download_time_end)
|
789
748
|
file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
|
790
749
|
old_str = f'var={variable_info[var]["var_name"]}'
|
791
750
|
new_str = f'var={variable_info[var]["var_name"]}'
|
@@ -795,6 +754,8 @@ def direct_download_whole_day(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_m
|
|
795
754
|
submit_url = submit_url.replace(old_str, new_str)
|
796
755
|
# file_name = f'HYCOM_{'-'.join([variable_info[v]["var_name"] for v in current_group])}_{download_time}.nc'
|
797
756
|
file_name = f'HYCOM_{key}_{download_time}.nc'
|
757
|
+
if download_time_end is not None:
|
758
|
+
file_name = f'HYCOM_{key}_{download_time}_{download_time_end}.nc'
|
798
759
|
dlownload_file(submit_url, store_path, file_name, check)
|
799
760
|
|
800
761
|
|
@@ -808,7 +769,7 @@ def convert_full_name_to_short_name(full_name):
|
|
808
769
|
return False
|
809
770
|
|
810
771
|
|
811
|
-
def download_task(var, time_str, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check):
|
772
|
+
def download_task(var, time_str, time_str_end, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check):
|
812
773
|
'''
|
813
774
|
# 并行下载任务
|
814
775
|
# 这个函数是为了并行下载而设置的,是必须的,直接调用direct_download并行下载会出问题
|
@@ -818,13 +779,11 @@ def download_task(var, time_str, lon_min, lon_max, lat_min, lat_max, depth, leve
|
|
818
779
|
这样,每个任务都是独立的,有自己的参数和数据,不会与其他任务共享或修改任何数据。
|
819
780
|
因此,即使多个任务同时执行,也不会出现数据交互错乱的问题。
|
820
781
|
'''
|
821
|
-
if len(time_str) == 8:
|
822
|
-
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
823
|
-
else:
|
824
|
-
direct_download_single_hour(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
825
782
|
|
783
|
+
prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, time_str_end, depth, level, store_path, dataset_name, version_name, check)
|
826
784
|
|
827
|
-
|
785
|
+
|
786
|
+
def download_hourly_func(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, ftimes=1):
|
828
787
|
'''
|
829
788
|
Description:
|
830
789
|
Download the data of single time or a series of time
|
@@ -847,80 +806,85 @@ def download_single_hour(var, time_s, time_e=None, lon_min=0, lon_max=359.92, la
|
|
847
806
|
Returns:
|
848
807
|
None
|
849
808
|
'''
|
850
|
-
|
851
|
-
if len(var) == 1:
|
852
|
-
var = convert_full_name_to_short_name(var[0])
|
853
|
-
else:
|
854
|
-
var = [convert_full_name_to_short_name(v) for v in var]
|
855
|
-
elif isinstance(var, str):
|
856
|
-
var = convert_full_name_to_short_name(var)
|
857
|
-
else:
|
858
|
-
raise ValueError('The var is invalid')
|
859
|
-
if var is False:
|
860
|
-
raise ValueError('The var is invalid')
|
861
|
-
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:
|
862
|
-
print('Please ensure the lon_min, lon_max, lat_min, lat_max are in the range')
|
863
|
-
print('The range of lon_min, lon_max is 0~359.92')
|
864
|
-
print('The range of lat_min, lat_max is -80~90')
|
865
|
-
raise ValueError('The lon or lat is invalid')
|
866
|
-
ymdh_time_s = str(time_s)
|
867
|
-
if len(ymdh_time_s) == 8:
|
868
|
-
ymdh_time_s += '00'
|
869
|
-
if time_e is None:
|
870
|
-
ymdh_time_e = ymdh_time_s[:]
|
871
|
-
else:
|
872
|
-
ymdh_time_e = str(time_e)
|
873
|
-
if len(ymdh_time_e) == 8:
|
874
|
-
ymdh_time_e += '21'
|
809
|
+
ymdh_time_s, ymdh_time_e = str(time_s), str(time_e)
|
875
810
|
if ymdh_time_s == ymdh_time_e:
|
876
|
-
|
811
|
+
prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, None, depth, level, store_path, dataset_name, version_name)
|
877
812
|
elif int(ymdh_time_s) < int(ymdh_time_e):
|
878
813
|
print('Downloading a series of files...')
|
879
814
|
time_list = get_time_list(ymdh_time_s, ymdh_time_e, 3, 'hour')
|
880
815
|
with Progress() as progress:
|
881
816
|
task = progress.add_task("[cyan]Downloading...", total=len(time_list))
|
882
|
-
if
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
817
|
+
if ftimes == 1:
|
818
|
+
if num_workers is None or num_workers <= 1:
|
819
|
+
# 串行方式
|
820
|
+
for i, time_str in enumerate(time_list):
|
821
|
+
prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, None, depth, level, store_path, dataset_name, version_name, check)
|
822
|
+
progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}')
|
823
|
+
else:
|
824
|
+
# 并行方式
|
825
|
+
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
826
|
+
futures = [executor.submit(download_task, var, time_str, None, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for time_str in time_list]
|
827
|
+
for i, future in enumerate(futures):
|
828
|
+
future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}'))
|
887
829
|
else:
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
830
|
+
new_time_list = get_time_list(ymdh_time_s, ymdh_time_e, 3*ftimes, 'hour')
|
831
|
+
total_num = len(new_time_list)
|
832
|
+
if num_workers is None or num_workers <= 1:
|
833
|
+
# 串行方式
|
834
|
+
for i, time_str in enumerate(new_time_list):
|
835
|
+
time_str_end_index = int(min(len(time_list), int(i*ftimes+ftimes-1)))
|
836
|
+
time_str_end = time_list[time_str_end_index]
|
837
|
+
prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, time_str_end, depth, level, store_path, dataset_name, version_name, check)
|
838
|
+
progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{total_num}')
|
839
|
+
else:
|
840
|
+
# 并行方式
|
841
|
+
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
842
|
+
futures = [executor.submit(download_task, var, new_time_list[i], time_list[int(min(len(time_list), int(i*ftimes+ftimes-1)))], lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for i in range(total_num)]
|
843
|
+
for i, future in enumerate(futures):
|
844
|
+
future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{total_num}'))
|
897
845
|
else:
|
898
|
-
print('Please ensure the time_s is
|
846
|
+
print('Please ensure the time_s is no more than time_e')
|
899
847
|
|
900
848
|
|
901
|
-
def
|
849
|
+
def download(var, time_s, time_e=None, 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, ftimes=1):
|
902
850
|
'''
|
903
851
|
Description:
|
904
852
|
Download the data of single time or a series of time
|
905
853
|
|
906
854
|
Parameters:
|
907
|
-
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'
|
908
|
-
time_s: str, the start time, such as '20241101',
|
909
|
-
time_e: str, the end time, such as '20241102',
|
855
|
+
var: str or list, 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'
|
856
|
+
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
|
857
|
+
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; default is None, if not set, the data of single time will be downloaded; or same as time_s, the data of single time will be downloaded
|
910
858
|
lon_min: float, the minimum longitude, default is 0
|
911
859
|
lon_max: float, the maximum longitude, default is 359.92
|
912
860
|
lat_min: float, the minimum latitude, default is -80
|
913
861
|
lat_max: float, the maximum latitude, default is 90
|
914
|
-
depth: float, the depth, default is None
|
915
|
-
level: int, the level number, default is None
|
916
|
-
store_path: str, the path to store the data, default is None
|
917
|
-
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08'
|
918
|
-
version_name: str, the version name, default is None, example: '53.X', '56.3'
|
919
|
-
num_workers: int, the number of workers, default is None
|
862
|
+
depth: float, the depth, default is None, if you wanna get the data of single depth, you can set the depth, suggest to set the depth in [0, 5000]
|
863
|
+
level: int, the level number, default is None, if you wanna get the data of single level, you can set the level, suggest to set the level in [1, 40]
|
864
|
+
store_path: str, the path to store the data, default is None, if not set, the data will be stored in the current working directory
|
865
|
+
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08', if not set, the dataset will be chosen according to the download_time
|
866
|
+
version_name: str, the version name, default is None, example: '53.X', '56.3', if not set, the version will be chosen according to the download_time
|
867
|
+
num_workers: int, the number of workers, default is None, if not set, the number of workers will be 1; suggest not to set the number of workers too large
|
868
|
+
check: bool, whether to check the existing file, default is False, if set to True, the existing file will be checked and not downloaded again; else, the existing file will be covered
|
869
|
+
ftimes: int, the number of time in one file, default is 1, if set to 1, the data of single time will be downloaded; the maximum is 8, if set to 8, the data of 8 times will be downloaded in one file
|
920
870
|
|
921
871
|
Returns:
|
922
872
|
None
|
923
873
|
'''
|
874
|
+
# 打印信息并处理数据集和版本名称
|
875
|
+
if dataset_name is None and version_name is None:
|
876
|
+
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.')
|
877
|
+
print('If you wanna choose the dataset and version by yourself, please set the dataset_name and version_name together.')
|
878
|
+
elif dataset_name is None and version_name is not None:
|
879
|
+
print('Please ensure the dataset_name is not None')
|
880
|
+
print('If you do not add the dataset_name, both the dataset and version will be chosen according to the download_time.')
|
881
|
+
elif dataset_name is not None and version_name is None:
|
882
|
+
print('Please ensure the version_name is not None')
|
883
|
+
print('If you do not add the version_name, both the dataset and version will be chosen according to the download_time.')
|
884
|
+
else:
|
885
|
+
print('The dataset_name and version_name are both set by yourself.')
|
886
|
+
print('Please ensure the dataset_name and version_name are correct.')
|
887
|
+
|
924
888
|
if isinstance(var, list):
|
925
889
|
if len(var) == 1:
|
926
890
|
var = convert_full_name_to_short_name(var[0])
|
@@ -937,84 +901,30 @@ def download_whole_day(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_
|
|
937
901
|
print('The range of lon_min, lon_max is 0~359.92')
|
938
902
|
print('The range of lat_min, lat_max is -80~90')
|
939
903
|
raise ValueError('The lon or lat is invalid')
|
940
|
-
time_s = str(time_s)[:8]
|
941
|
-
if time_e is None:
|
942
|
-
time_e = time_s[:]
|
943
|
-
else:
|
944
|
-
time_e = str(time_e)[:8]
|
945
|
-
|
946
|
-
if time_s == time_e:
|
947
|
-
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_s, depth, level, store_path, dataset_name, version_name)
|
948
|
-
elif int(time_s) < int(time_e):
|
949
|
-
print('Downloading a series of files...')
|
950
|
-
time_list = get_time_list(time_s, time_e, 1, 'day')
|
951
|
-
with Progress() as progress:
|
952
|
-
task = progress.add_task("[cyan]Downloading...", total=len(time_list))
|
953
|
-
if num_workers is None or num_workers <= 1:
|
954
|
-
# 串行方式
|
955
|
-
for i, time_str in enumerate(time_list):
|
956
|
-
direct_download_whole_day(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
|
957
|
-
progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}')
|
958
|
-
else:
|
959
|
-
# 并行方式
|
960
|
-
if num_workers > 10:
|
961
|
-
print('The number of workers is too large!')
|
962
|
-
print('In order to avoid the server being blocked, the number of workers is set to 10')
|
963
|
-
num_workers = 10
|
964
|
-
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
965
|
-
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]
|
966
|
-
for i, future in enumerate(futures):
|
967
|
-
future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}'))
|
968
|
-
else:
|
969
|
-
print('Please ensure the time_s is less than the time_e')
|
970
904
|
|
905
|
+
if ftimes != 1:
|
906
|
+
print('Please ensure the ftimes is in [1, 8]')
|
907
|
+
ftimes = max(min(ftimes, 8), 1)
|
971
908
|
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
909
|
+
if store_path is None:
|
910
|
+
store_path = str(Path.cwd())
|
911
|
+
else:
|
912
|
+
os.makedirs(str(store_path), exist_ok=True)
|
976
913
|
|
977
|
-
|
978
|
-
|
979
|
-
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
|
980
|
-
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
|
981
|
-
lon_min: float, the minimum longitude, default is 0
|
982
|
-
lon_max: float, the maximum longitude, default is 359.92
|
983
|
-
lat_min: float, the minimum latitude, default is -80
|
984
|
-
lat_max: float, the maximum latitude, default is 90
|
985
|
-
depth: float, the depth, default is None
|
986
|
-
level: int, the level number, default is None
|
987
|
-
store_path: str, the path to store the data, default is None
|
988
|
-
dataset_name: str, the dataset name, default is None, example: 'GLBv0.08', 'GLBu0.08', 'GLBy0.08'
|
989
|
-
version_name: str, the version name, default is None, example: '53.X', '56.3'
|
990
|
-
num_workers: int, the number of workers, default is None
|
914
|
+
if num_workers is not None:
|
915
|
+
num_workers = max(min(num_workers, 10), 1)
|
991
916
|
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
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.')
|
998
|
-
print('If you wanna choose the dataset and version by yourself, please set the dataset_name and version_name together.')
|
999
|
-
elif dataset_name is None and version_name is not None:
|
1000
|
-
print('Please ensure the dataset_name is not None')
|
1001
|
-
print('If you do not add the dataset_name, both the dataset and version will be chosen according to the download_time.')
|
1002
|
-
elif dataset_name is not None and version_name is None:
|
1003
|
-
print('Please ensure the version_name is not None')
|
1004
|
-
print('If you do not add the version_name, both the dataset and version will be chosen according to the download_time.')
|
917
|
+
time_s = str(time_s)
|
918
|
+
if len(time_s) == 8:
|
919
|
+
time_s += '00'
|
920
|
+
if time_e is None:
|
921
|
+
time_e = time_s[:]
|
1005
922
|
else:
|
1006
|
-
|
1007
|
-
|
923
|
+
time_e = str(time_e)
|
924
|
+
if len(time_e) == 8:
|
925
|
+
time_e += '21'
|
1008
926
|
|
1009
|
-
|
1010
|
-
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)
|
1011
|
-
elif resolution == 'day':
|
1012
|
-
print('Currently can not download the data of whole day...')
|
1013
|
-
# 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)
|
1014
|
-
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)
|
1015
|
-
else:
|
1016
|
-
print('Please ensure the resolution is in [hour, day]\n This will be set to hour')
|
1017
|
-
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)
|
927
|
+
download_hourly_func(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check, ftimes)
|
1018
928
|
|
1019
929
|
|
1020
930
|
def how_to_use():
|
@@ -1091,11 +1001,12 @@ if __name__ == '__main__':
|
|
1091
1001
|
|
1092
1002
|
# set depth or level, only one can be True
|
1093
1003
|
# if you wanna download all depth or level, set both False
|
1094
|
-
depth = None # or 0-
|
1004
|
+
depth = None # or 0-5000 meters
|
1095
1005
|
level = None # or 1-40 levels
|
1096
1006
|
num_workers = 1
|
1097
1007
|
|
1098
1008
|
check = True
|
1009
|
+
ftimes = 4
|
1099
1010
|
|
1100
1011
|
download_switch, single_var = True, False
|
1101
1012
|
combine_switch = True
|
@@ -1104,9 +1015,9 @@ if __name__ == '__main__':
|
|
1104
1015
|
if download_switch:
|
1105
1016
|
if single_var:
|
1106
1017
|
for var_name in var_list:
|
1107
|
-
download(var=var_name, time_s=time_s, time_e=time_e, store_path=Path(root_path), lon_min=location_dict['west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], num_workers=num_workers, check=check, depth=depth, level=level)
|
1018
|
+
download(var=var_name, time_s=time_s, time_e=time_e, store_path=Path(root_path), lon_min=location_dict['west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], num_workers=num_workers, check=check, depth=depth, level=level, ftimes=ftimes)
|
1108
1019
|
else:
|
1109
|
-
download(var=var_list, time_s=time_s, time_e=time_e, store_path=Path(root_path), lon_min=location_dict['west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], num_workers=num_workers, check=check, depth=depth, level=level)
|
1020
|
+
download(var=var_list, time_s=time_s, time_e=time_e, store_path=Path(root_path), lon_min=location_dict['west'], lon_max=location_dict['east'], lat_min=location_dict['south'], lat_max=location_dict['north'], num_workers=num_workers, check=check, depth=depth, level=level, ftimes=ftimes)
|
1110
1021
|
|
1111
1022
|
""" if combine_switch or copy_switch:
|
1112
1023
|
time_list = get_time_list(time_s, time_e, 3, 'hour')
|
@@ -1119,16 +1030,17 @@ if __name__ == '__main__':
|
|
1119
1030
|
else:
|
1120
1031
|
# 如果混合,需要看情况获取文件列表
|
1121
1032
|
fname = ''
|
1122
|
-
if var_name in ['water_u', 'water_v', 'water_u_bottom', 'water_v_bottom']
|
1033
|
+
if var_name in ['water_u', 'water_v', 'water_u_bottom', 'water_v_bottom']:
|
1123
1034
|
fname = 'uv3z'
|
1124
|
-
elif var_name in ['water_temp', 'salinity', 'water_temp_bottom', 'salinity_bottom']
|
1035
|
+
elif var_name in ['water_temp', 'salinity', 'water_temp_bottom', 'salinity_bottom']:
|
1125
1036
|
fname = 'ts3z'
|
1126
|
-
elif var_name in ['surf_el']
|
1037
|
+
elif var_name in ['surf_el']:
|
1127
1038
|
fname = 'surf_el'
|
1128
1039
|
for time_str in time_list:
|
1129
1040
|
file_list.append(Path(root_path)/f'HYCOM_{fname}_{time_str}.nc')
|
1130
1041
|
merge_path_name = Path(root_path)/f'HYCOM_{fname}_{merge_name}.nc'
|
1131
1042
|
if combine_switch:
|
1043
|
+
# 这里的var_name必须是官方变量名,不能再是简写了
|
1132
1044
|
merge5nc(file_list, var_name, 'time', merge_path_name)
|
1133
1045
|
if copy_switch:
|
1134
1046
|
copy_file(merge_path_name, copy_dir) """
|
@@ -7,7 +7,7 @@ oafuncs/oa_help.py,sha256=ppNktmtNzs15R20MD1bM7yImlTQ_ngMwvoIglePOKXA,1000
|
|
7
7
|
oafuncs/oa_nc.py,sha256=ALAYfqDy5lbUNJsTU29j6ZWkM4wgqQU3p2Fxn5pkvsQ,12102
|
8
8
|
oafuncs/oa_python.py,sha256=XPTP3o7zTFzfJR_YhsKfQksa3bSYwXsne9YxlJplCEA,3994
|
9
9
|
oafuncs/oa_down/__init__.py,sha256=a6rgxHQi8spvlI-TaVEqnrDNhYsKm5_IQf7ckAZ8U4w,603
|
10
|
-
oafuncs/oa_down/hycom_3hourly.py,sha256=
|
10
|
+
oafuncs/oa_down/hycom_3hourly.py,sha256=fSTAdHhWWTm7X_yx2RFg61FBvvJ6eROC9IANdcR20Wc,56524
|
11
11
|
oafuncs/oa_down/literature.py,sha256=dT3-7-beEzQ9mTP8LNV9Gf3q5Z1Pqqjc6FOS010HZeQ,17833
|
12
12
|
oafuncs/oa_down/refs_pdf.py,sha256=lgGKO2gQ0hRjuaBYOLeBgksJB_KXYpFcXMDwMQeYVkI,18719
|
13
13
|
oafuncs/oa_sign/__init__.py,sha256=QKqTFrJDFK40C5uvk48GlRRbGFzO40rgkYwu6dYxatM,563
|
@@ -16,8 +16,8 @@ oafuncs/oa_sign/ocean.py,sha256=xrW-rWD7xBWsB5PuCyEwQ1Q_RDKq2KCLz-LOONHgldU,5932
|
|
16
16
|
oafuncs/oa_sign/scientific.py,sha256=a4JxOBgm9vzNZKpJ_GQIQf7cokkraV5nh23HGbmTYKw,5064
|
17
17
|
oafuncs/oa_tool/__init__.py,sha256=IKOlqpWlb4cMDCtq2VKR_RTxQHDNqR_vfqqsOsp_lKQ,466
|
18
18
|
oafuncs/oa_tool/email.py,sha256=4lJxV_KUzhxgLYfVwYTqp0qxRugD7fvsZkXDe5WkUKo,3052
|
19
|
-
oafuncs-0.0.
|
20
|
-
oafuncs-0.0.
|
21
|
-
oafuncs-0.0.
|
22
|
-
oafuncs-0.0.
|
23
|
-
oafuncs-0.0.
|
19
|
+
oafuncs-0.0.71.dist-info/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
|
20
|
+
oafuncs-0.0.71.dist-info/METADATA,sha256=jIn5cFJMOTb0iQTdegUEdOIuFAqj5b8DhYh65RUYH7E,22531
|
21
|
+
oafuncs-0.0.71.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
|
22
|
+
oafuncs-0.0.71.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
|
23
|
+
oafuncs-0.0.71.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|