Exemple #1
0
        def job_handler(nnode, parameterizer_string, datacoder_string):
            parameterizer = load_paramfile(parameterizer_string, verbose=False)[0]
            datacoder = makedatacoder(datacoder_string, which=Datacoder_log)

            theory = Theory(parameterizer=parameterizer, datacoder=datacoder)

            return nnode, theory
Exemple #2
0
    def gen(rootnames, runmode):

        for rootname in rootnames:
            targetfile = "%s/_HerrMet.target" % rootname
            paramfile = "%s/_HerrMet.param" % rootname
            runfile = "%s/_HerrMet.run" % rootname

            if runmode == "append" and not os.path.exists(runfile):
                runmode = "restart"
            elif runmode == "restart" and os.path.exists(runfile):
                os.remove(runfile)
            elif runmode == "skip" and os.path.exists(runfile):
                print "skip %s" % rootname
                continue

            # ------
            p, logRHOM = load_paramfile(paramfile)
            # ------
            d = makedatacoder(targetfile, which=Datacoder_log)  # datacoder based on observations
            dobs, CDinv = d.target()
            duncs = CDinv ** -.5
            ND = len(dobs)
            dinfs = d(0.1 * np.ones_like(d.values))
            dsups = d(3.5 * np.ones_like(d.values))
            logRHOD = LogGaussND(dobs, duncs, dinfs, dsups, k=1000., nanbehavior=1)
            # ------
            G = Theory(parameterizer=p, datacoder=d)
            # ---------------------------------
            if runmode == "restart" or runmode == "skip":
                with RunFile(runfile, create=True, verbose=verbose) as rundb:
                    rundb.drop()
                    rundb.reset(p.NLAYER, d.waves, d.types, d.modes, d.freqs)
            elif runmode == "append":
                pass
            else:
                raise Exception('unexpected runmode %s' % runmode)

            # ---------------------------------
            for chainid in xrange(Nchain):
                M0 = np.random.rand(len(p.MINF)) * (p.MSUP - p.MINF) + p.MINF
                MSTD = p.MSTD
                yield Job(runfile=runfile,
                          rootname=rootname,
                          chainid=chainid,
                          M0=M0,
                          MSTD=MSTD,
                          G=G,
                          ND=ND,
                          logRHOD=logRHOD,
                          logRHOM=logRHOM,
                          p=p, d=d,
                          nkeep=Nkeep,
                          verbose=verbose)
Exemple #3
0
    def gen(rootnames):

        for rootname in rootnames:
            targetfile = "%s/_HerrMet.target" % rootname
            paramfile = "%s/_HerrMet.param" % rootname
            runfile = "%s/_HerrMet.run" % rootname

            # ------
            p, logRHOM = load_paramfile(paramfile)
            # ------
            d = makedatacoder(targetfile, which=Datacoder_log)  # datacoder based on observations
            dobs, CDinv = d.target()
            duncs = CDinv ** -.5
            ND = len(dobs)
            dinfs = d(0.1 * np.ones_like(d.values))
            dsups = d(3.5 * np.ones_like(d.values))
            logRHOD = LogGaussND(dobs, duncs, dinfs, dsups, k=1000., nanbehavior=1)
            # ------
            G = Theory(parameterizer=p, datacoder=d)
            # ---------------------------------
            with RunFile(runfile, verbose=verbose) as rundb:
                best = list(rundb.get(llkmin=top_llkmin, limit=top_limit, step=top_step, algo=None))

            # ---------------------------------
            for modelid, chainid, weight, llk, nlayer, model, dat in best:
                M0 = p(*model)
                DM = 1.0 #p.MSTD

                yield Job(runfile=runfile,
                          rootname=rootname,
                          chainid=chainid,
                          M0=M0,
                          DM=DM,
                          G=G,
                          ND=ND,
                          logRHOD=logRHOD,
                          logRHOM=logRHOM,
                          p=p, d=d,
                          verbose=verbose)
