Exemple #1
0
def test_all_transitions():
    error_msg = 'Something is wrong in all_transitions()'
    ism = LineList('ISM')
    #check simple case
    line = 'OVI'
    ovi_transitions = ism.all_transitions(line)
    assert len(ovi_transitions) == 2, error_msg
    #print(ovi_transitions['name'])
    #check unknown
    line = 'unknown'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    #check case of single transition ion
    line = 'CIII'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    #check case of transitions from excited levels
    line='FeII*'
    out = ism.all_transitions(line)
    assert len(out) == 27, "wrong line counts"
    print(out)
    # wrest
    out = ism.all_transitions(1215.6700*u.AA)
    assert len(out) == 30,"wrong line counts" # 30 Lyman series transitions
    #print('test_all_transitions() passed')
    h2 = LineList('H2')
    line = 'B19-0P(1)'
    out = h2.all_transitions(line)
    assert len(out) == 7
def test_unknown():
    ism = LineList('ISM')
    unknown = ism.unknown_line()
    assert unknown[
        'name'] == 'unknown', 'There is a problem in the LineList.unknown_line()'
    assert unknown[
        'wrest'] == 0. * u.AA, 'There is a problem in the LineList.unknown_line()'
Exemple #3
0
    def from_dict(cls, idict, **kwargs):
        """ Instantiate from a dict

        Parameters
        ----------
        idict : dict
          Required keys are:
           'RA' -- float (deg)
           'DEC' -- float(deg)
           'zem' -- float
           'name' -- str
           'components' -- list
         Other keys are added as attributes to the IgmSightline object

        Returns
        -------

        """
        if 'linelist' not in kwargs.keys():
            from linetools.lists.linelist import LineList
            ism = LineList('ISM')
            kwargs['linelist'] = ism
        from pyigm.abssys.utils import class_by_type
        ism = LineList('ISM')
        kwargs['linelist'] = ism
        # Load ISM to speed things up
        if 'meta' in idict.keys():
            meta = idict['meta']
        else:
            meta = idict
        # Components -- backwards compatability
        if 'cmps' in idict.keys():
            idict['components'] = idict['cmps'].copy()
        # Instantiate
        slf = cls(SkyCoord(ra=meta['RA'], dec=meta['DEC'], unit='deg'),
                  zem=meta['zem'],
                  name=meta['JNAME'],
                  **kwargs)
        # Other
        for key in idict.keys():
            if key in [
                    'RA', 'DEC', 'zem', 'name', 'components', 'meta', 'cmps'
            ]:
                continue
            else:
                setattr(slf, key, idict[key])
        add_comps_from_dict(slf, idict, **kwargs)

        # Systems
        if 'systems' in idict.keys():
            for key in idict['systems'].keys():
                asys = class_by_type(
                    idict['systems'][key]['abs_type']).from_dict(
                        idict['systems'][key], **kwargs)
                slf._abssystems.append(asys)
        # Return
        return slf
def test_subset():
    ism = LineList('ISM')
    subset = np.array([1215.6700, 1608.4511])*u.AA
    ism = ism.subset_lines(subset)
    assert len(ism._data) == 2
    np.testing.assert_allclose(ism['FeII 1608']['wrest'], 1608.4511*u.AA, rtol=1e-7)

    # Now with names
    ism = LineList('ISM')
    subset = ['HI 1215', 'HI 1025', 'CIV 1548']
    ism = ism.subset_lines(subset)
    np.testing.assert_allclose(ism['HI 1215']['wrest'], 1215.6700*u.AA, rtol=1e-7)
Exemple #5
0
def set_llist(llist, in_dict=None, sort=True):
    """ Method to set a line list dict for the Widgets

    Parameters
    ----------
    sort : bool, optional
      Sort lines by rest wavelength
    """
    from linetools.lists.linelist import LineList
    from astropy.units.quantity import Quantity

    if in_dict is None:
        in_dict = dict(Lists=[])

    if isinstance(llist,basestring): # Set line list from a file
        in_dict['List'] = llist
        in_dict['Lists'].append(llist)
        if llist == 'None':
            in_dict['Plot'] = False
        else:
            in_dict['Plot'] = True
            # Load?
            if not (llist in in_dict):
                # Homebrew
                if llist == 'OVI':
                    gdlines = u.AA*[629.730, 702.332, 770.409, 780.324, 787.711, 832.927, 972.5367, 977.0201,
                        1025.7222, 1031.9261, 1037.6167, 1206.5, 1215.6700, 1260.4221]
                    llist_cls = LineList('Strong')
                    llist_cls = llist_cls.subset_lines(gdlines)

                    in_dict[llist] = llist_cls
                else:
                    llist_cls = LineList(llist)
                    # Sort
                    llist_cls._data.sort('wrest')
                    # Load
                    in_dict[llist] = llist_cls
    elif isinstance(llist, (Quantity, list)): # Set from a list of wrest
        in_dict['List'] = 'input.lst'
        in_dict['Lists'].append('input.lst')
        in_dict['Plot'] = True
        # Fill
        if sort:
            llist.sort()
        llist_cls = LineList('ISM')
        llist_cls = llist_cls.subset_lines(llist)
        in_dict['input.lst'] = llist_cls
    else:
        raise IOError('Not ready for this type of input')

    # Return
    return in_dict
Exemple #6
0
    def fill_data(self, trans, linelist=None, closest=False, verbose=True):
        """ Fill atomic data and setup analy.

        Parameters
        ----------
        trans : Quantity or str
          Either a rest wavelength (e.g. 1215.6700*u.AA) or the name
          of a transition (e.g. 'CIV 1548'). For an unknown transition
          use string 'unknown'.
        linelist : LineList, optional
          Class of linelist or str setting LineList
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        """

        # Deal with LineList
        if linelist is None:
            llist = LineList('ISM')
        elif isinstance(linelist,basestring):
            llist = LineList(linelist)
        elif isinstance(linelist,LineList):
            llist = linelist
        else:
            raise ValueError('Bad input for linelist')

        # Closest?
        llist.closest = closest

        # Data
        newline = llist[trans]
        try:
            self.data.update(newline)  # Expected to be a LineList dict object
        except TypeError:
            pdb.set_trace()


        # Update
        self.wrest = self.data['wrest']
        self.name = self.data['name']

        #
        self.analy.update( {
            'flg_eye': 0,
            'flg_limit': 0, # No limit
            'datafile': '', 
            'name': self.data['name']
            })

        # Additional fundamental attributes for Absorption Line
        self.attrib.update(abs_attrib.copy())
Exemple #7
0
 def init_lines(self):
     '''Fill up the component lines
     '''
     if self.linelist is None:
         self.linelist = LineList('Strong')
     # Get the lines
     #QtCore.pyqtRemoveInputHook()
     #xdb.set_trace()
     #QtCore.pyqtRestoreInputHook()
     all_trans = self.linelist.all_transitions(self.init_wrest)
     for trans in all_trans:
         self.lines.append(AbsLine(trans['wrest'], linelist=self.linelist))
     # Sync
     self.sync_lines()
