def test( discipline_code=discipline_code, identification_section=identification_section, grid_definition_info=grid_definition_info, grid_definition_template=grid_definition_template, product_definition_template_number=product_definition_template_number, product_definition_template=product_definition_template, data_representation_template_number=data_representation_template_number, data_representation_template=data_representation_template): m4_fn = '/home/enso/max_micaps/data/tl.000' (data, stlon, edlon, stlat, edlat, xnum, ynum, xdelta, ydelta) = read_micaps_iv(m4_fn) identification_section[0] = 98 identification_section[5] = 2017 identification_section[6] = 3 identification_section[7] = 2 identification_section[8] = 17 grid_definition_info[1] = xnum * ynum grid_definition_template[7] = xnum grid_definition_template[8] = ynum grid_definition_template[11] = stlat * 1000000 grid_definition_template[12] = (stlon + 360) * 1000000 grid_definition_template[14] = edlat * 1000000 grid_definition_template[15] = (edlon + 360) * 1000000 grid_definition_template[16] = xdelta * 1000000 grid_definition_template[17] = ydelta * 1000000 product_definition_template[0] = 0 product_definition_template[1] = 4 product_definition_template[8] = 0 product_definition_template[9] = 103 product_definition_template[10] = 0 product_definition_template[11] = 2 (identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template) = [ np.array(_, dtype=np.int32) for _ in [ identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template ] ] fn = "201703021700_MICAPS-th_CHINA_27km" f = open(fn + '.grib2', 'wb') grbo = Grib2Encode(discipline_code, identification_section) grbo.addgrid(grid_definition_info, grid_definition_template) grbo.addfield(product_definition_template_number, product_definition_template, data_representation_template_number, data_representation_template, data) grbo.end() f.write(grbo.msg) f.close()
def encode_grib2_data(self): """ Encodes member percentile data to GRIB2 format. Returns: Series of GRIB2 messages """ lscale = 1e6 grib_id_start = [7, 0, 14, 14, 2] gdsinfo = np.array([0, np.product(self.data.shape[-2:]), 0, 0, 30], dtype=np.int32) lon_0 = self.proj_dict["lon_0"] sw_lon = self.grid_dict["sw_lon"] if lon_0 < 0: lon_0 += 360 if sw_lon < 0: sw_lon += 360 gdtmp1 = [1, 0, self.proj_dict['a'], 0, float(self.proj_dict['a']), 0, float(self.proj_dict['b']), self.data.shape[-1], self.data.shape[-2], self.grid_dict["sw_lat"] * lscale, sw_lon * lscale, 0, self.proj_dict["lat_0"] * lscale, lon_0 * lscale, self.grid_dict["dx"] * 1e3, self.grid_dict["dy"] * 1e3, 0b00000000, 0b01000000, self.proj_dict["lat_1"] * lscale, self.proj_dict["lat_2"] * lscale, -90 * lscale, 0] pdtmp1 = np.array([1, # parameter category Moisture 31, # parameter number Hail 4, # Type of generating process Ensemble Forecast 0, # Background generating process identifier 31, # Generating process or model from NCEP 0, # Hours after reference time data cutoff 0, # Minutes after reference time data cutoff 1, # Forecast time units Hours 0, # Forecast time 1, # Type of first fixed surface Ground 1, # Scale value of first fixed surface 0, # Value of first fixed surface 1, # Type of second fixed surface 1, # Scale value of 2nd fixed surface 0, # Value of 2nd fixed surface 0, # Derived forecast type 1 # Number of ensemble members ], dtype=np.int32) grib_objects = pd.Series(index=self.times, data=[None] * self.times.size, dtype=object) drtmp1 = np.array([0, 0, 4, 8, 0], dtype=np.int32) for t, time in enumerate(self.times): time_list = list(self.run_date.utctimetuple()[0:6]) if grib_objects[time] is None: grib_objects[time] = Grib2Encode(0, np.array(grib_id_start + time_list + [2, 1], dtype=np.int32)) grib_objects[time].addgrid(gdsinfo, gdtmp1) pdtmp1[8] = (time.to_pydatetime() - self.run_date).total_seconds() / 3600.0 data = self.data[t] / 1000.0 data[np.isnan(data)] = 0 masked_data = np.ma.array(data, mask=data<=0) pdtmp1[-2] = 0 grib_objects[time].addfield(1, pdtmp1, 0, drtmp1, masked_data) return grib_objects
def write_grib2(self, path): """ Writes data to grib2 file. Currently, grib codes are set by hand to hail. Args: path: Path to directory containing grib2 files. Returns: """ if self.percentile is None: var_type = "mean" else: var_type = "p{0:02d}".format(self.percentile) lscale = 1e6 grib_id_start = [7, 0, 14, 14, 2] gdsinfo = np.array([0, np.product(self.data.shape[-2:]), 0, 0, 30], dtype=np.int32) lon_0 = self.proj_dict["lon_0"] sw_lon = self.grid_dict["sw_lon"] if lon_0 < 0: lon_0 += 360 if sw_lon < 0: sw_lon += 360 gdtmp1 = np.array([7, 1, self.proj_dict['a'], 1, self.proj_dict['a'], 1, self.proj_dict['b'], self.data.shape[-2], self.data.shape[-1], self.grid_dict["sw_lat"] * lscale, sw_lon * lscale, 0, self.proj_dict["lat_0"] * lscale, lon_0 * lscale, self.grid_dict["dx"] * 1e3, self.grid_dict["dy"] * 1e3, 0, self.proj_dict["lat_1"] * lscale, self.proj_dict["lat_2"] * lscale, 0, 0], dtype=np.int32) pdtmp1 = np.array([1, 31, 2, 0, 116, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 192, 0, self.data.shape[0]], dtype=np.int32) for m, member in enumerate(self.members): pdtmp1[-2] = m for t, time in enumerate(self.times): time_list = list(time.utctimetuple()[0:6]) grbe = Grib2Encode(0, np.array(grib_id_start + time_list + [2, 1], dtype=np.int32)) grbe.addgrid(gdsinfo, gdtmp1) pdtmp1[8] = (time.to_pydatetime() - self.run_date).total_seconds() / 3600.0 drtmp1 = np.array([0, 0, 4, 8, 0], dtype=np.int32) data = self.data[m, t].astype(np.float32) / 1000.0 masked_data = np.ma.array(data, mask=data <= 0) grbe.addfield(1, pdtmp1, 0, drtmp1, masked_data) grbe.end() filename = path + "{0}_{1}_mlhail_{2}_{3}.grib2".format(self.ensemble_name.replace(" ", "-"), member, var_type, time.to_datetime().strftime("%Y%m%d%H%M")) print("Writing to " + filename) grib_file = open(filename, "wb") grib_file.write(grbe.msg) grib_file.close() return
def test( discipline_code=discipline_code, identification_section=identification_section, grid_definition_info=grid_definition_info, grid_definition_template=grid_definition_template, product_definition_template_number=product_definition_template_number, product_definition_template=product_definition_template, data_representation_template_number=data_representation_template_number, data_representation_template=data_representation_template): files = os.listdir(inputDir) files = sorted(files, key=lambda i: int(i.split('_')[1][0:10])) count = 0 for ff in files: fn = os.path.join(inputDir, ff) data = read_wrf(fn) identification_section[0] = 98 identification_section[5] = 2015 identification_section[6] = 7 identification_section[7] = 2 identification_section[8] = 0 grid_definition_info[1] = 500 * 420 grid_definition_template[7] = 500 grid_definition_template[8] = 420 product_definition_template[0] = 2 product_definition_template[1] = 3 product_definition_template[8] = count product_definition_template[9] = 103 product_definition_template[10] = 0 product_definition_template[11] = 10 (identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template) = [ np.array(_, dtype=np.int64) for _ in [ identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template ] ] if count < 10: tt = '0%s' % count else: tt = count fn = "2015070200%s_WRF-10mVWIND_CHINA_12km" % tt f = open(fn + '.grib2', 'wb') grbo = Grib2Encode(discipline_code, identification_section) grbo.addgrid(grid_definition_info, grid_definition_template) grbo.addfield(product_definition_template_number, product_definition_template, data_representation_template_number, data_representation_template, data) grbo.end() f.write(grbo.msg) f.close() count += 1
def test( discipline_code=discipline_code, identification_section=identification_section, grid_definition_info=grid_definition_info, grid_definition_template=grid_definition_template, product_definition_template_number=product_definition_template_number, product_definition_template=product_definition_template, data_representation_template_number=data_representation_template_number, data_representation_template=data_representation_template): files = os.listdir(os.path.join(inputDir, 'ecmwf_thin', 'T', '850')) for ff in files: m4_fn = os.path.join(inputDir, 'ecmwf_thin', 'T', '850', ff) (data, X, Y, year, month, day, hour, prep, xx, yy, stlon, edlon, stlat, edlat, xnum, ynum, xdelta, ydelta) = read_micaps_iv(m4_fn) identification_section[0] = 98 identification_section[5] = 2000 + int(year) identification_section[6] = month identification_section[7] = day identification_section[8] = hour grid_definition_info[1] = xnum * ynum grid_definition_template[7] = xnum grid_definition_template[8] = ynum grid_definition_template[11] = stlat * 1000000 grid_definition_template[12] = (stlon + 360) * 1000000 grid_definition_template[14] = edlat * 1000000 grid_definition_template[15] = (edlon + 360) * 1000000 grid_definition_template[16] = xdelta * 1000000 grid_definition_template[17] = ydelta * 1000000 product_definition_template[0] = 0 product_definition_template[1] = 0 product_definition_template[8] = int(prep) product_definition_template[9] = 100 product_definition_template[10] = 0 product_definition_template[11] = 85000 (identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template) = [ np.array(_, dtype=np.int32) for _ in [ identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template ] ] fn = "20%s%s%s0000_EC-850hpa-air-temperature-%sh_CHINA_27km" % ( year, month, day, prep) f = open(fn + '.grib2', 'wb') grbo = Grib2Encode(discipline_code, identification_section) grbo.addgrid(grid_definition_info, grid_definition_template) grbo.addfield(product_definition_template_number, product_definition_template, data_representation_template_number, data_representation_template, data) grbo.end() f.write(grbo.msg) f.close()
def data2grib_smiple(self,discipline,category,element,statistical,status,year,month,day,hour,minute,second,forecasttime,timerange,field,ngrdpts,leveltype,level,generating_method,istimepoint): date_time=datetime.datetime(int(year),int(month),int(day),int(hour),int(minute),int(second))#起报时间 '''定义 section0-1 @discipline:Discipline or GRIB Master Table Number (Code Table 0.0). (0 for meteorlogical, 1 for hydrological, 2 for land surface, 3 for space, 10 for oceanographic products),学科,默认0 @idsect:Sequence containing identification section (section 1),section1内容 Must have len >= 13. listsec1[0]=Id of orginating centre (Common Code Table C-1),中心点,固定值38,北京 listsec1[1]=Id of orginating sub-centre (local table),子中心点,默认0 listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0),主表版本号,0:时间点产品,8:时间段产品 listsec1[3]=GRIB Local Tables Version Number (Code Table 1.1),固定值0,没有本地表 listsec1[4]=Significance of Reference Time (Code Table 1.2),固定值1,表示起报时间 listsec1[5]=Reference Time - Year (4 digits) listsec1[6]=Reference Time - Month listsec1[7]=Reference Time - Day listsec1[8]=Reference Time - Hour listsec1[9]=Reference Time - Minute listsec1[10]=Reference Time - Second listsec1[11]=Production status of data (Code Table 1.3),产品状态 表:Status 产品状态定义 VALUE值 REMARKS描述 0 正式产品 1 测试产品 2 科研 3 再分析 4 TIGGE 5 TIGGE测试 listsec1[12]=Type of processed data (Code Table 1.4),数据类型,固定值1:预报产品 ''' # section1 #discipline = 0 # 学科 #year = 2019 #month = 11 #day = 19 #hour = 20 #minute = 0 #second = 0 #status = 0 # 产品状态 idsect = [38, 0, 0, 0, 1, year, month, day, hour, minute, second, status, 1] # 初始化Grib2Encode类 ge = Grib2Encode(discipline, idsect) gdsinfo = [0, ngrdpts, 0, 0, 0] '''格点定义模板的内容值,默认使用Template3.0 @param gdtmpl: Contains the data values for the specified Grid Definition Template ( NN=gdsinfo[4] ). Each element of this integer array contains an entry (in the order specified) of Grid Definition Template 3.NN, 按照顺序列出Template3.0的值 字节范围 类型 描述 内容 15 CHAR 地球模型参数 固定值为6:地球半径为 6,371,229.0米 16 CHAR 地球模型参数 固定值为0: 17-20 INT 地球模型参数 固定值为0: 21 CHAR 地球模型参数 固定值为0: 22-25 INT 地球模型参数 固定值为0: 26 CHAR 地球模型参数 固定值为0: 27-30 INT 地球模型参数 固定值为0: 31-34 INT 横向格点数 经度方向 35-38 INT 纵向格点数 纬度方向 39-42 INT 基本角度单位 固定值为1 43-46 INT 基本角度份数 固定值为1000000 47-50 INT 纬度起始点位置 值为:起始纬度* 1000000 51-54 INT 经度起始点位置 值为:起始经度* 1000000 55 CHAR 经度和纬度方向的增量信息 值为48 56-59 INT 纬度终止点位置 值为:终止纬度* 1000000 60-63 INT 经度终止点位置 值为:终止纬度* 1000000 64-67 INT 经度方向的格距 值为:经度格距* 1000000 68-71 INT 纬度方向的格距 值为:纬度格距* 1000000 72 CHAR 数据的扫描方向 值64表示:经度方向为从小到大,纬度方向为从小到大 ''' ge.addgrid(gdsinfo, self.gdtmpl) '''写入section4-7 @pdtnum:Product Definition Template Number 产品模板编号 默认0:使用模板4.0(时间点产品[温度,相对湿度,能见度,风-U,风-V,雾,霾,雷暴等]) 默认8:使用模板4.8(时间段产品[最大温度,最小相对湿度,累积降水等]) @pdtmpl:Sequence with the data values for the specified Product Definition Template (N=pdtnum),对应产品模板的内容,按照顺序排 ================================================================== 产品模版4.0 时间点产品 字节范围 类型 描述 内容 10 CHAR 产品的分类 *Note1 11 CHAR 产品的编号 *Note2 12 CHAR 生成方法 2: Forecast预报产品 8:Observation实况产品 13 CHAR 后台生成进程标识 固定值为0 14 CHAR 确定分析和预报生成过程 固定值为0 15-16 SHORT 在起报时间后,需cut-off的数据时间小时部分 固定值为0 17 CHAR 在起报时间后,需cut-off的数据时间分钟部分 固定值为0 18 CHAR 时间范围的单位 固定值为1:1小时 19-22 INT 相对于起报时间,预报时间的时间数 23 CHAR 第一层次类型 *Note3 24 CHAR 第一层次因子 固定值为0 25-28 INT 第一层次值 *Note4 29 CHAR 第二层次类型 固定值为255 30 CHAR 第二层次因子 固定值为0 31-34 INT 第二层次值 固定值为0 ===================================================================== 产品模版4.8 时间段产品 字节范围 类型 描述 内容 10 CHAR 产品的分类 *Note1 11 CHAR 产品的编号 *Note2 12 CHAR 生成方法 2: Forecast预报产品 8:Observation实况产品 13 CHAR 后台生成进程标识 固定值为0 14 CHAR 确定分析和预报生成过程 固定值为0 15-16 SHORT 在起报时间后,需cut-off的数据时间小时部分 固定值为0 17 CHAR 在起报时间后,需cut-off的数据时间分钟部分 固定值为0 18 CHAR 时间范围的单位 固定值为1:1小时 19-22 INT 相对于起报时间,预报时间的时间数 *Note6 23 CHAR 第一层次类型 *Note3 24 CHAR 第一层次因子 固定值为0 25-28 INT 第一层次值 *Note4 29 CHAR 第二层次类型 固定值为255 30 CHAR 第二层次因子 固定值为0 31-34 INT 第二层次值 固定值为0 35-36 SHORT 预报结束时间年 37 CHAR 预报结束时间月 38 CHAR 预报结束时间日 39 CHAR 预报结束时间时 40 CHAR 预报结束时间分 41 CHAR 预报结束时间秒 42 CHAR 时间范围的数量 固定为1 43-46 INT 缺测数据总个数 47 CHAR 统计处理方式 *Note5 48 CHAR 时间增量类型 固定值为2:对于同一起报时间的多个连续的预报,预报时间是递增的 49 CHAR 预报时间范围单位 固定为1:小时 50-53 INT 时间范围长度 以49字节为单位 54 CHAR 递增时间单位 固定为1:小时 55-58 INT 连续预报时间段的时间增量 @drtnum:Data Representation Template Number,数据表示段 模板编号 @drtmpl:Sequence with the data values for the specified Data Representation Template,对应数据段模板的内容,按照顺序排 字节范围 类型 描述 内容 12-15 FLOAT 参考值 9999 16-17 SHORT 二进制比例因子 0 18-19 SHORT 十进制比例因子 0 20 CHAR Simple压码每个包的字节个数 24 21 CHAR 原数据值的类型 固定为0:原始数据为浮点数 默认:drtmpl=[9999,0,0,24,0] @field:numpy array of data points to pack. If field is a masked array, then a bitmap is created from the mask,格点场数据,按先经度后纬度,经向先西后东(从小到大),纬向先南后北(从小到大)顺序装填 @coordlist:Sequence containing floating point values intended to document the vertical discretization with model data on hybrid coordinate vertical levels. Default None ''' # section 4 产品模板定义 #isTimePoint = True # 是否是时间点产品,温度,风,相对湿度,云量等都是时间点的数据,而降水,最高温,最低温,最大相对湿度,最小相对湿度等都是时间段的数据 pdtnum = 0 if istimepoint == True else 8 # 0:时间点产品;8:时间段产品 # 测试平均温度 某时间点的2米温度,level type:103,level:2,产品模板4.0,unit:k,category:0,element:0,statistical:0,status:0 #category = 0 #element = 0 product_type = generating_method # 2:预报产品 8:实况产品 再分析产品=? #statistical = 0 #time_range = 3 # 相对于起报时间,预报时间的时间数(该模版中的预报时效为每一段的起始预报时间的时间数,如3小时间隔的预报时间的时间数为0,3,6…) #level_type = 103 #level = 2 #连续预报时间段的时间增量 #time_increment=0 if istimepoint == True: pdtmpl = [category, element, product_type, 0, 0, 0, 0, 1, forecasttime, leveltype, 0, level, 255, 0, 0] else: # 缺测数据总个数,默认0 miss_value_count = 0 # 预报结束时间,根据起报时间+预报时效计算得出,是时间范围 forecast_time = gt.addtime_hour(date_time, forecasttime) forecast_year = forecast_time.year forecast_month = forecast_time.month forecast_day = forecast_time.day forecast_hour = forecast_time.hour forecast_minute = forecast_time.minute forecast_second = forecast_time.second pdtmpl = [category, element, product_type, 0, 0, 0, 0, 1, forecasttime, leveltype, 0, level, 255, 0, 0, forecast_year, forecast_month, forecast_day, forecast_hour, forecast_hour, forecast_minute, forecast_second, 1, miss_value_count, statistical, 2, 1, 49, 1,timerange] # section 5 drtnum = 0 # section5数据表示段,模板5.0,赋值 drtmpl = [9999, 0, 0, 24, 0] #drtmpl = [1208536781, -3, 1, 24, 0] #field = None ge.addfield(pdtnum, pdtmpl, drtnum, drtmpl, field) # finalize the grib message. ge.end() self.message=ge
def test( discipline_code = discipline_code, identification_section = identification_section, grid_definition_info = grid_definition_info, grid_definition_template = grid_definition_template, product_definition_template_number = product_definition_template_number, product_definition_template = product_definition_template, data_representation_template_number = data_representation_template_number, data_representation_template = data_representation_template): files = os.listdir(os.path.join(inputDir, 'ecmwf_thin', 'dt', '1000', '4')) files = sorted(files, key=lambda i:-int(i.split('.')[1])) count = 0 for ff in files: m4_fn = os.path.join(inputDir, 'ecmwf_thin', 'dt', '1000', '4', ff) ( data, X, Y, year, month, day, hour, prep, xx, yy, stlon, edlon, stlat, edlat, xnum, ynum, xdelta, ydelta ) = read_micaps_iv(m4_fn) identification_section[0] = 98 identification_section[5] = 2000 + int(year) identification_section[6] = month identification_section[7] = day identification_section[8] = hour grid_definition_info[1] = xnum * ynum grid_definition_template[7] = xnum grid_definition_template[8] = ynum grid_definition_template[11] = stlat * 1000000 grid_definition_template[12] = (stlon+360) * 1000000 grid_definition_template[14] = edlat * 1000000 grid_definition_template[15] = (edlon+360) * 1000000 grid_definition_template[16] = xdelta * 1000000 grid_definition_template[17] = ydelta * 1000000 product_definition_template[0] = 0 product_definition_template[1] = 9 product_definition_template[8] = int(prep) product_definition_template[9] = 100 product_definition_template[10] = 0 product_definition_template[11] = 1000*100 ( identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template ) = [np.array(_, dtype=np.int32) for _ in [ identification_section, grid_definition_info, grid_definition_template, product_definition_template, data_representation_template ]] if count < 10: tt = '0%s' %count else: tt =count if int(hour)-8 == 0: hh = '00' else: hh = int(hour) - 8 fn = "20%s%s%s%s%s_EC-1000hpa24hTemperature_CHINA_27km" %(year, month, day, hh, tt) f=open(fn + '.grib2','wb') grbo = Grib2Encode( discipline_code, identification_section) grbo.addgrid( grid_definition_info, grid_definition_template) grbo.addfield( product_definition_template_number, product_definition_template, data_representation_template_number, data_representation_template, data) grbo.end() f.write(grbo.msg) f.close() count +=1
from ncepgrib2 import Grib2Decode, Grib2Encode from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt # read soil moisture grib record with GRIB API. grbs = pygrib.open('../sampledata/gfs.t12z.pgrbf120.2p5deg.grib2') grbmsg = grbs[208] # soil moisture data = grbmsg.values print(data.min(), data.max()) # convert grib message to a ncepgrib2.Grib2Message instance. grb = Grib2Decode(grbmsg.tostring(), gribmsg=True) # re-write the grib message to a new file. f = open('test_masked.grb', 'wb') grbo = Grib2Encode(grb.discipline_code, grb.identification_section) grbo.addgrid(grb.grid_definition_info, grb.grid_definition_template) # add product definition template, data representation template # and data (including bitmap which is read from data mask). grbo.addfield(grb.product_definition_template_number, grb.product_definition_template, grb.data_representation_template_number, grb.data_representation_template, data) # finalize the grib message. grbo.end() # write it to the file. f.write(grbo.msg) # close the output file f.close() # read and plot the data in the new file.