Example #1
0
def plot(args):
    from matplotlib import pyplot as plt

    # 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 = tables.openFile(fn, mode='r')
        except IOError:
            raise SystemExit('failed to open HDF5 file: %s' % fn)

        try:
            H5 = f.root
            param = H5.param

            # determine file type, prefer precomputed SSF data
            if 'structure' in H5._v_groups and 'ssf' in H5.structure._v_groups:
                # load SSF from file
                H5ssf = H5.structure.ssf._v_children[args.flavour or 'AA']
                q = H5.structure.ssf.wavenumber[0]
                S_q, S_q_err = load_ssf(H5ssf, args)

            elif 'trajectory' in H5._v_groups:
                # compute SSF from trajectory data
                if args.flavour:
                    H5trj = H5.trajectory._v_children[args.flavour]
                else:
                    H5trj = H5.trajectory

                q, S_q = ssf_from_trajectory(H5trj, param, args)
            else:
                raise SystemExit('Input file provides neither SSF data nor a trajectory')

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

        except IndexError:
            raise SystemExit('invalid phase space sample offset')
        except tables.exceptions.NoSuchNodeError 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:
            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':
                x = logspace(log10(args.xlim[0] or .01), 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'$\lvert\textbf{q}\rvert\sigma$')
    plt.ylabel(args.ylabel or r'$S(\lvert\textbf{q}\rvert)$')

    if args.output is None:
        plt.show()
    else:
        plt.savefig(args.output, dpi=args.dpi)
Example #2
0
def plot(args):
    from matplotlib import pyplot as plot

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

    for k, fn in enumerate(args.input):
        try:
            f = tables.openFile(fn, mode='r')
        except IOError:
            raise SystemExit('failed to open HDF5 file: %s' % fn)

        # HDF5 root group
        H5 = f.root
        # backwards compatibility
        compatibility = 'file_version' not in H5.param._v_attrs
        if compatibility:
            print 'compatibility mode'

        try:
            try:
                # particle positions of phase space sample
                # possibly read several samples
                trajectory = H5.trajectory
                if args.flavour:
                    trajectory = trajectory._v_children[args.flavour]
                if not compatibility:
                    position = H5.trajectory.position
                else:
                    position = H5.trajectory.r

                idx = [int(x) for x in args.sample.split(':')]
                if len(idx) == 1 :
                    samples = array([position[idx[0]]])
                elif len(idx) == 2:
                    samples = position[idx[0]:idx[1]]
            except IndexError:
                raise SystemExit('out-of-bounds phase space sample number')

            if not compatibility:
                # positional coordinates dimension
                dim = H5.param.box._v_attrs.dimension
                # particle density
                density = H5.param.box._v_attrs.density
                # periodic simulation box length
                box = H5.param.box._v_attrs.length
                # number of particles
                N = H5.param.box._v_attrs.particles
                if args.flavour:
                    N = N[ord(args.flavour[:1]) - ord('A')]
                else:
                    N = N[0]
            else:
                # positional coordinates dimension
                dim = H5.param.mdsim._v_attrs.dimension
                # particle density
                density = H5.param.mdsim._v_attrs.density
                # periodic simulation box length
                box = H5.param.mdsim._v_attrs.box_length
                box = zeros(dim) + box
                # number of particles
                N = H5.param.mdsim._v_attrs.particles
                if not isscalar(N):
                    N = N[ord(args.flavour[:1]) - ord('A')]

            cutoff = args.xlim or (0, box[args.axis])
            # minimum image distances
            x = samples[..., args.axis]
            x = x - floor(x / box[args.axis]) * box[args.axis]
            histo, bins = histogram(x.flatten(), bins=args.bins, range=cutoff, new=True)
            # normalisation with volume of slabs (=bins) and number of samples,
            # the result is a local number density
            histo = array(histo, dtype=float64) / (diff(bins) * prod(box) / box[args.axis]) / samples.shape[0]

            if args.label:
                label = args.label[k % len(args.label)] % mdplot.label.attributes(H5.param)
            elif args.legend or not args.small:
                basen = os.path.splitext(os.path.basename(fn))[0]
                label = basen.replace('_', r'\_')

        except tables.exceptions.NoSuchNodeError as what:
            raise SystemExit(str(what) + '\nmissing simulation data in file: %s' % fn)

        finally:
            f.close()

        ax.plot(bins[:-1], histo, marker='.', label=label)
        if args.dump:
            f = open(args.dump, 'a')
            print >>f, '# %s' % label.replace(r'\_', '_')
            savetxt(f, array((bins[:-1], histo)).T)
            print >>f, '\n'

    ax.axis('tight')
    if args.xlim:
        plot.setp(ax, xlim=args.xlim)
    if args.ylim:
        plot.setp(ax, ylim=args.ylim)
    else:
        plot.setp(ax, ylim=(0, 1.3 * max(histo)))

    plot.setp(ax, xlabel=args.xlabel or r'$x / \sigma$')
    plot.setp(ax, ylabel=args.ylabel or r'density profile $n(x)$')
    if args.legend or not args.small:
        l = ax.legend(loc=args.legend)
        l.legendPatch.set_alpha(0.7)

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