Example #1
0
def plot(argv):
    """
    Handles commands

        argv[0] in ("plot", "show")
    """
    import getopt
    from pathtools import unpickle_path
    from pts.tools.tab2plot import colormap
    # from numpy import linspace #, empty, transpose
    # from numpy import array

    #
    # Only position arguments so far.  The first, argv[0], is the name
    # of the method, usually just "plot":
    #
    cmd = argv[0]

    # skip argv[1], it just tells that this precious function has been selected.
    opts, args = getopt.getopt(argv[2:], "", [])
    # print "opts=", opts
    # print "args=", args

    import matplotlib

    if cmd == "plot":
        # do not expect X11 to be available, use a different backend:
        matplotlib.use("Agg")

    from matplotlib import pyplot as plt

    def plot_energy(energies, color):
        # energy profile:
        plt.title("Energy profile", fontsize="large")
        plt.ylabel("Energy [eV]")
        plt.xlabel("Path point [arb. u.]")
        plt.plot(range(1, len(energies) + 1), energies, "o--", color=color)
        plt.xlim((1, len(energies)))

    def plot_energy_with_cubic_spline(geometries, energies, gradients,
                                      tangents, abscissas, color):
        """
        Plot the energy profile indicating  the slope of the energy at
        the vertices.

        Tangents are usually normalized,  if at all, quite differently
        from the  convention used  here -- one  unit of  "path length"
        between  neyboring images.  To  avoid visual  mismatch between
        finite difference (E[i+1] - E[i]) / 1.0 and differential slope
        dE  /  ds  =  dot(g,  t)  at  the  nodes  we  invent  a  local
        re-normalization of the tangents.
        """
        # energy profile:
        from numpy import dot, linspace, sqrt, array, shape, empty
        from pts.func import CubicSpline

        plt.title("Energy profile", fontsize="large")
        plt.ylabel("Energy [eV]")
        plt.xlabel("Path point [arb. u.]")

        if abscissas == None:
            # this will hold distances vectors between path points:
            xdeltas = empty(shape(geometries))
            xdeltas[0] = geometries[1] - geometries[0]
            xdeltas[-1] = geometries[-1] - geometries[-2]
            xdeltas[1:-1] = (geometries[2:] - geometries[:-2]) / 2.0

            # this is the measure  of the real separatioin between images,
            # each will correspond to one unit on the graph:
            scales = array([sqrt(dot(x, x)) for x in xdeltas])

            # re-normalize tangents:
            tangents = array(
                [s * t / sqrt(dot(t, t)) for s, t in zip(scales, tangents)])
            abscissas = range(1, len(energies) + 1)
        else:
            # If the distances in s are explicitely given, expect also the tangents to be
            # right
            tangents = array(tangents)
            abscissas = array(abscissas)

        # projection of the gradient on the new tangents, dE / ds:
        slopes = [dot(g, t) for g, t in zip(gradients, tangents)]

        # cubic spline
        spline = CubicSpline(abscissas, energies, slopes)

        # spline will be plotted with that many points:
        line = linspace(abscissas[0], abscissas[-1], 100)

        plt.plot(abscissas,
                 energies,
                 "o",
                 line,
                 map(spline, line),
                 "-",
                 color=color)
        plt.xlim((abscissas[0], abscissas[-1]))

    # number of curves on the same graph:
    N = len(args)

    #
    # This is the main loop over the input files:
    #
    for i, name in enumerate(args):
        geometries, energies, gradients, tangents, abscissas, symbols, trafo = unpickle_path(
            name)  # v2

        # tuple is printed in one line:
        # print tuple(energies)

        # energy profile:
        if tangents is not None:
            plot_energy_with_cubic_spline(geometries, energies, gradients,
                                          tangents, abscissas, colormap(i, N))
        else:
            plot_energy(energies, colormap(i, N))

    if cmd == "show":
        # Display the plot, needs X11:
        plt.show()

    if cmd == "plot":
        # Save in vecor format, allows post-processing:
        plt.savefig("plot.svg")
