def sub_color_mag(ax, galaxies, clrs, markers): """ Generate a color-magnitude diagram using PRIMUS data and FRB galaxies Args: ax (matplotlib.Axis): galaxies (list): List of FRB.galaxies.frbgalaxy.FRBGalaxy objects clrs (list): List of matplotlib colors markers (list): List of matplotlib marker types Returns: """ # Load up primus_zcat = Table.read(os.path.join(primus_path, 'PRIMUS_2013_zcat_v1.fits.gz')) #primus_mass = Table.read(os.path.join(primus_path, 'PRIMUS_2014_mass_v1.fits')) gdz = (primus_zcat['Z'] > 0.2) & (primus_zcat['Z'] < 0.4) gd_mag = primus_zcat['SDSS_ABSMAG'][:,0] != 0. # PRIMUS # Photometry gd_color = gdz & gd_mag u_r = primus_zcat['SDSS_ABSMAG'][gd_color,0] - primus_zcat['SDSS_ABSMAG'][gd_color,2] rmag = primus_zcat['SDSS_ABSMAG'][gd_color,2] xbins = 100 ybins = 100 counts, xedges, yedges = np.histogram2d(rmag, u_r, bins=(xbins, ybins)) cm = plt.get_cmap('Greys') mplt = ax.pcolormesh(xedges, yedges, counts.transpose(), cmap=cm) ''' cb = plt.colorbar(mplt, fraction=0.030, pad=0.04) cb.set_label('PRIMUS survey') ''' for kk,galaxy in enumerate(galaxies): ax.errorbar([galaxy.derived['M_r']], [galaxy.derived['u-r']], xerr=[galaxy.derived['M_r_err']], yerr=[galaxy.derived['u-r_err']], color=clrs[kk], marker=markers[kk], markersize="5", capsize=3, label=galaxy.name) # Label plt.ylabel(r"$u-r \textbf{(Rest-frame)}$") plt.xlabel(r"$r \textbf{(Rest-frame)}$") ax.legend(loc='lower right') ax.set_ylim(0.0, 3.3) ax.set_xlim(-15.5, -23) utils.set_fontsize(ax,11.)
def fig_bias_stats(camera='z3', use_overscan_row=True): if use_overscan_row: root = '_' else: root = '_norow_' outfile = 'fig_bias_stats{}{}.png'.format(root, camera) # Load table base = 'bias_stats{}{}.fits'.format(root, camera) tblfile = os.path.join(dpath, 'Stats', base) stat_tbl = Table.read(tblfile) nexp = len(stat_tbl) plt.figure(figsize=(10, 6)) plt.clf() gs = gridspec.GridSpec(1, 2) clrs = ['k', 'b', 'r', 'g'] for ss, lbias in enumerate(['old', 'new']): ax = plt.subplot(gs[ss]) for tt, amp in enumerate(['A', 'B', 'C', 'D']): xval = np.arange(nexp) + 1 - 0.2 + tt * 0.1 yval = stat_tbl[lbias + amp + '_zero'].data sig = stat_tbl[lbias + amp + '_rms'].data lbl = amp ax.scatter(xval, yval, color=clrs[tt], marker='s', label=lbl) #ax.errorbar(xval, yval, sig, color=clrs[tt], fmt='s', label=lbl, capsize=10) ax.set_xlim(0, nexp + 1) ax.set_ylim(-0.2, 0.2) # Label ax.text(0.05, 0.90, lbias, transform=ax.transAxes, fontsize=23, ha='left', color='black') ffutils.set_fontsize(ax, 13.) legend = ax.legend(loc='upper right', scatterpoints=1, borderpad=0.2, fontsize=13) # Layout and save print('Writing {:s}'.format(outfile)) plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1) # plt.subplots_adjust(hspace=0) plt.savefig(os.path.join(dpath, 'Figures', outfile), dpi=500) # , bbox_inches='tight') plt.close()
def sub_bpt(ax_BPT, galaxies, clrs, markers, show_kewley=True, SDSS_clr='BuGn', show_legend=True, bptdat=None): """ Generate a BPT diagram To use this code, you must download the SDSS_BPT_stellar_mass.fits file from https://drive.google.com/open?id=1yHlfsvcRPXK73F6hboT1nM4bRF59ESab and put it in data/Public/SDSS Args: ax_BPT (matplotlib.Axis): galaxies (list): List of FRBGalaxy objects clrs (list): List of colors markers (list): List of markers show_kewley (bool, optional): Show the BPT lines? SDSS_clr (str, optional): Set the color map for SDSS show_legend (bool, optional): Show a legend bptdat (Table like): SDSS BPT data Returns: ax_BPT is modified in place """ # Read in data if bptdat is None: sdss_file = os.path.join(resource_filename('frb', 'data'), 'Public', 'SDSS', 'SDSS_BPT_stellar_mass.fits') if not os.path.isfile(sdss_file): print("See the method notes to download the SDSS data!") return hdulist = fits.open(sdss_file) bptdat = hdulist[1].data # Select only non zero entries and SNR over 5 lines = np.array(bptdat.names)[[("flux" in name) & ("err" not in name) for name in bptdat.names]] line_err = np.array( bptdat.names)[["flux_err" in name for name in bptdat.names]] select = {} for line, err in zip(lines, line_err): select[line] = bptdat[line] / bptdat[err] >= 5 # SDSS bpt1 = select['oiii_5007_flux'] & select['h_beta_flux'] & select[ 'nii_6584_flux'] & select['h_alpha_flux'] y = bptdat['oiii_5007_flux'][bpt1] / bptdat['h_beta_flux'][bpt1] x = bptdat['nii_6584_flux'][bpt1] / bptdat['h_alpha_flux'][bpt1] xbins = 100 ybins = 100 # Plot counts, xedges, yedges = np.histogram2d(np.log10(x), np.log10(y), bins=(xbins, ybins)) cm = plt.get_cmap(SDSS_clr) mplt = ax_BPT.pcolormesh(xedges, yedges, np.log10(counts.transpose()), cmap=cm) # Loop on the Galaxies for kk, galaxy in enumerate(galaxies): # Parse the emission lines NII, NII_err = galaxy.calc_nebular_lum('[NII] 6584') Ha, Ha_err = galaxy.calc_nebular_lum('Halpha') Hb, Hb_err = galaxy.calc_nebular_lum('Hbeta') try: OIII, OIII_err = galaxy.calc_nebular_lum('[OIII] 5007') except: import pdb pdb.set_trace() # x0 = (NII / Ha).decompose().value y0 = (OIII / Hb).decompose().value x0_err = x0 * np.sqrt((NII_err / NII).decompose().value**2 + (Ha_err / Ha).decompose().value**2) y0_err = y0 * np.sqrt((OIII_err / OIII).decompose().value**2 + (Hb_err / Hb).decompose().value**2) # Require at least 20% error x0_err = max(x0_err, 0.2 * x0) y0_err = max(y0_err, 0.2 * y0) logx, xerr = utils.log_me(x0, x0_err) logy, yerr = utils.log_me(y0, y0_err) # Upper limit on [NII]/Ha? if NII_err.value < 0.: xerr = None # Left arrow plt.arrow(logx, logy, -0.05, 0., fc=clrs[kk], ec=clrs[kk], head_width=0.02, head_length=0.05) # Plot ax_BPT.errorbar([logx], [logy], xerr=xerr, yerr=yerr, color=clrs[kk], marker=markers[kk], markersize="8", capsize=3, label=galaxy.name) # Standard curves demarc = lambda x: 0.61 / ( x - 0.05 ) + 1.3 # Kauffman et al 2003, MNRAS, 346, 4, pp. 1055-1077. Eq 1 demarc_kewley = lambda x: 0.61 / ( x - 0.47 ) + 1.19 # Kewley F., Dopita M., Sutherland R., Heisler C., Trevena J., 2001, ApJ, 556,121 demarc_liner = lambda x: 1.01 * x + 0.48 # Cid Fernandes et al 2010, MNRAS, 403,1036 Eq 10 ax_BPT.plot(np.linspace(-2, 0), demarc(np.linspace(-2, 0)), "k-", lw=2) #, label="Kauffman et al 2003") if show_kewley: ax_BPT.plot(np.linspace(-2, 0.25), demarc_kewley(np.linspace(-2, 0.25)), "k--", lw=2) #, label="Kewley et al 2001") ax_BPT.plot(np.linspace(-0.43, 0.5), demarc_liner(np.linspace(-0.43, 0.5)), "k--", lw=2) #, label="Cid Fernandes et al 2010") # Labels lsz = 13. ax_BPT.annotate(r"\textbf{Star-forming}", (-1.30, 0), fontsize=lsz) ax_BPT.annotate(r"\textbf{LINER}", (0.23, 0), fontsize=lsz) ax_BPT.annotate(r"\textbf{Seyfert}", (-0.5, 1), fontsize=lsz) # Legend if show_legend: ax_BPT.legend(loc="lower left") # Axes ax_BPT.set_xlabel(r"$\log \, ({\rm [N\textsc{ii}]/H\,\alpha)}$") ax_BPT.set_ylabel(r"$\log \, ({\rm [O\textsc{iii}]/H\,\beta)}$") ax_BPT.set_xlim(-1.5, 0.5) ax_BPT.set_ylim(-1, 1.2) utils.set_fontsize(ax_BPT, 13.)
def sub_image(fig, hdu, FRB, img_center=None, imsize=30*units.arcsec, vmnx = (None,None), xyaxis=(0.15, 0.15, 0.8, 0.8), fsz=15., tick_spacing=None, invert=False, cmap='Blues', frb_clr='red'): """ Args: fig: hdu: FRB: img_center: imsize: vmnx: xyaxis: fsz: tick_spacing: invert: cmap: cclr: Returns: """ if isinstance(hdu, fits.HDUList): hdu = hdu[0] header = hdu.header hst_uvis = hdu.data size = units.Quantity((imsize, imsize), units.arcsec) if img_center is None: img_center = FRB.coord cutout = Cutout2D(hst_uvis, img_center, size, wcs=WCS(header)) axIMG = fig.add_axes(xyaxis, projection=cutout.wcs) lon = axIMG.coords[0] lat = axIMG.coords[1] #lon.set_ticks(exclude_overlapping=True) lon.set_major_formatter('hh:mm:ss.s') if tick_spacing is not None: lon.set_ticks(spacing=tick_spacing) lat.set_ticks(spacing=tick_spacing) lon.display_minor_ticks(True) lat.display_minor_ticks(True) # blues = plt.get_cmap(cmap) d = axIMG.imshow(cutout.data, cmap=blues, vmin=vmnx[0], vmax=vmnx[1]) plt.grid(color='gray', ls='dashed') axIMG.set_xlabel(r'\textbf{Right Ascension (J2000)}', fontsize=fsz) axIMG.set_ylabel(r'\textbf{Declination (J2000)}', fontsize=fsz, labelpad=-1.) if invert: axIMG.invert_xaxis() #c = SphericalCircle((FRB.coord.ra, FRB.coord.dec), # FRB.eellipse['a']*units.arcsec, transform=axIMG.get_transform('icrs'), # edgecolor=cclr, facecolor='none') aper = SkyEllipticalAperture(positions=FRB.coord, a=FRB.sig_a * units.arcsecond, b=FRB.sig_b * units.arcsecond, theta=FRB.eellipse['theta'] * units.deg) apermap = aper.to_pixel(cutout.wcs) apermap.plot(color=frb_clr, lw=2, ls='dashed') ''' ylbl = 0.05 axHST.text(0.05, ylbl, r'\textbf{HST/UVIS}', transform=axIMG.transAxes, fontsize=isz, ha='left', color='black') ''' utils.set_fontsize(axIMG, 15.) return cutout, axIMG
def fig_cosmic(frbs, clrs=None, outfile=None, multi_model=False, no_curves=False, widen=False, show_nuisance=False, ax=None, show_sigmaDM=False, cl=(16,84), beta=3., gold_only=True, gold_frbs=None): """ Args: frbs (list): list of FRB objects clrs (list, optional): outfile (str, optional): multi_model (deprecated): no_curves (bool, optional): If True, just show the data widen (bool, optional): If True, make the plot wide show_nuisance (bool, optional): if True, add a label giving the Nuiscance value show_sigmaDM (bool, optional): If True, show a model estimate of the scatter in the DM relation cl (tuple, optional): Confidence limits for the scatter beta (float, optional): Parameter to the DM scatter estimation gold_only (bool, optional): If True, limit to the gold standard sample gold_frbs (list, optional): List of gold standard FRBs ax (matplotlib.Axis, optional): Use this axis instead of creating one Returns: """ # Init if gold_frbs is None: gold_frbs = cosmic.gold_frbs # Plotting ff_utils.set_mplrc() bias_clr = 'darkgray' # Start the plot if ax is None: if widen: fig = plt.figure(figsize=(12, 8)) else: fig = plt.figure(figsize=(8, 8)) plt.clf() ax = plt.gca() # DM_cosmic from cosmology zmax = 0.75 DM_cosmic, zeval = frb_igm.average_DM(zmax, cumul=True) DMc_spl = IUS(zeval, DM_cosmic) if not no_curves: #ax.plot(zeval, DM_cosmic, 'k-', label=r'DM$_{\rm cosmic} (z) \;\; [\rm Planck15]$') ax.plot(zeval, DM_cosmic, 'k-', label='Planck15') if multi_model: # Change Omega_b cosmo_highOb = FlatLambdaCDM(Ob0=Planck15.Ob0*1.2, Om0=Planck15.Om0, H0=Planck15.H0) DM_cosmic_high, zeval_high = frb_igm.average_DM(zmax, cumul=True, cosmo=cosmo_highOb) ax.plot(zeval_high, DM_cosmic_high, '--', color='gray', label=r'DM$_{\rm cosmic} (z) \;\; [1.2 \times \Omega_b]$') # Change H0 cosmo_lowH0 = FlatLambdaCDM(Ob0=Planck15.Ob0, Om0=Planck15.Om0, H0=Planck15.H0/1.2) DM_cosmic_lowH0, zeval_lowH0 = frb_igm.average_DM(zmax, cumul=True, cosmo=cosmo_lowH0) ax.plot(zeval_lowH0, DM_cosmic_lowH0, ':', color='gray', label=r'DM$_{\rm cosmic} (z) \;\; [H_0/1.2]$') if show_sigmaDM: #f_C0 = frb_cosmology.build_C0_spline() f_C0_3 = cosmic.grab_C0_spline(beta=3.) # Updated F = 0.2 nstep=50 sigma_DM = F * zeval**(-0.5) #* DM_cosmic.value sub_sigma_DM = sigma_DM[::nstep] sub_z = zeval[::nstep] sub_DM = DM_cosmic.value[::nstep] # Loop me sigmas, C0s, sigma_lo, sigma_hi = [], [], [], [] for kk, isigma in enumerate(sub_sigma_DM): #res = frb_cosmology.minimize_scalar(frb_cosmology.deviate2, args=(f_C0, isigma)) #sigmas.append(res.x) sigmas.append(isigma) C0s.append(float(f_C0_3(isigma))) # PDF PDF = cosmic.DMcosmic_PDF(cosmic.Delta_values, C0s[-1], sigma=sigmas[-1], beta=beta) cumsum = np.cumsum(PDF) / np.sum(PDF) #if sub_DM[kk] > 200.: # embed(header='131') # DO it DM = cosmic.Delta_values * sub_DM[kk] sigma_lo.append(DM[np.argmin(np.abs(cumsum-cl[0]/100))]) sigma_hi.append(DM[np.argmin(np.abs(cumsum-cl[1]/100))]) # Plot ax.fill_between(sub_z, sigma_lo, sigma_hi, # DM_cosmic.value-sigma_DM, DM_cosmic.value+sigma_DM, color='gray', alpha=0.3) # Do each FRB DM_subs = [] for ifrb in frbs: DM_sub = ifrb.DM - ifrb.DMISM DM_subs.append(DM_sub.value) DM_subs = np.array(DM_subs) # chi2 DMs_MW_host = np.linspace(30., 100., 100) zs = np.array([ifrb.z for ifrb in frbs]) DM_theory = DMc_spl(zs) chi2 = np.zeros_like(DMs_MW_host) for kk,DM_MW_host in enumerate(DMs_MW_host): chi2[kk] = np.sum(((DM_subs-DM_MW_host)-DM_theory)**2) imin = np.argmin(chi2) DM_MW_host_chisq = DMs_MW_host[imin] print("DM_nuisance = {}".format(DM_MW_host)) # MW + Host term def DM_MW_host(z, min_chisq=False): if min_chisq: return DM_MW_host_chisq else: return 50. + 50./(1+z) # Gold FRBs for kk,ifrb in enumerate(frbs): if ifrb.frb_name not in gold_frbs: continue if clrs is not None: clr = clrs[kk] else: clr = None ax.scatter([ifrb.z], [DM_subs[kk]-DM_MW_host(ifrb.z)], label=ifrb.frb_name, marker='s', s=90, color=clr) # ################################ # Other FRBs s_other = 90 if not gold_only: labeled = False for kk, ifrb in enumerate(frbs): if ifrb.frb_name in gold_frbs: continue if not labeled: lbl = "Others" labeled = True else: lbl = None ax.scatter([ifrb.z], [ifrb.DM.value - ifrb.DMISM.value - DM_MW_host(ifrb.z)], label=lbl, marker='o', s=s_other, color=bias_clr) legend = ax.legend(loc='upper left', scatterpoints=1, borderpad=0.2, handletextpad=0.3, fontsize=19) ax.set_xlim(0, 0.7) ax.set_ylim(0, 1000.) #ax.set_xlabel(r'$z_{\rm FRB}$', fontname='DejaVu Sans') ax.set_xlabel(r'$z_{\rm FRB}$', fontname='DejaVu Sans') ax.set_ylabel(r'$\rm DM_{cosmic} \; (pc \, cm^{-3})$', fontname='DejaVu Sans') # if show_nuisance: ax.text(0.05, 0.60, r'$\rm DM_{MW,halo} + DM_{host} = $'+' {:02d} pc '.format(int(DM_MW_host))+r'cm$^{-3}$', transform=ax.transAxes, fontsize=23, ha='left', color='black') ff_utils.set_fontsize(ax, 23.) # Layout and save if outfile is not None: plt.tight_layout(pad=0.2,h_pad=0.1,w_pad=0.1) plt.savefig(outfile, dpi=400) print('Wrote {:s}'.format(outfile)) plt.close() else: return ax