Exemple #4
0
SURF96 R U T 0 2.727797 1.457564 0.1
SURF96 R U T 0 2.416465 1.165715 0.1
SURF96 R U T 0 2.140666 1.051432 0.1
SURF96 R U T 0 1.896345 1.051072 0.1
SURF96 R U T 0 1.679909 1.085069 0.1
SURF96 R U T 0 1.488176 1.126465 0.1
SURF96 R U T 0 1.318325 1.168252 0.1
SURF96 R U T 0 1.167861 1.206051 0.1
SURF96 R U T 0 1.034569 1.234272 0.1
SURF96 R U T 0 0.916490 1.246419 0.1
SURF96 R U T 0 0.811888 1.235000 0.1
SURF96 R U T 0 0.719225 1.192478 0.1
SURF96 R U T 0 0.637137 1.115804 0.1
SURF96 R U T 0 0.564419 1.017582 0.1
SURF96 R U T 0 0.500000 0.929962 0.1
"""

    A = AsciiFile_fromstring(parameter_file_string)
    # p = Parameterizer_mZVSPRRH(A)
    p = Parameterizer_mZVSVPvsRHvp(A)
    d = makedatacoder(surf96filename=dispersion_file_string,
                      which=Datacoder_log)

    t = Theory(parameterizer=p, datacoder=d)

    fd = t.frechet_derivatives(m=p.MMEAN, gm=None)

    import matplotlib.pyplot as plt
    plt.colorbar(plt.imshow(fd))
    plt.show()
def _display_function(rootname, argv, verbose, mapkwargs):
    """private"""
    targetfile = "%s/_HerrMet.target" % rootname
    paramfile = "%s/_HerrMet.param" % rootname
    runfile = '%s/_HerrMet.run' % rootname
    pngfile = '%s/_HerrMet.png' % rootname
    #HerrLininitfile = '%s/_HerrLin.init' % rootname

    # ------ Initiate the displayer using the target data if exists
    if "-compact" in argv.keys():  # compact mode
        which_displayer = DepthDispDisplayCompact
    else:
        which_displayer = DepthDispDisplay

    if os.path.exists(targetfile):
        rd = which_displayer(targetfile=targetfile)
        d = makedatacoder(
            targetfile, which=Datacoder_log)  # datacoder based on observations
        dobs, _ = d.target()
    else:
        print "no target file found in %s" % rootname
        rd = which_displayer()

    # ------ Display run results if exist
    if os.path.exists(runfile) and ("-plot" in argv.keys()
                                    or "-pdf" in argv.keys()):

        with RunFile(runfile, verbose=verbose) as rundb:
            s = rundb.select('select MODELID from MODELS limit 1')
            if s is not None:
                # --- display best models
                if "-plot" in argv.keys():

                    assert argv["-plot"] == [] or len(
                        argv["-plot"]) == 4  # unexpected argument number
                    if argv["-plot"] == []:
                        plot_mode, plot_limit, plot_llkmin, plot_step = \
                            default_plot_mode, default_plot_limit, \
                            default_plot_llkmin, default_plot_step
                    elif len(argv['-plot']) == 4:
                        plot_mode, plot_limit, plot_llkmin, plot_step = argv[
                            '-plot']
                    else:
                        raise Exception()

                    print "plot : %s, limit %d, llkmin %f, step %d" % (
                        plot_mode, plot_limit, plot_llkmin, plot_step),
                    if plot_mode == "best":
                        chainids, weights, llks, ms, ds = \
                            rundb.getzip(limit=plot_limit,
                                         llkmin=plot_llkmin,
                                         step=plot_step,
                                         algo="METROPOLIS")
                    elif plot_mode == "last":
                        chainids, weights, llks, ms, ds = \
                            rundb.getlastszip(limit=plot_limit,
                                              llkmin=plot_llkmin,
                                              step=plot_step,
                                              algo="METROPOLIS")
                    else:
                        raise Exception('unexpected plot mode %s' % plot_mode)

                    vmin, vmax = llks.min(), llks.max()
                    # colors = values2colors(llks, vmin=vmin, vmax=vmax, cmap=argv['-cmap'])

                    if "-overdisp" in argv.keys():
                        """note : recomputing dispersion with another frequency array might
                                  result in a completely different dispersion curve in case
                                  of root search failure """
                        waves, types, modes, freqs, _ = ds[0]
                        overwaves, overtypes, overmodes, _, _ = zip(*list(
                            groupbywtm(waves, types, modes, freqs,
                                       np.arange(len(freqs)), None, True)))
                        overfreqs = [
                            freqspace(0.6 * min(freqs), 1.4 * max(freqs), 100,
                                      "plog") for _ in xrange(len(overwaves))
                        ]
                        overwaves, overtypes, overmodes, overfreqs = \
                            igroupbywtm(overwaves, overtypes, overmodes, overfreqs)
                        for llk, (mms, dds) in zip(
                                llks[::-1],
                                overdisp(ms[::-1],
                                         overwaves,
                                         overtypes,
                                         overmodes,
                                         overfreqs,
                                         verbose=verbose,
                                         **mapkwargs)):
                            # rd.plotmodel(color=clr, alpha=1.0, linewidth=3, *mms)
                            rd.addmodel(colorvalue=llk, *mms)
                            try:
                                # rd.plotdisp(color=clr, alpha=1.0, linewidth=3, *dds)
                                rd.adddisp(colorvalue=llk, *dds)
                            except KeyboardInterrupt:
                                raise
                            except Exception as e:
                                print "Error : could not plot dispersion curve (%s)" % str(
                                    e)

                        # cb = makecolorbar(vmin=vmin, vmax=vmax, cmap=argv['-cmap'])
                        # pos = rd.axdisp[-1].get_position()
                        # cax = rd.fig.add_axes((pos.x0, 0.12, pos.width, 0.01))
                        # rd.fig.colorbar(cb, cax=cax, label="log likelyhood", orientation="horizontal")

                    else:
                        "display the dispersion curves as stored in the database"
                        for i in range(len(llks))[::-1]:
                            # rd.plotmodel(color=colors[i], alpha=1.0, linewidth=3, *ms[i])
                            # rd.plotdisp(color=colors[i], alpha=1.0, linewidth=3, *ds[i])
                            rd.addmodel(colorvalue=llks[i], *ms[i])
                            rd.adddisp(colorvalue=llks[i], *ds[i])
                        # cb = makecolorbar(vmin=vmin, vmax=vmax, cmap=argv['-cmap'])
                        # pos = rd.axdisp[-1].get_position()
                        # cax = rd.fig.add_axes((pos.x0, 0.12, pos.width, 0.01))
                        # rd.fig.colorbar(cb, cax=cax, label="log likelyhood", orientation="horizontal")
                        # cax.set_xticklabels(cax.get_xticklabels(), rotation=90., horizontalalignment="center")

                    rd.showdispcoll(vmin=vmin,
                                    vmax=vmax,
                                    cmap=argv['-cmap'],
                                    alpha=1.0,
                                    linewidth=3)
                    rd.showdepthcoll(vmin=vmin,
                                     vmax=vmax,
                                     cmap=argv['-cmap'],
                                     alpha=1.0,
                                     linewidth=3)
                    rd.colorbar(vmin=vmin,
                                vmax=vmax,
                                cmap=argv['-cmap'],
                                label="log likelyhood",
                                orientation="horizontal")
                    print rd.cax.get_position()
                    rd.cax.set_xticklabels(rd.cax.get_xticklabels(),
                                           rotation=90.,
                                           horizontalalignment="center")

                # ---- display posterior pdf
                if "-pdf" in argv.keys():

                    assert argv["-pdf"] == [] or len(
                        argv["-pdf"]) == 4  # unexpected argument number
                    if argv["-pdf"] == []:
                        pdf_mode, pdf_limit, pdf_llkmin, pdf_step = \
                            default_pdf_mode, default_pdf_limit, default_pdf_llkmin, default_pdf_step
                    elif len(argv['-pdf']) == 4:
                        pdf_mode, pdf_limit, pdf_llkmin, pdf_step = argv[
                            '-pdf']
                    else:
                        raise Exception()

                    print "pdf : %s, limit %d, llkmin %f, step %d" % (
                        pdf_mode, pdf_limit, pdf_llkmin, pdf_step),
                    if pdf_mode == "best":
                        chainids, weights, llks, ms, ds = \
                            rundb.getzip(limit=pdf_limit,
                                         llkmin=pdf_llkmin,
                                         step=pdf_step,
                                         algo="METROPOLIS")
                    elif pdf_mode == "last":
                        chainids, weights, llks, ms, ds = \
                            rundb.getlastszip(limit=pdf_limit,
                                              llkmin=pdf_llkmin,
                                              step=pdf_step,
                                              algo="METROPOLIS")
                    else:
                        raise Exception('unexpected pdf mode %s' % pdf_mode)

                    dms = [
                        depthmodel_from_arrays(ztop, vp, vs, rh)
                        for ztop, vp, vs, rh in ms
                    ]

                    # display percentiles of model and data pdfs
                    clr = "b" if "-plot" not in argv.keys() else "k"
                    alp = 1.0 if "-plot" not in argv.keys() else 0.5

                    for p, (vppc, vspc, rhpc, prpc) in \
                            dmstats1(dms,
                                     percentiles=[0.01, 0.16, 0.5, 0.84, 0.99],
                                     Ndepth=100,
                                     Nvalue=100,
                                     weights=weights,
                                     **mapkwargs):
                        try:
                            l = 3 if p == 0.5 else 1
                            for what, where in zip([vppc, vspc, rhpc, prpc], [
                                    rd.axdepth['VP'], rd.axdepth['VS'],
                                    rd.axdepth['RH'], rd.axdepth['PR']
                            ]):
                                if where is not None:
                                    what.show(where,
                                              color=clr,
                                              linewidth=l,
                                              alpha=alp)

                        except KeyboardInterrupt:
                            raise
                        except Exception as e:
                            print "Error", str(e)

                    # display the disp pdf
                    for p, (wpc, tpc, mpc, fpc, vpc) in \
                            dispstats(ds,
                                      percentiles=[0.01, 0.16, 0.5, 0.84, 0.99],
                                      Ndisp=100,
                                      weights=weights,
                                      **mapkwargs):
                        try:
                            l = 3 if p == 0.5 else 1
                            rd.plotdisp(wpc,
                                        tpc,
                                        mpc,
                                        fpc,
                                        vpc,
                                        dvalues=None,
                                        color=clr,
                                        alpha=alp,
                                        linewidth=l)

                        except KeyboardInterrupt:
                            raise
                        except Exception as e:
                            print "Error", str(e)

    # ------
    if os.path.exists(paramfile):
        p, _ = load_paramfile(paramfile)
        showvp, showvs, showrh, showpr = True, True, True, True
        if isinstance(p, Parameterizer_mZVSVPRH):
            showpr = False
        elif isinstance(p, Parameterizer_mZVSPRRH):
            showvp = False
        elif isinstance(p, Parameterizer_mZVSPRzRHvp):
            showvp = showpr = showrh = False
        elif isinstance(p, Parameterizer_mZVSPRzRHz):
            showvp = showpr = showrh = False
        else:
            raise Exception('')

        #
        vplow, vphgh, vslow, vshgh, rhlow, rhhgh, prlow, prhgh = p.boundaries()

        for what, where in zip(\
                [vplow, vphgh, vslow, vshgh, rhlow, rhhgh, prlow, prhgh],
                [rd.axdepth['VP'], rd.axdepth['VP'], rd.axdepth['VS'], rd.axdepth['VS'], rd.axdepth['RH'], rd.axdepth['RH'], rd.axdepth['PR'], rd.axdepth['PR']]):
            if where is not None:
                what.show(where,
                          alpha=1.0,
                          color="k",
                          marker="o--",
                          linewidth=1,
                          markersize=3)
        zmax = 1.1 * p.inv(p.MINF)[0][-1]

        if isinstance(p, Parameterizer_mZVSPRzRHvp):
            rd.axdepth['PR'].plot(p.PRz(np.linspace(0., zmax, 100)),
                                  np.linspace(0., zmax, 100),
                                  "r--",
                                  linewidth=3)
            legendtext(rd.axdepth['PR'], p.PRzName, loc=4)
            legendtext(rd.axdepth['RH'], p.RHvpName, loc=4)
        elif isinstance(p, Parameterizer_mZVSPRzRHz):
            rd.axdepth['PR'].plot(p.PRz(np.linspace(0., zmax, 100)),
                                  np.linspace(0., zmax, 100),
                                  "r--",
                                  linewidth=3)
            rd.axdepth['RH'].plot(p.RHz(np.linspace(0., zmax, 100)),
                                  np.linspace(0., zmax, 100),
                                  "r--",
                                  linewidth=3)
            legendtext(rd.axdepth['PR'], p.PRzName, loc=4)
            legendtext(rd.axdepth['RH'], p.RHzName, loc=4)

        rd.set_zlim(np.array([0, zmax]))
    else:
        print "call option --param to see prior depth boundaries"

    # --------------------
    if "-m96" in argv.keys():  # plot user data on top
        for m96 in argv['-m96']:
            try:
                dm = depthmodel_from_mod96(m96)
                dm.vp.show(rd.axdepth['VP'], "m", linewidth=3, label=m96)
                dm.vs.show(rd.axdepth['VS'], "m", linewidth=3)
                dm.rh.show(rd.axdepth['RH'], "m", linewidth=3)
                dm.pr().show(rd.axdepth['PR'], "m", linewidth=3)
            except KeyboardInterrupt:
                raise
            except:  #Exception as e:
                print 'could not read or display %s (reason : %s)' % (m96,
                                                                      str(e))
            rd.axdepth['VP'].legend(loc=3)
    if "-ritt" in argv.keys():
        a = AsciiFile('/mnt/labex2/home/max/data/boreholes/GRT1/GRT1.logsonic')

        for what, where in zip(
            [a.data['VS'], a.data['VP'], a.data['VP'] / a.data['VS']],
            [rd.axdepth['VS'], rd.axdepth['VP'], rd.axdepth['PR']]):
            if where is not None:
                where.plot(what, a.data['TVD'] / 1000., "m", alpha=0.5)

    # --------------------
    if os.path.exists(targetfile):
        # plot data on top
        rd.plotdisp(d.waves,
                    d.types,
                    d.modes,
                    d.freqs,
                    d.inv(dobs),
                    dvalues=d.dvalues,
                    alpha=.5,
                    color="r",
                    linewidth=2)

        if "-overdisp" in argv.keys():
            rd.set_vlim((0.5 * d.values.min(), 1.5 * d.values.max()))
            rd.set_plim((0.8 / overfreqs.max(), 1.2 / overfreqs.min()))
        else:
            rd.set_vlim((0.8 * d.values.min(), 1.2 * d.values.max()))
            rd.set_plim((0.8 / d.freqs.max(), 1.2 / d.freqs.min()))
    rd.tick()
    rd.grid()
    rd.fig.suptitle(rootname.split('_HerrMet_')[-1])
    if "-ftsz" in argv.keys():
        chftsz(rd.fig, argv["-ftsz"][0])
    else:
        chftsz(rd.fig, default_fontsize)
    if "-png" in argv.keys():
        dpi = argv['-png'][0] if len(argv['-png']) else default_dpi
        if verbose:
            print "writing %s" % pngfile
        rd.fig.savefig(pngfile, dpi=dpi)
    elif "-inline" in argv.keys():
        plt.show()
    else:
        showme()
    plt.close(rd.fig)
Exemple #6
0
def optimize(argv, verbose, mapkwargs):

    if '-h' in argv.keys() or "-help" in argv.keys():
        print(long_help)
        return

    check_keys(argv)

    # ===============================
    if "-temp" in argv.keys():
        template = OPTIMIZEPARAMTXT.format(
            nx=1,
            ny=1,
            newnz=1,
            dx=1.,
            dy=1.0,
            newdz=1.0,
            targetfiles=
            "./path/to/inversion/_HerrMet_node_iy{iy:03d}_ix{ix:03d}/_HerrMet.target",
            extractfiles=
            "./path/to/inversion/_HerrMet_node_iy{iy:03d}_ix{ix:03d}/_HerrMet.best_1000_0_1.p0.50.mod96",
            ndecim=1,
            Lh=1.0,
            Lv=0.5,
            vsunc=0.1,
            damping=1.0)

        if verbose:
            print(template)

        if os.path.isfile(HERRMETOPTIMIZEPARAMFILE):
            raise IOError(HERRMETOPTIMIZEPARAMFILE, ' exists already')

        with open(HERRMETOPTIMIZEPARAMFILE, 'w') as fid:
            fid.write(template)

        print('please customize {} and rerun this plugin'.format(
            HERRMETOPTIMIZEPARAMFILE))
        sys.exit(0)

    # ===============================
    if "-mprior" in argv.keys():

        if not os.path.isfile(HERRMETOPTIMIZEPARAMFILE):
            raise IOError(HERRMETOPTIMIZEPARAMFILE)

        # ==================== read the parameter file
        nx, ny, newnz, \
            dx, dy, newdz, ndecim, \
            Lh, Lv, vsunc, damping, \
            extractfiles, datafiles = \
            load_optimize_parameters()

        x = (np.arange(nx) * dx)[::ndecim]
        y = (np.arange(ny) * dy)[::ndecim]
        ixs = np.arange(nx)[::ndecim]  # indexs used to name the files
        iys = np.arange(ny)[::ndecim]
        ztop = np.arange(newnz) * newdz
        # WARNING : I update nx, ny
        del dx, dy  # to avoid confusion
        nz, ny, nx = len(ztop), len(y), len(x)

        # =============== load the results of the point wise inversion
        # config = z, y, x
        zmid = np.hstack((ztop[:-1] + 0.5 * (ztop[1:] - ztop[:-1]),
                          ztop[-1] + ztop[1] - ztop[0]))
        vs_cube = np.zeros((len(ztop), len(y), len(x)), float)
        vsunc_cube = np.zeros_like(vs_cube)

        for i, iy in enumerate(iys):
            for j, ix in enumerate(ixs):
                try:
                    m96file = extractfiles.format(iy=iy, ix=ix)
                    print('loading {}'.format(m96file))
                    dm = depthmodel_from_mod96(m96file)
                except Exception as e:
                    raise e

                vs_cube[:, i, j] = dm.vs.interp(z=zmid)
                vsunc_cube[:, i, j] = vsunc

        # ===============
        iz, jy, kx = np.mgrid[:nz, :ny, :nx]

        ixsflat = ixs[kx].flat[:]
        iysflat = iys[jy].flat[:]
        xflat = x[kx].flat[:]
        yflat = y[jy].flat[:]
        ztopflat = ztop[iz].flat[:]
        zmidflat = zmid[iz].flat[:]
        Mprior = vs_cube  # .flat[:]
        Munc = vsunc_cube  # .flat[:]

        xedges = np.hstack(
            (x - 0.5 * (x[1] - x[0]), x[-1] + 0.5 * (x[1] - x[0])))
        yedges = np.hstack(
            (y - 0.5 * (y[1] - y[0]), y[-1] + 0.5 * (y[1] - y[0])))
        zedges = np.hstack((ztop, ztop[-1] + 0.5 * (ztop[1] - ztop[0])))

        # ================== compute the parameterizers
        """
        construct parameterizers needed to define the theory function in each node
        """

        # write the header of the parameterizer for each node
        parameter_string_header = """
        #met NLAYER = {}
        #met TYPE = 'mZVSVPvsRHvp'
        #met VPvs = 'lambda VS: 0.9409+2.0947*VS-0.8206*VS**2+0.2683*VS**3-0.0251*VS**4'
        #met RHvp = 'lambda VP: 1.6612*VP-0.4721*VP**2+0.0671*VP**3-0.0043*VP**4+0.000106*VP**5'
        #fld KEY     VINF          VSUP
        #unt []      []            []
        #fmt %s      %f            %f
        """.format(len(ztop)).replace('    #', '#')

        for i in range(1, len(ztop)):
            # force VINF=VSUP => means lock the depth of the interfaces in the theory operator
            parameter_string_header += "-Z{} {} {}\n".format(
                i, -ztop[i], -ztop[i])  # add locked depth interfaces

        def job_generator():
            for iy in range(ny):
                for jx in range(nx):  # order matters!!!!
                    vs = Mprior[:, iy, jx]
                    yield Job(iy, jx, ztop, vs)

        def job_handler(iy, jx, ztop, vs):
            parameterizer_string = parameter_string_header

            for i in range(len(ztop)):
                # SET VINF < VS extracted from pointwise inv < VSUP
                # such as parameterizer.MMEAN corresponds to the extracted vs
                parameterizer_string += "VS{} {} {}\n".format(
                    i, vs[i] - 0.01, vs[i] + 0.01)
            # parameterizer = load_paramfile(parameter_string, verbose=False)[0]
            return iy, jx, parameterizer_string

        wb = None
        if verbose:
            wb = waitbarpipe('parameterizers')

        parameterizer_strings = []
        with MapSync(job_handler, job_generator(),
                     **mapkwargs) as ma:  # order matters!!!!
            for jobid, (iy, jx, parameter_string), _, _ in ma:
                parameterizer_strings.append(parameter_string)

                if verbose:
                    wb.refresh(jobid / float(nx * ny))

        if verbose:
            wb.close()

        parameterizer_strings = np.asarray(parameterizer_strings, str)

        np.savez(HERRMETOPTIMIZEPRIORFILE,
                 nz=nz,
                 ny=ny,
                 nx=nx,
                 x=x,
                 xedges=xedges,
                 xflat=xflat,
                 ixs=ixs,
                 ixsflat=ixsflat,
                 y=y,
                 yedges=yedges,
                 yflat=yflat,
                 iys=iys,
                 iysflat=iysflat,
                 ztop=ztop,
                 zmid=zmid,
                 zedges=zedges,
                 ztopflat=ztopflat,
                 zmidflat=zmidflat,
                 Mprior=Mprior,
                 Munc=Munc,
                 damping=damping,
                 Lv=Lv,
                 Lh=Lh,
                 parameterizer_strings=parameterizer_strings)

    # ===============================
    if "-dobs" in argv.keys():

        # ==================== read the parameter file
        nx, ny, newnz, \
            dx, dy, newdz, ndecim, \
            Lh, Lv, vsunc, damping, \
            extractfiles, datafiles = \
            load_optimize_parameters()

        # x = (np.arange(nx) * dx)[::ndecim]
        # y = (np.arange(ny) * dy)[::ndecim]
        ixs = np.arange(nx)[::ndecim]  # indexs used to name the files
        iys = np.arange(ny)[::ndecim]

        datacoder_strings = []
        for i, iy in enumerate(iys):
            for j, ix in enumerate(ixs):  # order matters!!!!

                try:
                    datafile = datafiles.format(iy=iy, ix=ix)
                    if verbose:
                        print('loading ', datafile)
                    s96 = surf96reader(filename=datafile)

                except Exception as e:
                    raise e

                datacoder_string = str(s96)
                datacoder_strings.append(datacoder_string)

        datacoder_strings = np.asarray(datacoder_strings, str)
        datacoders = [
            makedatacoder(datacoder_string, which=Datacoder_log)
            for datacoder_string in datacoder_strings
        ]

        Nobs = []
        Waves = []
        Types = []
        Modes = []
        Freqs = []
        Dobs = []
        Dunc = []
        for datacoder in datacoders:
            _dobs, _CDinv = datacoder.target()
            Nobs.append(len(datacoder.waves))
            Waves.append(datacoder.waves)
            Types.append(datacoder.types)
            Modes.append(datacoder.modes)
            Freqs.append(datacoder.freqs)
            Dobs.append(_dobs)
            Dunc.append(_CDinv**-0.5)

        Nobs = np.array(Nobs)
        Waves = np.hstack(Waves)
        Types = np.hstack(Types)
        Modes = np.hstack(Modes)
        Freqs = np.hstack(Freqs)
        Dobs = np.hstack(Dobs)
        Dunc = np.hstack(Dunc)

        np.savez(HERRMETOPTIMIZEDOBSFILE,
                 datacoder_strings=datacoder_strings,
                 Nobs=Nobs,
                 Waves=Waves,
                 Types=Types,
                 Modes=Modes,
                 Freqs=Freqs,
                 Dobs=Dobs,
                 Dunc=Dunc)

    # ===============================
    if "-inv" in argv.keys():

        # ========== Load inputs
        with np.load(HERRMETOPTIMIZEPRIORFILE) as loader:
            x = loader['x']
            y = loader['y']
            # xedges = loader['xedges']
            # yedges = loader['yedges']
            # zedges = loader['zedges']
            # ixs = loader['ixs']
            # iys = loader['iys']
            zmid = loader['zmid']
            xflat = loader['xflat']
            yflat = loader['yflat']
            zflat = zmidflat = loader['zmidflat']
            Lh = loader['Lh']
            Lv = loader['Lv']
            Mprior = loader['Mprior'].flat[:]
            Munc = loader['Munc'].flat[:]
            damping = loader['damping']
            parameterizer_strings = loader['parameterizer_strings']

        with np.load(HERRMETOPTIMIZEDOBSFILE) as loader:
            Nobs = loader['Nobs']
            # Waves = loader['Waves']
            # Types = loader['Types']
            # Modes = loader['Modes']
            # Freqs = loader['Freqs']
            Dobs = loader['Dobs']
            Dunc = loader['Dunc']
            datacoder_strings = loader['datacoder_strings']

        nx, ny, nz = len(x), len(y), len(zmid)
        nobs = len(Dobs)

        # save the grid
        # add_to_npz(HERRMETOPTIMIZEINVFILE,
        #            # 3D grid needed for display
        #            nx=nx, ny=ny, nz=nz,
        #            xedges=xedges, yedges=yedges, zedges=zedges,  # edge grid points (for pcolormesh)
        #            x=x, y=y, zmid=zmid,  # mid grid points
        #            ixs=ixs, iys=iys,  # indexs of the point wise inversion used
        #            Nobs=Nobs)   # number of disp point per node (array) flatten in the horizontal plane

        Munc *= np.sqrt(float(len(Mprior)) / float(
            len(Dobs))) / damping  # equilibrate the costs, apply damping here

        CD = sp.diags(Dunc**2., format="csc", shape=(len(Dobs), len(Dobs)))
        CDinvdiag = Dunc**-2.

        smoother = ModelSmoother(x=x,
                                 y=y,
                                 zmid=zmid,
                                 xflat=xflat,
                                 yflat=yflat,
                                 zmidflat=zflat,
                                 Lh=Lh,
                                 Lv=Lv)

        CM = ModelCovarianceMatrix(Munc=Munc,
                                   x=x,
                                   y=y,
                                   zmid=zmid,
                                   xflat=xflat,
                                   yflat=yflat,
                                   zmidflat=zflat,
                                   Lh=Lh,
                                   Lv=Lv)

        g = ForwardOperator(parameterizer_strings=parameterizer_strings,
                            datacoder_strings=datacoder_strings,
                            nx=nx,
                            ny=ny,
                            nz=nz,
                            Nobs=Nobs,
                            **mapkwargs)

        Dprior = g(Mprior)
        add_to_npz(HERRMETOPTIMIZEINVFILE, Dprior=Dprior)

        M0 = smoother.dot(Mprior, trunc=4.)

        D0 = g(M0)
        add_to_npz(HERRMETOPTIMIZEINVFILE, M0=M0.reshape((nz, ny, nx)), D0=D0)

        MI = M0.copy()
        DI = D0.copy()

        with Timer('CM_sparse'):
            CM_sparse = CM.sparse(trunc=4.)
        with Timer('CM_lu'):
            CM_sparse_lu = splinalg.splu(CM_sparse)

        G = None
        data_costs = [0.5 * (CDinvdiag * (Dobs - DI)**2.0).sum()]
        model_costs = [
            0.
        ]  #0.5 * (CM_sparse_lu.solve(MI - M0) * (MI - M0)).sum()
        for i in range(20):
            if G is None or True:
                G = g.frechet_derivatives(MI)
                with Timer('G * CM * GT + CD'):
                    Ksparse = G * CM_sparse * G.T + CD

                with Timer('splu(G * CM * GT + CD)'):
                    Klu = splinalg.splu(Ksparse)

            XI = Dobs - DI + G * (MI - M0)
            DM = CM.dot(G.T * Klu.solve(XI))
            DM = (M0 - MI + DM)

            if np.abs(DM).max() > 0.25:
                warnings.warn(str(np.abs(DM).max()))
                DM *= 0.25 / np.abs(DM).max()

            print("max correction:", np.abs(DM).max())
            MI = MI + DM
            DI = g(MI)

            # ============== costs
            chi2_data = 0.5 * (CDinvdiag * (Dobs - DI)**2.0).sum()
            chi2_model = 0.5 * (
                CM_sparse_lu.solve(MI - M0) *
                (MI - M0)).sum()  # fails if I use Mprior instead of M0
            if chi2_model < 0 or chi2_data < 0:
                raise ValueError(
                    chi2_model,
                    chi2_data)  # may happen after numerical instability

            print('data cost: ', chi2_data)
            print('model cost: ', chi2_model)
            print('total cost: ', chi2_data + chi2_model)

            data_costs.append(chi2_data)
            model_costs.append(chi2_model)

            add_to_npz(HERRMETOPTIMIZEINVFILE,
                       data_costs=np.asarray(data_costs),
                       model_costs=np.asarray(model_costs),
                       total_costs=np.asarray(model_costs) +
                       np.asarray(data_costs),
                       Msol=MI.reshape((nz, ny, nx)),
                       Dsol=DI)

            if np.abs(DM).max() <= 0.01:
                print('convergence achieved')
                break

    # ===============================
    if "-show" in argv.keys():
        import matplotlib.pyplot as plt

        with np.load(HERRMETOPTIMIZEPRIORFILE) as loader:
            x = loader['x']
            y = loader['y']
            zmid = loader['zmid']
            xedges = loader['xedges']
            yedges = loader['yedges']
            zedges = loader['zedges']
            vs_prior = loader['Mprior']

        with np.load(HERRMETOPTIMIZEINVFILE) as loader:
            vs_0 = loader['M0']
            vs_sol = loader['Msol']
            data_costs = loader['data_costs']
            model_costs = loader['model_costs']
            total_costs = loader['total_costs']

        plt.figure()

        plt.plot(data_costs, 'bs-', label="$ \chi_D^2 $"
                 )  #0.5 * (CDinvdiag * (Dobs - DI) ** 2.0).sum()
        plt.semilogy(
            model_costs, 'gs-', label="$ \chi_M^2 $"
        )  ##0.5 * (CM_sparse_lu.solve(MI - M0) * (MI - M0)).sum()  # fails if I use Mprior instead of M0
        plt.plot(total_costs, 'ro-', label="$ \chi_D^2 + chi_M^2 $")
        plt.gca().set_xlabel('iteration number')
        plt.gca().grid(True, linestyle=":")
        plt.gca().set_ylabel(r'$ \chi $')
        plt.gca().legend()

        if argv['-show'][0] == "z":
            zslice = argv['-show'][1]
            iz = np.argmin(abs(zmid - zslice))

            fig = plt.figure(figsize=(12, 4))
            ax1 = plt.subplot(131,
                              title="$ Vs^{prior} $",
                              aspect=1.0,
                              xlabel="x(km)",
                              ylabel="y(km)")
            ax2 = plt.subplot(132,
                              title="$ Vs^{0} $",
                              aspect=1.0,
                              xlabel="x(km)",
                              ylabel="y(km)",
                              sharex=ax1,
                              sharey=ax1)
            ax3 = plt.subplot(133,
                              title="$ Vs^{sol} $",
                              aspect=1.0,
                              xlabel="x(km)",
                              ylabel="y(km)",
                              sharex=ax1,
                              sharey=ax1)
            fig.suptitle('depth : {:.2f}km'.format(zmid[iz]))
            cax = fig.add_axes((0.95, 0.3, 0.012, 0.3))

            vsmin = min([vs[iz, ...].min() for vs in [vs_prior, vs_0, vs_sol]])
            vsmax = min([vs[iz, ...].max() for vs in [vs_prior, vs_0, vs_sol]])
            for ax, vs in zip([ax1, ax2, ax3], [vs_prior, vs_0, vs_sol]):
                coll = ax.pcolormesh(xedges,
                                     yedges,
                                     vs[iz, ...],
                                     vmin=vsmin,
                                     vmax=vsmax,
                                     cmap=plt.get_cmap('jet_r'))

            plt.colorbar(coll, cax=cax)
            plt.ion()
            plt.show()
            input('pause')

        elif argv['-show'][0] == "x":
            xslice = argv['-show'][1]
            ix = np.argmin(abs(x - xslice))

            fig = plt.figure(figsize=(12, 4))
            ax1 = plt.subplot(131,
                              title="$ Vs^{prior} $",
                              xlabel="y(km)",
                              ylabel="z(km)")
            ax2 = plt.subplot(132,
                              title="$ Vs^{0} $",
                              xlabel="y(km)",
                              ylabel="z(km)",
                              sharex=ax1,
                              sharey=ax1)
            ax3 = plt.subplot(133,
                              title="$ Vs^{sol} $",
                              xlabel="y(km)",
                              ylabel="z(km)",
                              sharex=ax1,
                              sharey=ax1)
            for ax in ax1, ax2, ax3:
                ax.invert_yaxis()
            fig.suptitle('x = {:.2f}km'.format(x[ix]))
            cax = fig.add_axes((0.95, 0.3, 0.012, 0.3))

            vsmin = min([vs[..., ix].min() for vs in [vs_prior, vs_0, vs_sol]])
            vsmax = min([vs[..., ix].max() for vs in [vs_prior, vs_0, vs_sol]])
            for ax, vs in zip([ax1, ax2, ax3], [vs_prior, vs_0, vs_sol]):
                coll = ax.pcolormesh(yedges,
                                     zedges,
                                     vs[..., ix],
                                     vmin=vsmin,
                                     vmax=vsmax,
                                     cmap=plt.get_cmap('jet_r'))

            plt.colorbar(coll, cax=cax)
            plt.ion()
            plt.show()
            input('pause')

        elif argv['-show'][0] == "y":
            yslice = argv['-show'][1]
            iy = np.argmin(abs(y - yslice))

            fig = plt.figure(figsize=(12, 4))
            ax1 = plt.subplot(131,
                              title="$ Vs^{prior} $",
                              xlabel="y(km)",
                              ylabel="z(km)")
            ax2 = plt.subplot(132,
                              title="$ Vs^{0} $",
                              xlabel="y(km)",
                              ylabel="z(km)",
                              sharex=ax1,
                              sharey=ax1)
            ax3 = plt.subplot(133,
                              title="$ Vs^{sol} $",
                              xlabel="y(km)",
                              ylabel="z(km)",
                              sharex=ax1,
                              sharey=ax1)
            for ax in ax1, ax2, ax3:
                ax.invert_yaxis()
            fig.suptitle('y = {:.2f}km'.format(y[iy]))
            cax = fig.add_axes((0.95, 0.3, 0.012, 0.3))

            vsmin = min(
                [vs[:, iy, :].min() for vs in [vs_prior, vs_0, vs_sol]])
            vsmax = min(
                [vs[:, iy, :].max() for vs in [vs_prior, vs_0, vs_sol]])
            for ax, vs in zip([ax1, ax2, ax3], [vs_prior, vs_0, vs_sol]):
                coll = ax.pcolormesh(xedges,
                                     zedges,
                                     vs[:, iy, :],
                                     vmin=vsmin,
                                     vmax=vsmax,
                                     cmap=plt.get_cmap('jet_r'))

            plt.colorbar(coll, cax=cax)
            plt.ion()
            plt.show()
            input('pause')