def krigall(self, pt, nnghs, stns_rm=None): ''' Run moving window variogram fitting and regression kriging to interpolate monthly temperature normals to a single point location. Parameters ---------- pt : structured array A structured array containing the point's latitude, longitude, elevation, topographic dissection index, and average land skin temperatures for each month. An empty point can be initialized with build_empty_pt() nnghs : int The number of neighboring stations to use. stns_rm : ndarray or str, optional An array of station ids or a single station id for stations that should not be considered neighbors for the specific point. Returns ---------- interp_norms : ndarray A 1-D array of size 12 containing the interpolated monthly normals ''' self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], nnghs, load_obs=False, stns_rm=stns_rm) nghs = self.stn_slct.ngh_stns ngh_lon = ri.FloatSexpVector(nghs[LON]) ngh_lat = ri.FloatSexpVector(nghs[LAT]) ngh_elev = ri.FloatSexpVector(nghs[ELEV]) ngh_tdi = ri.FloatSexpVector(nghs[TDI]) ngh_wgt = ri.FloatSexpVector(self.stn_slct.ngh_wgt) ngh_dists = ri.FloatSexpVector(self.stn_slct.ngh_dists) interp_norms = np.zeros(12) for mth in np.arange(1, 13): ngh_lst = ri.FloatSexpVector(nghs[get_lst_varname(mth)]) ngh_tair = ri.FloatSexpVector(nghs[get_norm_varname(mth)]) pt_svp = ri.FloatSexpVector((pt[LON], pt[LAT], pt[ELEV], pt[TDI], pt[get_lst_varname(mth)])) rslt = self.r_func(pt_svp, ngh_lon, ngh_lat, ngh_elev, ngh_tdi, ngh_lst, ngh_tair, ngh_wgt, ngh_dists) interp_norms[mth - 1] = rslt[0] return interp_norms
def gwr_mth(self, pt, mth, nnghs=None, stns_rm=None): if nnghs == None: # Get the nnghs to use from the optimal values at surrounding stations nnghs = self._GwrTairAnom__get_nnghs(pt, mth, stns_rm) self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], nnghs, load_obs=True, stns_rm=stns_rm, obs_mth=mth) ngh_obs = self.stn_slct.ngh_obs ngh_stns = self.stn_slct.ngh_stns ngh_wgt = self.stn_slct.ngh_wgt ngh_obs_cntr = ngh_obs - ngh_stns[get_norm_varname(mth)] a_pt = np.array( [pt[LON], pt[LAT], pt[ELEV], pt[TDI], pt[get_lst_varname(mth)]]) rslt = r.gwr_anomaly( robjects.FloatVector(ngh_stns[LON]), robjects.FloatVector(ngh_stns[LAT]), robjects.FloatVector(ngh_stns[ELEV]), robjects.FloatVector(ngh_stns[TDI]), robjects.FloatVector(ngh_stns[get_lst_varname(mth)]), robjects.FloatVector(ngh_wgt), robjects.Matrix(ngh_obs_cntr), robjects.FloatVector(a_pt)) fit_anom = np.array(rslt.rx('fit_anom')) nrow = np.array(rslt.rx('fit_nrow'))[0] ncol = np.array(rslt.rx('fit_ncol'))[0] fit_anom = np.reshape(fit_anom, (nrow, ncol), order='F') interp_anom = np.array(rslt.rx('pt_anom')).ravel() interp_vals = interp_anom + pt[get_norm_varname(mth)] return interp_vals
def gwr_predict(self, pt, mth, nnghs=None, stns_rm=None): if nnghs is None: # Get the nnghs to use from the optimal values at surrounding stations nnghs = self.__get_nnghs(pt, mth, stns_rm) self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], nnghs, load_obs=False, stns_rm=stns_rm) nghs = self.stn_slct.ngh_stns ngh_lon = ri.FloatSexpVector(nghs[LON]) ngh_lat = ri.FloatSexpVector(nghs[LAT]) ngh_elev = ri.FloatSexpVector(nghs[ELEV]) ngh_tdi = ri.FloatSexpVector(nghs[TDI]) ngh_lst = ri.FloatSexpVector(nghs[get_lst_varname(mth)]) ngh_tair = ri.FloatSexpVector(nghs[get_norm_varname(mth)]) pt_svp = ri.FloatSexpVector( (pt[LON], pt[LAT], pt[ELEV], pt[TDI], pt[get_lst_varname(mth)])) ngh_wgt = ri.FloatSexpVector(self.stn_slct.ngh_wgt) rslt = self.r_gwr_func(ngh_lon, ngh_lat, ngh_elev, ngh_tdi, ngh_lst, ngh_tair, ngh_wgt, pt_svp) tair_mean = rslt[0] tair_var = rslt[1] bad_interp = rslt[2] if bad_interp != 0: print "".join( ["ERROR: ", str(bad_interp), " bad interp: ", str(pt)]) return tair_mean, tair_var
def build_empty_pt(): ptDtype = [(LON, np.float64), (LAT, np.float64), (ELEV, np.float64), (TDI, np.float64), (CLIMDIV, np.float64), (MASK, np.float64)] ptDtype.extend([("tmin%02d" % mth, np.float64) for mth in np.arange(1, 13)]) ptDtype.extend([("tmax%02d" % mth, np.float64) for mth in np.arange(1, 13)]) ptDtype.extend([(get_norm_varname(mth), np.float64) for mth in np.arange(1, 13)]) ptDtype.extend([(get_optim_varname(mth), np.float64) for mth in np.arange(1, 13)]) ptDtype.extend([(get_lst_varname(mth), np.float64) for mth in np.arange(1, 13)]) ptDtype.extend([(get_optim_anom_varname(mth), np.float64) for mth in np.arange(1, 13)]) a_pt = np.empty(1, dtype=ptDtype) return a_pt[0]
def __init__(self, stn_slct): ''' Parameters ---------- stn_slct : StationSelect A StationSelect object for finding and selecting neighboring stations to a point. ''' self.stn_slct = stn_slct mthly_predictors = {} predictors = np.array(GWR_TREND_VARS, dtype="<S16") mthly_predictors[None] = predictors for mth in np.arange(1, 13): mthP = np.copy(predictors) mthP[mthP == LST] = get_lst_varname(mth) mthly_predictors[mth] = mthP self.mthly_predictors = mthly_predictors
def __init__(self, stn_da): ''' Parameters ---------- stnda : twx.db.StationSerialDataDb A StationSerialDataDb object pointing to the database from which observations will be loaded. ''' self.stn_da = stn_da mask_stns = np.isnan(self.stn_da.stns[BAD]) self.stn_slct = StationSelect(self.stn_da, stn_mask=mask_stns, rm_zero_dist_stns=True) self.vnames_norm = [get_norm_varname(mth) for mth in np.arange(1, 13)] self.vnames_lst = [get_lst_varname(mth) for mth in np.arange(1, 13)] self.df_stns = pd.DataFrame(self.stn_da.stns) self.df_stns.index = self.df_stns[STN_ID] # Calculate annual means for monthly LST and Tair normals self.df_stns['lst'] = self.df_stns[self.vnames_lst].mean(axis=1) self.df_stns['norm'] = self.df_stns[self.vnames_norm].mean(axis=1)
def krig(self, pt, mth, nnghs=None, vario_params=None, stns_rm=None): ''' Run moving window regression kriging to interpolate a temperature normal for a specific month to a single point location. Parameters ---------- pt : structured array A structured array containing the point's latitude, longitude, elevation, topographic dissection index, and average land skin temperatures for each month. An empty point can be initialized with build_empty_pt() mth : int, optional The month for which to interpolate a temperature normal nnghs : int, optional The number of neighboring stations to use. If not provided, nnghs will be determined from the previously determined optimal number at surrounding neighboring stations. vario_params : tuple, optional A tuple of size 3 (nugget, sill, range). If not provided, the variogram parameters will be determined from previously fit variogram parameters at neighboring stations stns_rm : ndarray or str, optional An array of station ids or a single station id for stations that should not be considered neighbors for the specific point. Returns ---------- tair_mean : float The interpolated temperature normal. tair_var : float The kriging prediction variance for the temperature normal. ''' if nnghs is None: # Get the nnghs to use from the optimal values at surrounding stations nnghs = self.__get_nnghs(pt, mth, stns_rm) self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], nnghs, load_obs=False, stns_rm=stns_rm) if vario_params is None: nug, psill, vrange = self.__get_vario_params(pt, mth) else: nug, psill, vrange = vario_params nghs = self.stn_slct.ngh_stns ngh_lon = ri.FloatSexpVector(nghs[LON]) ngh_lat = ri.FloatSexpVector(nghs[LAT]) ngh_elev = ri.FloatSexpVector(nghs[ELEV]) ngh_tdi = ri.FloatSexpVector(nghs[TDI]) ngh_lst = ri.FloatSexpVector(nghs[get_lst_varname(mth)]) ngh_tair = ri.FloatSexpVector(nghs[get_norm_varname(mth)]) pt_svp = ri.FloatSexpVector( (pt[LON], pt[LAT], pt[ELEV], pt[TDI], pt[get_lst_varname(mth)])) nug = ri.FloatSexpVector([nug]) psill = ri.FloatSexpVector([psill]) vrange = ri.FloatSexpVector([vrange]) ngh_wgt = ri.FloatSexpVector(self.stn_slct.ngh_wgt) rslt = self.r_krig_func(ngh_lon, ngh_lat, ngh_elev, ngh_tdi, ngh_lst, ngh_tair, ngh_wgt, pt_svp, nug, psill, vrange) tair_mean = rslt[0] tair_var = rslt[1] bad_interp = rslt[2] if bad_interp != 0: print "".join( ["ERROR: ", str(bad_interp), " bad interp: ", str(pt)]) return tair_mean, tair_var
def get_krig_params(self, pt, mth, rm_stnid=None): ''' Get the moving window regression kriging variogram parameters for a specific point and month. Currently assumes an exponential variogram Parameters ---------- pt : structured array A structured array containing the point's latitude, longitude, elevation, topographic dissection index, and average land skin temperatures for each month. An empty point can be initialized with build_empty_pt() mth : int The specific month as an integer (1-12) rm_stnid : ndarray or str, optional An array of station ids or a single station id for stations that should not be considered neighbors for the specific point. Returns ---------- nug : float Exponential variogram nugget. psill : float Exponential variogram partial sill. rng : float Exponential variogram range. ''' # First determine the nnghs to use based on smoothed weighted average of # the optimal nnghs bandwidth at each station point. self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], DFLT_INIT_NNGHS, load_obs=False) indomain_mask = np.isfinite( self.stn_slct.ngh_stns[get_optim_varname(mth)]) domain_stns = self.stn_slct.ngh_stns[indomain_mask] if domain_stns.size == 0: raise Exception( "Cannot determine the optimal # of neighbors to use!") n_wgt = self.stn_slct.ngh_wgt[indomain_mask] nnghs = np.int( np.round( np.average(domain_stns[get_optim_varname(mth)], weights=n_wgt))) # Now use the optimal nnghs to get the krig params for this mth self.stn_slct.set_ngh_stns(pt[LAT], pt[LON], nnghs, load_obs=False) nghs = self.stn_slct.ngh_stns ngh_lon = ri.FloatSexpVector(nghs[LON]) ngh_lat = ri.FloatSexpVector(nghs[LAT]) ngh_elev = ri.FloatSexpVector(nghs[ELEV]) ngh_tdi = ri.FloatSexpVector(nghs[TDI]) ngh_lst = ri.FloatSexpVector(nghs[get_lst_varname(mth)]) ngh_tair = ri.FloatSexpVector(nghs[get_norm_varname(mth)]) ngh_wgt = ri.FloatSexpVector(self.stn_slct.ngh_wgt) ngh_dists = ri.FloatSexpVector(self.stn_slct.ngh_dists) rslt = self.r_func(ngh_lon, ngh_lat, ngh_elev, ngh_tdi, ngh_lst, ngh_tair, ngh_wgt, ngh_dists) nug = rslt[0] psill = rslt[1] rng = rslt[2] return nug, psill, rng
def interp_pt(self, fix_invalid=True, stns_rm=None): ''' Interpolate daily and monthly normal Tmin and Tmax values for the current PtInterpTair.a_pt Parameters ---------- fix_invalid : boolean, optional If True, apply a fix on days where interpolated Tmax > Tmin. Default: True. stns_rm : ndarray or str, optional An array of station ids or a single station id for stations that should not be considered neighbors for the specific point. Returns ---------- tmin_dly : ndarray Daily interpolated Tmin tmax_dly : ndarray Daily interpolated Tmax tmin_norms : ndarray Interpolated monthly Tmin normals tmax_norms : ndarray Interpolated monthly Tmax normals tmin_se : ndarray Kriging standard error for monthly Tmin normals tmax_se : ndarray Kriging standard error for monthly Tmax normals ninvalid : int The number of days where Tmax > Tmin was fixed. If fix_invalid is False, will be set to 0. ''' # Set the monthly lst values and optim nnghs on the point for mth in np.arange(1, 13): self.a_pt[get_lst_varname(mth)] = self.a_pt["tmin%02d" % mth] self.a_pt[get_optim_varname(mth)], self.a_pt[ get_optim_anom_varname(mth)] = self.nnghparams_tmin[ self.a_pt[CLIMDIV]][mth] # Perform Tmin interpolation tmin_dly, tmin_norms, tmin_se = self.interp_tmin.interp( self.a_pt, stns_rm=stns_rm) # Set the monthly lst values and optim nnghs on the point for mth in np.arange(1, 13): self.a_pt[get_lst_varname(mth)] = self.a_pt["tmax%02d" % mth] self.a_pt[get_optim_varname(mth)], self.a_pt[ get_optim_anom_varname(mth)] = self.nnghparams_tmax[ self.a_pt[CLIMDIV]][mth] # Perform Tmax interpolation tmax_dly, tmax_norms, tmax_se = self.interp_tmax.interp( self.a_pt, stns_rm=stns_rm) ninvalid = 0 if fix_invalid: tmin_dly, tmax_dly, ninvalid = tmin_tmax_fixer(tmin_dly, tmax_dly) if ninvalid > 0: tmin_dly_norm = np.take(tmin_dly, self.daysNormMask) tmax_dly_norm = np.take(tmax_dly, self.daysNormMask) tmin_mthly = np.array([ np.mean(np.take(tmin_dly_norm, amask)) for amask in self.yrMthsMasks ]) tmax_mthly = np.array([ np.mean(np.take(tmax_dly_norm, amask)) for amask in self.yrMthsMasks ]) tmin_norms = np.array([ np.mean(np.take(tmin_mthly, amask)) for amask in self.mth_masks ]) tmax_norms = np.array([ np.mean(np.take(tmax_mthly, amask)) for amask in self.mth_masks ]) return tmin_dly, tmax_dly, tmin_norms, tmax_norms, tmin_se, tmax_se, ninvalid