Beispiel #1
0
def get_dv_closest_z(z1, z2, give_ids=False):
    """Returns an array of same lenght as z1, with the velocity difference
    (in km/s) associates to the closest redshift in z2, at restframe
    given by z2. (Using relativistic approximation for flat-space time;
    see ltu.dv_from_z() function)

    If give_ids is True , it also returns the indices of z2 where the
    difference is minimum.

    """

    z1 = np.array(z1)
    z2 = np.array(z2)

    dv = []
    inds = []
    for z in z1:
        dv_aux = ltu.dv_from_z(z, z2)
        # find minimum difference
        cond = np.fabs(dv_aux) == np.min(np.fabs(dv_aux))
        ind = np.where(cond)[0][0]
        # append dv
        dv += [dv_aux[ind]]
        inds += [ind]
    dv = np.array(dv)
    if give_ids:
        return dv, inds
    else:
        return dv
Beispiel #2
0
def get_dv_closest_z(z1, z2, give_ids=False):
    """Returns an array of same lenght as z1, with the velocity difference
    (in km/s) associates to the closest redshift in z2, at restframe
    given by z2. (Using relativistic approximation for flat-space time;
    see ltu.dv_from_z() function)

    If give_ids is True , it also returns the indices of z2 where the
    difference is minimum.

    """

    z1 = np.array(z1)
    z2 = np.array(z2)

    dv = []
    inds = []
    for z in z1:
        dv_aux = ltu.dv_from_z(z, z2)
        # find minimum difference
        cond = np.fabs(dv_aux) == np.min(np.fabs(dv_aux))
        ind = np.where(cond)[0][0]
        # append dv
        dv += [dv_aux[ind]]
        inds += [ind]
    dv = np.array(dv)
    if give_ids:
        return dv, inds
    else:
        return dv
Beispiel #3
0
    def pairs(self, sep, dv):
        """ Generate a pair catalog
        Parameters
        ----------
        sep : Angle or Quantity
        dv : Quantity
          Offset in velocity.  Positive for projected pairs (i.e. dz > input value)

        Returns
        -------

        """
        # Checks
        if not isinstance(sep, (Angle, Quantity)):
            raise IOError("Input radius must be an Angle type, e.g. 10.*u.arcsec")
        if not isinstance(dv, (Quantity)):
            raise IOError("Input velocity must be a quantity, e.g. u.km/u.s")
        # Match
        idx, d2d, d3d = match_coordinates_sky(self.coords, self.coords, nthneighbor=2)
        close = d2d < sep
        # Cut on redshift
        if dv > 0.:  # Desire projected pairs
            zem1 = self.cat['zem'][close]
            zem2 = self.cat['zem'][idx[close]]
            dv12 = ltu.dv_from_z(zem1,zem2)
            gdz = np.abs(dv12) > dv
            # f/g and b/g
            izfg = dv12[gdz] < 0*u.km/u.s
            ID_fg = self.cat[self.idkey][close][gdz][izfg]
            ID_bg = self.cat[self.idkey][idx[close]][gdz][izfg]
        else:
            pdb.set_trace()
        # Reload
        return ID_fg, ID_bg
Beispiel #4
0
 def reset(self):
     """ Update all the values
     """
     #self._data['zlim'] = self._zlim
     if self._wrest is not None:
         self._wvlim = self._wrest*(1+np.array(self._zlim))
     self._vlim = ltu.dv_from_z(self._zlim, self._z)
Beispiel #5
0
 def reset(self):
     """ Update all the values
     """
     #self._data['zlim'] = self._zlim
     if self._wrest is not None:
         self._wvlim = self._wrest*(1+np.array(self._zlim))
     self._vlim = ltu.dv_from_z(self._zlim, self._z)
Beispiel #6
0
 def get_vmnx(components):
     zlim_sys = ltu.z_from_dv(self.vlim, self.zabs, rel=False)
     zmin, zmax = zlim_sys
     for component in components:
         zlim_comp = ltu.z_from_dv(component.vlim, component.zcomp, rel=False)
         zmin = min(zmin, zlim_comp[0])
         zmax = max(zmax, zlim_comp[1])
     # Convert back to velocities
     return ltu.dv_from_z([zmin,zmax], self.zabs, rel=False)
Beispiel #7
0
 def get_vmnx(components):
     zlim_sys = ltu.z_from_dv(self.vlim, self.zabs, rel=False)
     zmin, zmax = zlim_sys
     for component in components:
         zlim_comp = ltu.z_from_dv(component.vlim, component.zcomp, rel=False)
         zmin = min(zmin, zlim_comp[0])
         zmax = max(zmax, zlim_comp[1])
     # Convert back to velocities
     return ltu.dv_from_z([zmin,zmax], self.zabs, rel=False)
Beispiel #8
0
    def repr_joebvp(self, specfile, flags=(2,2,2), b_default=10*u.km/u.s,
                    z_sys = None):
        """
        String representation for JOEBVP (line fitting software).

        Parameters
        ----------
        specfile : str
            Name of the spectrum file
        flags : tuple of ints, optional
            Flags (nflag, bflag, vflag). See JOEBVP input for details
            about these flags.
        b_default : Quantity, optional
            Doppler parameter value adopted in case an absorption
            line within the component has not set this attribute
            Default is 10 km/s.
        z_sys : float, optional
            Systemic redshift if different from zcomp; if provided,
            velocities will be transformed to this frame

        Returns
        -------
        repr_joebvp : str
            May contain multiple "\n" (1 per absline within component)

        """
        # Reference: (note that comment column must be the last one)
        # specfile|restwave|zsys|col|bval|vel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|z_comp|trans|rely|comment
        s = ''
        for aline in self._abslines:
            s += '{:s}|{:.5f}|'.format(specfile, aline.wrest.to('AA').value)
            logN = aline.attrib['logN']
            b_val = aline.attrib['b'].to('km/s').value
            if b_val == 0:  # set the default
                b_val = b_default.to('km/s').value

            if z_sys is None:
                z_sys = self.zcomp
                vel = 0.
            else:
                vel = ltu.dv_from_z(self.zcomp,z_sys).value


            # write string
            s += '{:.8f}|{:.4f}|{:.4f}|{:.4f}|'.format(z_sys, logN, b_val,vel)  # `vel` is set to 0. because zsys is zcomp
            s += '{}|{}|{}|'.format(int(flags[0]), int(flags[1]), int(flags[2]))
            vlim = aline.limits.vlim.to('km/s').value
            wvlim = aline.limits.wvlim.to('AA').value
            s += '{:.4f}|{:.4f}|{:.5f}|{:.5f}|'.format(vlim[0], vlim[1], wvlim[0], wvlim[1])
            s += '{:.8f}|{:s}|{:s}|{:s}'.format(self.zcomp, aline.ion_name, self.reliability, self.comment)  # zcomp again here

            # if len(self.comment) > 0:
            #     s += '# {:s}'.format(self.comment)
            s += '\n'
        return s
Beispiel #9
0
def test_dv_from_z():
    dv = ltu.dv_from_z(2.1, 2.)
    assert dv.unit == u.km / u.s
    np.testing.assert_allclose(dv.value, 9826.620063406788, rtol=1e-6)
    dv = ltu.dv_from_z([2.1, 2.1, 2.1], 2.)
    np.testing.assert_allclose(dv.value, [9826.620063406788] * 3, rtol=1e-6)
    # non-relativistic
    dv = ltu.dv_from_z(2.1, 2., rel=False)
    np.testing.assert_allclose(dv.value, 9993.08193333334, rtol=1e-6)

    # test expected errors
    with pytest.raises(IOError):
        ltu.dv_from_z('z_not_a_float_or_array', 1.)
    with pytest.raises(IOError):
        ltu.dv_from_z(2.1, 'zref_not_a_float_nor_array')
    with pytest.raises(IOError):
        ltu.dv_from_z(np.array([2.1, 2.1, 2.1]), np.array([2., 2.]))  # wrong shape for zref
Beispiel #10
0
def test_dv_from_z():
    dv = ltu.dv_from_z(2.1, 2.)
    assert dv.unit == u.km / u.s
    np.testing.assert_allclose(dv.value, 9826.620063406788, rtol=1e-6)
    dv = ltu.dv_from_z([2.1, 2.1, 2.1], 2.)
    np.testing.assert_allclose(dv.value, [9826.620063406788] * 3, rtol=1e-6)
    # non-relativistic
    dv = ltu.dv_from_z(2.1, 2., rel=False)
    np.testing.assert_allclose(dv.value, 9993.08193333334, rtol=1e-6)

    # test expected errors
    with pytest.raises(IOError):
        ltu.dv_from_z('z_not_a_float_or_array', 1.)
    with pytest.raises(IOError):
        ltu.dv_from_z(2.1, 'zref_not_a_float_nor_array')
    with pytest.raises(IOError):
        ltu.dv_from_z(np.array([2.1, 2.1, 2.1]), np.array([2., 2.]))  # wrong shape for zref
Beispiel #11
0
    def update_component_vel(self):
        """Change the velocities of each component to rest frame of zsys
        """
        from linetools.analysis.zlimits import zLimits

        for i, comp in enumerate(self._components):
            dv = ltu.dv_from_z(comp.zcomp, self.zabs)
            zmin = ltu.z_from_dv(comp.limits.vlim[0] + dv, self.zabs)
            zmax = ltu.z_from_dv(comp.limits.vlim[1] + dv, self.zabs)
            newzlim = zLimits(self.zabs, (zmin, zmax))
            comp.limits = newzlim
            comp.attrib['vel'] = comp.attrib['vel'] + dv
Beispiel #12
0
def associate_redshifts(z1, z2, dv):
    """Returns an array of same lenght as z1, with a 1 if z1 redshift
    lie within dv from any of the redshifts given by the array z2;
    otherwise it has a value of 0"""

    z1 = np.array(z1)
    z2 = np.array(z2)

    association = np.zeros(len(z1))
    for z in z2:
        dv_aux = np.fabs(ltu.dv_from_z(z1, z))
        association = np.where(dv_aux < dv, 1, association)
    return association
Beispiel #13
0
def associate_redshifts(z1, z2, dv):
    """Returns an array of same lenght as z1, with a 1 if z1 redshift
    lie within dv from any of the redshifts given by the array z2;
    otherwise it has a value of 0"""

    z1 = np.array(z1)
    z2 = np.array(z2)

    association = np.zeros(len(z1))
    for z in z2:
        dv_aux = np.fabs(ltu.dv_from_z(z1, z))
        association = np.where(dv_aux < dv, 1, association)
    return association
Beispiel #14
0
def cgm_from_galaxy_igmsystems(galaxy,
                               igmsystems,
                               R_max=300 * u.kpc,
                               dv_max=400 * u.km / u.s,
                               cosmo=None,
                               **kwargs):
    """ Generate a list of CGMAbsSys objects given an input galaxy and a list of IGMSystems

    Parameters
    ----------
    galaxy : Galaxy
    igmsystems : list
      list of IGMSystems
    R_max : Quantity
      Maximum projected separation from sightline to galaxy
    dv_max
      Maximum velocity offset between system and galaxy

    Returns
    -------
    cgm_list : list
      list of CGM objects generated

    """
    from pyigm.cgm.cgm import CGMAbsSys
    # Cosmology
    if cosmo is None:
        cosmo = cosmology.Planck15

    # R
    rho, angles = calc_rho(galaxy, igmsystems, cosmo)

    # dv
    igm_z = np.array([igmsystem.zabs for igmsystem in igmsystems])
    dv = ltu.dv_from_z(igm_z, galaxy.z)

    # Rules
    match = np.where((rho < R_max) & (np.abs(dv) < dv_max))[0]
    if len(match) == 0:
        print("No CGM objects match your rules")
        return []
    else:
        # Loop to generate
        cgm_list = []
        for imatch in match:
            cgm = CGMAbsSys(galaxy, igmsystems[imatch], cosmo=cosmo, **kwargs)
            cgm_list.append(cgm)

    # Return
    return cgm_list
Beispiel #15
0
def plot_vel(ax, spec, iline, z, dvlims, complist=None, fwhm=3, min_ew_blends=0.01*u.AA):

    # first normalize
    if not spec.normed:
        spec.normalize(co=spec.co)

    # first identify good components
    good_comps = []
    good_comps_aux = ltiu.get_components_at_z(complist, z, dvlims)
    for comp in good_comps_aux:
        for aline in comp._abslines:
            if aline.name == iline['name']:
                good_comps += [comp]
                break
    # bad comps will be those unrelated to the given redshift/transition
    bad_comps = []
    for comp in complist:
        if comp not in good_comps:
            bad_comps += [comp]
    # only good comps will have a model
    if len(good_comps) > 0:
        # import pdb; pdb.set_trace()
        model_spec = lav.voigt_from_components(spec.wavelength, good_comps, fwhm=fwhm)
    else:
        model_spec = XSpectrum1D.from_tuple((spec.wavelength, np.ones(spec.npix)))

    # main plot
    velo = ltu.dv_from_z(spec.wavelength/iline['wrest'] - 1. , z)
    ax.plot(velo, spec.flux, drawstyle='steps-mid', color=COLOR_FLUX)
    plot_spec_complist(ax, velo, spec, bad_comps, min_ew = min_ew_blends, color=COLOR_BLEND, lw=2, drawstyle='steps-mid')
    plot_spec_complist(ax, velo, model_spec, good_comps, min_ew = None, color=COLOR_MODEL, lw=1, ls='-')

    if spec.sig_is_set:
        ax.plot(velo, spec.sig, drawstyle='steps-mid', color=COLOR_SIG, lw=0.5)

    # Zero velocity line
    ax.plot([0., 0.], [-1e9, 1e9], ':', color='gray')
    # Unity flux level line
    ax.plot([-1e9, 1e9], [1, 1], ':', color='b', lw=0.5)
    # Zero flux level line
    ax.plot([-1e9, 1e9], [0, 0], '--', color='k', lw=1)
Beispiel #16
0
def get_components_at_z(complist, z, dvlims):
    """In a given list of AbsComponents, it finds
    the ones that are within dvlims from a given redshift
    and returns a list of those.

    Parameters
    ----------
    complist : list
        List of AbsComponents
    z : float
        Redshift to search for components
    dvlims : Quantity array
        Rest-frame velocity limits around z
        to look for components

    Returns
    -------
    components_at_z : list
        List of AbsComponents in complist within dvlims from z
    """
    # check input
    if not isinstance(complist[0], AbsComponent):
        raise IOError('complist must be a list of AbsComponents.')
    if len(dvlims) != 2:
        raise IOError(
            'dvlims must be a Quantity array of velocity limits (vmin, vmax).')
    else:
        try:
            dvlims_kms = dvlims.to('km/s')
        except u.UnitConversionError:
            raise IOError('dvlims must have velocity units.')

    good_complist = []
    for comp in complist:
        dv_comp = ltu.dv_from_z(comp.zcomp, z)
        if (dv_comp >= dvlims[0]) and (dv_comp <= dvlims[1]):
            good_complist += [comp]
    return good_complist
Beispiel #17
0
def get_components_at_z(complist, z, dvlims):
    """In a given list of AbsComponents, it finds
    the ones that are within dvlims from a given redshift
    and returns a list of those.

    Parameters
    ----------
    complist : list
        List of AbsComponents
    z : float
        Redshift to search for components
    dvlims : Quantity array
        Rest-frame velocity limits around z
        to look for components

    Returns
    -------
    components_at_z : list
        List of AbsComponents in complist within dvlims from z
    """
    # check input
    if not isinstance(complist[0], AbsComponent):
        raise IOError('complist must be a list of AbsComponents.')
    if len(dvlims) != 2:
        raise IOError('dvlims must be a Quantity array of velocity limits (vmin, vmax).')
    else:
        try:
            dvlims_kms = dvlims.to('km/s')
        except u.UnitConversionError:
            raise IOError('dvlims must have velocity units.')

    good_complist = []
    for comp in complist:
        dv_comp = ltu.dv_from_z(comp.zcomp, z)
        if (dv_comp >= dvlims[0]) and (dv_comp <= dvlims[1]):
            good_complist += [comp]
    return good_complist
Beispiel #18
0
def cgm_from_galaxy_igmsystems(galaxy,
                               igmsystems,
                               rho_max=300 * u.kpc,
                               dv_max=400 * u.km / u.s,
                               cosmo=None,
                               dummysys=False,
                               dummyspec=None,
                               verbose=True,
                               **kwargs):
    """ Generate a list of CGMAbsSys objects given an input galaxy and a list of IGMSystems

    Parameters
    ----------
    galaxy : Galaxy
    igmsystems : list
      list of IGMSystems
    rho_max : Quantity
      Maximum projected separation from sightline to galaxy
    dv_max
      Maximum velocity offset between system and galaxy
    dummysys: bool, optional
        If True, instantiate CGMAbsSys even if no match is found in igmsystems
    dummyspec : XSpectrum1D, optional
        Spectrum object to attach to dummy AbsLine/AbsComponent objects when
        adding IGMSystems if dummysys is True.

    Returns
    -------
    cgm_list : list
      list of CGM objects generated

    """
    from pyigm.cgm.cgm import CGMAbsSys
    # Cosmology
    if cosmo is None:
        cosmo = cosmology.Planck15

    if dummysys is True:
        if dummyspec is None:
            dummyspec = igmsystems[0]._components[0]._abslines[0].analy['spec']
        dummycoords = igmsystems[0].coord

    # R -- speed things up
    rho, angles = calc_cgm_rho(galaxy, igmsystems, cosmo, **kwargs)
    if len(igmsystems) == 1:  # Kludge
        rho = u.Quantity([rho])
        angles = u.Quantity([angles])

    # dv
    igm_z = np.array([igmsystem.zabs for igmsystem in igmsystems])
    dv = ltu.dv_from_z(igm_z, galaxy.z)

    # Rules
    match = np.where((rho < rho_max) & (np.abs(dv) < dv_max))[0]

    ### If none, see if some system has a component that's actually within dv_max
    if (len(match) == 0) & (rho[0] < rho_max):
        zcomps = []
        sysidxs = []
        for i, csys in enumerate(igmsystems):
            thesezs = [comp.zcomp for comp in csys._components]
            sysidxs.extend([i] * len(thesezs))
            zcomps.extend(thesezs)
        zcomps = np.array(zcomps)
        sysidxs = np.array(sysidxs)
        dv_comps = ltu.dv_from_z(zcomps, galaxy.z)
        match = np.unique(sysidxs[np.where(np.abs(dv_comps) < dv_max)[0]])

    if len(match) == 0:
        if dummysys is False:
            print(
                "No IGMSystem paired to this galaxy. CGM object not created.")
            return []
        else:
            if verbose:
                print("No IGMSystem match found. Attaching dummy IGMSystem.")
            dummysystem = IGMSystem(dummycoords, galaxy.z, vlim=None)
            dummycomp = AbsComponent(dummycoords, (1, 1), galaxy.z,
                                     [-100., 100.] * u.km / u.s)
            dummycomp.flag_N = 3
            dummyline = AbsLine(
                'HI 1215',
                **kwargs)  # Need an actual transition for comp check
            dummyline.analy['spec'] = dummyspec
            dummyline.attrib['coord'] = dummycoords
            dummycomp.add_absline(dummyline, chk_vel=False, chk_sep=False)
            dummysystem.add_component(dummycomp, chk_vel=False, chk_sep=False)
            cgm = CGMAbsSys(galaxy, dummysystem, cosmo=cosmo, **kwargs)
            cgm_list = [cgm]
    else:
        # Loop to generate
        cgm_list = []
        for imatch in match:
            # Instantiate new IGMSystem
            # Otherwise, updates to the IGMSystem cross-pollinate other CGMs
            sysmatch = igmsystems[imatch]
            newisys = sysmatch.copy()
            # Handle z limits
            zlim = ltu.z_from_dv((-dv_max.value, dv_max.value) * u.km / u.s,
                                 galaxy.z)
            newlims = zLimits(galaxy.z, zlim.tolist())
            newisys.limits = newlims
            # Allow for components extending beyond dv_max
            newisys.update_vlim()
            newisys.update_component_vel()
            # Finish
            cgm = CGMAbsSys(galaxy,
                            newisys,
                            cosmo=cosmo,
                            rho=rho[imatch],
                            ang_sep=angles[imatch],
                            **kwargs)
            cgm_list.append(cgm)

    # Return
    return cgm_list
Beispiel #19
0
def give_dv(z, zref, **kwargs):
    """Wrapper for convinience"""
    print(
        "This function is now in linetools.utils.dv_from_z(), please avoid using this one."
    )
    return ltu.dv_from_z(z, zref, **kwargs)
Beispiel #20
0
def give_dv(z, zref, **kwargs):
    """Wrapper for convinience"""
    print("This function is now in linetools.utils.dv_from_z(), please avoid using this one.")
    return ltu.dv_from_z(z, zref, **kwargs)
Beispiel #21
0
def plot_vel(ax,
             spec,
             iline,
             z,
             dvlims,
             complist=None,
             fwhm=3,
             min_ew_blends=0.01 * u.AA):

    # first normalize
    if not spec.normed:
        spec.normalize(co=spec.co)

    # first identify good components
    good_comps = []
    good_comps_aux = ltiu.get_components_at_z(complist, z, dvlims)
    for comp in good_comps_aux:
        for aline in comp._abslines:
            if aline.name == iline['name']:
                good_comps += [comp]
                break
    # bad comps will be those unrelated to the given redshift/transition
    bad_comps = []
    for comp in complist:
        if comp not in good_comps:
            bad_comps += [comp]
    # only good comps will have a model
    if len(good_comps) > 0:
        # import pdb; pdb.set_trace()
        model_spec = lav.voigt_from_components(spec.wavelength,
                                               good_comps,
                                               fwhm=fwhm)
    else:
        model_spec = XSpectrum1D.from_tuple(
            (spec.wavelength, np.ones(spec.npix)))

    # main plot
    velo = ltu.dv_from_z(spec.wavelength / iline['wrest'] - 1., z)
    ax.plot(velo, spec.flux, drawstyle='steps-mid', color=COLOR_FLUX)
    plot_spec_complist(ax,
                       velo,
                       spec,
                       bad_comps,
                       min_ew=min_ew_blends,
                       color=COLOR_BLEND,
                       lw=2,
                       drawstyle='steps-mid')
    plot_spec_complist(ax,
                       velo,
                       model_spec,
                       good_comps,
                       min_ew=None,
                       color=COLOR_MODEL,
                       lw=1,
                       ls='-')

    if spec.sig_is_set:
        ax.plot(velo, spec.sig, drawstyle='steps-mid', color=COLOR_SIG, lw=0.5)

    # Zero velocity line
    ax.plot([0., 0.], [-1e9, 1e9], ':', color='gray')
    # Unity flux level line
    ax.plot([-1e9, 1e9], [1, 1], ':', color='b', lw=0.5)
    # Zero flux level line
    ax.plot([-1e9, 1e9], [0, 0], '--', color='k', lw=1)
Beispiel #22
0
    def repr_joebvp(self,
                    specfile,
                    flags=(2, 2, 2),
                    b_default=10 * u.km / u.s,
                    z_sys=None):
        """
        String representation for JOEBVP (line fitting software).

        Parameters
        ----------
        specfile : str
            Name of the spectrum file
        flags : tuple of ints, optional
            Flags (nflag, bflag, vflag). See JOEBVP input for details
            about these flags.
        b_default : Quantity, optional
            Doppler parameter value adopted in case an absorption
            line within the component has not set this attribute
            Default is 10 km/s.
        z_sys : float, optional
            Systemic redshift if different from zcomp; if provided,
            velocities will be transformed to this frame

        Returns
        -------
        repr_joebvp : str
            May contain multiple "\n" (1 per absline within component)

        """
        # Reference: (note that comment column must be the last one)
        # specfile|restwave|zsys|col|bval|vel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|z_comp|trans|rely|comment
        s = ''
        for aline in self._abslines:
            s += '{:s}|{:.5f}|'.format(specfile, aline.wrest.to('AA').value)
            logN = aline.attrib['logN']
            b_val = aline.attrib['b'].to('km/s').value
            if b_val == 0:  # set the default
                b_val = b_default.to('km/s').value

            if z_sys is None:
                z_sys = self.zcomp
                vel = 0.
            else:
                vel = ltu.dv_from_z(self.zcomp, z_sys).value

            # write string
            s += '{:.8f}|{:.4f}|{:.4f}|{:.4f}|'.format(
                z_sys, logN, b_val,
                vel)  # `vel` is set to 0. because zsys is zcomp
            s += '{}|{}|{}|'.format(int(flags[0]), int(flags[1]),
                                    int(flags[2]))
            vlim = aline.limits.vlim.to('km/s').value
            wvlim = aline.limits.wvlim.to('AA').value
            s += '{:.4f}|{:.4f}|{:.5f}|{:.5f}|'.format(vlim[0], vlim[1],
                                                       wvlim[0], wvlim[1])
            s += '{:.8f}|{:s}|{:s}|{:s}'.format(
                self.zcomp, aline.ion_name, self.reliability,
                self.comment)  # zcomp again here

            # if len(self.comment) > 0:
            #     s += '# {:s}'.format(self.comment)
            s += '\n'
        return s
Beispiel #23
0
    def load_data(self, **kwargs):
        #
        #q8file = resource_filename('pyigm', 'data/CGM/QPQ/qpq8_all_measured.dat')
        q8file = self.data_file

        if self.from_dict:
            q8file = self.data_file
            qpq8dict = CGMAbsSurvey.from_json(q8file)
            ism = LineList('ISM')
            qpq8dict.build_systems_from_dict(llist=ism)
            self.survey_data = qpq8dict
            #self.cgm_abs = qpq8dict.cgm_abs

        else:

            qpqdata = Table.read(q8file, format='ascii')
            #nmax = len(qpqdata)   # max number of QSOs
            q8filecoord = resource_filename('pyigm',
                                            'data/CGM/QPQ/qpq8_pairs.fits')
            qpqdatacoord = Table.read(q8filecoord)
            if self.nmax is not None:
                nmax = self.nmax
            else:
                nmax = len(qpqdatacoord)  #(qpqdata)

            # match names with qpqdatacoord
            qnames = []
            for i in range(len(qpqdatacoord)):
                qname = qpqdatacoord['QSO'][i].strip()
                qnames.append(qname[-10:])
            qnames2 = []
            for i in range(len(qpqdata)):
                qname = qpqdata['Pair'][i]
                qnames2.append(qname)

            for j in range(nmax):  # i,j
                # match names with qpqdatacoord
                i = np.where(np.asarray(qnames2) == qnames[j])[0]
                # Instantiate the galaxy
                gal = Galaxy((qpqdatacoord['RAD'][j], qpqdatacoord['DECD'][j]),
                             z=qpqdatacoord['Z_FG'][j])
                gal.L_BOL = qpqdatacoord['L_BOL'][j]
                gal.L_912 = qpqdatacoord['L_912'][j]
                gal.G_UV = qpqdatacoord['G_UV'][j]
                gal.zsig = qpqdatacoord['Z_FSIG'][j] * u.km / u.s

                # Instantiate the IGM System
                igm_sys = IGMSystem(
                    (qpqdatacoord['RAD_BG'][j], qpqdatacoord['DECD_BG'][j]),
                    qpqdatacoord['Z_FG'][j], [-5500, 5500.] * u.km / u.s,
                    abs_type='CGM')
                # Redshifts: QSO emission redshifts
                igm_sys.zem = qpqdatacoord['Z_BG'][j]
                igm_sys.NHI = qpqdata['HIcol'][i]
                igm_sys.sig_NHI = [
                    qpqdata['HIcolhierr'][i], qpqdata['HIcolloerr'][i]
                ]
                igm_sys.s2n_lya = qpqdatacoord['S2N_LYA'][j]

                iname = qpqdata['Pair'][i][0]  #+'_'+qpqdata['subsys'][i]
                # Instantiate
                rho = qpqdatacoord['R_PHYS'][j] * u.kpc
                cgabs = CGMAbsSys(gal, igm_sys, name=iname, rho=rho, **kwargs)

                ### add metal lines
                ### not included CII*, SiII*
                lines = [
                    ['CII 1334'],  ## ['CII* 1335'],
                    ['CIV 1548', 'CIV 1550'],
                    ['NI 1134', 'NI 1199'],
                    ['NII 1083'],
                    ['NV 1238', 'NV 1242'],
                    ['OI 1302'],
                    ['OVI 1037'],
                    ['MgI 2852'],
                    ['MgII 2796', 'MgII 2803'],
                    ['AlII 1670'],
                    ['AlIII 1854', 'AlIII 1862'],
                    [
                        'SiII 1190', 'SiII 1193', 'SiII 1304', 'SiII 1260',
                        'SiII 1526', 'SiII 1808'
                    ],  ## ['SiII* 1264'],
                    ['SiIII 1206'],
                    ['SiIV 1393', 'SiIV 1402'],
                    [
                        'FeII 1608', 'FeII 2344', 'FeII 2374', 'FeII 2382',
                        'FeII 2586', 'FeII 2600'
                    ],
                    ['FeIII 1122']
                ]

                for kk in i:

                    for icmp in range(len(lines)):
                        abslines = []
                        for ii in range(len(lines[icmp])):
                            wave0 = float(lines[icmp][ii].split(' ')[1])
                            ewstr = str(lines[icmp][ii].split(' ')[1]) + 'EW'
                            ewerrstr = str(
                                lines[icmp][ii].split(' ')[1]) + 'EWerr'
                            if ewstr == '1808EW':
                                ewstr = '1808E'
                            if ewerrstr == '1122EWerr':
                                ewerrstr = '122EWerr'
                            if qpqdata[ewstr][kk] != '/':
                                # find z
                                v0 = 0.5 * (
                                    qpqdata['v_lobound'][kk] +
                                    qpqdata['v_upbound'][kk]) * u.km / u.s
                                dv = v0
                                zref = igm_sys.zabs
                                z_cmp = ltu.z_from_dv(dv, zref)

                                ## vlim
                                v1 = qpqdata['v_lobound'][kk] * u.km / u.s
                                z1 = ltu.z_from_dv(v1, zref)
                                v1_cmp = ltu.dv_from_z(z1, z_cmp)

                                v2 = qpqdata['v_upbound'][kk] * u.km / u.s
                                z2 = ltu.z_from_dv(v2, zref)
                                v2_cmp = ltu.dv_from_z(z2, z_cmp)

                                # iline
                                iline = AbsLine(wave0 * u.AA,
                                                closest=True,
                                                z=z_cmp)
                                iline.attrib['coord'] = igm_sys.coord

                                ## EW
                                iline.attrib['EW'] = float(
                                    qpqdata[ewstr][kk]) * u.AA  # Rest EW
                                iline.attrib['sig_EW'] = float(
                                    qpqdata[ewerrstr][kk]) * u.AA
                                flgew = 1
                                if iline.attrib[
                                        'EW'] < 3. * iline.attrib['sig_EW']:
                                    flgew = 3
                                iline.attrib['flag_EW'] = flgew

                                ## column densities
                                colstr = str(
                                    lines[icmp][ii].split(' ')[0]) + 'col'
                                colerrstr = str(
                                    lines[icmp][ii].split(' ')[0]) + 'colerr'
                                iline.attrib['logN'] = qpqdata[colstr][kk]
                                iline.attrib['sig_logN'] = qpqdata[colerrstr][
                                    kk]

                                abslines.append(iline)

                        if len(abslines) > 0:
                            comp = AbsComponent.from_abslines(abslines,
                                                              chk_vel=False)
                            comp.limits._vlim = [v1_cmp.value, v2_cmp.value
                                                 ] * u.km / u.s
                            cgabs.igm_sys.add_component(comp)

                # add ang_sep
                qsocoord = SkyCoord(ra=qpqdatacoord['RAD'][j],
                                    dec=qpqdatacoord['DECD'][j],
                                    unit='deg')
                bgcoord = SkyCoord(ra=qpqdatacoord['RAD_BG'][j],
                                   dec=qpqdatacoord['DECD_BG'][j],
                                   unit='deg')
                cgabs.ang_sep = qsocoord.separation(bgcoord).to('arcsec')

                self.cgm_abs.append(cgabs)