def test_igmDM(): DM = igm.average_DM(1.) # Value and unit assert DM.unit == u.pc/u.cm**3 assert np.isclose(DM.value, 966.62888, rtol=0.001) # Cumulative DM_cum, zeval = igm.average_DM(1., cumul=True) assert DM == DM_cum[-1] # Cross through HeII reionization DM4 = igm.average_DM(4.) assert np.isclose(DM4.value, 3650.434194, rtol=0.001)
def test_igmDM(): DM = igm.average_DM(1.) # Value and unit assert DM.unit == u.pc / u.cm**3 assert np.isclose(DM.value, 941.13451342, rtol=0.001) # Cumulative DM_cum, _ = igm.average_DM(1., cumul=True) assert DM == DM_cum[-1] # Cross through HeII reionization DM4 = igm.average_DM(4.) assert np.isclose(DM4.value, 3551.37492765, rtol=0.001)
def best_dm_from_z(frbc, DM_host=50., DM_MW=80.): """ Calculate an estimated DM_FRB provided the candidate info Calls ne2001 for Galactic ISM estimate in the given direction Args: frbc: FRBCandidate object Must include coord and z DM_host: float, optional WAG for the host DM in pc/cm^3 DM_MW: WAG for the MW halo DM in pc/cm^3 Returns: DM_FRB: float Estimated DM in pc/cm^3 """ # NE2001 ne = density.ElectronDensity() DM_ISM = ne.DM(frbc['coord'].galactic.l, frbc['coord'].galactic.b, 100.) # Cosmic DM_cosmic = average_DM(frbc['z']).value # Add em up DM_FRB = DM_ISM.value + DM_MW + DM_cosmic + DM_host # Return return DM_FRB
def sub_cartoon(ax1, ax2, coord, zFRB, halos=False, host_DM=50., ymax=None, IGM_only=True, smin=0.1, show_M31=None, fg_halos=None, dsmx=0.05, FRB_DM=None, yscl=0.97): """ Cartoon of DM cumulative Plot of increasing DM from Earth to the FRB Args: ax1 (matplotlib.Axis): First axis. Used for Milky Way and local group ax2 (matplotlib.Axis): Second axis. Used for Cosmic and Host coord (astropy.coord.SkyCoord): Coordinate of the FRB used with ne2001 zFRB (float): Redshift of the FRB halos (?, optional): Not implemented! host_DM (float): DM to use for the Host ymax (tuple or list): ymin, ymax values for the y-axis IGM_only (bool, optional): Use only the IGM for DM_Cosmic, i.e. ignore the presumed average halo contribution show_M31 (bool, optional): Include M31 in the calculation? NOT IMPLEMENTED RIGHT NOW fg_halos (dict or Table): Used to add to DM_IGM Keys must include 'z' 'DM' 'lbl' smin (float, optional): Minimum value in axis2 (Gpc) dsmx (float, optional): Padding on the x-axis; Gpc Allows for host. Set to 0 to ignore host FRB_DM (float): Observed value; sets ymax = FRB_DM+50 yscl (float, optional): Controls placement of labels """ if halos: embed() gcoord = coord.transform_to('galactic') l, b = gcoord.l.value, gcoord.b.value ds = [] # kpc DM_cumul = [] # ISM ne = density.ElectronDensity() # **PARAMS) for ss in np.linspace(2., 4, 5): # log pc idd = 10.**ss / 1e3 # kpc iDM = ne.DM(l, b, idd) # Append ds.append(idd) # kpc DM_cumul.append(iDM.value) # print(idd, iDM) max_ISM = DM_cumul[-1] # MW Mhalo = np.log10(1.5e12) # Boylan-Kolchin et al. 2013 f_hot = 0.75 # Allows for disk + ISM c = 7.7 mnfw_2 = ModifiedNFW(log_Mhalo=Mhalo, f_hot=f_hot, y0=2, alpha=2, c=c) # Zero out inner 10kpc mnfw_2.zero_inner_ne = 10. # kpc params = dict(F=1., e_density=1.) model_ne = density.NEobject(mnfw_2.ne, **params) for ss in np.linspace(1., np.log10(mnfw_2.r200.value), 5): # log kpc idd = 10.**ss # kpc iDM = model_ne.DM(l, b, idd).value # Add it in if idd == ds[-1]: DM_cumul[-1] = DM_cumul[-1] + iDM else: ds.append(idd) DM_cumul.append(max_ISM + iDM) DM_ISM_Halo = DM_cumul[-1] if show_M31: raise NotImplemented # M31 m31 = M31() a, c = 1, 0 x0, y0 = m31.distance.to( 'kpc' ).value, 0. # kpc (Riess, A.G., Fliri, J., & Valls - Gabaud, D. 2012, ApJ, 745, 156) sep = m31.coord.separation(coord) atan = np.arctan(sep.radian) b = -1 * a / atan M31_Rperp = np.abs(a * x0 + b * y0 + c) / np.sqrt(a**2 + b**2) # kpc zval, M31_DM_cumul = m31.Ne_Rperp(M31_Rperp * u.kpc, rmax=1., cumul=True) # Add em in ds += (zval + x0).tolist() DM_cumul += (M31_DM_cumul + DM_ISM_Halo).tolist() #DM_LG = 0. DM_LG = DM_cumul[-1] # IGM z0 = z_at_value(cosmo.comoving_distance, 1 * units.Mpc) zvals = np.linspace(z0, 0.5, 50) dz_vals = zvals[1] - zvals[0] # DM_cosmic_cumul, zeval = frb_igm.average_DM(zvals[-1], cumul=True) dzeval = zeval[1] - zeval[0] dDM_cosmic = DM_cosmic_cumul - np.roll(DM_cosmic_cumul, 1) dDM_cosmic[0] = dDM_cosmic[1] # DM_interp = IUS(zeval, dDM_cosmic) dDM_cosm = DM_interp(zvals) * dz_vals / dzeval sub_DM_cosm = np.cumsum(dDM_cosm) f_cosm = IUS(zvals, sub_DM_cosm) zvals2 = np.linspace(z0, zFRB, 1000) DM_cosmic = f_cosm(zvals2) # Ignore halos? if IGM_only: # fhalos = frb_halos.frac_in_halos(zvals, 3e10, 1e16, rmax=1.) fIGM = 1. - fhalos # dDM_IGM = DM_interp(zvals) * fIGM * dz_vals / dzeval sub_DM_IGM = np.cumsum(dDM_IGM) f_IGM = IUS(zvals, sub_DM_IGM) DM_IGM = f_IGM(zvals2) # DM_cosmic = DM_IGM.copy() # Halos at last if fg_halos is not None: for z, halo_DM, lbl in zip(fg_halos['z'], fg_halos['DM'], fg_halos['lbl']): iz = np.argmin(np.abs(zvals2 - z)) DM_cosmic[iz:] += halo_DM # Label d = cosmo.comoving_distance(z) ax1.text(d.to('Gpc').value, DM_cosmic[iz], lbl, color='black', fontsize=13, ha='left', va='top') Dc = cosmo.comoving_distance(zvals2).to('kpc') ds += Dc.value.tolist() DM_cumul += (DM_cosmic + DM_LG).tolist() # Host if host_DM > 0.: ds.append(ds[-1]) DM_cumul.append(DM_cumul[-1] + host_DM) # Plot the DM curve ax1.plot(ds, DM_cumul, 'k') # max_y = np.max(DM_cumul) if FRB_DM is not None: ymax = FRB_DM + 50. if ymax is not None: max_y = ymax # Shade me lsz = 14. ax1.fill_between((0.1, 10.), 0, max_y, color='green', alpha=0.4) # ISM ax1.text(0.15, max_y * yscl, r'\textbf{Galactic}' + '\n' + r'\textbf{ISM}', color='black', fontsize=lsz, ha='left', va='top') ax1.fill_between((10., mnfw_2.r200.value), 0, max_y, color='blue', alpha=0.4) # Galactic Halo ax1.text(12., max_y * yscl, r'\textbf{Galactic}' + '\n' + r'\textbf{Halo}', color='black', fontsize=lsz, ha='left', va='top') if show_M31: ax1.fill_between((mnfw_2.r200.value, 2e3), 0, max_y, color='red', alpha=0.4) # Galactic Halo ax1.text(300., max_y * yscl, r'\texgbf{M31}', color='black', fontsize=lsz, ha='left', va='top') ax1.set_xscale("log", nonposx='clip') # ax.set_yscale("log", nonposy='clip') if show_M31: ax1.set_xlim(0.1, 2e3) # kpc else: ax1.set_xlim(0.1, mnfw_2.r200.value) # kpc ax1.set_ylim(0., max_y) ax1.spines['right'].set_visible(False) ax1.set_xlabel(r'\textbf{Distance (kpc)}') ax1.set_ylabel(r'\textbf{Cumulative DM (pc cm$^{-3}$)}') # IGM Gds = np.array(ds) / 1e6 ax2.plot(Gds, DM_cumul, 'k') ax2.spines['left'].set_visible(False) ax2.yaxis.tick_right() ax2.tick_params(labelright='off') ax2.minorticks_on() ax2.set_xlabel(r'\textbf{Distance (Gpc)}') smax = cosmo.comoving_distance(zFRB).to('Gpc').value #ax2.fill_between((0.1, smax-dsmx), 0, max_y, color='gray', alpha=0.4) # Galactic Halo ax2.fill_between((smin, smax - dsmx), 0, max_y, color='gray', alpha=0.4) # Cosmic ilbl = r'\textbf{Cosmic}' ax2.text(0.2, max_y * yscl, ilbl, color='black', fontsize=lsz, ha='left', va='top') # Host if host_DM > 0.: ax2.fill_between((smax - dsmx, smax + dsmx), 0, max_y, color='red', alpha=0.4) # Host ax2.set_xlim(smin, smax + dsmx) # Gpc else: ax2.set_xlim(smin, smax) # Gpc if FRB_DM is not None: ax1.axhline(y=FRB_DM, ls='--', color='black', lw=3) ax2.axhline(y=FRB_DM, ls='--', color='black', lw=3)