Example #2
0
def visualize_path(filenames,
                   data_ase,
                   other_input,
                   values,
                   path_look,
                   for_plot,
                   hold,
                   file_range=[0, sys.maxint]):
    """
    Does the  actual plotting of a  path function. If hold  = True the
    actual plot is not done.  This allows to use the function together
    with some other functions changing the plot.
    """
    from pts.tools.path2tab import carts_to_int
    from pts.tools.tab2plot import setup_plot, plot_data, prepare_plot, colormap
    from pts.ui.read_COS import read_geos_from_file
    from pts.tools.path2tab import extract_data
    import numpy as np
    from copy import copy
    from sys import stderr
    # Expand the output, we need it further.
    ase, format_ts = data_ase
    num, ts_estimates, refs = path_look
    reference, reference_data = refs
    withs, allval, special_vals, appender, special_opt = values
    diff, symm, symshift = special_opt
    num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot
    cell, tomove, howmove = appender

    # plot environment
    setup_plot(title=title, x_label=xlab, y_label=ylab, log=logscale)

    # extract which options to take
    optraw, num_opts, xnum_opts, optx = makeoption(num_i, diff, symm, symshift,
                                                   withs)
    # num_opts_raw = copy(num_opts)
    opt = copy(optraw)

    if special_vals != []:
        for s_val in special_vals:
            # use the options for x and plot the data gotten from
            # the file directly
            opt = opt + " t %i" % (num_opts + 1)
            num_opts = num_opts + 1

    n = len(filenames) * (num_opts - 1)

    if not reference == []:
        for ref in reference:
            # Reference  point (geometry, energy)  to compare  the rest
            # data to it.  geometry is supposed to be in a ASE readable
            # format, energy in a separate file.
            atom_ref, y_ref = read_geos_from_file([ref], format=format_ts)

            # Reference  data  for  the  geometries.  The  Abscissa  is
            # supposed to be on 0.5
            reference_int_geos = np.array(
                carts_to_int(y_ref, [0.5], allval, cell, tomove, howmove,
                             withs))
            reference_int_geos = reference_int_geos.T
            reference_int_geos = reference_int_geos.tolist()

            # optref = optraw
            num_opts_ref = num_opts
            if special_vals != []:
                # From  the  special  vals  only the  energies  can  be
                # displaced. Therefore special treatment is required.
                for s_val in special_vals:
                    if s_val.startswith("en") and not reference_data == None:
                        # optref = optraw + " t %i" % (num_opts_raw + 1)
                        reference_data = np.loadtxt(reference_data)
                        reference_int_geos.append([reference_data.tolist()])
                    else:
                        num_opts_ref = num_opts_ref - 1

            if num_opts_ref > 1:
                colors = [colormap(j, n) for j in range(0, num_opts)]
                prepare_plot(None, None, None, "_nolegend_",
                             reference_int_geos, "Reference", opt, colors)

    # For each file prepare the plot
    for i, filename in enumerate(filenames):
        if i < file_range[0] or i > file_range[1]:
            continue

        # Extract  the  data  for  beads,  path  if  availabe  and  TS
        # estimates if requested (else None).
        beads, path, ts_ests_geos = extract_data(filename, data_ase,
                                                 other_input, values,
                                                 ts_estimates, num, i)

        if ts_ests_geos == []:
            print >> stderr, "WARNING: No transition state found for file", filename
            ts_ests_geos = None

        # The name belonging to filename.
        name_p = str(i + 1)
        if names_of_lines[i] != []:
            name_p = names_of_lines[i]

        # prepare plot from the tables containing the path and bead

        def choose_color(j):
            return colormap(i * (num_opts - 1) + j, n)

        # data only if there are enough for x AND y values
        colors = map(choose_color, range(0, num_opts))
        if num_opts > 1:
            if ase:
                prepare_plot(None, None, None, "_nolegend_", beads, name_p,
                             opt, colors)
            else:
                prepare_plot(path, name_p, beads, "_nolegend_", ts_ests_geos,
                             "_nolegend_", opt, colors)

    # now plot
    plot_data(hold=hold, xrange=xran, yrange=yran, savefile=outputfile)
Example #3
0
 def choose_color(j):
     return colormap(i * (num_opts - 1) + j, n)
Example #4
0
 def choose_color(j):
      return colormap(i * (num_opts - 1 + len(special_val)) + j, n)
