In [3]:
from __future__ import print_function
import os
import numpy as np
import pyemu
from pyemu import Pst
We need to pass the name of a pest control file to instantiate the class. The class instance (or object) is assigned to the variable p.
In [4]:
pst_name = os.path.join("..", "..", "examples", "henry","pest.pst")
p = Pst(pst_name)
Now all of the relevant parts of the pest control file are attributes of the object. For example, the parameter_data, observation data, and prior information are available as pandas dataframes.
In [5]:
p.parameter_data.head()
Out[5]:
In [6]:
p.observation_data.head()
Out[6]:
In [7]:
p.prior_information.head()
Out[7]:
A residual file (.rei
or res
) can also be passed to the resfile
argument at instantiation to enable some simple residual analysis and weight adjustments. If the residual file is in the same directory as the pest control file and has the same base name, it will be accessed automatically:
In [8]:
p.res.head()
Out[8]:
The pst
class has some @decorated
convience methods related to the residuals allowing the user
to access the values and print in a straightforward way.
In [9]:
print(p.phi,p.phi_components)
Some additional @decorated
convience methods:
In [10]:
print(p.npar,p.nobs,p.nprior)
In [11]:
print(p.par_groups,p.obs_groups)
Printing the attribue type shows that some are returned as lists and others single values.
In [14]:
print(type(p.par_names)) # all parameter names
print(type(p.adj_par_names)) # adjustable parameter names
print(type(p.obs_names)) # all observation names
print(type(p.nnz_obs_names)) # non-zero weight observations
print(type(p.phi)) # float value that is the weighted total objective function
The "control_data" section of the pest control file is accessible in the Pst.control_data
attribute:
In [15]:
print('jacupdate = {0}'.format(p.control_data.jacupdate))
print('numlam = {0}'.format(p.control_data.numlam))
p.control_data.numlam = 100
print('numlam has been changed to --> {0}'.format(p.control_data.numlam))
The Pst
class also exposes a method to get a new Pst
instance with a subset of parameters and or obseravtions. Note this method does not propogate prior information to the new instance:
In [16]:
pnew = p.get(p.par_names[:10],p.obs_names[-10:])
print(pnew.prior_information)
You can also write a pest control file with altered parameters, observations, and/or prior information:
In [17]:
pnew.write("test.pst")
Some other methods in Pst
include:
In [18]:
# add preferred value regularization with weights proportional to parameter bounds
pyemu.utils.helpers.zero_order_tikhonov(pnew)
pnew.prior_information.head()
Out[18]:
In [19]:
# add preferred value regularization with unity weights
pyemu.utils.helpers.zero_order_tikhonov(pnew,parbounds=False)
pnew.prior_information.head()
Out[19]:
Some more res
functionality
In [20]:
# adjust observation weights to account for residual phi components
#pnew = p.get()
print(p.phi, p.nnz_obs, p.phi_components)
p.adjust_weights_resfile()
print(p.phi, p.nnz_obs, p.phi_components)
adjust observation weights by an arbitrary amount by groups:
In [21]:
print(p.phi, p.nnz_obs, p.phi_components)
grp_dict = {"head":100}
p.adjust_weights(obsgrp_dict=grp_dict)
print(p.phi, p.nnz_obs, p.phi_components)
adjust observation weights by an arbitrary amount by individual observations:
In [22]:
print(p.phi, p.nnz_obs, p.phi_components)
obs_dict = {"h_obs01_1":25}
p.adjust_weights(obs_dict=obs_dict)
print(p.phi, p.nnz_obs, p.phi_components)
setup weights inversely proportional to the observation values
In [23]:
p.adjust_weights_resfile()
print(p.phi, p.nnz_obs, p.phi_components)
p.proportional_weights(fraction_stdev=0.1,wmax=20.0)
print(p.phi, p.nnz_obs, p.phi_components)