def test_all_transitions():
    error_msg = 'Something is wrong in all_transitions()'
    ism = LineList('ISM')
    #check simple case
    line = 'OVI'
    ovi_transitions = ism.all_transitions(line)
    assert len(ovi_transitions) == 2, error_msg
    #print(ovi_transitions['name'])
    #check unknown
    line = 'unknown'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    #check case of single transition ion
    line = 'CIII'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    #check case of transitions from excited levels
    line='FeII*'
    out = ism.all_transitions(line)
    assert len(out) == 27, "wrong line counts"
    print(out)
    # wrest
    out = ism.all_transitions(1215.6700*u.AA)
    assert len(out) == 30,"wrong line counts" # 30 Lyman series transitions
    #print('test_all_transitions() passed')
    h2 = LineList('H2')
    line = 'B19-0P(1)'
    out = h2.all_transitions(line)
    assert len(out) == 7
Exemple #9
0
def measure_sodium_EW(filename):
    from linetools.lists.linelist import LineList
    from astropy import units as u
    from linetools.spectralline import AbsLine
    from linetools.spectra.xspectrum1d import XSpectrum1D
    import matplotlib.pyplot as plt

    sp = XSpectrum1D.from_file('RF_' + filename)
    sp.normalize(co=sp.co)

    wvlim = [5880, 6030] * u.AA
    strong = LineList('Strong')
    transitions = strong.available_transitions(wvlim,
                                               n_max_tuple=None,
                                               min_strength=0.0)
    line1 = transitions['wrest'][0]
    line2 = transitions['wrest'][1]
    avg_line = (line1 + line2) / 2.0

    # Plot the spectrum to get limits for EW
    fig = plt.figure()
    plt.axvline(x=line1, color='k', linestyle='--')
    plt.axhline(y=1.0, color='r', linestyle='--')
    plt.axvline(x=line2, color='k', linestyle='--')
    sp.plot(xlim=(avg_line - 30, avg_line + 30))

    S1 = AbsLine(transitions['wrest'][0] * u.AA, z=0.0)
    S1.analy['spec'] = sp
    S2 = AbsLine(transitions['wrest'][1] * u.AA, z=0.0)
    S2.analy['spec'] = sp

    #x = float(input("Enter a lower lim: "))
    #y = float(input("Enter a higher lim: "))

    x = 5888
    y = 5896

    S1.limits.set([x, y] * u.AA)
    S1.measure_ew(flg=1)  # Measure the EW of the first line
    EW1 = S1.attrib['EW'], S1.attrib['sig_EW']

    #x = float(input("Enter a lower lim: "))
    #y = float(input("Enter a higher lim: "))

    x = 5895
    y = 5905
    S2.limits.set([x, y] * u.AA)
    S2.measure_ew()  # Measure the EW of the second line
    EW2 = S2.attrib['EW'], S2.attrib['sig_EW']
    return EW1, EW2
Exemple #10
0
    def fill_data(self, trans, linelist=None, closest=False, verbose=True):
        """ Fill atomic data and setup analy.

        Parameters
        ----------
        trans : Quantity or str
          Either a rest wavelength (e.g. 1215.6700*u.AA) or the name
          of a transition (e.g. 'CIV 1548'). For an unknown transition
          use string 'unknown'.
        linelist : LineList, optional
          Class of linelist or str setting LineList
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        """

        # Deal with LineList
        if linelist is None:
            if self.ltype == 'Abs':
                llist = LineList('ISM')
            elif self.ltype == 'Em':
                llist = LineList('Galaxy')
            else:
                raise ValueError("Not ready for ltype = {:s}".format(self.ltype))
        elif isinstance(linelist,basestring):
            llist = LineList(linelist)
        elif isinstance(linelist,LineList):
            llist = linelist
        else:
            raise ValueError('Bad input for linelist')

        # Closest?
        llist.closest = closest

        # Data
        newline = llist[trans]
        if newline is None:
            raise ValueError("Transition {} not found in LineList {:s}".format(trans, llist.list))
        try:
            self.data.update(newline)  # Expected to be a LineList dict object
        except TypeError:
            raise TypeError("Probably should not be here")


        # Update
        self.wrest = self.data['wrest']
        self.name = self.data['name']

        #
        self.update()  # is this used ?
Exemple #11
0
    def fill_data(self, trans, linelist=None, closest=False):
        """ Fill atomic data and setup analy.

        Parameters
        ----------
        trans : Quantity or str
          Either a rest wavelength (e.g. 1215.6700*u.AA) or the name
          of a transition (e.g. 'CIV 1548'). For an unknown transition
          use string 'unknown'.
        linelist : LineList, optional
          Class of linelist or str setting LineList
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        """

        # Deal with LineList
        if linelist is None:
            llist = LineList('ISM')
        elif isinstance(linelist,basestring):
            llist = LineList(linelist)
        elif isinstance(linelist,LineList):
            llist = linelist
        else:
            raise ValueError('Bad input for linelist')

        # Closest?
        llist.closest = closest

        # Data
        newline = llist[trans]
        self.data.update(newline)

        # Update
        self.wrest = self.data['wrest']
        self.trans = self.data['name']

        #
        self.analy.update( {
            'flg_eye': 0,
            'flg_limit': 0, # No limit
            'datafile': '', 
            'name': self.data['name']
            })

        # Additional attributes for Absorption Line
        self.attrib.update({'N': 0., 'Nsig': 0., 'flagN': 0, # Column
                       'b': 0.*u.km/u.s, 'bsig': 0.*u.km/u.s  # Doppler
                       } )
Exemple #12
0
    def read_ion_file(self,ion_fil,zabs=0.,RA=0.*u.deg, Dec=0.*u.deg):
        """Read in JXP-style .ion file in an appropriate manner

        NOTE: If program breaks in this function, check the all file 
        to see if it is properly formatted.
        """
        # Read
        names=('wrest', 'clm', 'sig_clm', 'flg_clm', 'flg_inst') 
        table = ascii.read(ion_fil, format='no_header', names=names) 

        if self.linelist is None:
            self.linelist = LineList('ISM')

        # Generate AbsLine's
        for row in table:
            # Generate the line
            aline = AbsLine(row['wrest']*u.AA, linelist=self.linelist, closest=True)
            # Set z, RA, DEC, etc.
            aline.attrib['z'] = self.zabs
            aline.attrib['RA'] = self.coord.ra
            aline.attrib['Dec'] = self.coord.dec
            # Check against existing lines
            mt = [kk for kk,oline in enumerate(self.lines) if oline.ismatch(aline)]
            if len(mt) > 0:
                mt.reverse()
                for imt in mt:
                    print('read_ion_file: Removing line {:g}'.format(self.lines[imt].wrest))
                    self.lines.pop(imt)
            # Append
            self.lines.append(aline)
Exemple #13
0
def test_euv():
    euv = LineList('EUV')
    #
    assert np.max(euv._data['wrest']) < 1000.
    # Test for X-ray lines
    ovii = euv['OVII 21']
    assert np.isclose(ovii['wrest'].value, 21.6019)
