verify pyEMU results with the henry problem


In [1]:
%matplotlib inline
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pyemu


setting random seed

instaniate pyemu object and drop prior info. Then reorder the jacobian and save as binary. This is needed because the pest utilities require strict order between the control file and jacobian


In [16]:
la = pyemu.Schur("pest.jco",verbose=False,forecasts=[])
la.drop_prior_information()
jco_ord = la.jco.get(la.pst.obs_names,la.pst.adj_par_names)
ord_base = "pest_ord"
jco_ord.to_binary(ord_base + ".jco")  
la.pst.write(ord_base+".pst")

extract and save the forecast sensitivity vectors


In [17]:
pv_names = []
predictions =  ["pd_ten", "c_obs10_2"]
for pred in predictions:
    pv = jco_ord.extract(pred).T
    pv_name = pred + ".vec"
    pv.to_ascii(pv_name)
    pv_names.append(pv_name)

save the prior parameter covariance matrix as an uncertainty file


In [18]:
prior_uncfile = "pest.unc"
la.parcov.to_uncfile(prior_uncfile,covmat_file=None)

PRECUNC7

write a response file to feed stdin to predunc7


In [19]:
post_mat = "post.cov"
post_unc = "post.unc"
args = [ord_base + ".pst","1.0",prior_uncfile,
        post_mat,post_unc,"1"]
pd7_in = "predunc7.in"
f = open(pd7_in,'w')
f.write('\n'.join(args)+'\n')
f.close()
out = "pd7.out"
pd7 = os.path.join("i64predunc7.exe")
os.system(pd7 + " <" + pd7_in + " >"+out)
for line in open(out).readlines():
    print(line)



 PREDUNC7 Version 13.6. Watermark Numerical Computing.



 Enter name of PEST control file:  Enter observation reference variance: 

 Enter name of prior parameter uncertainty file: 

 Enter name for posterior parameter covariance matrix file:  Enter name for posterior parameter uncertainty file: 

 Use which version of linear predictive uncertainty equation:-

     if version optimized for small number of parameters   - enter 1

     if version optimized for small number of observations - enter 2

 Enter your choice: 

 - reading PEST control file pest_ord.pst....

 - file pest_ord.pst read ok.



 - reading Jacobian matrix file pest_ord.jco....

 - file pest_ord.jco read ok.



 - reading parameter uncertainty file pest.unc....

 - parameter uncertainty file pest.unc read ok.

 - forming XtC-1(e)X matrix....

 - inverting prior C(p) matrix....

 - inverting [XtC-1(e)X + C-1(p)] matrix....

 - writing file post.cov...

 - file post.cov written ok.

 - writing file post.unc...

 - file post.unc written ok.

load the posterior matrix written by predunc7


In [20]:
post_pd7 = pyemu.Cov.from_ascii(post_mat)

la_ord = pyemu.Schur(jco=ord_base+".jco",predictions=predictions)
post_pyemu = la_ord.posterior_parameter
#post_pyemu = post_pyemu.get(post_pd7.row_names)

The cumulative difference between the two posterior matrices:


In [22]:
delta = (post_pd7 - post_pyemu).x
(post_pd7 - post_pyemu).to_ascii("delta.cov")
print(delta.sum())
print(delta.max(),delta.min())


1.70407836726e-06
4.97750649031e-08 -4.9877244529e-08

PREDUNC1

write a response file to feed stdin. Then run predunc1 for each forecast


In [23]:
args = [ord_base + ".pst", "1.0", prior_uncfile, None, "1"]
pd1_in = "predunc1.in"
pd1 = os.path.join("i64predunc1.exe")
pd1_results = {}
for pv_name in pv_names:
    args[3] = pv_name
    f = open(pd1_in, 'w')
    f.write('\n'.join(args) + '\n')
    f.close()
    out = "predunc1" + pv_name + ".out"
    os.system(pd1 + " <" + pd1_in + ">" + out)
    f = open(out,'r')
    for line in f:
        if "pre-cal " in line.lower():
            pre_cal = float(line.strip().split()[-2])
        elif "post-cal " in line.lower():
            post_cal = float(line.strip().split()[-2])
    f.close()        
    pd1_results[pv_name.split('.')[0].lower()] = [pre_cal, post_cal]

organize the pyemu results into a structure for comparison


