def get_member(grd, num): dat = grd.values[num, 0, 0, 0, :, :] grid0 = bd.get_grid_of_data(grd) grid1 = bd.grid(grid0.glon, grid0.glat, grid0.gtime, grid0.gdtime, grid0.levels) grd1 = bd.grid_data(grid1, dat) return grd1
def interpolation_linear(grd, sta, other_info='left'): grid = bd.get_grid_of_data(grd) sta1 = fun.get_from_sta.sta_in_grid_xy(sta, grid) dat0 = grd.values dat = np.squeeze(dat0) ig = ((sta1['lon'] - grid.slon) // grid.dlon).astype(dtype='int16') jg = ((sta1['lat'] - grid.slat) // grid.dlat).astype(dtype='int16') dx = (sta1['lon'] - grid.slon) / grid.dlon - ig dy = (sta1['lat'] - grid.slat) / grid.dlat - jg c00 = (1 - dx) * (1 - dy) c01 = dx * (1 - dy) c10 = (1 - dx) * dy c11 = dx * dy ig1 = np.minimum(ig + 1, grid.nlon - 1) jg1 = np.minimum(jg + 1, grid.nlat - 1) dat_sta = c00 * dat[jg, ig] + c01 * dat[jg, ig1] + c10 * dat[ jg1, ig] + c11 * dat[jg1, ig1] data_name = bd.get_data_names(sta)[0] sta1.loc[:, data_name] = dat_sta[:] if other_info == 'left': sta1['time'] = grid.stime sta1['dtime'] = grid.sdtimedelta sta1['level'] = grid.levels[0] bd.set_data_name(sta1, grid.members[0]) return sta1
def get_mean(grd, member_name): grid0 = bd.get_grid_of_data(grd) grid1 = bd.grid(grid0.glon, grid0.glat, grid0.gtime, grid0.gdtime, grid0.levels, members=[member_name]) dat = np.squeeze(grd.values) dat = np.mean(dat, axis=0) grd1 = bd.grid_data(grid1, dat) return grd
def interpolation_linear(grd, grid, other_info='left'): if (grd is None): return None # 六维转换为二维的值 dat0 = grd.values dat = np.squeeze(dat0) grd0 = bd.get_grid_of_data(grd) if (grd0.dlon * grd0.nlon >= 360): grd1 = bd.grid([grd0.slon, grd0.dlon, grd0.elon + grd0.dlon], [grd0.slat, grd0.dlat, grd0.elat]) dat1 = np.zeros((grd1.nlat, grd1.nlon)) dat1[:, 0:-1] = dat[:, :] dat1[:, -1] = dat[:, 0] else: dat1 = dat grd1 = grd0 if other_info == 'left': grd2 = bd.grid(grid.glon, grid.glat, grd0.gtime, grd0.gdtime, grd0.levels, grd0.members) else: grd2 = grid.copy() if (grd2.elon > grd1.elon or grd2.slon < grd1.slon or grd2.elat > grd1.elat or grd2.slat < grd1.slat): print("object grid is out range of original grid") return None #插值处理 x = ((np.arange(grd2.nlon) * grd2.dlon + grd2.slon - grd1.slon) / grd1.dlon) ig = x[:].astype(dtype='int16') dx = x - ig y = (np.arange(grd2.nlat) * grd2.dlat + grd2.slat - grd1.slat) / grd1.dlat jg = y[:].astype(dtype='int16') dy = y[:] - jg ii, jj = np.meshgrid(ig, jg) ii1 = np.minimum(ii + 1, grd1.nlon - 1) jj1 = np.minimum(jj + 1, grd1.nlat - 1) ddx, ddy = np.meshgrid(dx, dy) c00 = (1 - ddx) * (1 - ddy) c01 = ddx * (1 - ddy) c10 = (1 - ddx) * ddy c11 = ddx * ddy dat2 = (c00 * dat1[jj, ii] + c10 * dat1[jj1, ii] + c01 * dat1[jj, ii1] + c11 * dat1[jj1, ii1]) #print(grd2.tostring()) #print(dat2) grd_new = bd.grid_data(grd2, dat2) return grd_new
def add(grd1, grd2, other_info='left'): if (grd1 is None): return grd2 elif (grd2 is None): return grd1 else: grid1 = bd.get_grid_of_data(grd1) grid2 = bd.get_grid_of_data(grd2) slon = max(grid1.slon, grid2.slon) elon = min(grid1.elon, grid2.elon) slat = max(grid1.slat, grid2.slat) elat = min(grid1.elat, grid2.elat) if other_info == 'left': grid_in = bd.grid([slon, elon, grid1.dlon], [slat, elat, grid1.dlat], grid1.gtime, grid1.gdtime, grid1.levels, grid1.members) else: grid_in = bd.grid([slon, elon, grid2.dlon], [slat, elat, grid2.dlat], grid2.gtime, grid2.gdtime, grid2.levels, grid2.members) grd1_in = interpolation_linear(grd1, grid_in) grd2_in = interpolation_linear(grd2, grid_in) grd = bd.grid_data(grid_in, grd1_in.values + grd2_in.values) return grd
def interpolation_nearest(grd, sta, other_info='left'): grid = bd.get_grid_of_data(grd) sta1 = fun.get_from_sta.sta_in_grid_xy(sta, grid) dat0 = grd.values dat = np.squeeze(dat0) ig = np.round((sta1['lon'] - grid.slon) // grid.dlon).astype(dtype='int16') jg = np.round((sta1['lat'] - grid.slat) // grid.dlat).astype(dtype='int16') dat_sta = dat[jg, ig] data_name = bd.get_data_names(sta)[0] sta1.loc[:, data_name] = dat_sta[:] if other_info == 'left': sta1['time'] = grid.stime sta1['dtime'] = grid.sdtimedelta sta1['level'] = grid.levels[0] bd.set_data_name(sta1, grid.members[0]) return sta1
def transform(grd): x = grd['lon'] y = grd['lat'] grid_x, grid_y = np.meshgrid(x, y) grid_num = len(x) * len(y) dat = np.empty((grid_num, 4)) dat[:, 0] = np.arange(grid_num) dat[:, 1] = grid_x.reshape(-1) dat[:, 2] = grid_y.reshape(-1) dat[:, 3] = grd.values.reshape(-1) member = grd['member'][0] df = pd.DataFrame(dat, columns=['id', 'lon', 'lat', member]) sta = bd.sta_data(df) grid = bd.get_grid_of_data(grd) sta['time'] = grid.stime sta['dtime'] = grid.sdtimedelta sta['level'] = grid.levels[0] sta['alt'] = 9999 return sta
def cubicInterpolation(grd, sta, other_info='left'): grid = bd.get_grid_of_data(grd) sta1 = fun.get_from_sta_data.sta_in_grid_xy(sta, grid) dat0 = grd.values dat = np.squeeze(dat0) ig = ((sta1['lon'] - grid.slon) // grid.dlon).astype(dtype='int16') jg = ((sta1['lat'] - grid.slat) // grid.dlat).astype(dtype='int16') dx = (sta1['lon'] - grid.slon) / grid.dlon - ig dy = (sta1['lat'] - grid.slat) / grid.dlat - jg data_name = bd.get_data_names(sta1)[0] for p in range(-1, 3, 1): iip = np.minimum(np.maximum(ig + p, 0), grid.nlon - 1) fdx = cubic_f(p, dx) for q in range(-1, 3, 1): jjq = np.minimum(np.maximum(jg + q, 0), grid.nlat - 1) fdy = cubic_f(q, dy) fdxy = fdx * fdy sta1[data_name] += fdxy * dat[jjq, iip] if other_info == 'left': sta1['time'] = grid.stime sta1['dtime'] = grid.sdtimedelta sta1['level'] = grid.levels[0] bd.set_data_name(sta1, grid.members[0]) return sta1
def sta_to_grid_oa2(sta0, background, sm=1, effect_R=1000, rate_of_model=0): sta = fun.sxy_sxy.drop_nan(sta0) data_name = bd.get_data_names(sta)[0] grid = bd.get_grid_of_data(background) sta = fun.get_from_sta.sta_in_grid_xy(sta, grid) #print(sta) grd = background.copy() dat = np.squeeze(grd.values) ig = ((sta.ix[:, 'lon'] - grid.slon) // grid.dlon).astype(dtype='int16') jg = ((sta.ix[:, 'lat'] - grid.slat) // grid.dlat).astype(dtype='int16') dx = (sta.ix[:, 'lon'] - grid.slon) / grid.dlon - ig dy = (sta.ix[:, 'lat'] - grid.slat) / grid.dlat - jg c00 = (1 - dx) * (1 - dy) c01 = dx * (1 - dy) c10 = (1 - dx) * dy c11 = dx * dy lat = np.arange(grid.nlat) * grid.dlat + grid.slat sr = 1 / np.power(np.cos(lat * math.pi / 180), 4) def targe(x): grdv = x.reshape(grid.nlat, grid.nlon) dx = grdv[:, :-2] + grdv[:, 2:] - 2 * grdv[:, 1:-1] cost1 = np.sum(dx * dx) dy = grdv[:-2, :] + grdv[2:, :] - 2 * grdv[1:-1, :] dy2 = dy * dy sum_dy = np.sum(dy2, axis=1) cost1 = cost1 + np.dot(sum_dy, sr[1:-1]) sta_g = c00 * dat[jg, ig] + c01 * dat[jg, ig + 1] + c10 * dat[ jg + 1, ig] + c11 * dat[jg + 1, ig + 1] error = sta.ix[:, 7] - sta_g cost2 = np.sum(error * error) cost = sm * cost1 + cost2 return cost def grads(x): grdv = x.reshape(grid.nlat, grid.nlon) g1 = np.zeros(grdv.shape) dx = 2 * (grdv[:, :-2] + grdv[:, 2:] - 2 * grdv[:, 1:-1]) g1[:, :-2] = dx g1[:, 2:] += dx g1[:, 1:-1] -= 2 * dx sr_expend = np.tile(sr[1:-1], [grid.nlon, 1]).T dy = 2 * (grdv[:-2, :] + grdv[2:, :] - 2 * grdv[1:-1, :]) dy_sr = dy * sr_expend g1[:-2, :] += dy_sr g1[2:, :] += dy_sr g1[1:-1, :] -= 2 * dy_sr g2 = np.zeros(grdv.shape) sta_g = c00 * dat[jg, ig] + c01 * dat[jg, ig + 1] + c10 * dat[ jg + 1, ig] + c11 * dat[jg + 1, ig + 1] d = 2 * (sta_g - sta.ix[:, 7]) g2[jg, ig] += d * c00 g2[jg, ig + 1] += d * c01 g2[jg + 1, ig] += d * c10 g2[jg + 1, ig + 1] += d * c11 g = sm * g1 + g2 return g.reshape(-1) x = grd.values.reshape(-1) x_oa = frprmn2(x, targe, grads) grd.values = x_oa.reshape(1, 1, 1, 1, grid.nlat, grid.nlon) return grd
def write_to_micaps4(da, path="a.txt", effectiveNum=6): """ 输出micaps4格式文件 :param micaps_abspath:生成文件绝对路径 :param grid_data:网格数据 """ grid = bd.get_grid_of_data(da) nlon = grid.nlon nlat = grid.nlat slon = grid.slon slat = grid.slat elon = grid.elon elat = grid.elat dlon = grid.dlon dlat = grid.dlat level = grid.levels[0] stime = grid.stime_str year = stime[0:4] month = stime[4:6] day = stime[6:8] hour = stime[8:10] hour_range = str(grid.ddt_int) values = da.values grid_values = np.squeeze(values) vmax = math.ceil(max(grid_values.flatten())) vmin = math.ceil(min(grid_values.flatten())) dif = (vmax - vmin) / 10.0 if dif == 0: inte = 1 else: inte = math.pow(10, math.floor(math.log10(dif))) # 用基本间隔,将最大最小值除于间隔后小数点部分去除,最后把间隔也整数化 r = dif / inte if r < 3 and r >= 1.5: inte = inte * 2 elif r < 4.5 and r >= 3: inte = inte * 4 elif r < 5.5 and r >= 4.5: inte = inte * 5 elif r < 7 and r >= 5.5: inte = inte * 6 elif r >= 7: inte = inte * 8 vmin = inte * ((int)(vmin / inte) - 1) vmax = inte * ((int)(vmax / inte) + 1) end = len(path) start = max(0, end - 16) title = ("diamond 4 " + path[start:end] + "\n" + year + " " + month + " " + day + " " + hour + " " + hour_range + " " + str(level) + "\n" + str(grid.dlon) + " " + str(grid.dlat) + " " + str(grid.slon) + " " + str(grid.elon) + " " + str(grid.slat) + " " + str(grid.elat) + " " + str(grid.nlon) + " " + str(grid.nlat) + " " + str(inte) + " " + str(vmin) + " " + str(vmax) + " 1 0") # 第一行标题 title0 = 'diamond 4 %s\n' % stime # 第二行标题 title1 = '%s %s %s %s %s 999 %s %s %s %s %s %s %d %d 4 %s %s 2 0.00' \ % (year, month, day, hour, hour_range, dlon, dlat, slon, elon, slat, elat, nlon, nlat, vmax, vmin) #title = title0 + title1 # 二维数组写入micaps文件 format_str = "%." + str(effectiveNum) + "f " np.savetxt(path, grid_values, delimiter=' ', fmt=format_str, header=title, comments='') print('Create [%s] success' % path)
time_fo = datetime.datetime(2018,9,15,12) grid = bd.grid([105,115,0.5],[18,30,0.5]) sum_fo = None for dh in range(18,37,6): path = path_tools.get_path(dir_fo,time_fo,dh) sta = rs.read_from_micaps3(path) grd = fun.sxy_gxy.transform(sta) sum_fo = fun.gxy_gxy.add(sum_fo,grd) #输出累积降水量 #wg.write_to_micaps4(sum_fo) #读取站点观测数据,累加成24小时降水量 station = rs.read_from_micaps3("国家站.txt") station.iloc[:,7] = 0 grid_fo = bd.get_grid_of_data(sum_fo) station = fun.get_from_sta.sta_in_grid_xy(station,grid_fo) sum_ob = None for dh in range(13,37,1): time_ob = time_fo + datetime.timedelta(hours=8+dh) path = path_tools.get_path(dir_ob,time_ob) #print(path) sta = rs.read_from_micaps3(path,station=station) #print(sta) sum_ob = fun.sxy_sxy.add_on_id(sum_ob,sta) #ws.write_to_micaps3(sum_ob) #提取站点观测数据列至一个numpy数组 ob = sum_ob.iloc[:,7].values