Exemple #14
0
def _write_ref_ISM_table():
    """ Write a reference table enabling faster I/O for ISM-related lists

    For developer use only.

    Note that after running this, you need to manually copy the table
    produced to linetools/data/lines/ISM_table.fits inside the github
    repository, and then check it in.
    """
    from linetools.lists.linelist import LineList

    ism = LineList('ISM', use_ISM_table=False)
    strong = LineList('Strong', use_ISM_table=False)
    euv = LineList('EUV', use_ISM_table=False)
    hi = LineList('HI', use_ISM_table=False)

    # need a Table to write
    tab = ism._data.copy()
    tab.sort(('wrest'))

    # Using np.in1d doesn't work for some reason. Do it the long way
    cond = []
    for table in (strong, euv, hi):
        igood = []
        for row in Table(table._data):
            ind = tab['wrest'].searchsorted(row['wrest'])
            dw = abs(tab['wrest'][ind] - row['wrest'])
            if abs(tab['wrest'][ind + 1] - row['wrest']) < dw:
                ind = ind + 1
            rism = tab[ind]
            # check this is the right row.
            if all(row[k] == rism[k] for k in hi._data.colnames
                   if not hasattr(row[k], 'mask') or not row[k].mask):
                igood.append(ind)
            else:
                raise RuntimeError('No match found!')

        cond.append(np.zeros(len(tab), dtype=bool))
        cond[-1][np.array(igood)] = True

    col1 = Column(cond[0], name='is_Strong')
    col2 = Column(cond[1], name='is_EUV')
    col3 = Column(cond[2], name='is_HI')
    tab.add_columns([col1, col2, col3])

    tab.write('ISM_table.fits', overwrite=True)
def test_molecules():
    h2 = LineList('H2')
    #
    for kk, name in enumerate(h2.name):
        lyi = AbsLine(name, linelist=h2)
    # gamma values
    h2_B3_0R0 = AbsLine('B3-0R(0)', linelist=h2)
    assert h2_B3_0R0.data['gamma'].value > 0.
Exemple #16
0
def test_sortdata():
    error_msg = 'Something is wrong in sortdata()'
    ism = LineList('ISM', sort_by='name')
    assert ism.name[0] == 'AlII 1670', error_msg
    ism.sortdata('name', reverse=True)
    assert ism.name[0] == 'ZrIII 1798', error_msg
    ism.sortdata(['abundance', 'rel_strength'], reverse=True)
    assert ism.name[0] == 'HI 1215', error_msg
    ism.sortdata(['rel_strength'])
    assert ism.name[0] == 'CI** 1123b', error_msg
Exemple #17
0
def test_available_transitions():
    error_msg = 'Something is wrong in available_transitions()'
    ism = LineList('ISM')
    wvlims = (900,1800)*u.AA
    z = 0.1

    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=5)
    assert transitions[2]['name'] == 'HI 972' , error_msg
    assert isinstance(transitions,Table), error_msg

    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert transitions[2]['name'] == 'CIII 977' , error_msg

    wvlims = (1200,1800)*u.AA
    z = 0.5
    transitions = ism.available_transitions(wvlims/(1+z), n_max_tuple=2)
    assert transitions[0]['name'] == 'HI 1025', error_msg 
    assert 'OVI 1031' in transitions['name'], error_msg 
    assert 'CIII 977' in transitions['name'], error_msg

    wvlims = (1000,3000)*u.AA
    z = 1.5
    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert 'NeVIII 770' in transitions['name'], error_msg
    assert 'MgX 609' in transitions['name'], error_msg
    assert 'HI 1215' not in transitions['name'], error_msg

    wvlims = (1215.6,1217)*u.AA
    z = 0
    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert isinstance(transitions,dict), error_msg
def test_mk_absline():
    # Init HI Lya
    abslin = AbsLine(1215.6700 * u.AA)
    np.testing.assert_allclose(abslin.data['f'], 0.4164)

    # Init CII 1334 with LineList
    abslin2 = AbsLine(1334.5323 * u.AA, linelist='Strong', use_CACHE=True)
    np.testing.assert_allclose(abslin2.data['Ek'], 74932.62 / u.cm)

    # Init CII 1334 with multiple linelists
    ism = LineList('ISM')
    H2 = LineList('H2')
    abslin2b = AbsLine(1334.5323 * u.AA, linelist=[H2, ism])
    np.testing.assert_allclose(abslin2.data['Ek'], 74932.62 / u.cm)

    # Init CII 1334 by name
    abslin3 = AbsLine('CII 1334')
    np.testing.assert_allclose(abslin3.data['wrest'], 1334.5323 * u.AA)
    def load_sys(self, tfile=None, empty=True, debug=False, **kwargs):
        """ Load the COS-Halos survey from JSON files

        Empties the list

        Parameters
        ----------
        tfile : str, optional
        empty : bool, optional
          Empty the list
        debug : bool, optional
          Only load the first 5

        Returns
        -------

        """
        import tarfile
        import json
        from linetools.lists.linelist import LineList
        llist = LineList('ISM')

        # Tar file
        if tfile is None:
            tarfiles = glob.glob(self.cdir + 'cos-halos_systems.v*.tar.gz')
            tarfiles.sort()
            tfile = tarfiles[-1]
        print("Be patient, using {:s} to load".format(tfile))
        # Empty
        if empty:
            self.cgm_abs = []
        # Load
        tar = tarfile.open(tfile)
        for kk, member in enumerate(tar.getmembers()):
            if '.' not in member.name:
                print('Skipping a likely folder: {:s}'.format(member.name))
                continue
            # Debug
            if debug and (kk == 5):
                break
            # Extract
            f = tar.extractfile(member)
            tdict = json.load(f)
            # Generate
            cgmsys = CGMAbsSys.from_dict(tdict,
                                         chk_vel=False,
                                         chk_sep=False,
                                         chk_data=False,
                                         use_coord=True,
                                         use_angrho=True,
                                         linelist=llist,
                                         **kwargs)
            self.cgm_abs.append(cgmsys)
        tar.close()
        # Werk+14
        if ('Halos' in self.fits_path) and (self.werk14_cldy is not None):
            self.load_werk14()
def test_agn():
    agn = LineList('AGN')
    #
    np.testing.assert_allclose(agn["Halpha"]['wrest'],
                               6564.613 * u.AA,
                               rtol=1e-5)
    np.testing.assert_allclose(agn["NV 1242"]['wrest'],
                               1242.804 * u.AA,
                               rtol=1e-5)
Exemple #21
0
class Component(AbsComponent):
    def __init__(self, z, wrest, vlim=[-300.,300]*u.km/u.s,
        linelist=None):

        # Init
        self.init_wrest = wrest
        self.linelist = linelist
        self.lines = []
        self.init_lines()

        # Generate with type
        radec = (0*u.deg,0*u.deg)
        Zion = (self.lines[0].data['Z'],self.lines[0].data['ion'])
        Ej = self.lines[0].data['Ej']
        AbsComponent.__init__(self,radec, Zion, z, vlim, Ej, comment='None')

        # Init cont.
        self.attrib = {'N': 0./u.cm**2, 'Nsig': 0./u.cm**2, 'flagN': 0, # Column
                       'logN': 0., 'sig_logN': 0.,
                       'b': 0.*u.km/u.s, 'bsig': 0.*u.km/u.s,  # Doppler
                       'z': self.zcomp, 'zsig': 0.,
                       'Quality': 'None'}

        # Sync
        self.sync_lines()

        # Use different naming convention here
        self.name = 'z{:.5f}_{:s}'.format(
            self.zcomp,self.lines[0].data['name'].split(' ')[0])



    def init_lines(self):
        '''Fill up the component lines
        '''
        if self.linelist is None:
            self.linelist = LineList('Strong')
        # Get the lines
        all_trans = self.linelist.all_transitions(self.init_wrest)
        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()
        if isinstance(all_trans,dict):
            all_trans = [all_trans]
        for trans in all_trans:
            self.lines.append(AbsLine(trans['wrest'],
                linelist=self.linelist))


    def sync_lines(self):
        '''Synchronize attributes of the lines
        '''
        for line in self.lines:
            line.attrib['logN'] = self.attrib['logN']
            line.attrib['b'] = self.attrib['b']
            line.attrib['z'] = self.attrib['z']
