oafuncs 0.0.69__py2.py3-none-any.whl → 0.0.70__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.
@@ -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-30 20:24:34
7
+ LastEditTime: 2024-12-01 10:57:04
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': transform_time(time_str_ymdh),
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
- # 如果没有找到匹配的数据集和版本,返回 None
438
- return None, None
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,31 @@ 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 direct_download_single_hour(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
+ 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
- dataset_name, version_name = check_dataset_version(dataset_name, version_name, download_time)
701
- if dataset_name is None and version_name is None:
702
- return
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
- os.makedirs(str(store_path), exist_ok=True)
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
-
772
733
  dlownload_file(submit_url, store_path, file_name, check)
773
734
  else:
774
735
  varlist = [_ for _ in var]
@@ -781,11 +742,7 @@ def direct_download_whole_day(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_m
781
742
  continue
782
743
 
783
744
  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')
745
+ 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
746
  file_name = f"HYCOM_{variable_info[var]['var_name']}_{download_time}.nc"
790
747
  old_str = f'var={variable_info[var]["var_name"]}'
791
748
  new_str = f'var={variable_info[var]["var_name"]}'
@@ -808,7 +765,7 @@ def convert_full_name_to_short_name(full_name):
808
765
  return False
809
766
 
810
767
 
811
- def download_task(var, time_str, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check):
768
+ 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
769
  '''
813
770
  # 并行下载任务
814
771
  # 这个函数是为了并行下载而设置的,是必须的,直接调用direct_download并行下载会出问题
@@ -818,13 +775,11 @@ def download_task(var, time_str, lon_min, lon_max, lat_min, lat_max, depth, leve
818
775
  这样,每个任务都是独立的,有自己的参数和数据,不会与其他任务共享或修改任何数据。
819
776
  因此,即使多个任务同时执行,也不会出现数据交互错乱的问题。
820
777
  '''
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)
778
+
779
+ 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)
825
780
 
826
781
 
827
- def download_single_hour(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):
782
+ def download_hourly_func(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):
828
783
  '''
829
784
  Description:
830
785
  Download the data of single time or a series of time
@@ -847,22 +802,6 @@ def download_single_hour(var, time_s, time_e=None, lon_min=0, lon_max=359.92, la
847
802
  Returns:
848
803
  None
849
804
  '''
850
- if isinstance(var, list):
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
805
  ymdh_time_s = str(time_s)
867
806
  if len(ymdh_time_s) == 8:
868
807
  ymdh_time_s += '00'
@@ -873,54 +812,91 @@ def download_single_hour(var, time_s, time_e=None, lon_min=0, lon_max=359.92, la
873
812
  if len(ymdh_time_e) == 8:
874
813
  ymdh_time_e += '21'
875
814
  if ymdh_time_s == ymdh_time_e:
876
- direct_download_single_hour(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, depth, level, store_path, dataset_name, version_name)
815
+ 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
816
  elif int(ymdh_time_s) < int(ymdh_time_e):
878
817
  print('Downloading a series of files...')
879
818
  time_list = get_time_list(ymdh_time_s, ymdh_time_e, 3, 'hour')
880
819
  with Progress() as progress:
881
820
  task = progress.add_task("[cyan]Downloading...", total=len(time_list))
882
- if num_workers is None or num_workers <= 1:
883
- # 串行方式
884
- for i, time_str in enumerate(time_list):
885
- direct_download_single_hour(var, lon_min, lon_max, lat_min, lat_max, time_str, depth, level, store_path, dataset_name, version_name, check)
886
- progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}')
821
+ if ftimes == 1:
822
+ if num_workers is None or num_workers <= 1:
823
+ # 串行方式
824
+ for i, time_str in enumerate(time_list):
825
+ 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)
826
+ progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}')
827
+ else:
828
+ # 并行方式
829
+ if num_workers > 10:
830
+ print('The number of workers is too large!')
831
+ print('In order to avoid the server being blocked, the number of workers is set to 10')
832
+ num_workers = 10
833
+ with ThreadPoolExecutor(max_workers=num_workers) as executor:
834
+ 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]
835
+ for i, future in enumerate(futures):
836
+ future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}'))
887
837
  else:
888
- # 并行方式
889
- if num_workers > 10:
890
- print('The number of workers is too large!')
891
- print('In order to avoid the server being blocked, the number of workers is set to 10')
892
- num_workers = 10
893
- with ThreadPoolExecutor(max_workers=num_workers) as executor:
894
- 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]
895
- for i, future in enumerate(futures):
896
- future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{len(time_list)}'))
838
+ new_time_list = get_time_list(ymdh_time_s, ymdh_time_e, 3*ftimes, 'hour')
839
+ total_num = len(new_time_list)
840
+ if num_workers is None or num_workers <= 1:
841
+ # 串行方式
842
+ for i, time_str in enumerate(new_time_list):
843
+ time_str_end_index = int(min(len(time_list), int(i*ftimes+ftimes-1)))
844
+ time_str_end = time_list[time_str_end_index]
845
+ 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)
846
+ progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{total_num}')
847
+ else:
848
+ # 并行方式
849
+ if num_workers > 10:
850
+ print('The number of workers is too large!')
851
+ print('In order to avoid the server being blocked, the number of workers is set to 10')
852
+ num_workers = 10
853
+ with ThreadPoolExecutor(max_workers=num_workers) as executor:
854
+ 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)]
855
+ for i, future in enumerate(futures):
856
+ future.add_done_callback(lambda _: progress.update(task, advance=1, description=f'[cyan]Downloading... {i+1}/{total_num}'))
897
857
  else:
898
858
  print('Please ensure the time_s is less than the time_e')
899
859
 
900
860
 
901
- def download_whole_day(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):
861
+ 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
862
  '''
903
863
  Description:
904
864
  Download the data of single time or a series of time
905
865
 
906
866
  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', without hour
909
- time_e: str, the end time, such as '20241102', without hour
867
+ 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'
868
+ 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
869
+ 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
870
  lon_min: float, the minimum longitude, default is 0
911
871
  lon_max: float, the maximum longitude, default is 359.92
912
872
  lat_min: float, the minimum latitude, default is -80
913
873
  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
874
+ 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]
875
+ 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]
876
+ 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
877
+ 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
878
+ 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
879
+ 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
880
+ 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
881
+ 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
882
 
921
883
  Returns:
922
884
  None
923
885
  '''
886
+ # 打印信息并处理数据集和版本名称
887
+ if dataset_name is None and version_name is None:
888
+ 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.')
889
+ print('If you wanna choose the dataset and version by yourself, please set the dataset_name and version_name together.')
890
+ elif dataset_name is None and version_name is not None:
891
+ print('Please ensure the dataset_name is not None')
892
+ print('If you do not add the dataset_name, both the dataset and version will be chosen according to the download_time.')
893
+ elif dataset_name is not None and version_name is None:
894
+ print('Please ensure the version_name is not None')
895
+ print('If you do not add the version_name, both the dataset and version will be chosen according to the download_time.')
896
+ else:
897
+ print('The dataset_name and version_name are both set by yourself.')
898
+ print('Please ensure the dataset_name and version_name are correct.')
899
+
924
900
  if isinstance(var, list):
925
901
  if len(var) == 1:
926
902
  var = convert_full_name_to_short_name(var[0])
@@ -937,84 +913,17 @@ def download_whole_day(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_
937
913
  print('The range of lon_min, lon_max is 0~359.92')
938
914
  print('The range of lat_min, lat_max is -80~90')
939
915
  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
-
971
-
972
- 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, resolution='hour'):
973
- '''
974
- Description:
975
- Download the data of single time or a series of time
976
916
 
977
- Parameters:
978
- 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'
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
917
+ if ftimes != 1:
918
+ print('Please ensure the ftimes is in [1, 8]')
919
+ ftimes = max(min(ftimes, 8), 1)
991
920
 
992
- Returns:
993
- None
994
- '''
995
- # 打印信息并处理数据集和版本名称
996
- if dataset_name is None and version_name is None:
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.')
921
+ if store_path is None:
922
+ store_path = str(Path.cwd())
1005
923
  else:
1006
- print('The dataset_name and version_name are both set by yourself.')
1007
- print('Please ensure the dataset_name and version_name are correct.')
924
+ os.makedirs(str(store_path), exist_ok=True)
1008
925
 
1009
- if resolution == 'hour':
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)
926
+ 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
927
 
1019
928
 
1020
929
  def how_to_use():
@@ -1091,11 +1000,12 @@ if __name__ == '__main__':
1091
1000
 
1092
1001
  # set depth or level, only one can be True
1093
1002
  # if you wanna download all depth or level, set both False
1094
- depth = None # or 0-4000 meters
1003
+ depth = None # or 0-5000 meters
1095
1004
  level = None # or 1-40 levels
1096
1005
  num_workers = 1
1097
1006
 
1098
1007
  check = True
1008
+ ftimes = 4
1099
1009
 
1100
1010
  download_switch, single_var = True, False
1101
1011
  combine_switch = True
@@ -1104,9 +1014,9 @@ if __name__ == '__main__':
1104
1014
  if download_switch:
1105
1015
  if single_var:
1106
1016
  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)
1017
+ 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
1018
  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)
1019
+ 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
1020
 
1111
1021
  """ if combine_switch or copy_switch:
1112
1022
  time_list = get_time_list(time_s, time_e, 3, 'hour')
@@ -1119,16 +1029,17 @@ if __name__ == '__main__':
1119
1029
  else:
1120
1030
  # 如果混合,需要看情况获取文件列表
1121
1031
  fname = ''
1122
- if var_name in ['water_u', 'water_v', 'water_u_bottom', 'water_v_bottom'] or var_name in ['u', 'v', 'u_b', 'v_b']:
1032
+ if var_name in ['water_u', 'water_v', 'water_u_bottom', 'water_v_bottom']:
1123
1033
  fname = 'uv3z'
1124
- elif var_name in ['water_temp', 'salinity', 'water_temp_bottom', 'salinity_bottom'] or var_name in ['temp', 'salt', 'temp_b', 'salt_b']:
1034
+ elif var_name in ['water_temp', 'salinity', 'water_temp_bottom', 'salinity_bottom']:
1125
1035
  fname = 'ts3z'
1126
- elif var_name in ['surf_el'] or var_name in ['ssh']:
1036
+ elif var_name in ['surf_el']:
1127
1037
  fname = 'surf_el'
1128
1038
  for time_str in time_list:
1129
1039
  file_list.append(Path(root_path)/f'HYCOM_{fname}_{time_str}.nc')
1130
1040
  merge_path_name = Path(root_path)/f'HYCOM_{fname}_{merge_name}.nc'
1131
1041
  if combine_switch:
1042
+ # 这里的var_name必须是官方变量名,不能再是简写了
1132
1043
  merge5nc(file_list, var_name, 'time', merge_path_name)
1133
1044
  if copy_switch:
1134
1045
  copy_file(merge_path_name, copy_dir) """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oafuncs
3
- Version: 0.0.69
3
+ Version: 0.0.70
4
4
  Summary: My short description for my project.
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -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=AcSIxnM8_Gop3Jc2JWxiPGPB_i51yAdRLu38CyPy_1g,60994
10
+ oafuncs/oa_down/hycom_3hourly.py,sha256=ATKA-p-gLTUR4MInzN5yql1sCKi8C9nvQ_yXqjMwzQI,56655
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.69.dist-info/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
20
- oafuncs-0.0.69.dist-info/METADATA,sha256=V2O9xc2_-G0H07DxFipqLP2AYO7llEY_QElndbs-ddQ,22531
21
- oafuncs-0.0.69.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
22
- oafuncs-0.0.69.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
23
- oafuncs-0.0.69.dist-info/RECORD,,
19
+ oafuncs-0.0.70.dist-info/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
20
+ oafuncs-0.0.70.dist-info/METADATA,sha256=6u5-PblWLD9YmMabXD7zKarROPKOxaoSTSHmwGXKqQ4,22531
21
+ oafuncs-0.0.70.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
22
+ oafuncs-0.0.70.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
23
+ oafuncs-0.0.70.dist-info/RECORD,,