示例#1
0
def test_igmDM():
    DM = igm.average_DM(1.)
    # Value and unit
    assert DM.unit == u.pc / u.cm**3
    assert np.isclose(DM.value, 917.6353186402, 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, 3527.87768558123, rtol=0.001)
示例#2
0
def test_igmDM():
    DM = igm.average_DM(1.)
    # Value and unit
    assert DM.unit == u.pc / u.cm**3
    assert np.isclose(DM.value, 923.074, 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, 3542.598, rtol=0.001)
示例#3
0
def test_igmDM_varyH0():
    DM = igm.average_DM(1., cosmo=Planck15)

    # New cosmology
    cosmo2 = FlatLambdaCDM(H0=Planck15.H0.value * 2,
                           Ob0=Planck15.Ob0,
                           Om0=Planck15.Om0,
                           Neff=Planck15.Neff,
                           Tcmb0=2.725)
    DM2 = igm.average_DM(1., cosmo=cosmo2)

    # Test
    assert DM2 > DM * 2  # Not sure why it is so much higher
示例#4
0
文件: prob_dmz.py 项目: FRBs/FRB
def grid_P_DMcosmic_z(beta=3.,
                      F=0.31,
                      zvals=None,
                      DM_cosmics=None,
                      cosmo=defs.frb_cosmo):
    """
    Generate a grid of P(DM_cosmic|z)

    Args:
        beta (float, optional):
            sigma_DM_cosmic parameter
        F (float, optional):
            Feedback parameter (higher F means weaker feedback)
        zvals (np.ndarray, optional):
            Redshifts for the grid
        DMcosmic (np.ndarray, optional):
            DMs for the grid
        cosmo (optional):
            Cosmology

    Returns:
        tuple: z, DM_cosmic, P(DM_cosmic|z)
    """
    # Check
    if not np.isclose(beta, 3.):
        raise IOError("Not prepared for this beta value (yet)")
    # Load
    # sigma_DM
    f_C0_3 = cosmic.grab_C0_spline()

    # Grid
    if zvals is None:
        zvals = np.linspace(0., 2., 200)
    if DM_cosmics is None:
        DM_cosmics = np.linspace(1., 5000., 1000)

    PDF_grid = np.zeros((DM_cosmics.size, zvals.size))

    # Loop
    for kk, zval in enumerate(zvals):
        # z=0
        if zval == 0:
            PDF_grid[0, 0] = 1.
            continue
        avgDM = igm.average_DM(zval, cosmo=cosmo).value
        # Params
        sigma = F / np.sqrt(zval)
        C0 = f_C0_3(sigma)
        #  Delta
        Delta = DM_cosmics / avgDM
        # PDF time
        PDF = cosmic.DMcosmic_PDF(Delta, C0, sigma)
        # Normalize
        PDF_grid[:, kk] = PDF / np.sum(PDF)

    # Return
    return zvals, DM_cosmics, PDF_grid
示例#5
0
文件: mcmc.py 项目: FRBs/FRB
Delta_values = np.linspace(1./400., 20., 20000)# / 400.  # Fiducial
DM_MWhalo = 50.  # Fixed value for Macquart+20

# Init as blank
frbs = []
frb_DMs = None #np.array([frb.DM.value-frb.DMISM.value for frb in frbs])
frb_zs = None #np.array([frb.z for frb in frbs])
DM_FRBp_grid = None
DMhost_grid = None #np.outer(DM_values, (1+z_FRB))  # Host rest-frame DMs
DMvalues_grid = None # np.outer(DM_values, np.ones(DM_FRBp.size))
Deltavalues_grid = None  #np.outer(Delta_values, np.ones_like(C0)), 

#

# DM Cosmic
DM_cosmic, zeval = igm.average_DM(1., cosmo=defs.frb_cosmo, cumul=True)
spl_DMc = IUS(zeval, DM_cosmic.value)
cosmo_ObH0 = defs.frb_cosmo.Ob0 * defs.frb_cosmo.H0.value
cosmo_Obh70 = defs.frb_cosmo.Ob0 * (defs.frb_cosmo.H0.value/70.)

# Load splines
spl_sigma = cosmic.grab_sigma_spline()
f_C0_3 = cosmic.grab_C0_spline()


