예제 #1
0
def mock_HIlines(HI_comps, wvmnx, tau0_min=5e-3):
    """Generate list of absorption lines for a sightline
    Parameters:
    ------------
    HI_comps : QTable
      HI components ('z','lgNHI','bval')
    wvmnx : tuple (Quantity,Quantity)
      min/max wavelength
    tau0_min : float, optional
      Minimum optical depth to include

    Returns:
    --------
    abs_lines: list
      List of HI Lyman lines
    """
    # Linelist
    HIlines = lll.LineList('HI')
    wrest = HIlines._data['wrest']

    # All wvobs
    grid_zp1 = np.outer(HI_comps['z']+1, np.ones(len(wrest)))
    grid_wr = np.outer(np.ones(len(HI_comps)), wrest)
    all_wvobs = grid_zp1 * grid_wr

    # All tau0
    # Grids
    grid_NHI = np.outer(10.**HI_comps['lgNHI'], np.ones(len(wrest)))
    grid_b = np.outer(HI_comps['bval'].to('cm/s'), np.ones(len(wrest)))
    grid_f = np.outer(np.ones(len(HI_comps)), HIlines._data['f'])
    # tau0 (Spitzer 1979)
    grid_tau0 = 1.497e-2 * grid_wr * 1e-8 * grid_f * grid_NHI / grid_b

    # Good ones
    gdlin = np.where( (all_wvobs>wvmnx[0].value) &
        (all_wvobs<wvmnx[1].value) & (grid_tau0>tau0_min))

    # Generate the line list for Lyman series
    grid_lgNHI = np.log10(grid_NHI)
    grid_z = grid_zp1 - 1.
    grid_bkms = grid_b / 1e5 * u.km/u.s

    # Parameters
    parm = []
    for ii,jj in zip(gdlin[0],gdlin[1]): # lambda, z, N, b
        parm.append([grid_wr[ii,jj]*u.AA, grid_z[ii,jj],
            grid_lgNHI[ii,jj], grid_bkms[ii,jj]])

    # Generate a large batch of AbsLines
    all_wrest = [iparm[0] for iparm in parm]
    abs_lines = spectralline.many_abslines(all_wrest, HIlines)
    # Fill in the rest
    for jj,iparm in enumerate(parm):
        abs_lines[jj].setz(iparm[1])
        abs_lines[jj].attrib['logN'] = iparm[2]
        abs_lines[jj].attrib['N'] = 10**iparm[2] / u.cm**2
        abs_lines[jj].attrib['b'] = iparm[3]

    # Retrun
    return abs_lines
예제 #2
0
파일: lls.py 프로젝트: SunilSimha/pyigm
    def fill_lls_lines(self, bval=20. * u.km / u.s, do_analysis=1):
        """
        Generate an HI line list for an LLS.
        Goes into self.lls_lines 

        Now generates a component too.
        Should have it check for an existing HI component..

        Parameters
        ----------
        bval : float, optional
          Doppler parameter in km/s
        do_analysis : int, optional
          flag for analysis
        """
        from linetools.lists import linelist as lll

        # May be replaced by component class (as NT desires)
        HIlines = lll.LineList('HI')

        self.lls_lines = []
        Nval = 10**self.NHI / u.cm**2
        for wrest in u.Quantity(HIlines._data['wrest']):
            aline = AbsLine(wrest, linelist=HIlines)
            # Attributes
            aline.attrib['N'] = Nval
            aline.attrib['b'] = bval
            aline.setz(self.zabs)
            aline.limits.set(self.vlim)
            aline.analy['do_analysis'] = do_analysis
            aline.attrib['coord'] = self.coord
            self.lls_lines.append(aline)
        # Generate a component (should remove any previous HI)
        self.add_component(AbsComponent.from_abslines(self.lls_lines))
예제 #3
0
    def fill_lls_lines(self, bval=20. * u.km / u.s):
        """
        Generate an HI line list for an LLS.
        Goes into self.lls_lines 

        Parameters
        ----------
        bval : float (20.)  Doppler parameter in km/s
        """
        from linetools.lists import linelist as lll
        from linetools.spectralline import AbsLine

        # May be replaced by component class (as NT desires)
        HIlines = lll.LineList('HI')

        self.lls_lines = []
        for lline in HIlines._data:
            aline = AbsLine(lline['wrest'], linelist=HIlines)
            # Attributes
            aline.attrib['N'] = self.NHI
            aline.attrib['b'] = bval
            aline.attrib['z'] = self.zabs
            # Could set RA and DEC too
            aline.attrib['RA'] = self.coord.ra
            aline.attrib['DEC'] = self.coord.dec
            self.lls_lines.append(aline)
예제 #4
0
파일: nebular.py 프로젝트: lao19881213/FRB
def calc_lum(neb_lines, line, z, cosmo, AV=None, curve='MW'):
    """
    Calculate the line luminosity (and error) from input nebular line emission

    Error is -999.*erg/s if input line flux has negative error

    Args:
        neb_lines (dict):  Observed line fluxes and errors
        line (str): Line to analyze
        z (float):  Emission redshift -- for Luminosity distance
        cosmo (astropy.cosmology.FLRW): Cosmology
        AV (float, optional):  Visual extinction, if supplied will apply
        curve (str):  Name of the extinction curve.  Only used if A_V is supplied

    Returns:
        Quantity, Quantity:  Luminosity, sig(Luminosity)
    """
    # Grab rest wavelength (vacuum)
    llist = linelist.LineList('Galaxy')
    wave = llist[line]['wrest']

    # Dust correct?
    if AV is not None:
        alAV = load_extinction(curve)
        al = AV * alAV(wave.to('Angstrom').value)
    else:
        al = 0.

    # Cosmology
    DL = cosmo.luminosity_distance(z)

    # Luminosity
    flux = neb_lines[line]
    Lum = flux * units.erg/units.s/units.cm**2 * 10**(al/2.5) * (4*np.pi * DL**2)

    # Error
    if neb_lines[line+'_err'] > 0.:
        flux_err = neb_lines[line+'_err']
        Lum_err = flux_err * units.erg/units.s/units.cm**2 * 10**(al/2.5) * (4*np.pi * DL**2)
    else:
        Lum_err = -999 * units.erg/units.s
    # Return
    return Lum.to('erg/s'), Lum_err.to('erg/s')
예제 #5
0
def fig_abs_gallery(wrest=None,
                    lbl=None,
                    outfil=None,
                    cos_halos=None,
                    passback=False,
                    axes_flg=0):
    # import tlk_coshalos as tch
    # reload(tch)
    # cos_halos = tch.fig_abs_gallery(passback=True)
    '''Gallery of absorption lines
    Default is M* vs. sSFR
      But you can do rho vs. M* too
    axes_flg: int, optional
      0: M* vs. sSFR
      1: rho vs. M*
    '''
    # Linelist
    llist = lll.LineList('Strong')
    if wrest is None:
        wrest = 1215.670 * u.AA
    Zion = (llist[wrest]['Z'], llist[wrest]['ion'])
    if lbl is None:
        lbl = r'HI Ly$\alpha$'
    if outfil is None:
        outfil = 'fig_HI_gallery.pdf'
    # Init COS-Halos (slow)
    if cos_halos is None:
        cos_halos = COSHalos()
        cos_halos.load_mega()  #skip_ions=True)
        if passback:
            return cos_halos

    if axes_flg == 0:
        xmnx = (9.4, 11.7)
        ymnx = (-13., -9.)
    elif axes_flg == 1:
        ymnx = (9.4, 11.7)  # log Msun
        xmnx = (15., 163)  # kpc
    vmnx = (-600., 600.)  # km/s
    wbox = {'facecolor': 'white', 'edgecolor': 'white'}
    lclr = 'blue'

    # To help with looping
    def sngl_abs(ax,
                 field_gal,
                 wbox=wbox,
                 lclr=lclr,
                 vmnx=vmnx,
                 xmnx=xmnx,
                 ymnx=ymnx,
                 cos_halos=cos_halos,
                 show_xylbl=True,
                 srect=0.2,
                 show_ewlbl=True,
                 lw=1.3,
                 axes_flg=axes_flg):
        #
        cgm_abs = cos_halos[field_gal]
        if axes_flg == 0:
            xplt = cgm_abs.galaxy.stellar_mass
            yplt = np.log10(
                cgm_abs.galaxy.sfr[1]) - cgm_abs.galaxy.stellar_mass
        elif axes_flg == 1:
            yplt = cgm_abs.galaxy.stellar_mass
            xplt = cgm_abs.rho.value
        # Spec
        spec = cos_halos.load_bg_cos_spec(field_gal, wrest)
        velo = spec.relative_vel(wrest * (cgm_abs.galaxy.z + 1))
        # EW
        data = cgm_abs.abs_sys.ions[Zion]
        itrans = np.where(np.abs(data['LAMBDA'] - wrest.value) < 1e-3)[0]
        if len(itrans) == 0:
            print('No measurement of {:g} for {:s} {:s}'.format(
                wrest, field_gal[0], field_gal[1]))
            return
        EW = data['WREST'][itrans][0] * u.AA / 1e3
        sigEW = data['SIGWREST'][itrans][0] * u.AA / 1e3
        if sigEW <= 0.:  # Something must be wrong
            return
        if EW > 3 * sigEW:
            sclr = 'k'
        else:
            sclr = 'r'
        #
        xrect = (xplt - xmnx[0]) / (xmnx[1] - xmnx[0])
        yrect = (yplt - ymnx[0]) / (ymnx[1] - ymnx[0])
        rect = [xrect, yrect, srect, srect]
        axsp = xpsimp.add_subplot_axes(ax, rect)  #,axisbg=axisbg)
        axsp.set_xlim(vmnx)
        axsp.set_ylim(-0.1, 1.3)
        if show_xylbl:
            axsp.set_xlabel('Relative Velocity (km/s)', fontsize=9.)
            axsp.set_ylabel('Normalized Flux', fontsize=9.)
        # Plot
        axsp.plot(velo, spec.flux, sclr, drawstyle='steps', lw=lw)
        # Label
        #llbl = (r'$W_\lambda = $'+'{:0.2f} A \n'.format(EW.value)+
        #    '$z=${:.3f}\n'.format(cgm_abs.galaxy.z)+
        #    r'$\rho=$'+'{:d}kpc'.format(int(np.round(cgm_abs.rho.to('kpc').value))))
        if show_ewlbl:
            llbl = r'$W_\lambda = $' + '{:0.2f} A'.format(EW.value)
            axsp.text(-300.,
                      1.1,
                      llbl,
                      ha='left',
                      fontsize=7.,
                      color=lclr,
                      bbox=wbox)  #multialignment='left')

    # Start the plot
    pp = PdfPages(outfil)

    if axes_flg == 0:
        loop = range(4)
    else:
        loop = range(3, 4)

    for ss in loop:
        plt.figure(figsize=(8, 5))
        plt.clf()
        gs = gridspec.GridSpec(1, 1)

        # Axes
        ax = plt.subplot(gs[0, 0])
        ax.set_xlim(xmnx)
        ax.set_ylim(ymnx)
        if axes_flg == 0:
            ax.set_ylabel('sSFR')
            ax.set_xlabel('log M*')
            ax.text(9.75, -12., lbl, color=lclr, fontsize=21.)
        elif axes_flg == 1:
            ax.set_ylabel('log M*')
            ax.set_xlabel('Impact Parameter (kpc)')
            ax.text(40., 11.5, lbl, color=lclr, fontsize=21.)
        #ax.xaxis.set_major_locator(plt.MultipleLocator(300.))

        #
        if ss == 0:  # Single system
            field_gal = ('J0950+4831', '177_27')
            sngl_abs(ax, field_gal)
        elif ss == 1:  # Two systems
            cgm_list = [('J0950+4831', '177_27'), ('J1245+3356', '236_36')]
            for field_gal in cgm_list:
                sngl_abs(ax, field_gal)
        elif ss > 1:  # Half systems
            if ss == 2:
                iend = 20
            else:
                iend = -1
            for cgm_abs in cos_halos.cgm_abs[0:iend]:
                field_gal = (cgm_abs.field, cgm_abs.gal_id)
                sngl_abs(ax,
                         field_gal,
                         show_xylbl=False,
                         srect=0.1,
                         show_ewlbl=False,
                         lw=0.5)
        else:
            pass

        xputils.set_fontsize(ax, 17.)
        # Write
        plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1)
        pp.savefig()
        plt.close()

    # Finish
    print('tlk_coshalos: Wrote {:s}'.format(outfil))
    pp.close()