Example #5
0
def visualize_dimer(log_file, values, dimer_special, for_plot, hold, file_range = [0, sys.maxint]):
    """
    this function might be called by another program. It contains
    the main body of plotting a progress path.

    if hold = True the plot will be prepared but not plotted (so that afterwards
    other plots can be added). For hold = False the plot will be done.
    """
    from pts.tools.tab2plot import setup_plot,prepare_plot, plot_data, colormap
    from pts.tools.path2plot import makeoption
    from pts.tools.path2tab import beads_to_int
    from pts.tools.dimer2xyz import read_from_pickle_log

    num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot
    withs, allval, special_val, appender, special_opt =  values
    diff, __, __ =  special_opt
    cell, tomove, howmove = appender

    # These two are extra values only for the progress tools
    arrow_len, vec_angle_raw = dimer_special

    decrease = [0, 0]

    #default values of interesting parameters
    vec_angle = interestingdirection()

    #FIXME: interestingdirection class is a bit unhandy. Maybe exchange it soon.
    for raw in vec_angle_raw:
        m1, m2 = raw
        value = "vec"
        # For both vectors find the code and whether the first or last
        # points of the other variables have to be removed in order to have
        # all vectors of the same length.
        for mi in m1, m2:
            vec_angle.set_name(mi)
            range_v = vec_angle.get_range()
            for i, j in enumerate(range_v):
                 if not j == 0:
                    decrease[i] = j
            value += vec_angle.get_string()

        if value[3:5] == value[5:]:
            decrease[0] = -1
        special_val.append(value)

    if arrow_len == None:
        arrow = False
    else:
        arrow = True

    if "step" in special_val:
         # There will be one value less for the step, as it is the difference to the last
         # one.
         decrease[1] = 1

    # plot environment
    setup_plot(title = title, x_label = xlab, y_label = ylab, log = logscale)

    # extract which options to take
    opt, num_opts, xnum_opts, optx = makeoption(num_i, diff, [], [], withs)

    # decide how many color are used
    n = len(log_file) * (num_opts - 1 + len(special_val))
    for i, geo_file in enumerate(log_file):
        if i < file_range[0] or i > file_range[1]:
            continue

        # extract refinement process information from log.pickle file
        obj, geos, modes, curv, energy, grad = read_from_pickle_log(geo_file)
        # initial and final point to plot used because arrays to be plotted may have
        # different lengths
        ifplot = [0, len(geos)]
        ifplot = [ip - dec for ip, dec in zip(ifplot, decrease)]

        x = list(range(0,len(geos)))[ifplot[0]: ifplot[1]]
        # internal coordinates for plotting
        beads = beads_to_int(geos[ifplot[0]: ifplot[1]], x, obj, \
                        allval, cell, tomove, howmove, withs)
        beads = np.asarray(beads)
        beads = beads.T
        # name of the plot
        name_p = str(i + 1)
        if names_of_lines[i] != []:
             name_p = names_of_lines[i]
        # make plot only when there are enough points
        if num_opts > 1:
            def choose_color(j):
                 return colormap(i * (num_opts - 1 + len(special_val)) + j, n)

            # data only if there are enough for x AND y values
            colors = map(choose_color, range(0, num_opts))
            prepare_plot( None, None, None, None, beads, name_p, opt, colors)

            if arrow:
                for j in range(ifplot[0], ifplot[1]):
                    # for each bead we plotted, a line is added to the center point
                    # indicating the dimer mode direction projected in internal coordinates

                    assert(arrow_len > 0)

                    # use finite difference method to extract the projection of modes
                    arrows = beads_to_int([geos[j] - modes[j] * arrow_len, geos[j] + modes[j] * arrow_len], \
                                [x[j]] * 2, obj, allval, cell, tomove, howmove, withs)
                    arrows = np.asarray(arrows)
                    arrows = arrows.T

                    #arrows = rescale(arrows, arrow_len)


                    prepare_plot(arrows, "_nolegend_", None, None, None, None, opt, colors)

        if special_val != []:
            # Two kinds of dictionary store share the same interface
            for j, s_val in enumerate(special_val):
                # use the options for x and plot the data gotten from
                # the file directly

                optlog = optx + " t %i" % (xnum_opts + 1)
                log_points = beads
                log_points = log_points[:xnum_opts + 1,:]
                log_points = log_points.tolist()

                if s_val.startswith("en"):
                    log_points.append(energy[ifplot[0]: ifplot[1]])
                elif s_val.startswith("gr"):
                    val = s_val[3:]
                    log_points.append(grads_dimer(modes, grad[ifplot[0]: ifplot[1]], val))
                elif s_val.startswith("curv"):
                    log_points.append(curv)
                elif s_val.startswith("step"):
                    log_points.append(stepsize(geos[ifplot[0]: ifplot[1]+1]))
                elif s_val.startswith("vec"):
                    val = s_val[3:]
                    log_points.append(array_angles(*vec_angle(val, modes, geos, grad, ifplot)))
                log_points = np.asarray(log_points)

                prepare_plot( None, None, None, None, log_points, \
                               s_val + " " + name_p, optlog, [colormap(i * (num_opts - 1 + len(special_val)) + j, n)])

    # finally make the picture visible
    plot_data(hold = hold, xrange = xran, yrange = yran, savefile = outputfile)
