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

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 [2]:
la = pyemu.Schur("pest.jco",verbose=False)
la.drop_prior_information()
jco_ord = la.jco.get(la.pst.obs_names,la.pst.par_names)
ord_base = "pest_ord"
jco_ord.to_binary(ord_base + ".jco")

extract and save the forecast sensitivity vectors


In [3]:
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 [4]:
prior_uncfile = "pest.unc"
la.parcov.to_uncfile(prior_uncfile,covmat_file=None)

PRECUNC7

write a response file to feed stdin to predunc7


In [5]:
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("exe","i64predunc7.exe")
os.system(pd7 + " <" + pd7_in + " >"+out)
for line in open(out).readlines():
    print line,


 PREDUNC7 Version 13.3. 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 [7]:
post_pd7 = pyemu.Cov()
post_pd7.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 [8]:
delta = (post_pd7 - post_pyemu).x
(post_pd7 - post_pyemu).to_ascii("delta.cov")
print delta.sum()
print delta.max(),delta.min()


1.70407836758e-06
4.97750648476e-08 -4.98772445567e-08

PREDUNC1

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


In [9]:
args = [ord_base + ".pst", "1.0", prior_uncfile, None, "1"]
pd1_in = "predunc1.in"
pd1 = os.path.join("exe", "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 [10]:
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 [11]:
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()


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

PREDVAR1b

write the nessecary files to run predvar1b


In [15]:
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 xrange(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()

os.system("exe\\predvar1b.exe <predvar1b.in")


Out[15]:
0

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

now for pyemu


In [18]:
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[18]:
first second third
c_obs10_2 pd_ten c_obs10_2 pd_ten c_obs10_2 pd_ten
0 0.015706 0.076700 0.000000 0.000000e+00 0.007078 0.145723
1 0.006040 0.046811 0.000832 2.573705e-03 0.115553 0.132455
2 0.005905 0.045945 0.000920 3.138167e-03 0.077244 0.271644
3 0.004850 0.042798 0.004136 1.273156e-02 0.029392 0.497192
4 0.004582 0.037457 0.005613 4.213813e-02 0.034111 0.417314
5 0.004233 0.031039 0.008757 9.996844e-02 0.041801 0.534001
6 0.004156 0.031010 0.009698 1.003232e-01 0.038039 0.525583
7 0.004155 0.030849 0.009728 1.032245e-01 0.038043 0.525723
8 0.004084 0.029342 0.011234 1.354974e-01 0.041175 0.579882
9 0.004084 0.029109 0.011234 1.422348e-01 0.041173 0.581877
10 0.004084 0.028689 0.011250 1.547092e-01 0.041273 0.571117
11 0.004083 0.027723 0.011272 1.870549e-01 0.041139 0.552224
12 0.004044 0.027693 0.013735 1.889087e-01 0.041676 0.553927
13 0.003870 0.027380 0.025100 2.094440e-01 0.038285 0.571023
14 0.003397 0.023741 0.056471 4.508064e-01 0.029120 0.680726
15 0.003397 0.023106 0.056482 4.973744e-01 0.029097 0.687914
16 0.003397 0.022881 0.056549 5.176496e-01 0.029181 0.695037
17 0.003395 0.022858 0.056737 5.202939e-01 0.029307 0.692737
18 0.003021 0.022763 0.124035 5.373727e-01 0.029080 0.692178
19 0.002723 0.022762 3.052508 5.493474e-01 0.031426 0.692896
20 0.002716 0.022580 47.713253 1.123392e+03 0.025201 0.856170
21 0.002714 0.022526 67.547943 1.881534e+03 0.025839 0.833455
22 0.002700 0.022522 353.320934 1.958512e+03 0.021420 0.819873
23 0.002695 0.022522 509.777285 1.959862e+03 0.020532 0.820389
24 0.002693 0.022217 612.541276 1.771097e+04 0.019521 0.902417
25 0.002685 0.014189 2167.707065 1.588460e+06 0.021336 0.559757
26 0.002672 0.013960 432974.547310 9.693291e+06 0.023606 0.610005
27 0.002672 0.013958 432882.571185 9.719003e+06 0.023856 0.612478
28 0.002668 0.013958 928051.002876 9.840488e+06 0.020469 0.621548
29 0.002668 0.013958 928051.002876 9.840488e+06 0.020469 0.621548
30 0.002668 0.013958 928051.002876 9.840488e+06 0.020469 0.621548
31 0.002657 0.013909 4280982.075554 4.383865e+07 0.019858 0.602480
32 0.002643 0.013880 14894803.894406 8.198704e+07 0.044134 0.762777
33 0.002642 0.013857 7521602.712976 1.682389e+07 0.056628 0.848982
34 0.002636 0.013822 33113666.501427 1.100326e+08 0.018645 0.575540
35 0.002635 0.013771 21848460.416614 3.198781e+08 0.011795 0.551340

generate some plots to verify


In [19]:
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 [20]:
cmd_args = [os.path.join("exe","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)


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

D:\Home\git\pyemu\verification\henry
Out[20]:
0

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

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


Out[22]:
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.491440e-30 3.728600e-31 1.026328e-30 8.389351e-31 3.729563e-30
kr01c02 0.000000e+00 0.000000e+00 1.733337e-31 5.108048e-31 8.332343e-30 9.016482e-30
kr01c03 0.000000e+00 0.000000e+00 1.232595e-32 3.478711e-33 1.097828e-30 1.113633e-30
kr01c04 6.831969e-134 0.000000e+00 0.000000e+00 0.000000e+00 4.930381e-32 4.930381e-32
kr01c05 6.634155e-134 0.000000e+00 0.000000e+00 0.000000e+00 1.232595e-32 1.232595e-32
kr01c06 6.885196e-98 0.000000e+00 0.000000e+00 1.925930e-34 4.930381e-32 4.949640e-32
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.672152e-76 0.000000e+00 0.000000e+00 0.000000e+00 3.137234e-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.680029e-59 0.000000e+00 0.000000e+00 2.763515e-59
kr01c12 1.018490e-62 8.246736e-61 2.725988e-59 0.000000e+00 0.000000e+00 2.809474e-59
kr01c13 1.018490e-62 8.246735e-61 2.725897e-59 1.593092e-58 0.000000e+00 1.874030e-58
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 [23]:
fig = plt.figure()
ax = plt.subplot(111)
axt = plt.twinx()
ax.plot(identpar_df["identifiability"])
ax.plot(df["ident"])
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[23]:
<matplotlib.text.Text at 0x102611d0>

In [ ]: