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)
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)