def test_Wr_from_N_and_N_from_Wr():
    hi_list = LineList('HI')
    lya = hi_list['HI 1215']
    N = 10**np.linspace(12.0, 12.3, 4) / (u.cm * u.cm)
    # test array like
    Wr = Wr_from_N(N, lya['wrest'], lya['f'])
    Wr_test = [0.00544783, 0.00685842, 0.00863423, 0.01086986] * u.AA
    np.testing.assert_allclose(Wr, Wr_test, rtol=1e-5)
    N_new = N_from_Wr(Wr, lya['wrest'], lya['f'])
    np.testing.assert_allclose(N_new, N, rtol=1e-5)
def test_all_transitions():
    error_msg = 'Something is wrong in all_transitions()'
    ism = LineList('ISM')
    #check simple case
    line = 'OVI'
    ovi_transitions = ism.all_transitions(line)
    assert len(ovi_transitions) == 2, error_msg
    #print(ovi_transitions['name'])
    #check unknown
    line = 'unknown'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    #check case of single transition ion
    line = 'CIII'
    out = ism.all_transitions(line)
    assert type(out) == dict, error_msg
    # wrest
    out = ism.all_transitions(1215.6700*u.AA)
    assert len(out) == 30 # 30 Lyman series transitions
def test_strongest_transitions():
    error_msg = 'Something is wrong in strongest_transitions()'
    ism = LineList('ISM')
    wvlims = (1200,1800)*u.AA
    z = 0.5
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert len(transitions) == 5,  error_msg
    assert transitions[0]['name'] == 'HI 1025' , error_msg
    assert isinstance(transitions,QTable), error_msg

    wvlims = (1500,1700)*u.AA
    z = 0.5
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert isinstance(transitions,dict), error_msg #only Lyb should be available, so dict is expected
    assert transitions['name'] == 'HI 1025'

    wvlims = (1100,1200)*u.AA
    z = 0.0
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert transitions is None, error_msg
Exemple #25
0
def test_strongest_transitions():
    error_msg = 'Something is wrong in strongest_transitions()'
    ism = LineList('ISM')
    wvlims = (1200,1800)*u.AA
    z = 0.5
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert len(transitions) == 5,  error_msg
    assert transitions[0]['name'] == 'HI 1025' , error_msg
    assert isinstance(transitions,Table), error_msg

    wvlims = (1500,1700)*u.AA
    z = 0.5
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert isinstance(transitions,dict), error_msg #only Lyb should be available, so dict is expected
    assert transitions['name'] == 'HI 1025'

    wvlims = (1100,1200)*u.AA
    z = 0.0
    transitions = ism.strongest_transitions('HI',wvlims/(1+z),n_max=5)
    assert transitions is None, error_msg
def test_sortdata():
    error_msg = 'Something is wrong in sortdata()'
    ism = LineList('ISM', sort_by='name')
    assert ism.name[0] == 'AlII 1670', error_msg
    ism.sortdata('name', reverse=True)
    assert ism.name[0] == 'ZrIII 1798', error_msg
    ism.sortdata(['abundance', 'rel_strength'], reverse=True)
    assert ism.name[0] == 'HI 1215', error_msg
    ism.sortdata(['rel_strength'])
    assert ism.name[0] == 'CI** 1123b', error_msg
Exemple #27
0
def main(args=None):
    pargs = parser(options=args)
    if pargs.inp is None and pargs.all is False:
        print("No option selected.  Use -h for Help")
        return
    # Setup
    from astropy import units as u
    from astropy.table import Column
    from linetools.lists.linelist import LineList
    from linetools.abund import ions as ltai
    import numpy as np
    if pargs.llist in ['CO']:
        cols = ['mol', 'label', 'wrest', 'f']
    elif pargs.llist in ['H2']:
        cols = ['mol', 'name', 'wrest', 'f']
    else:
        cols = ['name', 'wrest', 'f', 'A']
    # LineList
    llist = LineList(pargs.llist)
    # Redshift?
    if float(pargs.redshift) != 0.:
        z = llist._data['wrest']*(1+float(pargs.redshift))
        llist._data.add_column(Column(z, name='z'))
        cols += ['z']
    # All?
    if pargs.all:
        try:
            llist._data[cols].pprint(99999)
        except ValueError:
            pdb.set_trace()
        return
    # Grab line(s)
    if ustr(pargs.inp[0]).isdecimal():  # Input rest wavelength
        wrest = float(pargs.inp)*u.AA
        mtch = np.abs(wrest-llist.wrest) < pargs.toler*u.AA
        llist._data[cols][mtch].pprint(99999)
    else:  # Either ion or transition
        istrans = False
        for jj,char in enumerate(pargs.inp):
            if char.isdigit():
                istrans = True
                i0 = jj
                break
        if istrans:
            trans = pargs.inp[0:i0]+' '+pargs.inp[i0:]
            tdict = llist[trans]
            for key,value in tdict.items():
                if key in cols:
                    print('{:s}: {}'.format(key,value))
        else:  # Ion
            Zion = ltai.name_ion(pargs.inp)
            mtion = (llist.Z == Zion[0]) & (llist.ion == Zion[1])
            llist._data[cols][mtion].pprint(99999)
def test_available_transitions():
    error_msg = 'Something is wrong in available_transitions()'
    ism = LineList('ISM')
    wvlims = (900,1800)*u.AA
    z = 0.1

    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=5)
    assert transitions[2]['name'] == 'HI 972' , error_msg
    assert isinstance(transitions,QTable), error_msg

    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert transitions[2]['name'] == 'CIII 977' , error_msg

    wvlims = (1200,1800)*u.AA
    z = 0.5
    transitions = ism.available_transitions(wvlims/(1+z), n_max_tuple=2)
    assert transitions[0]['name'] == 'HI 1025', error_msg 
    assert 'OVI 1031' in transitions['name'], error_msg 
    assert 'CIII 977' in transitions['name'], error_msg

    wvlims = (1000,3000)*u.AA
    z = 1.5
    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert 'NeVIII 770' in transitions['name'], error_msg
    assert 'MgX 609' in transitions['name'], error_msg
    assert 'HI 1215' not in transitions['name'], error_msg

    wvlims = (1215.6,1217)*u.AA
    z = 0
    transitions = ism.available_transitions(wvlims/(1+z),n_max_tuple=2)
    assert isinstance(transitions,dict), error_msg