In [24]:
pyemu_results = {}
for pname in la_ord.prior_prediction.keys():
    pyemu_results[pname] = [np.sqrt(la_ord.prior_prediction[pname]),
                            np.sqrt(la_ord.posterior_prediction[pname])]

compare the results:


In [26]:
f = open("predunc1_textable.dat",'w')
for pname in pd1_results.keys():
    print(pname)
    f.write(pname+"&{0:6.5f}&{1:6.5}&{2:6.5f}&{3:6.5f}\\\n"\
            .format(pd1_results[pname][0],pyemu_results[pname][0],
                    pd1_results[pname][1],pyemu_results[pname][1]))
    print("prior",pname,pd1_results[pname][0],pyemu_results[pname][0])
    print("post",pname,pd1_results[pname][1],pyemu_results[pname][1])
f.close()


pd_ten
prior pd_ten 0.4716172 0.471617160877
post pd_ten 0.2267402 0.226740171374
c_obs10_2
prior c_obs10_2 0.1509421 0.150942104963
post c_obs10_2 0.089084382 0.0890843823278

PREDVAR1b

write the nessecary files to run predvar1b


In [31]:
f = open("pred_list.dat",'w')
out_files = []
for pv in pv_names:
    out_name = pv+".predvar1b.out"
    out_files.append(out_name)
    f.write(pv+" "+out_name+"\n")
f.close()
args = [ord_base+".pst","1.0","pest.unc","pred_list.dat"]
for i in range(36):
    args.append(str(i))
args.append('')    
args.append("n") #no for most parameters
args.append("y") #yes for mult
f = open("predvar1b.in", 'w')
f.write('\n'.join(args) + '\n')
f.close()

In [32]:
os.system("predvar1b.exe <predvar1b.in")


Out[32]:
0

In [33]:
pv1b_results = {}
for out_file in out_files:
    pred_name = out_file.split('.')[0]
    f = open(out_file,'r')
    for _ in range(3):
        f.readline()
    arr = np.loadtxt(f)
    pv1b_results[pred_name] = arr

now for pyemu


In [34]:
la_ord_errvar = pyemu.ErrVar(jco=ord_base+".jco",
                             predictions=predictions,
                             omitted_parameters="mult1",
                             verbose=False)
df = la_ord_errvar.get_errvar_dataframe(np.arange(36))
df


Out[34]:
first second third
c_obs10_2 pd_ten c_obs10_2 pd_ten c_obs10_2 pd_ten
0 0.015706 0.076700 0.000000e+00 0.000000e+00 0.007078 0.145723
1 0.006040 0.046811 8.323523e-04 2.573705e-03 0.115553 0.132455
2 0.005905 0.045945 9.201068e-04 3.138167e-03 0.077244 0.271644
3 0.004850 0.042798 4.135876e-03 1.273156e-02 0.029392 0.497192
4 0.004582 0.037457 5.612732e-03 4.213813e-02 0.034111 0.417314
5 0.004233 0.031039 8.756785e-03 9.996844e-02 0.041801 0.534001
6 0.004156 0.031010 9.697704e-03 1.003232e-01 0.038039 0.525583
7 0.004155 0.030849 9.728439e-03 1.032245e-01 0.038043 0.525723
8 0.004084 0.029342 1.123436e-02 1.354974e-01 0.041175 0.579882
9 0.004084 0.029109 1.123444e-02 1.422348e-01 0.041173 0.581877
10 0.004084 0.028689 1.124962e-02 1.547092e-01 0.041273 0.571117
11 0.004083 0.027723 1.127209e-02 1.870549e-01 0.041139 0.552224
12 0.004044 0.027693 1.373466e-02 1.889087e-01 0.041676 0.553927
13 0.003870 0.027380 2.509977e-02 2.094440e-01 0.038285 0.571023
14 0.003397 0.023741 5.647082e-02 4.508064e-01 0.029120 0.680726
15 0.003397 0.023106 5.648180e-02 4.973744e-01 0.029097 0.687914
16 0.003397 0.022881 5.654890e-02 5.176496e-01 0.029181 0.695037
17 0.003395 0.022858 5.673687e-02 5.202939e-01 0.029307 0.692737
18 0.003021 0.022763 1.240355e-01 5.373727e-01 0.029080 0.692178
19 0.002723 0.022762 3.052508e+00 5.493474e-01 0.031426 0.692896
20 0.002716 0.022580 4.771325e+01 1.123392e+03 0.025201 0.856170
21 0.002714 0.022526 6.754794e+01 1.881534e+03 0.025839 0.833455
22 0.002700 0.022522 3.533209e+02 1.958512e+03 0.021420 0.819873
23 0.002695 0.022522 5.097773e+02 1.959862e+03 0.020532 0.820389
24 0.002693 0.022217 6.125413e+02 1.771097e+04 0.019521 0.902417
25 0.002685 0.014189 2.167707e+03 1.588460e+06 0.021336 0.559757
26 0.002672 0.013960 4.329660e+05 9.693253e+06 0.023606 0.610005
27 0.002672 0.013793 4.318456e+05 9.916109e+06 0.023103 0.614989
28 0.002671 0.013791 4.407275e+05 9.888319e+06 0.021816 0.610333
29 0.002669 0.013747 9.125185e+05 2.079073e+07 0.022247 0.665320
30 0.002669 0.013747 9.125185e+05 2.079073e+07 0.022247 0.665320
31 0.002669 0.013747 9.125185e+05 2.079073e+07 0.022247 0.665320
32 0.002658 0.013747 7.327654e+05 2.060216e+07 0.018931 0.634997
33 0.002656 0.013735 5.753541e+05 1.776287e+07 0.014904 0.617035
34 0.002636 0.013724 3.068116e+07 6.167094e+07 0.012985 0.644300
35 0.002634 0.013670 3.545243e+07 9.163153e+07 0.027613 0.782823

