예제 #1
0
def plot(args):
    import os, os.path
    import h5py
    from matplotlib import pyplot as plt
    import h5md._plot.label
    from numpy import *

    ax = plt.axes()
    label = None
    ax.axhline(y=1, color="black", lw=0.5)
    ax.set_color_cycle(args.colors)

    for (i, fn) in enumerate(args.input):
        try:
            f = h5py.File(fn, "r")
        except IOError:
            raise SystemExit("failed to open HDF5 file: %s" % fn)

        try:
            param = f["halmd" in f.keys() and "halmd" or "parameters"]  # backwards compatibility

            # determine file type, prefer precomputed static structure factor data
            if "structure" in f.keys() and "ssf" in f["structure"].keys():
                import filon
                import h5md._plot.ssf as ssf
                from scipy.constants import pi

                # load static structure factor from file
                H5 = f["structure/ssf/" + "/".join(args.flavour)]
                q = f["structure/ssf/wavenumber"].__array__()  # convert to NumPy array
                S_q, S_q_err = ssf.load_ssf(H5, args)

                # read some parameters
                dim = param["box"].attrs["dimension"]
                density = param["box"].attrs["density"]
                length = param["box"].attrs["length"]

                # compute pair distribution function
                xlim = args.xlim or (0, min(length) / 2)
                r = linspace(xlim[0], xlim[1], num=args.bins)
                if r[0] == 0:
                    r = r[1:]
                if dim == 3:
                    # convert 3-dim Fourier transform F[S_q - 1] / (2π)³ to 1-dim Fourier integral
                    pdf = filon.filon(q * (S_q - 1), q, r).imag / (2 * pi * pi * r)
                    pdf_err = filon.filon(q * S_q_err, q, r).imag / (2 * pi * pi * r)
                pdf = 1 + pdf / density  # add δ-contribution
                pdf_err = pdf_err / density

            elif "trajectory" in f.keys():
                # compute SSF from trajectory data
                H5 = f["trajectory/" + args.flavour[0]]
                r, pdf, pdf_err = pdf_from_trajectory(H5["position"], param, args)
            else:
                raise SystemExit("Input file provides neither data for the static structure factor nor a trajectory")

            # before closing the file, store attributes for later use
            attrs = h5md._plot.label.attributes(param)

        except IndexError:
            raise SystemExit("invalid phase space sample offset")
        except KeyError as what:
            raise SystemExit(str(what) + "\nmissing simulation data in file: %s" % fn)
        finally:
            f.close()

        if args.label:
            label = args.label[i % len(args.label)] % attrs

        elif args.legend or not args.small:
            basename = os.path.splitext(os.path.basename(fn))[0]
            label = r"%s" % basename.replace("_", r"\_")

        if args.title:
            title = args.title % attrs

        c = args.colors[i % len(args.colors)]
        ax.plot(r, pdf, "-", color=c, label=label)
        if "pdf_err" in locals():
            ax.errorbar(
                r, pdf, pdf_err, fmt="o", color=c, markerfacecolor=c, markeredgecolor=c, markersize=2, linewidth=0.5
            )
        else:
            ax.plot(r, pdf, "o", markerfacecolor=c, markeredgecolor=c, markersize=2)

        # write plot data to file
        if args.dump:
            f = open(args.dump, "a")
            print >> f, "# %s, sample %s" % (label.replace(r"\_", "_"), args.sample)
            if "pdf_err" in locals():
                print >> f, "# r   g(r)   g_err(r)"
                savetxt(f, array((r, pdf, pdf_err)).T)
            else:
                print >> f, "# r   g(r)"
                savetxt(f, array((r, pdf)).T)
            print >> f, "\n"
            f.close()

    # adjust axis ranges
    ax.axis("tight")
    if args.xlim:
        plt.setp(ax, xlim=args.xlim)
    if args.ylim:
        plt.setp(ax, ylim=args.ylim)
    else:
        plt.setp(ax, ylim=(0, plt.ylim()[1]))

    # optionally plot with logarithmic scale(s)
    if args.axes == "xlog":
        ax.set_xscale("log")
    if args.axes == "ylog":
        ax.set_yscale("log")
    if args.axes == "loglog":
        ax.set_xscale("log")
        ax.set_yscale("log")

    if args.legend or not args.small:
        l = ax.legend(loc=args.legend)
        l.legendPatch.set_alpha(0.7)

    plt.xlabel(args.xlabel or r"distance $r / \sigma$")
    plt.ylabel(args.ylabel or r"pair distribution function $g(r)$")

    if args.output is None:
        plt.show()
    else:
        plt.savefig(args.output, dpi=args.dpi)
예제 #2
0
def plot(args):
    import os, os.path
    import h5py
    from matplotlib import pyplot as plt
    import h5md._plot.label
    from numpy import *
    #from matplotlib import ticker
    # import ssf

    # import pycuda only if required
    if args.cuda:
        import pycuda.autoinit
        make_cuda_kernels()

    ax = plt.axes()
    label = None
    ax.axhline(y=1, color='black', lw=0.5)
    ax.set_color_cycle(args.colors)

    for (i, fn) in enumerate(args.input):
        try:
            f = h5py.File(fn, 'r')
        except IOError:
            raise SystemExit('failed to open HDF5 file: %s' % fn)

        try:
            try:
                param = f['halmd' in f.keys() and 'halmd' or 'parameters'] # backwards compatibility
            except KeyError:
                param = None

            # determine file type, prefer precomputed SSF data
            ssf_path = 'structure/' + '/'.join(args.flavour) + '/static_structure_factor'
            if ssf_path in f:
                # load SSF from file
                H5 = f[ssf_path]
                q = H5['wavenumber'].__array__() # store in memory by conversion to NumPy array
                S_q, S_q_err = load_ssf(H5, args)

            elif 'structure/ssf/' + '/'.join(args.flavour) in f: # backwards compatibility
                # load SSF from file
                H5 = f['structure/ssf/' + '/'.join(args.flavour)]
                q = f['structure/ssf/wavenumber'].__array__() # store in memory by conversion to NumPy array
                S_q, S_q_err = load_ssf(H5, args)

            elif 'trajectory' in f.keys() and param:
                # compute SSF from trajectory data
                H5 = f['trajectory/' + args.flavour[0]]
                q, S_q = ssf_from_trajectory(H5['position'], param, args)
            else:
                raise SystemExit('Input file provides neither SSF data nor a trajectory')

            # before closing the file, store attributes for later use
            if param:
                attrs = h5md._plot.label.attributes(param)
            else:
                attrs = {}

        except IndexError:
            raise SystemExit('invalid phase space sample offset')
        except KeyError as what:
            raise SystemExit(str(what) + '\nmissing simulation data in file: %s' % fn)
        finally:
            f.close()

        if args.label:
            label = args.label[i % len(args.label)] % attrs

        elif args.legend or not args.small:
            basename = os.path.splitext(os.path.basename(fn))[0]
            label = r'%s' % basename.replace('_', r'\_')

        if args.title:
            title = args.title % attrs

        c = args.colors[i % len(args.colors)]
        ax.plot(q, S_q, '-', color=c, label=label)
        if 'S_q_err' in locals():
            ax.errorbar(q, S_q, S_q_err, fmt='o', color=c, markerfacecolor=c, markeredgecolor=c, markersize=2, linewidth=.5)
        else:
            ax.plot(q, S_q, 'o', markerfacecolor=c, markeredgecolor=c, markersize=2)

        # optionally fit Ornstein-Zernike form
        if args.fit_ornstein_zernike:
            import scipy.odr as odr

            density = attrs['density']
            temperature = attrs['temperature']
            idx, = where(q <= args.fit_limit)
            kappa = mean(S_q[idx]) / density / temperature  # initial guess
            # result is a tuple (param, param_err, covariance_matrix)
            param, param_err = odr.odr(
                ornstein_zernike_log                    # fit model
              , (kappa, 1)                              # initial parameter values (kappa, xi)
              , S_q[idx], log(q[idx])                   # data (y, x)
              , extra_args=(density, temperature,), full_output=0
            )[:2]
            kappa, xi = abs(param)
            kappa_err, xi_err = param_err
            if args.verbose:
                print 'Density: {0:g}'.format(density)
                print 'Temperature: {0:g}'.format(temperature)
                print 'Compressibility: {0:g} ± {1:g}'.format(kappa, kappa_err)
                print 'Correlation length: {0:g} ± {1:g}'.format(xi, xi_err)

            if args.axes == 'loglog' or args.axes == 'xlog':
                xmin = args.xlim and args.xlim[0] or 0.01
                x = logspace(log10(xmin), log10(3 * args.fit_limit), num=20)
            else:
                x = linspace(0, 3 * args.fit_limit, num=20)
            y = ornstein_zernike((kappa, xi), x, density, temperature)
            ax.plot(x, y, ':', color=c, linewidth=.8)

        # write plot data to file
        if args.dump:
            f = open(args.dump, 'a')
            print >>f, '# %s, sample %s' % (label.replace(r'\_', '_'), args.sample)
            if 'S_q_err' in locals():
                print >>f, '# q   S_q   S_q_err'
                savetxt(f, array((q, S_q, S_q_err)).T)
            else:
                print >>f, '# q   S_q'
                savetxt(f, array((q, S_q)).T)
            print >>f, '\n'
            f.close()

    # optionally plot power laws
    if args.power_law:
        p = reshape(args.power_law, (-1, 4))
        for (pow_exp, pow_coeff, pow_xmin, pow_xmax) in p:
            px = logspace(log10(pow_xmin), log10(pow_xmax), num=100)
            py = pow_coeff * pow(px, pow_exp)
            ax.plot(px, py, 'k--')

    # adjust axis ranges
    ax.axis('tight')
    if args.xlim:
        plt.setp(ax, xlim=args.xlim)
    if args.ylim:
        plt.setp(ax, ylim=args.ylim)
    else:
        plt.setp(ax, ylim=(0, plt.ylim()[1]))

    # optionally plot with logarithmic scale(s)
    if args.axes == 'xlog':
        ax.set_xscale('log')
    if args.axes == 'ylog':
        ax.set_yscale('log')
    if args.axes == 'loglog':
        ax.set_xscale('log')
        ax.set_yscale('log')

    if args.legend or not args.small:
        l = ax.legend(loc=args.legend)
        l.legendPatch.set_alpha(0.7)

    plt.xlabel(args.xlabel or r'Wavenumber $q\sigma$')
    plt.ylabel(args.ylabel or r'Static structure factor $S(q)$')

    if args.output is None:
        plt.show()
    else:
        plt.savefig(args.output, dpi=args.dpi)