Exemple #29
0
def set_llist(llist, in_dict=None, sort_by='wrest'):
    """ Method to set a line list dict for the Widgets

    Parameters
    ----------
    sort_by : str or list of str, optional
        Key(s)to sort the lines by. Default is 'wrest'.
        If sort_by='as_given', it preserves the order
        as given by llist.
    """
    from linetools.lists.linelist import LineList
    from astropy.units.quantity import Quantity

    if in_dict is None:
        in_dict = dict(Lists=[])

    if isinstance(llist,basestring): # Set line list from a file
        in_dict['List'] = llist
        in_dict['Lists'].append(llist)
        if llist == 'None':
            in_dict['Plot'] = False
        else:
            in_dict['Plot'] = True
            # Load?
            if not (llist in in_dict):
                # Homebrew
                if llist == 'OVI':
                    gdlines = u.AA*[629.730, 702.332, 770.409, 780.324, 787.711, 832.927, 972.5367, 977.0201,
                        1025.7222, 1031.9261, 1037.6167, 1206.5, 1215.6700, 1260.4221]
                    llist_cls = LineList('Strong', sort_by=sort_by)
                    llist_cls = llist_cls.subset_lines(gdlines, sort_by='as_given')

                    in_dict[llist] = llist_cls
                else:
                    llist_cls = LineList(llist, sort_by=sort_by)
                    # Load
                    in_dict[llist] = llist_cls
    elif isinstance(llist, (Quantity, list)): # Set from a list of wrest
        in_dict['List'] = 'input.lst'
        in_dict['Lists'].append('input.lst')
        in_dict['Plot'] = True
        # Fill
        llist_cls = LineList('ISM', sort_by=sort_by)
        llist_cls = llist_cls.subset_lines(llist, sort_by=sort_by)
        in_dict['input.lst'] = llist_cls
    else:
        raise IOError('Not ready for this type of input')

    # Return
    return in_dict
Exemple #30
0
    def get_ions(self, idict=None, closest=False):
        """Parse the ions for each Subsystem
        And put them together for the full system
        Fills .ions with a Ions_Clm Class

        Parameters:
        -----------
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        idict : dict, optional
          dict containing the IonClms info
        """
        if idict is not None:
            # Not setup for SubSystems
            self._ionclms = IonClms(idict=idict)
        else:
            # Subsystems
            if self.nsub > 0:  # This speeds things up (but is rarely used)
                if self.linelist is None:
                    self.linelist = LineList('ISM')
            lbls = map(chr, range(65, 91))
            for ii in range(self.nsub):
                clm_fil = self.tree + self.subsys[lbls[ii]].clm_file
                # Parse .clm and .all files
                self.subsys[lbls[ii]].clm_analy = Ionic_Clm_File(clm_fil)
                ion_fil = self.tree + self.subsys[lbls[ii]].clm_analy.ion_fil
                all_fil = ion_fil.split('.ion')[0] + '.all'
                self.all_fil = all_fil  #MF: useful to have
                self.subsys[lbls[ii]]._ionclms = IonClms(all_fil)
                # Linelist (for speed)
                if self.subsys[lbls[ii]].linelist is None:
                    self.subsys[lbls[ii]].linelist = self.linelist
                self.subsys[lbls[ii]].linelist.closest = closest
                # Parse .ion file
                self.subsys[lbls[ii]].read_ion_file(ion_fil)

            # Combine
            if self.nsub == 1:
                self._ionclms = self.subsys['A']._ionclms
                self.clm_analy = self.subsys['A'].clm_analy
                self.lines = self.subsys['A'].lines
                #xdb.set_trace()
            elif self.nsub == 0:
                raise ValueError(
                    'lls_utils.get_ions: Cannot have 0 subsystems..')
            else:
                self._ionclms = self.subsys['A']._ionclms
                self.clm_analy = self.subsys['A'].clm_analy
                self.lines = self.subsys['A'].lines
                print(
                    'lls_utils.get_ions: Need to update multiple subsystems!! Taking A.'
                )
Exemple #31
0
def plotspec(args):
    """Plot spectrum files
    """
    from linetools.spectra.io import readspec
    import warnings
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    warnings.simplefilter('ignore', mpl.mplDeprecation)

    plt.rcParams['axes.formatter.useoffset'] = False  # avoid scientific notation in axes tick labels

    spec_cache = {}

    fig = plt.figure(figsize=(10,5))
    fig.subplots_adjust(left=0.07, right=0.95, bottom=0.11)
    ax = fig.add_subplot(111)
    i = 0
    quit = False
    print("#### Use left and right arrow keys to navigate, 'Q' to quit ####")

    while quit is False:
        filename = args.filenames[i]
        if filename not in spec_cache:
            spec_cache[filename] = readspec(filename)
        sp = spec_cache[filename]
        ax.cla()
        sp.plot(show=False)
        ax.set_xlabel(str(sp.wavelength.unit))
        ax.set_title(filename)
        if args.redshift is not None:
            from linetools.lists.linelist import LineList
            ll = LineList('Strong')
            #import pdb ;pdb.set_trace()
            wlines = ll._data['wrest'] * (1 + args.redshift)
            y0, y1 = ax.get_ylim()
            ax.vlines(wlines.to(sp.wavelength.unit).value, y0, y1,
                      linestyle='dotted')

        while True:
            plt.waitforbuttonpress()
            if sp._plotter.last_keypress == 'right':
                i += 1
                i = min(i, len(args.filenames) - 1)
                # Note this only breaks out of the inner while loop
                break
            elif sp._plotter.last_keypress == 'left':
                i -= 1
                i = max(i, 0)
                break
            elif sp._plotter.last_keypress == 'Q':
                quit = True
                break
def test_set_extra_columns_to_datatable():
    # bad calls
    #ism = LineList('ISM')
    #with pytest.raises(ValueError) as tmp:  # This is failing Python 2.7 for reasons unbenknownst to me
    #    ism.set_extra_columns_to_datatable(abundance_type='incorrect_one')
    #ism = LineList('ISM')
    #with pytest.raises(ValueError):
    #    ism.set_extra_columns_to_datatable(ion_correction='incorrect_one', redo=True)
    # test expected strongest value
    ism = LineList('ISM')
    #np.testing.assert_allclose(ism['HI 1215']['rel_strength'], 14.704326420257642)  # THIS IS NO LONGER SUPPORTED
    tab = ism._extra_table
    np.testing.assert_allclose(np.max(tab['rel_strength']), 14.704326420257642)
def test_Wr_from_N_b():
    hi_list = LineList('HI')
    lya = hi_list['HI 1215']
    N = 10**np.linspace(12.0, 22.0, 4) / (u.cm * u.cm)
    b = np.ones_like(N.value) * 10 * u.km / u.s
    # test array like
    Wr = Wr_from_N_b(N, b, lya['wrest'], lya['f'], lya['gamma'])
    Wr_test = [5.30565005e-03, 1.92538448e-01, 1.60381902e+00, 7.31826938e+01
               ] * u.AA
    np.testing.assert_allclose(Wr, Wr_test, rtol=1e-5)
    # test float like input for logN
    Wr = Wr_from_N_b(N[0], b[0], lya['wrest'], lya['f'], lya['gamma'])
    np.testing.assert_allclose(Wr, Wr_test[0], rtol=1e-5)
Exemple #34
0
    def linetools_linelist(self):
        '''Handler for a linetools LineList class.
        '''

        if not hasattr(self, '_linetools_linelist'):

            # Only doing the import here so rest of the class doesn't
            # break if the feature isn't enabled.
            from linetools.lists.linelist import LineList

            self._linetools_linelist = LineList('ISM')

        return self._linetools_linelist
Exemple #35
0
def main(*args, **kwargs):
    """ Runs the XAbsSysGui on input files
    """
    import argparse

    parser = argparse.ArgumentParser(description='Parse for XAbsSys')
    parser.add_argument("spec_file", type=str, help="Spectral file")
    parser.add_argument("abssys_file", type=str, help="AbsSys file (JSON)")
    parser.add_argument("-outfile", type=str, help="Output filename")
    parser.add_argument("-llist", type=str, help="Name of LineList")
    #parser.add_argument("-exten", type=int, help="FITS extension")
    parser.add_argument("--un_norm",
                        help="Spectrum is NOT normalized",
                        action="store_true")

    pargs = parser.parse_args()

    from PyQt5.QtWidgets import QApplication
    from linetools.guis.xabssysgui import XAbsSysGui

    # Normalized?
    norm = True
    if pargs.un_norm:
        norm = False

    # Extension
    #exten = (pargs.exten if hasattr(pargs, 'exten') else 0)

    # Read spec keywords
    rsp_kwargs = {}

    # Line list
    if pargs.llist is not None:
        from linetools.lists.linelist import LineList
        llist = LineList(pargs.llist)
    else:
        llist = None

    # Read AbsSystem
    from linetools.isgm.abssystem import GenericAbsSystem
    abs_sys = GenericAbsSystem.from_json(pargs.abssys_file)  #, chk_vel=False)

    app = QApplication(sys.argv)

    gui = XAbsSysGui(pargs.spec_file,
                     abs_sys,
                     norm=norm,
                     llist=llist,
                     outfil=pargs.outfile)
    gui.show()
    app.exec_()
Exemple #36
0
def cgmsurvey_from_sightlines_fields(fields,
                                     sightlines,
                                     rho_max=300 * u.kpc,
                                     name=None,
                                     dummysys=True,
                                     embuffer=None,
                                     **kwargs):
    """Instantiate CGMAbsSurvey object from lists fo IgmGalaxyFields and IGMSightlines

    Parameters
    ----------
    fields: list of IgmGalaxyFields
    sightlines : list of IGMSightlines
    name : str, optional
        Name for the survey
    dummysys : bool, optional
        Passed on to 'cgm_from_galaxy_igmsystems()'.  If True, create CGMAbsSys
        even if no matching IGMSystem is found in any sightline for some galaxy
    embuffer : Quantity, optional
        Velocity buffer between background source (e.g., QSO) and CGMAbsSys

     Returns
    -------
    cgmsurvey: CGMAbsSurvey
    """
    if ((not isinstance(fields, list)) | (not isinstance(sightlines, list)) |
        (len(fields) != len(sightlines))):
        raise IOError(
            "Inputs fields and sightlines must lists of the same length")

    if dummysys is True:
        from linetools.spectralline import AbsLine
        ismlist = LineList('ISM')

    from pyigm.cgm.cgmsurvey import CGMAbsSurvey
    cgmsys = []
    for i, ff in enumerate(fields):
        print(ff.name)
        thiscgmlist = cgmabssys_from_sightline_field(ff,
                                                     sightlines[i],
                                                     rho_max=rho_max,
                                                     dummysys=dummysys,
                                                     linelist=ismlist,
                                                     embuffer=embuffer,
                                                     **kwargs)
        cgmsys.extend(thiscgmlist)
    if name is not None:
        cgmsurvey = CGMAbsSurvey.from_cgmabssys(cgmsys, survey=name)
    else:
        cgmsurvey = CGMAbsSurvey.from_cgmabssys(cgmsys)
    return cgmsurvey
Exemple #37
0
    def fill_data(self, trans, linelist=None, closest=False, verbose=True):
        """ Fill atomic data and setup analy.

        Parameters
        ----------
        trans : Quantity or str
          Either a rest wavelength (e.g. 1215.6700*u.AA) or the name
          of a transition (e.g. 'CIV 1548'). For an unknown transition
          use string 'unknown'.
        linelist : LineList, optional
          Class of linelist or str setting LineList
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        """

        # Deal with LineList
        if linelist is None:
            if self.ltype == 'Abs':
                llist = LineList('ISM')
            elif self.ltype == 'Em':
                llist = LineList('Galaxy')
            else:
                raise ValueError("Not ready for ltype = {:s}".format(
                    self.ltype))
        elif isinstance(linelist, basestring):
            llist = LineList(linelist)
        elif isinstance(linelist, LineList):
            llist = linelist
        else:
            raise ValueError('Bad input for linelist')

        # Closest?
        llist.closest = closest

        # Data
        newline = llist[trans]
        if newline is None:
            raise ValueError("Transition {} not found in LineList {:s}".format(
                trans, llist.list))
        try:
            self.data.update(newline)  # Expected to be a LineList dict object
        except TypeError:
            raise TypeError("Probably should not be here")

        # Update
        if isinstance(self.data, dict):
            self.wrest = self.data['wrest']
        else:
            self.wrest = self.data['wrest'] * self.data['wrest'].unit
        self.name = self.data['name']

        #
        self.update()  # is this used ?
def generate_line_list_file(ions = []):
    out = open('pyigm_line_list.txt', 'w')
    out.write('#Ion\tWavelength [A]\tgamma\t\tf_value\t\talt. name\n')

    llist = LineList('ISM')
    for ion in ions:
        ion_data = llist.all_transitions(ion.replace(" ", ""))
        print(ion)
        wls      = ion_data['wrest']
        gammas   = ion_data['gamma']
        fvals    = ion_data['f']
        altnames = ion_data['name']
        if wls.size == 1:
            sys.stdout.flush()
            wls      = [wls.value]
            gammas    = [gammas.value]
            fvals    = [fvals]
            altnames = [altnames]
        for wl, gamma, fval, altname in zip(wls, gammas, fvals, altnames):
            out.write("%s\t%0.6f\t%e\t%e\t%s\n"\
                          %(ion, wl, gamma, fval, altname))
            
    out.close()
Exemple #39
0
    def __init__(self,
                 spec,
                 z,
                 wrest,
                 parent=None,
                 vmnx=[-300., 300.] * u.km / u.s,
                 norm=True,
                 linelist=None):
        '''
        spec = Spectrum1D
        '''
        super(AODMWidget, self).__init__(parent)

        # Initialize
        self.spec = spec
        self.norm = norm
        self.z = z
        self.vmnx = vmnx
        self.wrest = wrest  # Expecting (requires) units
        self.lines = []
        if linelist is None:
            self.linelist = LineList('ISM')
        for iwrest in self.wrest:
            self.lines.append(AbsLine(iwrest, linelist=self.linelist))

        self.psdict = {}  # Dict for spectra plotting
        self.psdict[
            'x_minmax'] = self.vmnx.value  # Too painful to use units here
        self.psdict['y_minmax'] = [-0.1, 1.1]
        self.psdict['nav'] = ltgu.navigate(0, 0, init=True)

        # Create the mpl Figure and FigCanvas objects.
        #
        self.dpi = 150
        self.fig = Figure((8.0, 4.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)

        self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas.setFocus()
        self.canvas.mpl_connect('key_press_event', self.on_key)
        self.canvas.mpl_connect('button_press_event', self.on_click)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.canvas)

        self.setLayout(vbox)

        # Draw on init
        self.on_draw()
