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.
@@ -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 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': 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,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 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
-
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
- 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):
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
- 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
- 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
- direct_download_single_hour(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, depth, level, store_path, dataset_name, version_name)
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 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)}')
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
- 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)}'))
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 less than the time_e')
846
+ print('Please ensure the time_s is no more than time_e')
899
847
 
900
848
 
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):
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', without hour
909
- time_e: str, the end time, such as '20241102', without hour
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
- 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
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
- 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
914
+ if num_workers is not None:
915
+ num_workers = max(min(num_workers, 10), 1)
991
916
 
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.')
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
- print('The dataset_name and version_name are both set by yourself.')
1007
- print('Please ensure the dataset_name and version_name are correct.')
923
+ time_e = str(time_e)
924
+ if len(time_e) == 8:
925
+ time_e += '21'
1008
926
 
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)
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-4000 meters
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'] or var_name in ['u', 'v', 'u_b', 'v_b']:
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'] or var_name in ['temp', 'salt', 'temp_b', 'salt_b']:
1035
+ elif var_name in ['water_temp', 'salinity', 'water_temp_bottom', 'salinity_bottom']:
1125
1036
  fname = 'ts3z'
1126
- elif var_name in ['surf_el'] or var_name in ['ssh']:
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) """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oafuncs
3
- Version: 0.0.69
3
+ Version: 0.0.71
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=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.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.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,,