Exemplo n.º 1
0
def test_electron_density_trapz():
    tol = 1e-3
    ne = density.ElectronDensity()
    l, b, d = -2, 12, 1
    DM = 23.98557
    assert abs(ne.DM(l, b, d, integrator=integrate.trapz).value -
               DM) / DM < tol
Exemplo n.º 2
0
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
Exemplo n.º 3
0
def ismDM(coord):
    gcoord = coord.transform_to('galactic')
    l, b = gcoord.l.value, gcoord.b.value
    
    ne = density.ElectronDensity()#**PARAMS)
    ismDM = ne.DM(l, b, 100.)
    
    # Return
    return ismDM
Exemplo n.º 4
0
def mwdm(ra, dec, distance):
    co = coordinates.SkyCoord(ra, dec, unit='deg')
    # or pass sexagesimal
    #    co = coordinates.SkyCoord(rastr, decstr, unit=(units.hourangle, units.deg))

    ne = density.ElectronDensity(**ne_io.Params())
    dm = ne.DM(co.galactic.l, co.galactic.b, distance)
    
    print(f'For (RA, Dec) = ({ra}, {dec}), (l, b) = ({co.galactic.l}, {co.galactic.b}), DM={dm} pc/cm3')
Exemplo n.º 5
0
def test_dist():
    seed(123)
    for i in range(1):
        tol = 0.1
        ne = density.ElectronDensity()
        l = rand() * 360
        b = np.arccos(1 - 2 * rand()) / np.pi * 180
        d = rand() * 5
        DM = ne.DM(l, b, d)
        d_DM = ne.dist(l, b, DM)
        err = abs(d_DM.value - d) / d
        print(err, l, b, d, d_DM)
        assert err < tol, (l, b, d)
Exemplo n.º 6
0
def main(pargs, **kwargs):
    """ Run
    """
    # init
    ne = density.ElectronDensity()

    # DM
    DM = ne.DM(pargs.l, pargs.b, pargs.d)
    print("----------------------------------------------")
    print("DM:")
    print("  Along l={:g} deg and b={:g} deg to d={:g} kpc".format(
        pargs.l, pargs.b, pargs.d))
    print("  DM = {:g}".format(DM))
    print("----------------------------------------------")
Exemplo n.º 7
0
Arquivo: dm.py Projeto: starlism/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)
Exemplo n.º 8
0
    def calc_dm_galaxy(self, model='ymw16'):
        """
        Calculates the dispersion measure contribution of the Milky Way
        from either (:attr:`raj`, :attr:`decj`) or (:attr:`gl`,
        :attr:`gb`). Uses the YMW16 model of the Milky Way free
        electron column density.

        Parameters
        ----------
        model : 'ymw16' or 'ne2001', optional
            The Milky Way dispersion measure model. To use 'ne2001' you
            will need to install the python port. See 
            https://fruitbat.readthedocs.io/en/latest/user_guide/ne2001_installation.html
            Default: 'ymw16'

        Returns
        -------
        :obj:`astropy.units.Quantity`
            The dispersion measure contribution from the Milky Way of
            the FRB.
        """
        YMW16_options = ["ymw16", "YMW16"]

        NE2001_options = ["ne2001", "NE2001"]

        if model in YMW16_options:
            # Since the YMW16 model only gives you a dispersion measure out to a
            # distance within the galaxy, to get the entire DM contribution of the
            # galaxy we need to specify the furthest distance in the YMW16 model.
            max_galaxy_dist = 25000  # units: pc

            # Check to make sure some of the keyword are not None
            coord_list = [
                self.skycoords, self.raj, self.decj, self.gl, self.gb
            ]
            if all(val is None for val in coord_list):
                raise ValueError(
                    """Can not calculate dm_galaxy since coordinates
                                 for FRB burst were not provided. Please provide
                                 (raj, decj) or (gl, gb) coordinates.""")

            # Calculate skycoords position if it
            elif (self.skycoords is None and
                  (self.raj is not None and self.decj is not None)
                  or (self.gl is not None and self.gb is not None)):

                self._skycoords = self.calc_skycoords()

            dm_galaxy, tau_sc = ymw16.dist_to_dm(self._skycoords.galactic.l,
                                                 self._skycoords.galactic.b,
                                                 max_galaxy_dist)

        elif model in NE2001_options:
            try:
                from ne2001 import density
            except ModuleNotFoundError:
                msg = ("""
                By default only the YMW16 Milky Way electron density model
                is installed with Fruitbat. However Fruitbat due support using  
                the NE2001 model via a python port from JXP and Ben Baror. 

                To install the ne2001 model compatible with Fruitbat download
                and install it from github:

                >>> git clone https://github.com/FRBs/ne2001
                >>> cd ne2001
                >>> pip install .

                Once you have installed it you should be able to use Fruitbat
                in exactly the same way by passing 'ne2001' instead of 'ymw16'.
                """)
                raise ModuleNotFoundError(msg)

            # This is the same max distanc e that we used for the YMW16 model
            # However the NE2001 model specifies distance in kpc not pc.
            max_galaxy_dist = 25  # units kpc

            # NE2001 models needs gl and gb in floats
            gl = float(self._skycoords.galactic.l.value)
            gb = float(self._skycoords.galactic.b.value)

            ne = density.ElectronDensity()
            dm_galaxy = ne.DM(gl, gb, max_galaxy_dist)

        self.dm_galaxy = dm_galaxy.value
        self.calc_dm_excess()
        return self.dm_galaxy
Exemplo n.º 9
0
""" Module to correct pulsar and FRB DMs for the MW ISM """

from ne2001 import ne_io, density  #ne2001 ism model
import pygedm  #ymw ism model
import numpy as np
import pandas as pd
from astropy import units as u
from astropy.coordinates import SkyCoord, Galactic
import logging

logging.basicConfig(format='%(asctime)s - %(message)s',
                    datefmt='%d-%b-%y %H:%M:%S',
                    level=logging.INFO)
ne = density.ElectronDensity()


def find_delta_dm(transient_type,
                  transient_data,
                  ism_model,
                  b_val,
                  mc_deg=5,
                  save_df=True):
    """
    Find pulsar/FRB DMs corrected for by the MW ISM DM and remove observations in complex DM regions.
    Returns array of DMs
    FRB data is available as a csv in the FRBs/FRB/frb/data/FRBs repo (FRB catalogue [Petroff et al. 2017])
    Pulsar data is avaiable as a csv in the FRBs/pulsars/pulsars/data/atnf_cat repo (v1.61 ATNF pulsar catalogue [Manchester et al. 2005])
    
    Arguments:
        transient_type (str):
            Accepts 'frb' or 'pulsar'.
Exemplo n.º 10
0
def test_electron_density_quad():
    tol = 1e-3
    ne = density.ElectronDensity()
    l, b, d = -2, 12, 1
    DM = 23.98557
    assert abs(ne.DM(l, b, d).value - DM) / DM < tol
Exemplo n.º 11
0
import time

import numpy as np
from numpy.random import rand
from numpy.random import randint

from ne2001 import density

sys.path.append(os.path.dirname(os.path.realpath(__file__)) + '/../../src/')

PARAMS = density.PARAMS
density.set_xyz_sun(np.array([0, 8.5, 0]))


if __name__ == '__main__':
    tol = 1e-3
    ne = density.ElectronDensity(**PARAMS)
    l, b, d = -2, 12, 1
    DM = 23.98557
    start = time.time()
    DMc = ne.DM(l, b, d)
    t1 = time.time() - start
    start = time.time()
    DMc = ne.DM(l, b, d)
    t2 = time.time() - start
    assert abs(DMc - DM)/DM < tol
    cProfile.run('ne.DM(l, b, d)', 'restats')
    print(t1,t2)
    p = pstats.Stats('restats')
    p.strip_dirs().sort_stats('cumulative').print_stats(50)