Exemple #40
0
class Component(object):
    def __init__(self,
                 z,
                 wrest,
                 vlim=[-300., 300] * u.km / u.s,
                 linelist=None):
        # Init
        self.init_wrest = wrest
        self.zcomp = z
        self.vlim = vlim
        self.attrib = {
            'N': 0.,
            'Nsig': 0.,
            'flagN': 0,  # Column
            'b': 0. * u.km / u.s,
            'bsig': 0. * u.km / u.s,  # Doppler
            'z': self.zcomp,
            'zsig': 0.
        }
        #
        self.linelist = linelist
        self.lines = []
        self.init_lines()
        #
        self.name = 'z{:.5f}_{:s}'.format(
            self.zcomp, self.lines[0].data['name'].split(' ')[0])
        #
    def init_lines(self):
        '''Fill up the component lines
        '''
        if self.linelist is None:
            self.linelist = LineList('Strong')
        # Get the lines
        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()
        all_trans = self.linelist.all_transitions(self.init_wrest)
        for trans in all_trans:
            self.lines.append(AbsLine(trans['wrest'], linelist=self.linelist))
        # Sync
        self.sync_lines()

    def sync_lines(self):
        '''Synchronize attributes of the lines
        '''
        for line in self.lines:
            line.attrib['N'] = self.attrib['N']
            line.attrib['b'] = self.attrib['b']
            line.attrib['z'] = self.attrib['z']
Exemple #41
0
 def init_lines(self):
     '''Fill up the component lines
     '''
     if self.linelist is None:
         self.linelist = LineList('Strong')
     # Get the lines
     #QtCore.pyqtRemoveInputHook()
     #xdb.set_trace()
     #QtCore.pyqtRestoreInputHook()
     all_trans = self.linelist.all_transitions(self.init_wrest)
     for trans in all_trans:
         self.lines.append(AbsLine(trans['wrest'],
             linelist=self.linelist))
     # Sync
     self.sync_lines()
Exemple #42
0
 def init_lines(self):
     '''Fill up the component lines
     '''
     if self.linelist is None:
         self.linelist = LineList('Strong')
     # Get the lines
     all_trans = self.linelist.all_transitions(self.init_wrest)
     #QtCore.pyqtRemoveInputHook()
     #xdb.set_trace()
     #QtCore.pyqtRestoreInputHook()
     if isinstance(all_trans,dict):
         all_trans = [all_trans]
     for trans in all_trans:
         self.lines.append(AbsLine(trans['wrest'],
             linelist=self.linelist))
Exemple #43
0
def Wr_from_N_b_transition(N, b, transition, llist='ISM'):
    """ For a given transition this function looks
    for the atomic parameters (wa0, fosc, gamma) and returns the
    rest-frame equivalent width for a given N and b. It uses the approximation given by
    Draine 2011 book (eq. 9.27), which comes from atomic physics considerations
    See also Rodgers & Williams 1974 (NT: could not find the reference
    given by Draine)

    Parameters
    ----------
    N : Quantity or Quantity array
        Column density
    b : Quantity or Quantity array of same shape as N
        Doppler parameter
    transition : str
        Name of the transition using linetools' naming
        convention, e.g. 'HI 1215'.
    llist : str
        Name of the linetools.lists.linelist.LineList
        object where to look for the transition name.
        Default is 'ISM', which means the function looks
        within `list = LineList('ISM')`.

    Returns
    -------
    Wr : Quantity
        Rest-frame equivalent width

    Notes
    -----
    See also Wr_from_N_b()

    """
    linelist = LineList(llist)
    transition_dict = linelist[transition]
    if transition_dict is None:
        raise ValueError(
            'Transition {:s} not found within LineList {:s}'.format(
                transition, linelist.list))
    else:
        # get atomic parameters
        wrest = transition_dict['wrest']
        fosc = transition_dict['f']
        gamma = transition_dict['gamma']

    # return
    return Wr_from_N_b(N, b, wrest, fosc, gamma)
Exemple #44
0
class Component(object):
    def __init__(self, z, wrest, vlim=[-300.,300]*u.km/u.s,
        linelist=None):
        # Init
        self.init_wrest = wrest
        self.zcomp = z
        self.vlim = vlim
        self.attrib = {'N': 0., 'Nsig': 0., 'flagN': 0, # Column
                       'b': 0.*u.km/u.s, 'bsig': 0.*u.km/u.s,  # Doppler
                       'z': self.zcomp, 'zsig': 0.,
                       'Quality': 'None'}
        self.comment = 'None'
        #
        self.linelist = linelist
        self.lines = []
        self.init_lines()
        #
        self.name = 'z{:.5f}_{:s}'.format(
            self.zcomp,self.lines[0].data['name'].split(' ')[0])
        #
    def init_lines(self):
        '''Fill up the component lines
        '''
        if self.linelist is None:
            self.linelist = LineList('Strong')
        # Get the lines

        all_trans = self.linelist.all_transitions(self.init_wrest)
        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()
        if isinstance(all_trans,dict):
            all_trans = [all_trans]
        for trans in all_trans:
            self.lines.append(AbsLine(trans['wrest'],
                linelist=self.linelist))

        # Sync
        self.sync_lines()

    def sync_lines(self):
        '''Synchronize attributes of the lines
        '''
        for line in self.lines:
            line.attrib['N'] = self.attrib['N']
            line.attrib['b'] = self.attrib['b']
            line.attrib['z'] = self.attrib['z']
def test_set_extra_columns_to_datatable():
    ism = LineList('ISM')
    # bad calls
    try:
        ism.set_extra_columns_to_datatable(abundance_type='incorrect_one')
    except ValueError:
        pass
    try:
        ism.set_extra_columns_to_datatable(ion_correction='incorrect_one')
    except ValueError:
        pass
    # test expected strongest value
    ism.set_extra_columns_to_datatable(ion_correction='none', abundance_type='solar')
    np.testing.assert_allclose(ism['HI 1215']['rel_strength'], 14.704326420257642)
    tab = ism._data

    np.testing.assert_allclose(np.max(tab['rel_strength']), 14.704326420257642)
Exemple #46
0
    def add_abslines_from_linelist(self, llist='ISM', wvlim=None, min_Wr=None, **kwargs):
        """
        It adds associated AbsLines satisfying some conditions (see parameters below).

        Parameters
        ----------
        llist : str
            Name of the linetools.lists.linelist.LineList
            object where to look for the transition names.
            Default is 'ISM', which means the function looks
            within `list = LineList('ISM')`.
        wvlims : Quantity array, optional
            Observed wavelength limits for AbsLines to be added.
            e.g. [1200, 2000]*u.AA.
        min_Wr : Quantity, optional
            Minimum rest-frame equivalent with for AbsLines to be added.
            This is calculated in the very low optical depth regime tau0<<1,
            where Wr is independent of Doppler parameter or gamma (see eq. 9.15 of
            Draine 2011). Still, a column density attribute for the AbsComponent
            is needed.

        Returns
        -------
        Adds AbsLine objects to the AbsComponent._abslines list.

        Notes
        -----
        **kwargs are passed to AbsLine.add_absline() method.

        """
        # get the transitions from LineList
        llist = LineList(llist)
        name = ions.ion_name(self.Zion, nspace=0)
        transitions = llist.all_transitions(name)
        # unify output to be always QTable
        if isinstance(transitions, dict):
            transitions = llist.from_dict_to_qtable(transitions)

        # check wvlims
        if wvlim is not None:
            cond = (transitions['wrest']*(1+self.zcomp) >= wvlim[0]) & \
                   (transitions['wrest']*(1+self.zcomp) <= wvlim[1])
            transitions = transitions[cond]

        # check outputs
        if len(transitions) == 0:
            warnings.warn("No transitions satisfying the criteria found. Doing nothing.")
            return

        # loop over the transitions when more than one found
        for transition in transitions:
            iline = AbsLine(transition['name'], z=self.zcomp)
            iline.limits.set(self.vlim)
            iline.attrib['coord'] = self.coord
            iline.attrib['logN'] = self.logN
            iline.attrib['sig_logN'] = self.sig_logN
            iline.attrib['flag_N'] = self.flag_N
            iline.attrib['N'] = 10**iline.attrib['logN'] / (u.cm * u.cm)
            iline.attrib['sig_N'] = 10**iline.attrib['sig_logN'] / (u.cm * u.cm)

            for key in self.attrib.keys():
                iline.attrib[key] = self.attrib[key]

            if min_Wr is not None:
                # check logN is defined
                logN = self.logN
                if logN == 0:
                    warnings.warn("AbsComponent does not have logN defined. Appending AbsLines "
                                 "regardless of min_Wr.")
                else:
                    N = 10**logN / (u.cm*u.cm)
                    Wr_iline = iline.get_Wr_from_N(N=N)  # valid for the tau0<<1 regime.
                    if Wr_iline < min_Wr:  # do not append
                        continue
            # add the absline
            self.add_absline(iline)
Exemple #47
0
def test_unknown():
	ism = LineList('ISM')
	unknown = ism.unknown_line()
	assert unknown['name'] == 'unknown', 'There is a problem in the LineList.unknown_line()'
	assert unknown['wrest'] == 0.*u.AA, 'There is a problem in the LineList.unknown_line()'
	print(ism['unknown'])
Exemple #48
0
    def add_abslines_from_linelist(self, llist='ISM', init_name=None, wvlim=None, min_Wr=None, **kwargs):
        """
        It adds associated AbsLines satisfying some conditions (see parameters below).

        Parameters
        ----------
        llist : str, optional
            Name of the linetools.lists.linelist.LineList
            object where to look for the transition names.
            Default is 'ISM', which means the function looks
            within `list = LineList('ISM')`.
        init_name : str, optional
            Name of the initial transition used to define the AbsComponent
        wvlim : Quantity array, optional
            Observed wavelength limits for AbsLines to be added.
            e.g. [1200, 2000]*u.AA.
        min_Wr : Quantity, optional
            Minimum rest-frame equivalent with for AbsLines to be added.
            This is calculated in the very low optical depth regime tau0<<1,
            where Wr is independent of Doppler parameter or gamma (see eq. 9.15 of
            Draine 2011). Still, a column density attribute for the AbsComponent
            is needed.

        Returns
        -------
        Adds AbsLine objects to the AbsComponent._abslines list.

        Notes
        -----
        **kwargs are passed to AbsLine.add_absline() method.

        """
        from linetools.lists import utils as ltlu

        # get the transitions from LineList
        llist = LineList(llist)
        if init_name is None:  # we have to guess it
            if (self.Zion) == (-1, -1):  # molecules
                # init_name must be in self.attrib (this is a patch)
                init_name = self.attrib['init_name']
            else:  # atoms
                init_name = ions.ion_to_name(self.Zion, nspace=0)
        transitions = llist.all_transitions(init_name)

        # unify output to be a Table
        if isinstance(transitions, dict):
            transitions = ltlu.from_dict_to_table(transitions)

        # check wvlims
        if wvlim is not None:
            # Deal with units
            wrest = transitions['wrest'].data * transitions['wrest'].unit
            # Logic
            cond = (wrest*(1+self.zcomp) >= wvlim[0]) & \
                   (wrest*(1+self.zcomp) <= wvlim[1])
            transitions = transitions[cond]

        # check outputs
        if len(transitions) == 0:
            warnings.warn("No transitions satisfying the criteria found. Doing nothing.")
            return

        # loop over the transitions when more than one found
        for transition in transitions:
            iline = AbsLine(transition['name'], z=self.zcomp, linelist=llist)
            iline.limits.set(self.vlim)
            iline.attrib['coord'] = self.coord
            iline.attrib['logN'] = self.logN
            iline.attrib['sig_logN'] = self.sig_logN
            iline.attrib['flag_N'] = self.flag_N
            iline.attrib['N'] = 10**iline.attrib['logN'] / (u.cm * u.cm)
            iline.attrib['sig_N'] = 10**iline.attrib['sig_logN'] / (u.cm * u.cm)

            for key in self.attrib.keys():
                iline.attrib[key] = self.attrib[key]

            if min_Wr is not None:
                # check logN is defined
                if self.logN == 0:
                    pass
                else:
                    N = 10.**self.logN / u.cm**2
                    Wr_iline = iline.get_Wr_from_N(N=N)  # valid for the tau0<<1 regime.
                    if Wr_iline < min_Wr:  # do not append
                        continue
            # add the absline
            self.add_absline(iline)
def test_closest():
    ism = LineList('ISM')
    ism.closest=True
    # 
    line = ism[1250.584*u.AA]
    np.testing.assert_allclose(line['wrest'], 1250.578*u.AA, rtol=1e-7)
Exemple #50
0
    def fill_data(self, trans, linelist=None, closest=False, verbose=True,
                  use_CACHE=False, **kwargs):
        """ Fill atomic data and setup analy.

        Parameters
        ----------
        trans : Quantity or str
          Either a rest wavelength (e.g. 1215.6700*u.AA) or the name
          of a transition (e.g. 'CIV 1548'). For an unknown transition
          use string 'unknown'.
        linelist : str or LineList or list of LineList objects, optional
          Class of linelist or str setting LineList
          or list of LineList objects
        closest : bool, optional
          Take the closest line to input wavelength? [False]
        """
        global CACHE_LLIST   # Only cached if LineList is *not* input
        # Deal with LineList
        flg_list = False
        if linelist is None:
            if use_CACHE and (CACHE_LLIST is not None):
                llist = CACHE_LLIST
            else:
                if self.ltype == 'Abs':
                    llist = LineList('ISM')
                elif self.ltype == 'Em':
                    llist = LineList('Galaxy')
                else:
                    raise ValueError("Not ready for ltype = {:s}".format(self.ltype))
        elif isinstance(linelist,basestring):
            llist = LineList(linelist)
        elif isinstance(linelist,LineList):
            llist = linelist
        elif isinstance(linelist,list):
            llist = linelist[0]
            flg_list = True
        else:
            raise ValueError('Bad input for linelist')

        # Cache
        CACHE_LLIST = llist
        # Closest?
        llist.closest = closest

        # Data
        if flg_list:  # Allow for a list of LineList
            for llist in linelist:
                llist.closest = closest
                newline = llist[trans]
                if newline is not None:
                    break
        else:
            newline = llist[trans]

        # Success?
        if newline is None:
            print("Transition {} not found in LineList {:s}".format(trans, llist.list))
            raise ValueError("You may need to set clear_CACHE_LLIST=True")
        try:
            self.data.update(newline)  # Expected to be a LineList dict object
        except TypeError:
            raise TypeError("Probably should not be here")


        # Update
        if isinstance(self.data, dict):
            self.wrest = self.data['wrest']
        else:
            self.wrest = self.data['wrest']*self.data['wrest'].unit
        self.name = self.data['name']

        #
        self.update()  # is this used ?