Example #6
0
def plot(argv):
    """
    Handles commands

        argv[0] in ("plot", "show")
    """
    import getopt
    from pathtools import unpickle_path
    from pts.tools.tab2plot import colormap
    # from numpy import linspace #, empty, transpose
    # from numpy import array

    #
    # Only position arguments so far.  The first, argv[0], is the name
    # of the method, usually just "plot":
    #
    cmd = argv[0]

    # skip argv[1], it just tells that this precious function has been selected.
    opts, args = getopt.getopt(argv[2:], "", [])
    # print "opts=", opts
    # print "args=", args

    import matplotlib

    if cmd == "plot":
        # do not expect X11 to be available, use a different backend:
        matplotlib.use("Agg")

    from matplotlib import pyplot as plt

    def plot_energy(energies, color):
        # energy profile:
        plt.title("Energy profile", fontsize="large")
        plt.ylabel("Energy [eV]")
        plt.xlabel("Path point [arb. u.]")
        plt.plot(range(1, len(energies)+1), energies, "o--", color=color)
        plt.xlim((1, len(energies)))

    def plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, color):
        """
        Plot the energy profile indicating  the slope of the energy at
        the vertices.

        Tangents are usually normalized,  if at all, quite differently
        from the  convention used  here -- one  unit of  "path length"
        between  neyboring images.  To  avoid visual  mismatch between
        finite difference (E[i+1] - E[i]) / 1.0 and differential slope
        dE  /  ds  =  dot(g,  t)  at  the  nodes  we  invent  a  local
        re-normalization of the tangents.
        """
        # energy profile:
        from numpy import dot, linspace, sqrt, array, shape, empty
        from pts.func import CubicSpline

        plt.title("Energy profile", fontsize="large")
        plt.ylabel("Energy [eV]")
        plt.xlabel("Path point [arb. u.]")

        if abscissas == None:
            # this will hold distances vectors between path points:
            xdeltas =  empty(shape(geometries))
            xdeltas[0] = geometries[1] - geometries[0]
            xdeltas[-1] = geometries[-1] - geometries[-2]
            xdeltas[1:-1] = (geometries[2:] - geometries[:-2]) / 2.0

            # this is the measure  of the real separatioin between images,
            # each will correspond to one unit on the graph:
            scales = array([sqrt(dot(x, x)) for x in xdeltas])

            # re-normalize tangents:
            tangents = array([s * t / sqrt(dot(t, t)) for s, t in zip(scales, tangents)])
            abscissas = range(1, len(energies)+1)
        else:
            # If the distances in s are explicitely given, expect also the tangents to be
            # right
            tangents = array(tangents)
            abscissas = array(abscissas)

        # projection of the gradient on the new tangents, dE / ds:
        slopes = [dot(g, t) for g, t in zip(gradients, tangents)]

        # cubic spline
        spline = CubicSpline(abscissas, energies, slopes)

        # spline will be plotted with that many points:
        line = linspace(abscissas[0], abscissas[-1], 100)

        plt.plot( abscissas, energies, "o",
                 line, map(spline, line), "-",
                 color = color)
        plt.xlim((abscissas[0], abscissas[-1]))

    # number of curves on the same graph:
    N = len(args)

    #
    # This is the main loop over the input files:
    #
    for i, name in enumerate(args):
        geometries, energies, gradients, tangents, abscissas, symbols, trafo = unpickle_path(name) # v2

        # tuple is printed in one line:
        # print tuple(energies)

        # energy profile:
        if tangents is not None:
            plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, colormap(i, N))
        else:
            plot_energy(energies, colormap(i, N))

    if cmd == "show":
        # Display the plot, needs X11:
        plt.show()

    if cmd == "plot":
        # Save in vecor format, allows post-processing:
        plt.savefig("plot.svg")