# Parameters
def grab_parmdict(tight_ObH=False):
    """ Generate the parameter dict for the MCMC run

    Args:
        tight_ObH (bool, optional): [description]. Defaults to False.
示例#6
0
 def estimate_dm_cosmic(self):
     if not frb_installed:
         raise ImportError("FRB is not installed.")
     return igm.average_DM(self.host_galaxy.z, cosmo=cosmo.Planck18)
示例#7
0
def fig_mag_vs_DM(outfile='fig_mag_vs_DM.png'):
    """
    mini Maquart relation

    Args:
        outfile:

    Returns:

    """
    set_mplrc()

    # Load f_mL
    f_mL = analysis.load_f_mL()

    # Init prior
    prior = associate_defs.adopted.copy()

    # Plot
    plt.figure(figsize=(8, 5))
    gs = gridspec.GridSpec(1, 1)

    cm = plt.get_cmap('jet')

    # Bayesian + parse
    frbA_tbl, model_mags, model_theta, max_PMix = analysis.run(prior)

    # Colors
    N = len(frbA_tbl) + 1
    plt.rcParams["axes.prop_cycle"] = plt.cycler("color",
                                                 cm(np.linspace(0, 1, N)))

    # Plot -- must come after colors
    ax = plt.subplot(gs[0])

    # Plot em
    Pmin = 0.01
    unit_size = 150.
    order = [0, 1, 6, 3, 2, 4, 5, 7, 8, 9, 10, 11, 12]
    DMcosmic = [
        frb_row.frbA.frb.DM.value - frb_row.frbA.frb.DMISM.value - 100
        for _, frb_row in frbA_tbl.iterrows()
    ]
    order = np.argsort(DMcosmic)
    #for _, frb_row in frbA_tbl.iterrows():
    for ss in order:
        # Restrict to candiates with min
        frb_row = frbA_tbl.iloc[ss]
        ok_c = frb_row.frbA.candidates.P_Ox > Pmin
        N_c = np.sum(ok_c)
        # Scatter plot em
        ax.scatter(
            [frb_row.frbA.frb.DM.value - frb_row.frbA.frb.DMISM.value - 100] *
            N_c,
            frb_row.frbA.candidates[ok_c][frb_row.frbA.filter],
            label=frb_row.frb,
            edgecolor='darkslategrey',
            marker='o',
            s=unit_size * frb_row.frbA.candidates[ok_c].P_Ox,
        )

    # Fiducial relation
    L_Lstar = 0.270  # Grabbed from PL
    numL = int(np.round(1. / L_Lstar))
    log10_L_Lstar = np.log10(L_Lstar)
    std_log10_L_Lstar = 0.47  # Grabbed from fig_PL

    # Load up DM_cosmic
    dm_cosmic, z = igm.average_DM(1., cumul=True)
    f_DMz = interp1d(z, dm_cosmic.value)

    zval = np.linspace(0.02, 1., 100)
    DMs = f_DMz(zval)

    mLstar = f_mL(zval)
    m_FRB = mLstar - 2.5 * log10_L_Lstar

    ax.plot(DMs, m_FRB, 'k-', label=r'$L=L*/${}'.format(numL))

    # Label me
    ax.set_xlabel(
        r'DM$_{\rm cosmic} \equiv$ DM$_{\rm FRB}$ - DM$_{\rm ISM}$ - 100')
    ax.set_ylabel(r'$m_r$')
    #ax.xaxis.set_major_locator(plt.MultipleLocator(1.))
    #ax.xaxis.set_major_formatter(FormatStrFormatter(r'$%.3f$'))
    ax.set_xlim(0., 800.)

    # Legend
    legend = ax.legend(loc='lower right',
                       scatterpoints=1,
                       borderpad=0.0,
                       handletextpad=handletextpad,
                       fontsize=10.)

    # Font size
    set_fontsize(ax, 15.)

    # End
    plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1)
    print('Writing {:s}'.format(outfile))
    kwargs = {}
    if 'png' in outfile:
        kwargs['dpi'] = 700
    plt.savefig(outfile, **kwargs)
    plt.close()
示例#8
0
def sub_cartoon(ax1, ax2, coord, zFRB, halos=False, host_DM=50., ymax=None,
                IGM_only=True, smin=0.1, cosmo=None,
                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
        cosmo (astropy.cosmology, optional):
            Defaults to Planck15

    """
    if cosmo is None:
        cosmo = Planck15

    if halos:
        # NOT READY FOR THIS
        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)
示例#9
0
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
示例#10
0
def simulate_frb_dm(frb_data, z_stepsize=10**-4, z_max=3, dm_min=0, dm_max=3000, dm_stepsize=10**-2, save_to_path=None):
    """
    Simulate DM_FRB by constructing PDFs for DM_cosmic, DM_host and DM_halo.
    Please check your frbcat_df matches the template used here.
    Change the halo and host distributions as you feel appropriate.

    Arguments:
        transient_data (str):
            Path to data (in .csv format).
        z_stepsize (float, optional):
            Redshift stepsize. Default=10**-4.
        z_max (int, optimal):
            Maximum redshift value. Default=3.
        dm_min (int, optional):
            Minimum value of DM grid. Default=-10.
        dm_max (int, optional):
            Minimum value of DM grid. Default=5000.
        dm_stepsize (float, optional):
            DM_grid stepsize. Default=10**-2.
        save_to_path (str, optional):
            To save data outputs (as .npy), specify path. Default=None.

    Outputs:
        dm_grid (array):
            DM grid
        dm_frb_sim (array):
            PDF of DM_FRB

    """
    # Estimate redshift distribution from observed FRB DMs (corrected for ISM)
    logging.info('Estimating redshift distribution...')
    frbcat_df = pd.read_csv(frb_data)
    dm_frb = np.array(frbcat_df['deltaDM'])*units.pc/units.cm**3
    z_grid = np.arange(0,z_max,z_stepsize)
    z = []
    for i in range(len(dm_frb)):
        z_ = igm.z_from_DM(dm_frb[i], corr_nuisance=False)
        z = np.append(z,z_)

    # Kernel density estimation
    z_func_ = make_kde_funtion(grid=z_grid, draws=z, min_bandwidth=0.01, max_bandwidth=0.5, bandwidth_stepsize=0.01, cv=5, kernel='gaussian')
    z_func = z_func_/np.sum(z_func_)
    z = make_pdf(distribution=z_func,num_of_draws=rv_amount,grid=z_grid,stepsize=z_stepsize)
    z_draws = z[0]

    # Calculate average cosmic DM
    logging.info('Estimating cosmic DM...')
    dm_ave_fn = igm.average_DM(z_max, cumul=True, neval=rv_amount+1, mu=1.3)
    dm_ave_ = dm_ave_fn[0].value
    z_ave = dm_ave_fn[1]
    dm_int_ave = sp.interpolate.CubicSpline(z_ave,dm_ave_)
    dm_ave = np.sort(dm_int_ave(z_draws))
    
    # Find cosmic DM
    F = 0.2
    sigma_dm = np.minimum(F*z_draws**(-0.5),0.5)
    sigma_dm = [i for i in sigma_dm if i<0.5]
    sigma_gauss = 1
    rand_draws_gauss = np.random.normal(loc=0, scale=sigma_gauss, size=rv_amount)
    rand_draws_gauss = [i for i in rand_draws_gauss if i>-sigma_gauss and i<sigma_gauss]
    sigma_dm = random.sample(sigma_dm,len(rand_draws_gauss))
    dm_ave = np.array(random.sample(list(dm_ave),len(rand_draws_gauss)))
    dm_cos = dm_ave + rand_draws_gauss*dm_ave*sigma_dm
    dm_cos = [i for i in dm_cos if i > 0]

    # Estimate halo
    logging.info('Adding MW halo and host...')
    dm_halo  = 30. #some assigned MW halo DM 

    # Host DM - adjust this to your prefered (estimated) host DM
    mu_host = 40.
    sigma_host = 0.5
    dm_host = lognorm(s=sigma_host, loc=-4, scale=mu_host).rvs(size=len(dm_cos))
    dm_host = np.random.normal(mu_host, sigma_host, len(dm_cos))
    dm_host = [i for i in dm_host if i > 0]
    dm_cos = np.array(random.sample(list(dm_cos),len(dm_host))) 

    dm_frb_sim = np.sort(dm_cos)+dm_halo+np.sort(dm_host)
    dm_grid = np.arange(dm_min,dm_max,dm_stepsize)

    if save_to_path==None:
        pass
    else:
        np.save(save_to_path+'/dm_frb_sim_gauss.npy', dm_frb_sim)
        np.save(save_to_path+'/dm_grid.npy', dm_grid)
        logging.info('Data saved to '+save_to_path)

    return dm_grid, dm_frb_sim