generate some plots to verify


In [35]:
fig = plt.figure(figsize=(6,6))
max_idx = 15
idx = np.arange(max_idx)
for ipred,pred in enumerate(predictions):
    arr = pv1b_results[pred][:max_idx,:]
    first = df[("first", pred)][:max_idx]
    second = df[("second", pred)][:max_idx]
    third = df[("third", pred)][:max_idx]
    ax = plt.subplot(len(predictions),1,ipred+1)
    #ax.plot(arr[:,1],color='b',dashes=(6,6),lw=4,alpha=0.5)
    #ax.plot(first,color='b')
    #ax.plot(arr[:,2],color='g',dashes=(6,4),lw=4,alpha=0.5)
    #ax.plot(second,color='g')
    #ax.plot(arr[:,3],color='r',dashes=(6,4),lw=4,alpha=0.5)
    #ax.plot(third,color='r')
    
    ax.scatter(idx,arr[:,1],marker='x',s=40,color='g',
               label="PREDVAR1B - first term")
    ax.scatter(idx,arr[:,2],marker='x',s=40,color='b',
               label="PREDVAR1B - second term")
    ax.scatter(idx,arr[:,3],marker='x',s=40,color='r',
               label="PREVAR1B - third term")
    ax.scatter(idx,first,marker='o',facecolor='none',
               s=50,color='g',label='pyEMU - first term')
   
    ax.scatter(idx,second,marker='o',facecolor='none',
               s=50,color='b',label="pyEMU - second term")
    
    ax.scatter(idx,third,marker='o',facecolor='none',
               s=50,color='r',label="pyEMU - third term")
    ax.set_ylabel("forecast variance")
    ax.set_title("forecast: " + pred)
    if ipred == len(predictions) -1:
        ax.legend(loc="lower center",bbox_to_anchor=(0.5,-0.75),
                  scatterpoints=1,ncol=2)
        ax.set_xlabel("singular values")
    #break
plt.savefig("predvar1b_ver.eps")


Identifiability


In [37]:
cmd_args = [os.path.join("i64identpar.exe"),ord_base,"5",
            "null","null","ident.out","/s"]
cmd_line = ' '.join(cmd_args)+'\n'
print(cmd_line)
print(os.getcwd())
os.system(cmd_line)


i64identpar.exe pest_ord 5 null null ident.out /s

E:\git\pyemu\verification\henry
Out[37]:
0

In [38]:
identpar_df = pd.read_csv("ident.out",delim_whitespace=True)

In [39]:
la_ord_errvar = pyemu.ErrVar(jco=ord_base+".jco",
                             predictions=predictions,
                             verbose=False)
df = la_ord_errvar.get_identifiability_dataframe(5)
df


