Python 批量下载 ERA-5 Reanalysis 数据

ECMWF大气再分析数据集 ERA-interim 已被 ERA-5 数据集取代,ERA-5 详细信息看这里 

 

下面介绍下载的具体步骤:

 

1. 要下载 ERA-5 数据集,需要先注册一个 CDS 账号。登录之后进入 Climate Data Store API 页面复制自己的 key 和 url,如下图

2. 创建 .cdsapirc 文件,windows系统就是自己的用户目录下面,linux就是根目录,内容为自己的 key 和 url,示例如下图

3. 安装 cdsapi   用 pip install cdsapi,或者 conda install cdaspi 都可

4. 直接上代码,多线程下载

"""
@author: zhe zhang
@contact: zhangzhesci@gmail.com
@software: PyCharm
@file: ERA5_Download
@time: 2021年5月21日14:40:49
"""

from queue import Queue
from threading import Thread
import cdsapi
from time import time
import datetime
import os
import numpy as np

def readTyphoonByTime(file_path):
    list_bst_all = []
    list_temp = []
    with open(file_path, "r") as f:
        for line in f.readlines():
            line = line.strip('\n')
            line_np = line.split()
            if line_np[0] == '66666':
                # print(line_np[3])
                if len(list_temp) > 1:
                    list_bst_all.append(list_temp)
                list_temp = []
            else:
                list_temp.append(line_np)
        list_bst_all.append(list_temp)
    return list_bst_all


def downloadSingleGrib(single_trk):
    '''
    :param year: 2020
    :param month: 11
    :param day: 13
    :param time: 09:00
    :param file_name:  './data_era5/download.grib'
    :return:
    '''
    # 示例值 ['2020061106', '1', '145', '1226', '1004', '13']
    year = single_trk[0][0:4]
    subdir = './data_era5/' + year
    if not os.path.exists(subdir):
        os.makedirs(subdir)
    month = single_trk[0][4:6]
    day = single_trk[0][6:8]
    time = single_trk[0][8:10] + ':00'
    file_name = str(single_trk[6]) + '_' + str(single_trk[0]) + '.grib'
    file_name = os.path.join(subdir, file_name)
    if os.path.exists(file_name):
        print('file == ' + file_name + ' == alreay exist!')
    else:
        c = cdsapi.Client()
        try:
            c.retrieve(
                'reanalysis-era5-pressure-levels',
                {
                    'product_type': 'reanalysis',
                    'variable': [
                        'relative_humidity', 'temperature', 'u_component_of_wind', 'v_component_of_wind',
                    ],
                    'pressure_level': [
                        '50', '150',
                        '350', '550', '750', '950',
                    ],
                    'year': year,
                    'month': month,
                    'day': day,
                    'time': time,
                    'format': 'grib',
                    'area': [  
                        90, 90, 0,
                        180,
                    ],
                    # 'nocache': str(random.randint(1000, 2000)),
                },
                file_name)
        except Exception as e:
            print("*****exception*****" + file_name)
            list_fail_grib.append(file_name)
        else:
            print('------------download successfully:' + file_name + '------------')

# 下载脚本
class DownloadWorker(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            # 从队列中获取任务并扩展tuple
            data = self.queue.get()
            downloadSingleGrib(data)
            self.queue.task_done()


list_fail_grib = []
if __name__ == '__main__':
    # 定义程序起始时间,下载结束后,根据结束时间计算共花费多长时间

    bst_file_path = ['./cma_bst/CH2020BST.txt', './cma_bst/CH2019BST.txt',
                     './cma_bst/CH2018BST.txt', './cma_bst/CH2017BST.txt']


    # 建立下载日期序列
    links = []

    for bst_file in bst_file_path:
        bst_file_list = readTyphoonByTime(bst_file)
        for idx, typhoon_bst in enumerate(bst_file_list):
            for single_trk in typhoon_bst:
                single_trk.append(idx)
                links.append(single_trk)


    # 创建一个主进程与工作进程通信
    queue = Queue()

    # 注意,每个用户同时最多接受4个
    # 参考:request https://cds.climate.copernicus.eu/vision

    # 创建四个工作线程
    for x in range(4):
        worker = DownloadWorker(queue)
        # 将daemon设置为True将会使主线程退出,即使所有worker都阻塞了
        worker.daemon = True
        worker.start()

    # 将任务以tuple的形式放入队列中
    for link in links:
        queue.put((link))

    # 让主线程等待队列完成所有的任务
    queue.join()
    print('*********** ALL Done *************')

    # 将下载失败的文件写出为npy
    fail_arr = np.array(list_fail_grib)
    np.save('./failure_file.npy', fail_arr)
    print('over')

问题:

1. 数据一直 Queued,速度很慢怎么办?

1. CDSAPI 有同时请求个数的限制,主要不要超过。发送请求时注意 “cache” 参数,如果为随机数的话,每次都会重新下载,但如果没有 cache 参数,会直接返回你已经请求过的数据(速度快,但之前没下过就没用了)
2. 可以在CDS网站反馈,会有客服回答,服务很好。

2. 其他

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值