Example #7
0
 def choose_color(j):
      return colormap(i * (num_opts - 1) + j, n)
Example #8
0
def visualize_path(filenames, data_ase, other_input, values, path_look, for_plot, hold, file_range = [0, sys.maxint]):
    """
    Does the  actual plotting of a  path function. If hold  = True the
    actual plot is not done.  This allows to use the function together
    with some other functions changing the plot.
    """
    from pts.tools.path2tab import carts_to_int
    from pts.tools.tab2plot import setup_plot, plot_data, prepare_plot, colormap
    from pts.ui.read_COS import read_geos_from_file
    from pts.tools.path2tab import extract_data
    import numpy as np
    from copy import copy
    from sys import stderr
    # Expand the output, we need it further.
    ase, format_ts = data_ase
    num, ts_estimates, refs = path_look
    reference, reference_data = refs
    withs, allval, special_vals, appender, special_opt =  values
    diff, symm, symshift =  special_opt
    num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot
    cell, tomove, howmove = appender

    # plot environment
    setup_plot(title = title, x_label = xlab, y_label = ylab, log = logscale)

    # extract which options to take
    optraw, num_opts, xnum_opts, optx = makeoption(num_i, diff, symm, symshift, withs)
    # num_opts_raw = copy(num_opts)
    opt = copy(optraw)

    if special_vals != []:
        for s_val in special_vals:
             # use the options for x and plot the data gotten from
             # the file directly
             opt = opt + " t %i" % (num_opts + 1)
             num_opts = num_opts + 1

    n = len(filenames) * (num_opts - 1)

    if not reference == []:
       for ref in reference:
           # Reference  point (geometry, energy)  to compare  the rest
           # data to it.  geometry is supposed to be in a ASE readable
           # format, energy in a separate file.
           atom_ref, y_ref = read_geos_from_file([ref], format=format_ts)

           # Reference  data  for  the  geometries.  The  Abscissa  is
           # supposed to be on 0.5
           reference_int_geos = np.array(carts_to_int(y_ref, [0.5], allval, cell, tomove, howmove, withs))
           reference_int_geos = reference_int_geos.T
           reference_int_geos = reference_int_geos.tolist()

           # optref = optraw
           num_opts_ref = num_opts
           if special_vals != []:
               # From  the  special  vals  only the  energies  can  be
               # displaced. Therefore special treatment is required.
               for s_val in special_vals:
                   if s_val.startswith("en") and not reference_data == None:
                       # optref = optraw + " t %i" % (num_opts_raw + 1)
                       reference_data = np.loadtxt(reference_data)
                       reference_int_geos.append([reference_data.tolist()])
                   else:
                       num_opts_ref = num_opts_ref - 1

           if num_opts_ref > 1:
               colors = [colormap(j, n) for j in range(0, num_opts)]
               prepare_plot( None, None, None, "_nolegend_", reference_int_geos, "Reference", opt, colors )


    # For each file prepare the plot
    for i, filename in enumerate(filenames):
        if i < file_range[0] or i > file_range[1]:
            continue

        # Extract  the  data  for  beads,  path  if  availabe  and  TS
        # estimates if requested (else None).
        beads, path, ts_ests_geos = extract_data(filename, data_ase, other_input, values, ts_estimates, num, i)

        if ts_ests_geos == []:
            print >> stderr, "WARNING: No transition state found for file", filename
            ts_ests_geos = None

        # The name belonging to filename.
        name_p = str(i + 1)
        if names_of_lines[i] != []:
             name_p = names_of_lines[i]

        # prepare plot from the tables containing the path and bead

        def choose_color(j):
             return colormap(i * (num_opts - 1) + j, n)

        # data only if there are enough for x AND y values
        colors = map(choose_color, range(0, num_opts))
        if num_opts > 1:
            if ase:
               prepare_plot( None, None, None, "_nolegend_", beads, name_p, opt, colors)
            else:
               prepare_plot( path, name_p, beads, "_nolegend_", ts_ests_geos, "_nolegend_", opt, colors)


    # now plot
    plot_data(hold = hold, xrange = xran, yrange = yran, savefile = outputfile )