Out[39]:
right_sing_vec_1 right_sing_vec_2 right_sing_vec_3 right_sing_vec_4 right_sing_vec_5 ident
mult1 9.907986e-01 4.284511e-03 6.814463e-04 3.047248e-05 6.673591e-05 9.958617e-01
kr01c01 0.000000e+00 1.972152e-31 2.773339e-32 1.112417e-30 2.043219e-30 3.380585e-30
kr01c02 0.000000e+00 0.000000e+00 1.301929e-31 5.243344e-32 1.972152e-31 3.798415e-31
kr01c03 0.000000e+00 0.000000e+00 0.000000e+00 2.890099e-32 2.461459e-31 2.750469e-31
kr01c04 6.831969e-134 0.000000e+00 0.000000e+00 1.232595e-32 0.000000e+00 1.232595e-32
kr01c05 6.634155e-134 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.634155e-134
kr01c06 6.885196e-98 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.885196e-98
kr01c07 6.885196e-98 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.885196e-98
kr01c08 4.650818e-77 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 4.650818e-77
kr01c09 4.650818e-77 2.732538e-76 0.000000e+00 0.000000e+00 0.000000e+00 3.197619e-76
kr01c10 1.018490e-62 8.246736e-61 3.982730e-59 0.000000e+00 0.000000e+00 4.066216e-59
kr01c11 1.018490e-62 8.246736e-61 2.731320e-59 0.000000e+00 0.000000e+00 2.814806e-59
kr01c12 1.018490e-62 8.246736e-61 2.725888e-59 0.000000e+00 0.000000e+00 2.809374e-59
kr01c13 1.018490e-62 8.246735e-61 2.725897e-59 1.593092e-58 6.681912e-52 6.681914e-52
kr01c14 1.018490e-62 8.246735e-61 2.725897e-59 1.687036e-58 0.000000e+00 1.967974e-58
kr01c15 3.299907e-62 2.671942e-60 8.831906e-59 5.465996e-58 6.730813e-57 7.368437e-57
kr01c16 1.516538e-13 1.730879e-11 2.657139e-10 2.349485e-09 6.670054e-12 2.639329e-09
kr01c17 1.516538e-13 1.730879e-11 2.657139e-10 2.349485e-09 6.670054e-12 2.639329e-09
kr01c18 1.689710e-12 3.435674e-10 4.040117e-10 6.125469e-09 5.575720e-10 7.432310e-09
kr01c19 6.771186e-12 1.768986e-09 8.204037e-11 4.036113e-10 8.610630e-12 2.270019e-09
kr01c20 2.856076e-12 7.872498e-10 2.994106e-10 1.822953e-09 2.508480e-09 5.420950e-09
kr01c21 2.855035e-12 7.961069e-10 3.759236e-10 2.565655e-09 3.655515e-09 7.396055e-09
kr01c22 2.853845e-12 8.062900e-10 4.740158e-10 3.569481e-09 5.230077e-09 1.008272e-08
kr01c23 2.947269e-11 7.868983e-09 1.427736e-09 3.647682e-08 1.083557e-08 5.663858e-08
kr01c24 3.834766e-11 9.814016e-09 7.145350e-09 1.051617e-07 2.680758e-08 1.489670e-07
kr01c25 9.927371e-11 2.660170e-08 1.678764e-08 1.879720e-07 5.698605e-08 2.884467e-07
kr01c26 1.210747e-10 3.218574e-08 1.162450e-08 2.017060e-07 4.851545e-08 2.941527e-07
kr01c27 2.542484e-10 7.126949e-08 5.618722e-08 6.819429e-07 5.985907e-08 8.695130e-07
kr01c28 3.873812e-10 1.126630e-07 1.043589e-07 1.274519e-06 1.675742e-07 1.659502e-06
kr01c29 8.191800e-10 1.676060e-07 2.582029e-07 2.629976e-06 3.216076e-07 3.378212e-06
... ... ... ... ... ... ...
kr10c31 4.425886e-09 1.116456e-06 1.396047e-06 1.732384e-05 2.537642e-06 2.237841e-05
kr10c32 1.137889e-08 2.822269e-06 3.720455e-06 4.534496e-05 5.758522e-06 5.765758e-05
kr10c33 3.588215e-08 9.316037e-06 1.323923e-05 1.585990e-04 1.939569e-05 2.005858e-04
kr10c34 1.224817e-07 3.403386e-05 4.951200e-05 5.768248e-04 6.164343e-05 7.221366e-04
kr10c35 2.367926e-08 4.643896e-06 5.443163e-06 7.036323e-05 1.661460e-05 9.708857e-05
kr10c36 1.285277e-06 4.564989e-04 7.337831e-04 8.232850e-03 4.914926e-04 9.915910e-03
kr10c37 1.704861e-06 6.139625e-04 1.019910e-03 1.149173e-02 6.907033e-04 1.381801e-02
kr10c38 1.164442e-06 4.495602e-04 8.429683e-04 9.557730e-03 5.696886e-04 1.142111e-02
kr10c39 7.422905e-07 3.285621e-04 7.907323e-04 9.272533e-03 5.962308e-04 1.098880e-02
kr10c40 9.354420e-07 4.161282e-04 7.437063e-04 7.882653e-03 3.660321e-04 9.409455e-03
kr10c41 3.809338e-06 1.364063e-03 5.633123e-04 3.037827e-03 2.950124e-05 4.998513e-03
kr10c42 4.177440e-06 1.575037e-03 6.220073e-04 2.600636e-03 8.136598e-05 4.883224e-03
kr10c43 3.274124e-06 1.441772e-03 8.747121e-04 3.539435e-03 2.216704e-05 5.881360e-03
kr10c44 2.491068e-06 1.388550e-03 1.465370e-03 5.116170e-03 2.587720e-07 7.972840e-03
kr10c45 2.453819e-06 1.605318e-03 1.816518e-03 1.809485e-03 2.507430e-04 5.484518e-03
kr10c46 4.628308e-06 2.550787e-03 6.721066e-04 9.539755e-03 2.703711e-03 1.547099e-02
kr10c47 4.127472e-06 3.009588e-03 1.139289e-03 1.636292e-02 5.376032e-03 2.589196e-02
kr10c48 2.609145e-06 3.362098e-03 2.050871e-03 1.369552e-02 7.302114e-03 2.641321e-02
kr10c49 1.221140e-06 3.991206e-03 2.507531e-03 1.142849e-02 8.722282e-03 2.665073e-02
kr10c50 3.269887e-07 5.054358e-03 1.533563e-03 1.356292e-02 1.254669e-02 3.269785e-02
kr10c51 1.679056e-08 6.755028e-03 6.750343e-08 3.005230e-02 2.558409e-02 6.239150e-02
kr10c52 7.678419e-07 8.529936e-03 1.857435e-04 2.908250e-02 3.167992e-02 6.947887e-02
kr10c53 1.896385e-06 6.715658e-03 7.497045e-06 1.921480e-02 2.848636e-02 5.442621e-02
kr10c54 1.794861e-08 7.288896e-04 1.601741e-03 7.638060e-03 1.613413e-02 2.610284e-02
kr10c55 2.087881e-05 9.999500e-03 2.079331e-02 3.581035e-04 3.152841e-05 3.120332e-02
kr10c56 9.272447e-05 5.060300e-02 6.289279e-02 1.645269e-03 1.718243e-02 1.324162e-01
kr10c57 8.804878e-05 5.177846e-02 6.315216e-02 2.754754e-03 1.896659e-02 1.367400e-01
kr10c58 5.417485e-05 3.482474e-02 4.655854e-02 1.816723e-03 1.032155e-02 9.357573e-02
kr10c59 3.029422e-05 2.166433e-02 3.357527e-02 8.844889e-04 4.457364e-03 6.061175e-02
kr10c60 1.160736e-05 8.971124e-03 1.540375e-02 2.870299e-04 1.341417e-03 2.601493e-02

601 rows × 6 columns

cheap plot to verify


In [41]:
fig = plt.figure()
ax = plt.subplot(111)
axt = plt.twinx()
ax.plot(identpar_df["identifiability"])
ax.plot(df["ident"].values)
ax.set_xlim(-10,600)
diff = identpar_df["identifiability"].values - df["ident"].values
#print(diff)
axt.plot(diff)
axt.set_ylim(-1,1)
ax.set_xlabel("parmaeter")
ax.set_ylabel("identifiability")
axt.set_ylabel("difference")


Out[41]:
<matplotlib.text.Text at 0x4487c3fc88>

In [ ]: