示例#1
0
    def load_hotgas(self):
        """ Load data on hot gas (e.g. OVII, OVIII)
        Fang+15
        """
        from linetools.lists.linelist import LineList
        from linetools.analysis.absline import linear_clm

        llist = LineList('EUV',use_ISM_table=False)
        ovii = AbsLine('OVII 21', linelist=llist)

        # Fang+15  Table 1  [OVII]
        self.fang15 = Table.read(pyigm.__path__[0]+'/data/CGM/Galaxy/fang15_table1.dat', format='cds')
        print('Loading Fang+15 for OVII')
        # Reference
        if len(self.refs) > 0:
            self.refs += ','
        self.refs += 'Fang+15'
        # Generate the systems
        # # (should check to see if low-ion ones exist already)
        for row in self.fang15:
            # Coordinates
            gc = SkyCoord(l=row['GLON']*u.degree, b=row['GLAT']*u.degree, frame='galactic')
            # Limits
            # OVII line
            aline = ovii.copy()
            aline.attrib['coord'] = gc
            z = row['Vel']/c_kms
            try:
                aline.setz(z)
            except IOError:
                z = 0.
                vlim = np.array([-300,300]) * u.km/u.s
                aline.attrib['flag_EW'] = 3
                aline.attrib['flag_N'] = 0  # Might be able to set an upper limit
                aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA
                aline.attrib['sig_EW'] = 99. * u.AA
            else:
                aline.attrib['b'] = row['b'] * u.km / u.s
                aline.attrib['flag_EW'] = 1
                aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA
                aline.attrib['sig_EW'] = row['e_EW1'] / 1e3 * u.AA
                vlim = np.array([-1,1]) * (2 * row['b'] + 2 * row['E_b']) * u.km/u.s
                # N_OVII
                aline.attrib['flag_N'] = 1
                aline.attrib['logN'] = row['logNO']
                aline.attrib['sig_logN'] = np.array([row['e_logNO'], row['E_logNO']])
                # Fill linear
                _,_ = linear_clm(aline.attrib)
            # OVII
            aline.limits.set(vlim)
            # Generate component and add
            comp = AbsComponent.from_abslines([aline])
            comp.synthesize_colm()
            # Instantiate
            abssys = IGMSystem(gc, z, vlim, name=row['Name']+'_z0', zem=row['z'])
            abssys.add_component(comp, chk_sep=False)
            # CGM Abs
            cgmabs = CGMAbsSys(self.galaxy, abssys, Galactic=True)
            # Add to cgm_abs
            self.abs.cgm_abs.append(cgmabs)

        scoord = self.abs.scoord  # Sightline coordiantes
        # Savage+03  Table 2  [OVI] -- Thick disk/halo only??
        print('Loading Savage+03 for OVI')
        self.savage03 = Table.read(pyigm.__path__[0] + '/data/CGM/Galaxy/savage03_table2.fits')
        # Reference
        if len(self.refs) > 0:
            self.refs += ','
        self.refs += 'Savage+03'
        # Generate the systems
        # # (should check to see if low-ion ones exist already)
        for row in self.savage03:
            # Coordinates
            coord = SkyCoord(ra=row['_RA']*u.deg, dec=row['_DE']*u.deg, frame='fk5')
            gc = coord.transform_to('galactic')
            # Build the component
            vlim = np.array([row['V-'],row['V_']])*u.km/u.s
            comp = AbsComponent(gc, (8,6), 0., vlim)
            # Add attributes
            if row['b'] > 0.:
                comp.attrib['vcen'] = row['__v_obs']*u.km/u.s
                comp.attrib['sig_vcen'] = row['e__v_obs']*u.km/u.s
                comp.attrib['b'] = row['b']*u.km/u.s
                comp.attrib['sig_b'] = row['e_b']*u.km/u.s
                # Column
                comp.flag_N = 1
                comp.logN = row['logN_OVI_']
                comp.sig_logN = np.sqrt(row['e_sc']**2 + row['e_sys']**2)
            else: # Upper limit
                comp.flag_N = 3
                comp.logN = row['logN_OVI_']
                comp.sig_logN = 99.
            # Check for existing system
            minsep = np.min(comp.coord.separation(scoord).to('arcsec'))
            if minsep < 30*u.arcsec:
                idx = np.argmin(comp.coord.separation(scoord).to('arcsec'))
                self.abs.cgm_abs[idx].igm_sys.add_component(comp, chk_sep=False, debug=True)
            else:  # New
                if row['RV'] > 0:
                    zem = row['RV']/c_kms
                else:
                    zem = row['z']
                abssys = IGMSystem(gc, comp.zcomp, vlim, name=row['Name']+'_z0', zem=zem)
                abssys.add_component(comp, chk_sep=False, debug=True)
                # CGM Abs
                cgmabs = CGMAbsSys(self.galaxy, abssys, Galactic=True)
                # Add to cgm_abs
                self.abs.cgm_abs.append(cgmabs)
示例#2
0
文件: utils.py 项目: yzhenggit/pyigm
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
示例#3
0
文件: galaxy.py 项目: yzhenggit/pyigm
    def load_hotgas(self):
        """ Load data on hot gas (e.g. OVII, OVIII)
        Fang+15
        """

        # Init
        llist = LineList('EUV')
        ovii = AbsLine('OVII 21', linelist=llist)
        scoord = self.abs.scoord  # Sightline coordiantes

        # Fang+15  Table 1  [OVII]
        fang15_file = resource_filename('pyigm',
                                        '/data/CGM/Galaxy/fang15_table1.dat')
        self.fang15 = Table.read(fang15_file, format='cds')
        print('Loading Fang+15 for OVII')
        # Reference
        if len(self.refs) > 0:
            self.refs += ','
        self.refs += 'Fang+15'
        # Generate the systems
        # # (should check to see if low-ion ones exist already)
        for row in self.fang15:
            # Coordinates
            gc = SkyCoord(l=row['GLON'] * u.degree,
                          b=row['GLAT'] * u.degree,
                          frame='galactic')
            # Limits
            # OVII line
            aline = ovii.copy()
            aline.attrib['coord'] = gc
            z = row['Vel'] / c_kms
            try:
                aline.setz(z)
            except IOError:
                z = 0.
                vlim = np.array([-300, 300]) * u.km / u.s
                aline.attrib['flag_EW'] = 3
                aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA
                aline.attrib['sig_EW'] = 99. * u.AA
                #
                aline.attrib[
                    'flag_N'] = 0  # Might be able to set an upper limit
            else:
                aline.attrib['b'] = row['b'] * u.km / u.s
                aline.attrib['flag_EW'] = 1
                aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA
                aline.attrib['sig_EW'] = row['e_EW1'] / 1e3 * u.AA
                vlim = np.array(
                    [-1, 1]) * (2 * row['b'] + 2 * row['E_b']) * u.km / u.s
                # N_OVII
                aline.attrib['flag_N'] = 1
                aline.attrib['logN'] = row['logNO']
                aline.attrib['sig_logN'] = np.array(
                    [row['e_logNO'], row['E_logNO']])
                # Fill linear
                _, _ = linear_clm(aline.attrib)
            # OVII
            aline.limits.set(vlim)
            # Generate component and add
            comp = AbsComponent.from_abslines([aline])
            if aline.attrib['flag_N'] == 0:  # Hack to merge later
                comp.attrib['sig_logN'] = np.array([0., 0.])
            else:
                pass
            # Check for existing system
            minsep = np.min(comp.coord.separation(scoord).to('arcsec'))
            if minsep < 30 * u.arcsec:  # Add component to existing system
                idx = np.argmin(comp.coord.separation(scoord).to('arcsec'))
                if self.verbose:
                    print("Adding OVII system to {}".format(
                        self.abs.cgm_abs[idx].igm_sys))
                self.abs.cgm_abs[idx].igm_sys.add_component(comp,
                                                            chk_sep=False,
                                                            debug=True)
            else:  # Instantiate
                abssys = IGMSystem(gc,
                                   z,
                                   vlim,
                                   name=row['Name'] + '_z0',
                                   zem=row['z'])
                abssys.add_component(comp, chk_sep=False)
                # CGM Abs
                rho, ang_sep = calc_Galactic_rho(abssys.coord)
                cgmabs = CGMAbsSys(self.galaxy,
                                   abssys,
                                   rho=rho,
                                   ang_sep=ang_sep,
                                   cosmo=self.cosmo)
                # Add to cgm_abs
                self.abs.cgm_abs.append(cgmabs)

        scoord = self.abs.scoord  # Sightline coordiantes
        # Savage+03  Table 2  [OVI] -- Thick disk/halo only??
        print('Loading Savage+03 for OVI')
        savage03_file = resource_filename(
            'pyigm', '/data/CGM/Galaxy/savage03_table2.fits')
        self.savage03 = Table.read(savage03_file)
        # Reference
        if len(self.refs) > 0:
            self.refs += ','
        self.refs += 'Savage+03'
        # Generate the systems
        # # (should check to see if low-ion ones exist already)
        for row in self.savage03:
            # Coordinates
            coord = SkyCoord(ra=row['_RA'] * u.deg,
                             dec=row['_DE'] * u.deg,
                             frame='icrs')
            gc = coord.transform_to('galactic')
            # Build the component
            vlim = np.array([row['V-'], row['V_']]) * u.km / u.s
            comp = AbsComponent(gc, (8, 6), 0., vlim)
            # Add attributes
            if row['b'] > 0.:
                comp.attrib['vcen'] = row['__v_obs'] * u.km / u.s
                comp.attrib['sig_vcen'] = row['e__v_obs'] * u.km / u.s
                comp.attrib['b'] = row['b'] * u.km / u.s
                comp.attrib['sig_b'] = row['e_b'] * u.km / u.s
                # Column
                comp.attrib['flag_N'] = 1
                comp.attrib['logN'] = row['logN_OVI_']
                comp.attrib['sig_logN'] = np.array(
                    [np.sqrt(row['e_sc']**2 + row['e_sys']**2)] * 2)
            else:  # Upper limit
                comp.attrib['flag_N'] = 3
                comp.attrib['logN'] = row['logN_OVI_']
                comp.attrib['sig_logN'] = np.array([99.] * 2)
            # Set linear quantities
            _, _ = linear_clm(comp.attrib)
            # Check for existing system
            minsep = np.min(comp.coord.separation(scoord).to('arcsec'))
            if minsep < 30 * u.arcsec:
                idx = np.argmin(comp.coord.separation(scoord).to('arcsec'))
                self.abs.cgm_abs[idx].igm_sys.add_component(comp,
                                                            chk_sep=False,
                                                            debug=True,
                                                            update_vlim=True)
            else:  # New
                if row['RV'] > 0:
                    zem = row['RV'] / c_kms
                else:
                    zem = row['z']
                abssys = IGMSystem(gc,
                                   comp.zcomp,
                                   vlim,
                                   name=row['Name'] + '_z0',
                                   zem=zem)
                abssys.add_component(comp, chk_sep=False, debug=True)
                # CGM Abs
                rho, ang_sep = calc_Galactic_rho(abssys.coord)
                cgmabs = CGMAbsSys(self.galaxy,
                                   abssys,
                                   rho=rho,
                                   ang_sep=ang_sep,
                                   cosmo=self.cosmo)
                # Add to cgm_abs
                self.abs.cgm_abs.append(cgmabs)