def __init__(self, basename=None, parameter_data=None, res_df=None, jco_df=None): ''' Create ObSen class Parameters ---------- basename : str, optional basename for PEST control file, if full path not provided the current working directory is assumed. Optional but must be provided if any of parameter_data, res_df, or jco_df are not provided. parameter_data : DataFrame, optional Pandas DataFrame of the paramter data from a .pst file. If not provided it will be read in based on the base name of pest file provided. jco_df : DataFrame, optional Pandas DataFrame of the jacobian. If not provided then it will be read in based on base name of pest file provided. Providing a jco_df offers some efficiencies if working interactively. Otherwise the jco is read in every time ObSen class is initialized. res_df : DataFrame, optional Residual DataFrame used to define the weights to calculate the observation sensitivity. Providing a res_df offers some efficiencies if working interactively. If not provided it will look for basename+'.res'. Weights are not taken from PEST control file (.pst) because regularization weights in PEST conrtrol file do not reflect the current weights. Attributes ---------- df : Pandas DataFrame DataFrame of observation sensitivity. Index entries of the DataFrame are the observation names. Methods ------- #plot() tail() head() #par() group() sum_group() #plot_sum_group() #plot_mean_group() Notes ------ ''' if basename is not None: self.basename = os.path.split(basename)[-1].split('.')[0] self.directory = os.path.split(basename)[0] if len(self.directory) == 0: self.directory = os.getcwd() if jco_df is None: jco_file = os.path.join(self.directory, self.basename + '.jco') jco = Jco() jco.from_binary(jco_file) self.jco_df = jco.to_dataframe() else: self.jco_df = jco_df if res_df is None: res_file = os.path.join(self.directory, self.basename + '.res') pst = Pst(filename=None, load=False, resfile=res_file) self.res_df = pst.load_resfile(res_file) else: self.res_df = res_df # Set index of res_df self.res_df.set_index('name', drop=False, inplace=True) # Build _obs_data weights = [] ob_groups = [] obs = [] for ob in self.jco_df.index: weight = self.res_df.loc[ob.lower()]['weight'] ob_group = self.res_df.loc[ob.lower()]['group'] weights.append(weight) ob_groups.append(ob_group) obs.append(ob) self._obs_data = pd.DataFrame({ 'OBSNME': obs, 'OBGNME': ob_groups, 'WEIGHT': weights, 'ObSen_Weight': weights }) self._obs_data.set_index('OBSNME', inplace=True) # Fill DataFrame self.df = self.calc_sensitivity()
def __init__(self, basename=None, parameter_data=None, res_df=None, jco_df=None, drop_regul=False, drop_groups=None, keep_groups=None, keep_obs=None, remove_obs=None): ''' Create ParSen class Parameters ---------- basename : str, optional basename for PEST control file, if full path not provided the current working directory is assumed. Optional but must be provided if any of parameter_data, res_df, or jco_df are not provided. parameter_data : DataFrame, optional Pandas DataFrame of the paramter data from a .pst file. If not provided it will be read in based on the base name of pest file provided. jco_df : DataFrame, optional Pandas DataFrame of the jacobian. If not provided then it will be read in based on base name of pest file provided. Providing a jco_df offers some efficiencies if working interactively. Otherwise the jco is read in every time ParSen class is initialized. res_df : DataFrame, optional Residual DataFrame used to define the weights to calculate the parameter sensitivity. Providing a res_df offers some efficiencies if working interactively. If not provided it will look for basename+'.res'. Weights are not taken from PEST control file (.pst) because regularization weights in PEST conrtrol file do not reflect the current weights. drop_regul: {False, True}, optional Flag to drop regularization information in calculating parameter sensitivity. Will set weight to zero for all observations with 'regul' in the observation group name drop_groups: list, optional List of observation groups to drop when calculating parameter sensitivity. If all groups are part of regularization it may be easier to use the drop_regul flag keep_groups: list, optional List of observation groups to include in calculating parameter sensitivity. Sometimes easier to use when looking at sensitivity to a single, or small number, or observation groups keep_obs: list, optional List of observations to include in calculating parameter sensitivity. If keep_obs != None then weights for all observations not in keep_obs will be set to zero. remove_obs: list, optional List of observations to remove in calculating parameter sensitivity. If remove_obs != None then weights for all observations in remove_obs will be set to zero. Attributes ---------- df : Pandas DataFrame DataFrame of parameter sensitivity. Index entries of the DataFrame are the parameter names. The DataFrame has two columns: 1) Parameter Group and 2) Sensitivity Methods ------- plot() tail() head() par() group() sum_group() plot_sum_group() plot_mean_group() Notes ------ ''' if basename is not None: self.basename = os.path.split(basename)[-1].split('.')[0] self.directory = os.path.split(basename)[0] if len(self.directory) == 0: self.directory = os.getcwd() if jco_df is None: jco_file = os.path.join(self.directory, self.basename + '.jco') jco = Jco() jco.from_binary(jco_file) self.jco_df = jco.to_dataframe() else: self.jco_df = jco_df if res_df is None: res_file = os.path.join(self.directory, self.basename + '.res') pst = Pst(filename=None, load=False, resfile=res_file) self.res_df = pst.load_resfile(res_file) else: self.res_df = res_df # Set index of res_df self.res_df.set_index('name', drop=False, inplace = True) if parameter_data is None: pst_file = os.path.join(self.directory, self.basename + '.pst') pst = Pst(pst_file, load=True, resfile = None) self.parameter_data = pst.parameter_data else: self.parameter_data = parameter_data # Build pars_dict # key is PARNME value is PARGP self._pars_dict = {} for index, row in self.parameter_data.iterrows(): self._pars_dict[row['parnme'].lower()] = row['pargp'].lower() # Build _obs_data weights = [] ob_groups = [] obs = [] for ob in self.jco_df.index: weight = self.res_df.loc[ob.lower()]['weight'] ob_group = self.res_df.loc[ob.lower()]['group'] weights.append(weight) ob_groups.append(ob_group) obs.append(ob) self._obs_data = pd.DataFrame({'OBSNME': obs, 'OBGNME': ob_groups, 'WEIGHT': weights, 'ParSen_Weight' : weights}) self._obs_data.set_index('OBSNME', inplace=True) if drop_regul is True: self.drop_regul(calc_sensitivity=False) if drop_groups is not None: self.drop_groups(drop_groups=drop_groups, calc_sensitivity=False) if keep_groups is not None: self.keep_groups(keep_groups = keep_groups, calc_sensitivity=False) if keep_obs is not None: self.keep_obs(keep_obs=keep_obs, calc_sensitivity=False) if remove_obs is not None: self.remove_obs(remove_obs=remove_obs, calc_sensitivity=False) # Fill DataFrame self.df = self.calc_sensitivity()
def __init__(self, basename=None, parameter_data=None, res_df=None, jco_df=None): ''' Create ObSen class Parameters ---------- basename : str, optional basename for PEST control file, if full path not provided the current working directory is assumed. Optional but must be provided if any of parameter_data, res_df, or jco_df are not provided. parameter_data : DataFrame, optional Pandas DataFrame of the paramter data from a .pst file. If not provided it will be read in based on the base name of pest file provided. jco_df : DataFrame, optional Pandas DataFrame of the jacobian. If not provided then it will be read in based on base name of pest file provided. Providing a jco_df offers some efficiencies if working interactively. Otherwise the jco is read in every time ObSen class is initialized. res_df : DataFrame, optional Residual DataFrame used to define the weights to calculate the observation sensitivity. Providing a res_df offers some efficiencies if working interactively. If not provided it will look for basename+'.res'. Weights are not taken from PEST control file (.pst) because regularization weights in PEST conrtrol file do not reflect the current weights. Attributes ---------- df : Pandas DataFrame DataFrame of observation sensitivity. Index entries of the DataFrame are the observation names. Methods ------- #plot() tail() head() #par() group() sum_group() #plot_sum_group() #plot_mean_group() Notes ------ ''' if basename is not None: self.basename = os.path.split(basename)[-1].split('.')[0] self.directory = os.path.split(basename)[0] if len(self.directory) == 0: self.directory = os.getcwd() if jco_df is None: jco_file = os.path.join(self.directory, self.basename + '.jco') jco = Jco() jco.from_binary(jco_file) self.jco_df = jco.to_dataframe() else: self.jco_df = jco_df if res_df is None: res_file = os.path.join(self.directory, self.basename + '.res') pst = Pst(filename=None, load=False, resfile=res_file) self.res_df = pst.load_resfile(res_file) else: self.res_df = res_df # Set index of res_df self.res_df.set_index('name', drop=False, inplace = True) # Build _obs_data weights = [] ob_groups = [] obs = [] for ob in self.jco_df.index: weight = self.res_df.loc[ob.lower()]['weight'] ob_group = self.res_df.loc[ob.lower()]['group'] weights.append(weight) ob_groups.append(ob_group) obs.append(ob) self._obs_data = pd.DataFrame({'OBSNME': obs, 'OBGNME': ob_groups, 'WEIGHT': weights, 'ObSen_Weight' : weights}) self._obs_data.set_index('OBSNME', inplace=True) # Fill DataFrame self.df = self.calc_sensitivity()