在Python中读取二维二进制数据并以NetCDF格式写入

时间:2014-10-11 07:58:53

标签: python python-2.7 netcdf

我的二进制数据包含以下标题信息:

DSET ../prcp/cmorph_test
OPTIONS template little_endian
UNDEF  -999.0
TITLE  Precipitation estimates
XDEF 1440 LINEAR    0.125  0.25
YDEF  480 LINEAR  -59.875  0.25
ZDEF   01 LEVELS 1
TDEF 999999 LINEAR  00z01jan2014  3hr
VARS 1
cmorph   1   99 RAW CMORPH integrated satellite precipitation estimates [mm/3hr]
ENDVARS

请建议是否可以阅读(并且任何示例代码段真的很有帮助)并使用Python将其转换为NetCDF?

2 个答案:

答案 0 :(得分:2)

我无法帮助读取二进制数据,但您可以读取/写入netcdf文件: https://github.com/unidata/netcdf4-python

答案 1 :(得分:0)

美国国家航空航天局的家伙似乎没有回复任何电子邮件。

它下载数据并作图以比较可在其中找到的内容 ftp://ftp.cpc.ncep.noaa.gov/precip/global_CMORPH/3-hourly_025deg/cmorph-precip_3hrly-025deg.gif

import numpy as np
import os
import datetime
import bz2
import urllib.request as request
from contextlib import closing
import shutil
import matplotlib.pyplot as plt


def get_closest_file_index(hour=None, dataHours=np.array([0,3,6,9,12,15,18,21,24])):
    """
    hour is in decimal format: that is 7:40 am is 7.66666
    assuming here we have 8 data files/ 24h == 0,3,6,9,12,15,18,21
    (24 is with to get datapoints from the next 24h period)
    """
    return (np.argmin(np.abs(float(hour)-dataHours)))

def cmorph_download(year=None, month=None, day=None, hour=None,
                    urlStart='ftp://ftp.cpc.ncep.noaa.gov/precip/CMORPH_V1.0/CRT/0.25deg-3HLY/',
                    ext='.bz2'):
    """
    Returns rain-rate in single grid, first dimension is lat, second lon
    first data is from data[lat=-59.875, lon=0.125] , step is 0.25

    download cmorph water data from
    ftp://ftp.cpc.ncep.noaa.gov/precip/CMORPH_V1.0/CRT/0.25deg-3HLY/

    data is real*4 little endian binary

    ftp://ftp.cpc.ncep.noaa.gov/precip/CMORPH_V1.0/CTL/CMORPH_V1.0_CRT_0.25deg-3HLY.ctl
    There it says:
    OPTIONS template little_endian
    UNDEF  -999.0
    TITLE  Precipitation estimates
    XDEF 1440 LINEAR    0.125  step 0.25 last is 359.875
    YDEF  480 LINEAR   59.875  step 0.25 last is -59.875
    ZDEF   01 LEVELS 1

    motivation:
  
    The CMORPH technique provides a passive
    microwave (PMW) rain-rate dataset that is derived from
    low-Earth-orbit microwave satellite observations, and
    these observations are translated via spatial propagation
    information obtained from geostationary IR1 data.
    """
    fileNumber = get_closest_file_index(hour=hour)
    if fileNumber == 8:
        # data is from the next day...
        # so we take it next day at 0am
        fileNumber = 0
        minute = round((float(hour) - int(hour)) * 60.)
        dataDate = datetime.datetime(int(year), int(month), int(day), int(hour), int(minute))
        year = dataDate.year
        month = dataDate.month
        day = dataDate.day
    print("fileNumber:", fileNumber)
    file = 'CMORPH_V1.0_ADJ_0.25deg-3HLY_' \
           + str(year) + str(month).rjust(2,'0') + str(day).rjust(2,'0') \
           + ext

    ftppath = urlStart \
              + '/' + str(year) \
              + '/' + str(year) + str(month).rjust(2,'0') \
              + '/' + file


    fileName = file
    if not os.path.exists(fileName):
        with closing(request.urlopen(ftppath)) as r:
            print(f"Downloading... {ftppath}")
            with open(fileName, 'wb') as f:
                shutil.copyfileobj(r, f)
    else:
        print("using old file:", fileName)

    with bz2.open(fileName, "rb") as f:
        # Decompress data from file
        data = f.read()
    data = np.fromstring(data, dtype='<f4')
    data = np.reshape(data, (8, (120 * 4), (360 * 4)))
    data = data[fileNumber, ...]
    data = np.squeeze(data)

    return data

data = cmorph_download(year=2012, month=3, day=19, hour=3)
# to compare with
# ftp://ftp.cpc.ncep.noaa.gov/precip/global_CMORPH/3-hourly_025deg/cmorph-precip_3hrly-025deg.gif
plt.contour(data)
plt.show()