""" Code for plotting results of galario_gaussian.py or galario_binary.py Used in Ansdell et al. 2019 (Dipper Disc Inclinations, in prep) """ # ======================== Import Packages ================ from __future__ import (division, print_function, absolute_import, unicode_literals) import os, pdb, sys import numpy as np import argparse import matplotlib as mpl mpl.use('agg') import matplotlib.pyplot as plt import matplotlib.backends.backend_pdf from galario import arcsec, deg import galario.double as g_double from uvplot import UVTable import corner # ====================== Parse Arguments ================== ### example command-line input # python galario_plot.py 'EPIC_203824153' 'EPIC_203824153/uvtable_EPIC_203824153.txt' 'EPIC_203824153/chain_5000.npy' 1.3e-3 'EPIC_203824153' --uvbin 30e3 # python galario_plot.py 'EPIC_203770559' 'EPIC_203770559/uvtable_EPIC_203770559.txt' 'EPIC_203770559/chain_10000.npy' 1.3e-3 'EPIC_203770559' --binary True # python galario_plot.py 'EPIC_204630363' 'EPIC_204630363/uvtable_EPIC_204630363.txt' 'EPIC_204630363/chain_10000.npy' 1.3e-3 'EPIC_204630363' --cavity True parser = argparse.ArgumentParser() parser.add_argument("targname", help="name target") parser.add_argument("uvtable", help="name of UV table to fit") parser.add_argument("mcmcfile", help="name of mcmc results file") parser.add_argument("wavelength", help="wavelength of data [m]", type=float) parser.add_argument("outdir", help="name of directory to output things") parser.add_argument("--binary", help="set if binary system", type=bool, default=False) parser.add_argument("--cavity", help="set if binary system", type=bool, default=False) parser.add_argument("--uvbin", help="size of uvbin for plotting data + model", type=float) parser.add_argument("--chain_recall", help="number of steps backward to use for plotting", type=int) parser.add_argument("--incl", help="manually set inclination", type=float) parser.add_argument("--pa", help="manually set position angle", type=float) parser.add_argument("--dra", help="manually set ra offset", type=float) parser.add_argument("--ddec", help="manually set dec offset", type=float) parser.add_argument("--sigma", help="manually set FWHM", type=float) parser.add_argument("--f0", help="manually set flux normalization", type=float) parser.add_argument("--r_in", help="set if inner cavity", type=float) args = parser.parse_args() # ===================== Define Functions ================== def GaussianProfile(f0, sigma, rmin, dr, nr): """ Gaussian brightness profile. """ ### calculate radial grid r = np.linspace(rmin, rmin + dr * nr, nr, endpoint=False) ### calculate gaussian profile f = f0 * np.exp(-0.5 * (r / sigma)**2) ### return gaussian profile return f, r # ========================== Code ========================= ### READ UV TABLE AND GET VISIBILITIES print("\nReading in UV table: " + args.uvtable) u, v, re, im, w = np.loadtxt(args.uvtable, unpack=True) u, v = np.ascontiguousarray(u), np.ascontiguousarray(v) u /= args.wavelength v /= args.wavelength ### GET IMAGE SIZE print("\nImage size: ") nxy, dxy = g_double.get_image_size(u, v, verbose=True, f_max=2.1, f_min=2.0) rmin, dr, nr = 1e-4 * arcsec, 0.001 * arcsec, 20000 ### CHECK FOR EMCEE RESULTS FILE if os.path.isfile(args.mcmcfile) == False: print("File for plotting not found!") sys.exit() ### GET EMCEE RESULTS if args.chain_recall: chain_recall = args.chain_recall else: chain_recall = 500 samples_all = np.load(args.mcmcfile) nwalkers, nsteps, ndim = samples_all.shape samples = samples_all[:, -chain_recall:, :].reshape((-1, ndim)) ### SET LABELS FOR PLOTTING if args.cavity == True: labels = [r"$f_0$", r"$\sigma$", r"$r_{in}$", r"incl", r"PA", r"$\Delta$RA", r"$\Delta$Dec"] elif args.binary == True: labels = [r"$f_{0a}$", r"$\sigma_a$", r"incl$_a$", r"PA$_a$", r"$\Delta$RA$_a$", r"$\Delta$Dec$_a$", r"$f_{0b}$", r"$\sigma_b$", r"incl$_b$", r"PA$_b$", r"$\Delta$RA$_b$", r"$\Delta$Dec$_b$"] else: labels = [r"$f_0$", r"$\sigma$", r"incl", r"PA", r"$\Delta$RA", r"$\Delta$Dec"] ### PLOT CORNER PLOT print("\nPlotting corner plot...") fig = corner.corner(samples, labels=labels, show_titles=True, quantiles=[0.16, 0.50, 0.84], label_kwargs={'labelpad': 20, 'fontsize': 0}, fontsize=8) fig.savefig(os.path.join(args.outdir, args.targname + '_corner.png'), rastersize=True, dpi=100) ### PLOT CHAINS print("\nPlotting chains plot...") fig, axes = plt.subplots(len(labels), 1, figsize=(9, len(labels) * 2 + 1)) for walker in samples_all: for i, (ax, lab) in enumerate(zip(axes, labels)): ax.plot(walker[:, i]) ax.set_xlabel('step number', fontsize=14) ax.set_ylabel(lab, fontsize=14) fig.savefig(os.path.join(args.outdir, args.targname + '_chains.png'), bbox='tight', rastersize=True, dpi=100) plt.close('all') ### GET BEST FIT RESULTS bestfit = [np.percentile(samples[:, i], 50) for i in range(ndim)] if args.cavity == True: f0, sigma, r_in, inc, pa, dra, ddec = bestfit r_in *= arcsec elif args.binary == True: f0_a, sigma_a, inc_a, pa_a, dra_a, ddec_a, f0_b, sigma_b, inc_b, pa_b, dra_b, ddec_b = bestfit else: f0, sigma, inc, pa, dra, ddec = bestfit # f0, sigma, inc, pa, dra, ddec, f0_b, sigma_b, inc_b, pa_b, dra_b, ddec_b = bestfit print("\nBESTFIT", bestfit) ### REAPLCE WITH MANUAL VALUES? if args.incl: inc = args.incl print("\n using manual inclination") if args.pa: pa = args.pa print("\n using manual position angle") if args.dra: dra = args.dra print("\n using manual ra offset") if args.ddec: ddec = args.ddec print("\n using manual dec offset") if args.sigma: sigma = args.sigma print("\n using manual sigma") if args.f0: f0 = args.f0 print("\n using manual f0") if args.r_in: r_in = args.r_in r_in *= arcsec print("\n using manual r_in") ### CREATE BEST-FIT MODEL print("\nSaving best-fit model as uvtable_mod.txt") if args.binary == False: f0 = 10.**f0 sigma *= arcsec inc *= deg pa *= deg dra *= arcsec ddec *= arcsec f, r = GaussianProfile(f0, sigma, rmin, dr, nr) if args.cavity == True: f[r < r_in] *= 0 vis_mod = g_double.sampleProfile(f, rmin, dr, nxy, dxy, np.ascontiguousarray(u), np.ascontiguousarray(v), inc=inc, PA=pa, dRA=dra, dDec=ddec) else: f0_a = 10.**f0_a f0_b = 10.**f0_b sigma_a *= arcsec sigma_b *= arcsec inc_a *= deg inc_b *= deg pa_a *= deg pa_b *= deg dra_a *= arcsec dra_b *= arcsec ddec_a *= arcsec ddec_b *= arcsec f_a = GaussianProfile(f0_a, sigma_a, rmin, dr, nr) f_b = GaussianProfile(f0_b, sigma_b, rmin, dr, nr) vis_mod_a = g_double.sampleProfile(f_a[0], rmin, dr, nxy, dxy, np.ascontiguousarray(u), np.ascontiguousarray(v), inc=inc_a, PA=pa_a, dRA=dra_a, dDec=ddec_a) vis_mod_b = g_double.sampleProfile(f_b[0], rmin, dr, nxy, dxy, np.ascontiguousarray(u), np.ascontiguousarray(v), inc=inc_b, PA=pa_b, dRA=dra_b, dDec=ddec_b) vis_mod = vis_mod_a + vis_mod_b np.savetxt(os.path.join(args.outdir, args.targname + '_uvtable_mod.txt'), np.stack([u * args.wavelength, v * args.wavelength, vis_mod.real, vis_mod.imag, w], axis=-1)) ### GET VISIBILITIES OF DATA OF DATA print("\nCreating UV plot of best-fit model...") uv = UVTable(filename=args.uvtable, wle=args.wavelength) if args.binary == False: uv.apply_phase(-dra, -ddec) uv.deproject(inc, pa) else: uv.apply_phase(-dra_a, -ddec_a,) uv.deproject(inc_a, pa_a,) ### GET VISIBILITIES OF BEST-FIT MODEL uv_mod = UVTable(filename=os.path.join(args.outdir, args.targname + '_uvtable_mod.txt'), wle=args.wavelength) if args.binary == False: uv_mod.apply_phase(-dra, -ddec) uv_mod.deproject(inc, pa) else: uv_mod.apply_phase(-dra_a, -ddec_a) uv_mod.deproject(inc_a, pa_a) ### PLOT DATA + MODEL if args.uvbin: uvbin_size = args.uvbin else: uvbin_size = 30.e3 axes = uv.plot(linestyle='.', color='k', label='Data', uvbin_size=uvbin_size) uv_mod.plot(axes=axes, linestyle='-', color='r', label='Model', yerr=False, uvbin_size=uvbin_size) axes[0].figure.savefig(os.path.join(args.outdir, args.targname + '_uvplot.png'), rasterisized=True, dpi=400) ### SAVE DATA + MODEL np.savetxt(os.path.join(args.outdir, args.targname + '_visfit.txt'), np.stack([uv.bin_re, uv.bin_re_err, uv.bin_uvdist, uv_mod.bin_re, uv_mod.bin_re_err, uv_mod.bin_uvdist], axis=-1))